Skip to main content

Apify Data Source Plugin

The Apify plugin imports items from Apify datasets and actor runs into Ever Works works. It implements both the data source interface (to query items) and the form schema provider interface (to add configuration fields to the generation form).

Source: packages/plugins/apify/src/apify.plugin.ts

Overview

PropertyValue
Plugin IDapify
Categorydata-source
Capabilitiesdata-source, form-schema-provider
Version1.0.0
Built-inNo
System pluginNo
Auto-enableNo

Unlike system plugins, the Apify plugin must be explicitly installed and enabled by users. It implements two interfaces: IDataSourcePlugin for querying items and IFormSchemaProvider for injecting fields into the work generation form.

Architecture

Three-Level Configuration

The plugin uses a three-level configuration approach:

LevelWhereWhat
Level 1Settings > PluginsAPI token (admin or user scope)
Level 2Work plugin settingsEnable/disable per work
Level 3Generation formDataset ID, actor run ID, max items, relevance filter

Configuration

Settings Schema (Level 1)

SettingTypeRequiredScopeDescription
apiTokenstringYesuserApify API token (marked as secret)
defaultFieldMappingobjectNo--Default mapping from Apify fields to item fields

Default Field Mapping

The field mapping controls how Apify dataset fields are transformed into Ever Works ItemData properties:

ItemData FieldDefault Apify FieldDescription
nametitleItem display name
descriptiondescriptionItem description text
source_urlurlOriginal source URL
categorycategoryCategory classification
image_urlimageImage URL (mapped to images[] array)

Generation Form Fields (Level 3)

The plugin injects these fields into the generation form via IFormSchemaProvider:

Field NameTypeDefaultDescription
apify_datasetIdtext(empty)Apify dataset ID to import from
apify_actorRunIdtext(empty)Import from a specific actor run instead
apify_maxItemsnumber100Maximum items to import (0 = no limit)
apify_filterByRelevancebooleantrueOnly import items relevant to the work prompt

These fields are grouped under a collapsible "Apify" section:

getFormGroups(): FormFieldGroup[] {
return [{
name: 'apify',
title: 'Apify',
description: 'Import items from Apify datasets',
collapsible: true,
collapsed: true,
order: 100
}];
}

The order: 100 places the Apify section after the default pipeline fields in the form.

Data Source Query Flow

API URL Construction

The plugin constructs different API URLs depending on whether a dataset ID or actor run ID is provided:

SourceAPI Endpoint
Datasethttps://api.apify.com/v2/datasets/{datasetId}/items
Actor runhttps://api.apify.com/v2/actor-runs/{actorRunId}/dataset/items

The API token and item limit are passed as query parameters.

Field Mapping

The mapToItemData() method transforms each Apify item using the configured field mapping:

private mapToItemData(item: Record<string, unknown>, mapping: FieldMapping): Partial<ItemData> {
const name = getValue('name') || String(item.title || item.name || 'Untitled');
return {
name,
slug: this.generateSlug(name),
description: getValue('description') || '',
source_url: getValue('source_url') || '',
category: getValue('category'),
images: imageUrl ? [imageUrl] : undefined
};
}

Slugs are auto-generated from the item name: lowercased, non-alphanumeric characters replaced with hyphens, truncated to 100 characters.

Relevance Filtering

When filterByRelevance is enabled and a filterContext is provided, the plugin filters items by keyword matching:

  1. Keywords are extracted from the work's prompt, subject, and explicit keywords using extractKeywords() from @ever-works/plugin/keywords.
  2. Each item's name and description are checked against the keyword set.
  3. Items containing at least one keyword are kept; others are removed.

Form Validation

The validateFormInput() method ensures that either a dataset ID or actor run ID is provided when the plugin is enabled:

validateFormInput(values: Record<string, unknown>): ValidationResult {
if (!datasetId && !actorRunId) {
return {
valid: false,
errors: [{
path: 'apify_datasetId',
message: 'Either Dataset ID or Actor Run ID is required'
}]
};
}
return { valid: true };
}

Form Value Transformation

Before form values are passed to the pipeline, transformFormValues() nests the Apify-prefixed fields under an apify key:

transformFormValues(values) {
return {
...values,
apify: {
datasetId: values['apify_datasetId'],
actorRunId: values['apify_actorRunId'],
maxItems: values['apify_maxItems'] ?? 100,
filterByRelevance: values['apify_filterByRelevance'] ?? true
}
};
}

Getting Started

  1. Create an Apify account at apify.com.
  2. Run an actor or prepare a dataset with the items you want to import.
  3. Enable the Apify plugin in Settings > Plugins and enter your API token.
  4. When creating a work, expand the Apify section in the generation form and provide your dataset ID.
  5. Optionally enable relevance filtering to import only items related to your work topic.

Troubleshooting

IssueCauseSolution
Empty import resultsInvalid dataset ID or empty datasetVerify the dataset ID in the Apify console
"Apify API token not configured"No API token setEnter your token in plugin settings
"Apify API error: 401"Invalid API tokenRegenerate the token in Apify Settings > Integrations
Irrelevant items importedRelevance filter disabled or keywords too broadEnable filtering and refine the work prompt
Missing fields in imported itemsField mapping does not match dataset structureUpdate the default field mapping in plugin settings