Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
feat(tools): added apify
  • Loading branch information
waleedlatif1 committed Nov 30, 2025
commit a721ae101715a9e0be8e55a238b2e5a84e40f721
847 changes: 126 additions & 721 deletions apps/docs/components/icons.tsx

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions apps/docs/components/ui/icon-mapping.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import type { ComponentType, SVGProps } from 'react'
import {
AirtableIcon,
ApifyIcon,
ApolloIcon,
ArxivIcon,
AsanaIcon,
Expand Down Expand Up @@ -187,5 +188,6 @@ export const blockTypeToIconMap: Record<string, IconComponent> = {
asana: AsanaIcon,
arxiv: ArxivIcon,
apollo: ApolloIcon,
apify: ApifyIcon,
airtable: AirtableIcon,
}
69 changes: 69 additions & 0 deletions apps/docs/content/docs/en/tools/apify.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
---
title: Apify
description: Run Apify actors and retrieve results
---

import { BlockInfoCard } from "@/components/ui/block-info-card"

<BlockInfoCard
type="apify"
color="#E0E0E0"
/>

## Usage Instructions

Integrate Apify into your workflow. Run any Apify actor with custom input and retrieve results. Supports both synchronous and asynchronous execution with automatic dataset fetching.



## Tools

### `apify_run_actor_sync`

#### Input

| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |

#### Output

| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `success` | boolean | Whether the actor run succeeded |
| `runId` | string | Apify run ID |
| `status` | string | Run status \(SUCCEEDED, FAILED, etc.\) |
| `datasetId` | string | Dataset ID containing results |
| `items` | json | Dataset items \(if completed\) |

### `apify_run_actor_async`

Run an APIFY actor asynchronously with polling for long-running tasks

#### Input

| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `apiKey` | string | Yes | APIFY API token from console.apify.com/account#/integrations |
| `actorId` | string | Yes | Actor ID or username/actor-name \(e.g., "janedoe/my-actor" or actor ID\) |
| `input` | string | No | Actor input as JSON string |
| `waitForFinish` | number | No | Initial wait time in seconds \(0-60\) before polling starts |
| `itemLimit` | number | No | Max dataset items to fetch \(1-250000, default 100\) |
| `timeout` | number | No | Timeout in seconds \(default: actor default\) |
| `build` | string | No | Actor build to run \(e.g., "latest", "beta", or build tag/number\) |

#### Output

| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `success` | boolean | Whether the actor run succeeded |
| `runId` | string | APIFY run ID |
| `status` | string | Run status \(SUCCEEDED, FAILED, etc.\) |
| `datasetId` | string | Dataset ID containing results |
| `items` | array | Dataset items \(if completed\) |



## Notes

- Category: `tools`
- Type: `apify`
1 change: 1 addition & 0 deletions apps/docs/content/docs/en/tools/meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"pages": [
"index",
"airtable",
"apify",
"apollo",
"arxiv",
"asana",
Expand Down
42 changes: 42 additions & 0 deletions apps/sim/app/api/tools/apify/actors/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { type NextRequest, NextResponse } from 'next/server'

export async function GET(request: NextRequest) {
const apiKey = request.nextUrl.searchParams.get('apiKey')

if (!apiKey) {
return NextResponse.json({ error: 'apiKey required' }, { status: 400 })
}

try {
const response = await fetch('https://api.apify.com/v2/acts?my=1&limit=100', {
headers: {
Authorization: `Bearer ${apiKey}`,
},
})

if (!response.ok) {
const errorData = await response.json().catch(() => ({}))
return NextResponse.json(
{ error: errorData.error?.message || 'Failed to fetch actors' },
{ status: response.status }
)
}

const data = await response.json()

// Format for dropdown: { label, value }
const actors = data.data.items.map((actor: any) => ({
id: actor.id,
name: actor.name,
username: actor.username,
label: `${actor.username}/${actor.name}`,
value: actor.id,
description: actor.description,
}))

return NextResponse.json({ actors })
} catch (error) {
console.error('Error fetching APIFY actors:', error)
return NextResponse.json({ error: 'Internal server error' }, { status: 500 })
}
}
142 changes: 142 additions & 0 deletions apps/sim/blocks/blocks/apify.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
import { ApifyIcon } from '@/components/icons'
import type { BlockConfig } from '@/blocks/types'
import type { RunActorResult } from '@/tools/apify/types'

export const ApifyBlock: BlockConfig<RunActorResult> = {
type: 'apify',
name: 'Apify',
description: 'Run Apify actors and retrieve results',
longDescription:
'Integrate Apify into your workflow. Run any Apify actor with custom input and retrieve results. Supports both synchronous and asynchronous execution with automatic dataset fetching.',
docsLink: 'https://docs.sim.ai/tools/apify',
category: 'tools',
bgColor: '#E0E0E0',
icon: ApifyIcon,

subBlocks: [
{
id: 'operation',
title: 'Operation',
type: 'dropdown',
options: [
{ label: 'Run Actor', id: 'apify_run_actor_sync' },
{ label: 'Run Actor (Async)', id: 'apify_run_actor_async' },
],
value: () => 'apify_run_actor_sync',
},
{
id: 'apiKey',
title: 'Apify API Token',
type: 'short-input',
password: true,
placeholder: 'Enter your Apify API token',
required: true,
},
{
id: 'actorId',
title: 'Actor ID',
type: 'short-input',
placeholder: 'e.g., janedoe/my-actor or actor ID',
required: true,
},
{
id: 'input',
title: 'Actor Input',
type: 'code',
language: 'json',
placeholder: '{\n "startUrl": "https://example.com",\n "maxPages": 10\n}',
required: false,
},
{
id: 'timeout',
title: 'Timeout',
type: 'short-input',
placeholder: 'Actor timeout in seconds',
required: false,
},
{
id: 'build',
title: 'Build',
type: 'short-input',
placeholder: 'Actor build (e.g., "latest", "beta", or build tag)',
required: false,
},
{
id: 'waitForFinish',
title: 'Wait For Finish',
type: 'short-input',
placeholder: 'Initial wait time in seconds (0-60)',
required: false,
condition: {
field: 'operation',
value: 'apify_run_actor_async',
},
},
{
id: 'itemLimit',
title: 'Item Limit',
type: 'short-input',
placeholder: 'Max dataset items to fetch (1-250000)',
required: false,
condition: {
field: 'operation',
value: 'apify_run_actor_async',
},
},
],

tools: {
access: ['apify_run_actor_sync', 'apify_run_actor_async'],
config: {
tool: (params) => params.operation,
params: (params: Record<string, any>) => {
const { operation, ...rest } = params
const result: Record<string, any> = {
apiKey: rest.apiKey,
actorId: rest.actorId,
}

if (rest.input) {
result.input = rest.input
}

if (rest.timeout) {
result.timeout = Number(rest.timeout)
}

if (rest.build) {
result.build = rest.build
}

if (rest.waitForFinish) {
result.waitForFinish = Number(rest.waitForFinish)
}

if (rest.itemLimit) {
result.itemLimit = Number(rest.itemLimit)
}

return result
},
},
},

inputs: {
operation: { type: 'string', description: 'Operation to perform' },
apiKey: { type: 'string', description: 'Apify API token' },
actorId: { type: 'string', description: 'Actor ID or username/actor-name' },
input: { type: 'string', description: 'Actor input as JSON string' },
timeout: { type: 'number', description: 'Timeout in seconds' },
build: { type: 'string', description: 'Actor build version' },
waitForFinish: { type: 'number', description: 'Initial wait time in seconds' },
itemLimit: { type: 'number', description: 'Max dataset items to fetch' },
},

outputs: {
success: { type: 'boolean', description: 'Whether the actor run succeeded' },
runId: { type: 'string', description: 'Apify run ID' },
status: { type: 'string', description: 'Run status (SUCCEEDED, FAILED, etc.)' },
datasetId: { type: 'string', description: 'Dataset ID containing results' },
items: { type: 'json', description: 'Dataset items (if completed)' },
},
}
2 changes: 2 additions & 0 deletions apps/sim/blocks/registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { AgentBlock } from '@/blocks/blocks/agent'
import { AirtableBlock } from '@/blocks/blocks/airtable'
import { ApiBlock } from '@/blocks/blocks/api'
import { ApiTriggerBlock } from '@/blocks/blocks/api_trigger'
import { ApifyBlock } from '@/blocks/blocks/apify'
import { ApolloBlock } from '@/blocks/blocks/apollo'
import { ArxivBlock } from '@/blocks/blocks/arxiv'
import { AsanaBlock } from '@/blocks/blocks/asana'
Expand Down Expand Up @@ -119,6 +120,7 @@ import type { BlockConfig } from '@/blocks/types'
export const registry: Record<string, BlockConfig> = {
agent: AgentBlock,
airtable: AirtableBlock,
apify: ApifyBlock,
apollo: ApolloBlock,
api: ApiBlock,
arxiv: ArxivBlock,
Expand Down
Loading