diff --git a/nodes/AgenticscraperDescription.ts b/nodes/AgenticscraperDescription.ts new file mode 100644 index 0000000..04c073c --- /dev/null +++ b/nodes/AgenticscraperDescription.ts @@ -0,0 +1,127 @@ +import type { INodeProperties } from 'n8n-workflow'; + +export const agenticscraperOperations: INodeProperties[] = [ + { + displayName: 'Operation', + name: 'operation', + type: 'options', + noDataExpression: true, + displayOptions: { + show: { + resource: ['agenticscraper'], + }, + }, + options: [ + { + name: 'Automate', + value: 'automate', + action: 'AI-powered browser automation with custom steps • 15 credits per request', + description: 'AI-powered browser automation with custom steps • 15 credits per request', + }, + ], + default: 'automate', + }, +]; + +export const agenticscraperFields: INodeProperties[] = [ + { + displayName: 'URL', + name: 'url', + type: 'string', + required: true, + default: '', + description: 'URL of the website to interact with', + displayOptions: { + show: { + resource: ['agenticscraper'], + operation: ['automate'], + }, + }, + }, + { + displayName: 'Use Session', + name: 'useSession', + type: 'boolean', + default: true, + description: 'Whether to maintain session state across interactions (persistent browser session)', + displayOptions: { + show: { + resource: ['agenticscraper'], + operation: ['automate'], + }, + }, + }, + { + displayName: 'Steps', + name: 'steps', + type: 'collection', + typeOptions: { + multipleValues: true, + }, + default: [ + { + step: '', + }, + ], + description: 'List of automation steps to perform on the website', + displayOptions: { + show: { + resource: ['agenticscraper'], + operation: ['automate'], + }, + }, + options: [ + { + displayName: 'Step', + name: 'step', + type: 'string', + default: '', + required: true, + description: 'Automation step description (e.g., "Type email@gmail.com in email input box", "click on login button")', + placeholder: 'Type email@gmail.com in email input box', + }, + ], + }, + { + displayName: 'AI Extraction', + name: 'aiExtraction', + type: 'boolean', + default: false, + description: 'Whether to use AI for structured data extraction instead of returning markdown', + displayOptions: { + show: { + resource: ['agenticscraper'], + operation: ['automate'], + }, + }, + }, + { + displayName: 'User Prompt', + name: 'userPrompt', + type: 'string', + default: '', + description: 'Instructions for AI extraction (e.g., "Extract user information and available dashboard sections")', + displayOptions: { + show: { + resource: ['agenticscraper'], + operation: ['automate'], + aiExtraction: [true], + }, + }, + }, + { + displayName: 'Output Schema', + name: 'outputSchema', + type: 'json', + default: '{}', + description: 'JSON schema defining the structure of extracted data when using AI extraction', + displayOptions: { + show: { + resource: ['agenticscraper'], + operation: ['automate'], + aiExtraction: [true], + }, + }, + placeholder: '{"user_info": {"type": "object", "properties": {"username": {"type": "string"}, "email": {"type": "string"}}}}', + }, +]; diff --git a/nodes/ScrapegraphAI/ScrapegraphAi.node.ts b/nodes/ScrapegraphAI/ScrapegraphAi.node.ts index 3d64a6f..89d44df 100644 --- a/nodes/ScrapegraphAI/ScrapegraphAi.node.ts +++ b/nodes/ScrapegraphAI/ScrapegraphAi.node.ts @@ -10,6 +10,7 @@ import { smartscraperFields, smartscraperOperations } from '../SmartscraperDescr import { searchscraperFields, searchscraperOperations } from '../SearchscraperDescription'; import { markdownifyFields, markdownifyOperations } from '../MarkdownifyDescription'; import { smartcrawlerFields, smartcrawlerOperations } from '../SmartcrawlerDescription'; +import { agenticscraperFields, agenticscraperOperations } from '../AgenticscraperDescription'; export class ScrapegraphAi implements INodeType { description: INodeTypeDescription = { @@ -54,6 +55,10 @@ export class ScrapegraphAi implements INodeType { name: 'Markdownify', value: 'markdownify', }, + { + name: 'Agentic Scraper', + value: 'agenticscraper', + }, ], default: 'smartscraper', }, @@ -65,6 +70,8 @@ export class ScrapegraphAi implements INodeType { ...smartcrawlerFields, ...markdownifyOperations, ...markdownifyFields, + ...agenticscraperOperations, + ...agenticscraperFields, ], }; @@ -188,6 +195,46 @@ export class ScrapegraphAi implements INodeType { returnData.push({ json: response, pairedItem: { item: i } }); } } + + if (resource === 'agenticscraper') { + if (operation === 'automate') { + const url = this.getNodeParameter('url', i) as string; + const useSession = this.getNodeParameter('useSession', i) as boolean; + const stepsData = this.getNodeParameter('steps', i) as Array<{ step: string }>; + const aiExtraction = this.getNodeParameter('aiExtraction', i) as boolean; + + // Extract steps from the collection format + const steps = stepsData.map(item => item.step); + + const body: any = { + url: url, + use_session: useSession, + steps: steps, + }; + + // Add AI extraction parameters if enabled + if (aiExtraction) { + const userPrompt = this.getNodeParameter('userPrompt', i) as string; + const outputSchema = this.getNodeParameter('outputSchema', i) as string; + + body.user_prompt = userPrompt; + body.output_schema = outputSchema; + } + + const response = await this.helpers.httpRequestWithAuthentication.call(this, 'scrapegraphAIApi', { + method: 'POST', + url: `${baseUrl}/agenticscraper`, + headers: { + 'Accept': 'application/json', + 'Content-Type': 'application/json', + }, + body: body, + json: true, + }); + + returnData.push({ json: response, pairedItem: { item: i } }); + } + } } catch (error) { if (this.continueOnFail()) { returnData.push({ json: { error: error.message } });