UNPKG

n8n-nodes-a2a

Version:

n8n community node for A2A (Account to Account) transfers, account management, and Google Agent2Agent protocol communication with advanced features including file upload, custom JSON fields, custom requests, and streaming support

384 lines 20.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.A2a = void 0; const n8n_workflow_1 = require("n8n-workflow"); const TransferDescription_1 = require("./TransferDescription"); const AccountDescription_1 = require("./AccountDescription"); const AgentDescription_1 = require("./AgentDescription"); class A2a { constructor() { this.description = { displayName: 'A2A', name: 'a2a', icon: 'file:a2a.svg', group: ['transform'], version: 1, subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}', description: 'A2A (Account to Account) transfers, account management, and Agent2Agent protocol communication', defaults: { name: 'A2A', }, inputs: ["main"], outputs: ["main"], credentials: [ { name: 'a2aApi', required: true, }, ], requestDefaults: { baseURL: '={{$credentials.baseUrl}}', headers: { Accept: 'application/json', 'Content-Type': 'application/json', Authorization: 'Bearer {{$credentials.apiKey}}', 'X-API-Secret': '={{$credentials.apiSecret}}', }, }, properties: [ { displayName: 'Resource', name: 'resource', type: 'options', noDataExpression: true, options: [ { name: 'Transfer', value: 'transfer', description: 'Account to account transfers', }, { name: 'Account', value: 'account', description: 'Account management operations', }, { name: 'Agent', value: 'agent', description: 'Agent2Agent protocol communication', }, ], default: 'transfer', }, ...TransferDescription_1.transferOperations, ...TransferDescription_1.transferFields, ...AccountDescription_1.accountOperations, ...AccountDescription_1.accountFields, ...AgentDescription_1.agentOperations, ...AgentDescription_1.agentFields, ], }; } async execute() { var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q; const items = this.getInputData(); const returnData = []; let responseData; const resource = this.getNodeParameter('resource', 0); const operation = this.getNodeParameter('operation', 0); for (let i = 0; i < items.length; i++) { try { if (resource === 'transfer') { if (operation === 'create') { const amount = this.getNodeParameter('amount', i); const currency = this.getNodeParameter('currency', i); const fromAccountId = this.getNodeParameter('fromAccountId', i); const toAccountId = this.getNodeParameter('toAccountId', i); const reference = this.getNodeParameter('reference', i, ''); const description = this.getNodeParameter('description', i, ''); responseData = await this.helpers.httpRequestWithAuthentication.call(this, 'a2aApi', { method: 'POST', url: '/transfers', body: { amount, currency, fromAccountId, toAccountId, reference, description, }, }); } else if (operation === 'get') { const transferId = this.getNodeParameter('transferId', i); responseData = await this.helpers.httpRequestWithAuthentication.call(this, 'a2aApi', { method: 'GET', url: `/transfers/${transferId}`, }); } else if (operation === 'getMany') { const limit = this.getNodeParameter('limit', i, 50); const status = this.getNodeParameter('status', i, ''); const qs = { limit }; if (status) { qs.status = status; } responseData = await this.helpers.httpRequestWithAuthentication.call(this, 'a2aApi', { method: 'GET', url: '/transfers', qs, }); } else if (operation === 'cancel') { const transferId = this.getNodeParameter('transferId', i); responseData = await this.helpers.httpRequestWithAuthentication.call(this, 'a2aApi', { method: 'POST', url: `/transfers/${transferId}/cancel`, }); } } else if (resource === 'account') { if (operation === 'get') { const accountId = this.getNodeParameter('accountId', i); responseData = await this.helpers.httpRequestWithAuthentication.call(this, 'a2aApi', { method: 'GET', url: `/accounts/${accountId}`, }); } else if (operation === 'getMany') { const limit = this.getNodeParameter('limit', i, 50); const accountType = this.getNodeParameter('accountType', i, ''); const qs = { limit }; if (accountType) { qs.type = accountType; } responseData = await this.helpers.httpRequestWithAuthentication.call(this, 'a2aApi', { method: 'GET', url: '/accounts', qs, }); } else if (operation === 'getBalance') { const accountId = this.getNodeParameter('accountId', i); responseData = await this.helpers.httpRequestWithAuthentication.call(this, 'a2aApi', { method: 'GET', url: `/accounts/${accountId}/balance`, }); } else if (operation === 'getTransactions') { const accountId = this.getNodeParameter('accountId', i); const startDate = this.getNodeParameter('startDate', i, ''); const endDate = this.getNodeParameter('endDate', i, ''); const transactionLimit = this.getNodeParameter('transactionLimit', i, 100); const qs = { limit: transactionLimit }; if (startDate) { qs.start_date = startDate; } if (endDate) { qs.end_date = endDate; } responseData = await this.helpers.httpRequestWithAuthentication.call(this, 'a2aApi', { method: 'GET', url: `/accounts/${accountId}/transactions`, qs, }); } } else if (resource === 'agent') { if (operation === 'send' || operation === 'sendSubscribe') { const agentUrl = this.getNodeParameter('agentUrl', i); const additionalOptions = this.getNodeParameter('additionalOptions', i, {}); const useCustomJson = this.getNodeParameter('useCustomJson', i, false); const requestId = `call-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; let jsonRpcRequest; if (useCustomJson) { const customJsonMessage = this.getNodeParameter('customJsonMessage', i); const customParametersJson = this.getNodeParameter('customParametersJson', i, '{}'); let messageObject; let customParams; try { messageObject = JSON.parse(customJsonMessage); } catch (error) { throw new n8n_workflow_1.ApplicationError(`Invalid JSON in Custom JSON Message: ${error.message}`); } try { customParams = JSON.parse(customParametersJson); } catch (error) { throw new n8n_workflow_1.ApplicationError(`Invalid JSON in Custom Parameters: ${error.message}`); } jsonRpcRequest = { jsonrpc: '2.0', method: operation === 'send' ? 'tasks/send' : 'tasks/sendSubscribe', params: { message: messageObject, ...customParams, }, id: requestId, }; } else { const message = this.getNodeParameter('message', i); const sessionId = this.getNodeParameter('sessionId', i, ''); const taskId = this.getNodeParameter('taskId', i, ''); const includeFiles = this.getNodeParameter('includeFiles', i, false); const acceptedOutputModes = this.getNodeParameter('acceptedOutputModes', i, ['text']); const parts = [ { type: 'text', text: message, }, ]; if (includeFiles) { const files = this.getNodeParameter('files', i, {}); if (files.file && Array.isArray(files.file)) { for (const fileConfig of files.file) { const inputFieldName = fileConfig.inputFieldName; if (inputFieldName && ((_a = items[i].binary) === null || _a === void 0 ? void 0 : _a[inputFieldName])) { const binaryData = items[i].binary[inputFieldName]; const fileName = fileConfig.fileName || binaryData.fileName || 'file'; const mimeType = fileConfig.mimeType || binaryData.mimeType || 'application/octet-stream'; parts.push({ type: 'file', file: { name: fileName, bytes: binaryData.data, mime_type: mimeType, }, }); } } } } jsonRpcRequest = { jsonrpc: '2.0', method: operation === 'send' ? 'tasks/send' : 'tasks/sendSubscribe', params: { message: { role: additionalOptions.role || 'user', parts, }, sessionId: sessionId || `session-${Date.now()}`, id: taskId || `task-${Date.now()}`, acceptedOutputModes, }, id: requestId, }; } const headers = { 'Content-Type': 'application/json', Accept: operation === 'sendSubscribe' ? 'text/event-stream' : 'application/json', }; if (additionalOptions.apiKey) { headers['x-api-key'] = additionalOptions.apiKey; } if (operation === 'sendSubscribe') { headers['Cache-Control'] = 'no-cache'; } if ((_b = additionalOptions.headers) === null || _b === void 0 ? void 0 : _b.parameter) { for (const header of additionalOptions.headers.parameter) { if (header.name && header.value) { headers[header.name] = header.value; } } } const requestOptions = { method: 'POST', url: agentUrl, headers, body: jsonRpcRequest, }; responseData = await this.helpers.httpRequest.call(this, requestOptions); const responseFormat = additionalOptions.responseFormat || 'auto'; if (responseFormat === 'message') { if ((_e = (_d = (_c = responseData === null || responseData === void 0 ? void 0 : responseData.result) === null || _c === void 0 ? void 0 : _c.status) === null || _d === void 0 ? void 0 : _d.message) === null || _e === void 0 ? void 0 : _e.parts) { responseData = { message: responseData.result.status.message.parts .filter((part) => part.type === 'text') .map((part) => part.text) .join(''), taskId: (_f = responseData.result) === null || _f === void 0 ? void 0 : _f.id, state: (_h = (_g = responseData.result) === null || _g === void 0 ? void 0 : _g.status) === null || _h === void 0 ? void 0 : _h.state, }; } } else if (responseFormat === 'status') { if ((_j = responseData === null || responseData === void 0 ? void 0 : responseData.result) === null || _j === void 0 ? void 0 : _j.status) { responseData = { taskId: (_k = responseData.result) === null || _k === void 0 ? void 0 : _k.id, state: (_m = (_l = responseData.result) === null || _l === void 0 ? void 0 : _l.status) === null || _m === void 0 ? void 0 : _m.state, timestamp: (_p = (_o = responseData.result) === null || _o === void 0 ? void 0 : _o.status) === null || _p === void 0 ? void 0 : _p.timestamp, }; } } } else if (operation === 'getAgentCard') { const agentUrl = this.getNodeParameter('agentUrl', i); const cardUrl = agentUrl.replace(/\/$/, '') + '/.well-known/agent-card'; responseData = await this.helpers.httpRequest.call(this, { method: 'GET', url: cardUrl, headers: { Accept: 'application/json', }, }); } else if (operation === 'custom') { const agentUrl = this.getNodeParameter('agentUrl', i); const customMethod = this.getNodeParameter('customMethod', i); const customParams = this.getNodeParameter('customParams', i); const customRequestId = this.getNodeParameter('customRequestId', i, ''); const additionalOptions = this.getNodeParameter('additionalOptions', i, {}); let params; try { params = JSON.parse(customParams); } catch (error) { throw new n8n_workflow_1.ApplicationError(`Invalid JSON in Request Parameters: ${error.message}`); } const requestId = customRequestId || `call-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; const jsonRpcRequest = { jsonrpc: '2.0', method: customMethod, params, id: requestId, }; const headers = { 'Content-Type': 'application/json', Accept: 'application/json', }; if (additionalOptions.apiKey) { headers['x-api-key'] = additionalOptions.apiKey; } if ((_q = additionalOptions.headers) === null || _q === void 0 ? void 0 : _q.parameter) { for (const header of additionalOptions.headers.parameter) { if (header.name && header.value) { headers[header.name] = header.value; } } } const requestOptions = { method: 'POST', url: agentUrl, headers, body: jsonRpcRequest, }; responseData = await this.helpers.httpRequest.call(this, requestOptions); } } const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(responseData), { itemData: { item: i } }); returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { returnData.push({ json: { error: error.message, operation, resource, }, pairedItem: { item: i, }, }); continue; } throw error; } } return [returnData]; } } exports.A2a = A2a; //# sourceMappingURL=A2a.node.js.map