diff --git a/packages/@n8n/nodes-langchain/credentials/SearchApi.credentials.ts b/packages/@n8n/nodes-langchain/credentials/SearchApi.credentials.ts new file mode 100644 index 0000000000000..1b93cefdf8f76 --- /dev/null +++ b/packages/@n8n/nodes-langchain/credentials/SearchApi.credentials.ts @@ -0,0 +1,42 @@ +import type { + IAuthenticateGeneric, + ICredentialTestRequest, + ICredentialType, + INodeProperties, +} from 'n8n-workflow'; + +export class SearchApi implements ICredentialType { + name = 'searchApi'; + + displayName = 'SearchApi'; + + documentationUrl = 'searchapi'; + + properties: INodeProperties[] = [ + { + displayName: 'API Key', + name: 'apiKey', + type: 'string', + typeOptions: { password: true }, + required: true, + default: '', + }, + ]; + + authenticate: IAuthenticateGeneric = { + type: 'generic', + properties: { + headers: { + Authorization: '=Bearer {{$credentials.apiKey}}', + "X-SearchApi-Source": "N8n" + }, + }, + }; + + test: ICredentialTestRequest = { + request: { + baseURL: 'https://www.searchapi.io', + url: '/api/v1/search?engine=google&q=n8n', + }, + }; +} diff --git a/packages/@n8n/nodes-langchain/nodes/tools/ToolSearchApi/ToolSearchApi.node.ts b/packages/@n8n/nodes-langchain/nodes/tools/ToolSearchApi/ToolSearchApi.node.ts new file mode 100644 index 0000000000000..998746d471407 --- /dev/null +++ b/packages/@n8n/nodes-langchain/nodes/tools/ToolSearchApi/ToolSearchApi.node.ts @@ -0,0 +1,171 @@ +/* eslint-disable n8n-nodes-base/node-dirname-against-convention */ +import { + NodeConnectionType, + type IExecuteFunctions, + type INodeType, + type INodeTypeDescription, + type SupplyData, +} from 'n8n-workflow'; +import { SearchApi } from '@langchain/community/tools/searchapi'; +import { logWrapper } from '../../../utils/logWrapper'; +import { getConnectionHintNoticeField } from '../../../utils/sharedFields'; + +export class ToolSearchApi implements INodeType { + description: INodeTypeDescription = { + displayName: 'SearchApi (Google Search)', + name: 'toolSearchApi', + icon: 'file:searchApi.svg', + group: ['transform'], + version: 1, + description: 'Search in Google using SearchApi', + defaults: { + name: 'SearchApi', + }, + codex: { + categories: ['AI'], + subcategories: { + AI: ['Tools'], + Tools: ['Other Tools'], + }, + resources: { + primaryDocumentation: [ + { + url: 'https://docs.n8n.io/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.toolsearchapi/', + }, + ], + }, + }, + // eslint-disable-next-line n8n-nodes-base/node-class-description-inputs-wrong-regular-node + inputs: [], + // eslint-disable-next-line n8n-nodes-base/node-class-description-outputs-wrong + outputs: [NodeConnectionType.AiTool], + outputNames: ['Tool'], + credentials: [ + { + name: 'searchApi', + required: true, + }, + ], + properties: [ + getConnectionHintNoticeField([NodeConnectionType.AiAgent]), + { + displayName: 'Options', + name: 'options', + type: 'collection', + placeholder: 'Add Option', + default: {}, + options: [ + { + displayName: 'Engine', + name: 'engine', + type: 'string', + default: 'google', + description: + 'Defines the engine of the search. Supported engines are google, bing, baidu, google_news, youtube_transcripts, and more. Check the full list of supported in the documentation.', + }, + { + displayName: 'Country', + name: 'gl', + type: 'string', + default: 'us', + description: + 'Defines the country of the search. Check the full list of supported .', + displayOptions: { + hide: { + engine: ['youtube_transcripts'], + }, + }, + }, + { + displayName: 'Device', + name: 'device', + type: 'options', + options: [ + { + name: 'Desktop', + value: 'desktop', + }, + { + name: 'Mobile', + value: 'mobile', + }, + { + name: 'Tablet', + value: 'tablet', + }, + ], + default: 'desktop', + description: 'Device to use to get the results', + displayOptions: { + hide: { + engine: ['youtube_transcripts'], + }, + }, + }, + { + displayName: 'Google Domain', + name: 'google_domain', + type: 'string', + default: 'google.com', + description: + 'Defines the Google domain of the search. Check the full list of supported .', + displayOptions: { + hide: { + engine: ['youtube_transcripts'], + }, + }, + }, + { + displayName: 'Language', + name: 'hl', + type: 'string', + default: 'en', + description: + 'Defines the interface language of the search. Check the full list of supported .', + displayOptions: { + hide: { + engine: ['youtube_transcripts'], + }, + }, + }, + { + displayName: 'Video ID (For YouTube Transcripts)', + name: 'video_id', + type: 'string', + default: '', + description: + 'Specifies the ID of the video for which you want to retrieve transcripts. Only applicable for YouTube Transcripts engine.', + displayOptions: { + show: { + engine: ['youtube_transcripts'], + }, + }, + }, + { + displayName: 'Language (For YouTube Transcripts)', + name: 'lang', + type: 'string', + default: 'en', + description: + 'Specifies the language for transcripts. Only applicable for YouTube Transcripts engine.', + displayOptions: { + show: { + engine: ['youtube_transcripts'], + }, + }, + }, + ], + }, + ], + }; + + async supplyData(this: IExecuteFunctions, itemIndex: number): Promise { + const credentials = await this.getCredentials('searchApi'); + + const options = this.getNodeParameter('options', itemIndex) as object; + + return { + response: logWrapper(new SearchApi(credentials.apiKey as string, options), this), + }; + } +} diff --git a/packages/@n8n/nodes-langchain/nodes/tools/ToolSearchApi/searchApi.svg b/packages/@n8n/nodes-langchain/nodes/tools/ToolSearchApi/searchApi.svg new file mode 100644 index 0000000000000..99b86f23a6608 --- /dev/null +++ b/packages/@n8n/nodes-langchain/nodes/tools/ToolSearchApi/searchApi.svg @@ -0,0 +1 @@ +0479_octopus_verti \ No newline at end of file diff --git a/packages/@n8n/nodes-langchain/package.json b/packages/@n8n/nodes-langchain/package.json index d26fcb0b46df1..9d92462f391b1 100644 --- a/packages/@n8n/nodes-langchain/package.json +++ b/packages/@n8n/nodes-langchain/package.json @@ -33,6 +33,7 @@ "dist/credentials/OllamaApi.credentials.js", "dist/credentials/PineconeApi.credentials.js", "dist/credentials/QdrantApi.credentials.js", + "dist/credentials/SearchApi.credentials.js", "dist/credentials/SerpApi.credentials.js", "dist/credentials/WolframAlphaApi.credentials.js", "dist/credentials/XataApi.credentials.js", @@ -98,6 +99,7 @@ "dist/nodes/tools/ToolCalculator/ToolCalculator.node.js", "dist/nodes/tools/ToolCode/ToolCode.node.js", "dist/nodes/tools/ToolHttpRequest/ToolHttpRequest.node.js", + "dist/nodes/tools/ToolSearchApi/ToolSearchApi.node.js", "dist/nodes/tools/ToolSerpApi/ToolSerpApi.node.js", "dist/nodes/tools/ToolVectorStore/ToolVectorStore.node.js", "dist/nodes/tools/ToolWikipedia/ToolWikipedia.node.js",