UNPKG

n8n-nodes-chat-data

Version:

Chatdata integration for n8n. Manage chatbots, send messages, and retrieve leads from your Chatdata account.

871 lines 44.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ChatData = void 0; const n8n_workflow_1 = require("n8n-workflow"); const ActionDescription_1 = require("./ActionDescription"); const ChatbotDescription_1 = require("./ChatbotDescription"); class ChatData { constructor() { this.description = { displayName: 'Chat Data', name: 'chatData', group: ['transform'], version: 1, description: 'Basic Chat Data Node', defaults: { name: 'Chat Data', }, inputs: [n8n_workflow_1.NodeConnectionTypes.Main], outputs: [n8n_workflow_1.NodeConnectionTypes.Main], icon: 'file:ChatData.svg', subtitle: '={{$parameter["resource"] + ": " + $parameter["operation"]}}', credentials: [ { name: 'chatDataApi', required: true, }, ], requestDefaults: { baseURL: '{{$credentials.baseUrl}}', headers: { Accept: 'application/json', 'Content-Type': 'application/json', }, }, properties: [ { displayName: 'Resource', name: 'resource', type: 'options', noDataExpression: true, options: [ { name: 'Action', value: 'action', }, { name: 'Chatbot', value: 'chatbot', }, ], default: 'action', description: 'Choose a resource', }, ...ActionDescription_1.actionOperations, ...ActionDescription_1.actionFields, ...ChatbotDescription_1.chatbotOperations, ...ChatbotDescription_1.chatbotFields, ], }; this.methods = { loadOptions: { async getChatbots() { const credentials = await this.getCredentials('chatDataApi'); if (!credentials.baseUrl) { throw new n8n_workflow_1.NodeOperationError(this.getNode(), new Error('Base URL is missing in credentials. Please check your credentials configuration.'), { itemIndex: 0 }); } const baseUrl = credentials.baseUrl; const baseUrlFormatted = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl; const fullUrl = `${baseUrlFormatted}/api/v2/get-chatbots`; try { const response = await this.helpers.httpRequest({ url: fullUrl, method: 'GET', headers: { Authorization: `Bearer ${credentials.apiKey}`, 'Accept': 'application/json', 'Content-Type': 'application/json', }, json: true, ignoreHttpStatusErrors: true, }); if (response.status === 'error') { throw new n8n_workflow_1.NodeOperationError(this.getNode(), response.message, { itemIndex: 0 }); } if (!response.chatbots || !Array.isArray(response.chatbots)) { throw new n8n_workflow_1.NodeOperationError(this.getNode(), new Error('Invalid response format. Expected chatbots array.'), { itemIndex: 0, }); } const options = response.chatbots.map((chatbot) => ({ name: chatbot.chatbotName, value: chatbot.chatbotId, })); return options; } catch (error) { throw new n8n_workflow_1.NodeOperationError(this.getNode(), new Error(`Failed to fetch chatbots: ${error.message}`), { itemIndex: 0 }); } }, }, }; } async execute() { const items = this.getInputData(); const returnData = []; const resource = this.getNodeParameter('resource', 0); const operation = this.getNodeParameter('operation', 0); if (resource === 'action') { if (operation === 'sendMessage') { for (let i = 0; i < items.length; i++) { try { const chatbotId = this.getNodeParameter('chatbot_id', i); const messagesData = this.getNodeParameter('messages.messageValues', i, []); const additionalFields = this.getNodeParameter('additionalFields', i, {}); if (!messagesData.length) { throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'At least one message is required', { itemIndex: i }); } const messages = messagesData.map((message) => ({ role: message.role, content: message.content, })); const body = { chatbotId, messages, }; if (additionalFields.conversationId) { body.conversationId = additionalFields.conversationId; } if (additionalFields.baseModel) { body.baseModel = additionalFields.baseModel; } if (additionalFields.basePrompt) { body.basePrompt = additionalFields.basePrompt; } if (additionalFields.appendMessages !== undefined) { body.appendMessages = additionalFields.appendMessages; } else { body.appendMessages = true; } if (additionalFields.stream !== undefined) { body.stream = additionalFields.stream; } else { body.stream = false; } const credentials = await this.getCredentials('chatDataApi'); const baseUrl = credentials.baseUrl; const baseUrlFormatted = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl; const fullUrl = `${baseUrlFormatted}/api/v2/chat`; const response = await this.helpers.httpRequestWithAuthentication.call(this, 'chatDataApi', { url: fullUrl, method: 'POST', body, headers: { 'Accept': 'application/json', 'Content-Type': 'application/json', }, json: true, ignoreHttpStatusErrors: true, }); if (response.status === 'error') { throw new n8n_workflow_1.NodeOperationError(this.getNode(), response.message, { itemIndex: i }); } const newItem = { json: { output: response, }, pairedItem: { item: i, input: 0 } }; returnData.push(newItem); } catch (error) { let errorMessage = error.message; if (error.response && error.response.body) { const responseBody = error.response.body; if (typeof responseBody === 'object' && responseBody.message) { errorMessage = responseBody.message; } else if (typeof responseBody === 'string') { try { const parsedBody = JSON.parse(responseBody); if (parsedBody.message) { errorMessage = parsedBody.message; } } catch (e) { } } } if (this.continueOnFail()) { returnData.push({ json: { ...items[i].json, error: errorMessage, }, pairedItem: { item: i, input: 0 } }); continue; } throw new n8n_workflow_1.NodeOperationError(this.getNode(), errorMessage, { itemIndex: i }); } } } else if (operation === 'getLeads') { for (let i = 0; i < items.length; i++) { try { const chatbotId = this.getNodeParameter('chatbot_id', i); const limit = this.getNodeParameter('limit', i); const additionalFields = this.getNodeParameter('additionalFields', i, {}); let responseData = []; const qs = { size: 100, }; if (additionalFields.startDate) { const startDate = new Date(additionalFields.startDate); qs.startTimestamp = startDate.getTime().toString(); } if (additionalFields.endDate) { const endDate = new Date(additionalFields.endDate); qs.endTimestamp = endDate.getTime().toString(); } if (additionalFields.source) { qs.source = additionalFields.source; } let hasNextPage = true; let pageNumber = 0; const credentials = await this.getCredentials('chatDataApi'); const baseUrl = credentials.baseUrl; while (hasNextPage) { if (pageNumber > 0) { qs.start = (pageNumber * 100).toString(); } const endpoint = `/get-customers/${chatbotId}`; const baseUrlFormatted = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl; const fullUrl = `${baseUrlFormatted}/api/v2${endpoint}`; const response = await this.helpers.httpRequestWithAuthentication.call(this, 'chatDataApi', { url: fullUrl, method: 'GET', qs, headers: { 'Accept': 'application/json', 'Content-Type': 'application/json', }, json: true, ignoreHttpStatusErrors: true, }); if (response.status === 'error') { throw new n8n_workflow_1.NodeOperationError(this.getNode(), response.message, { itemIndex: i }); } if (response && response.customers && Array.isArray(response.customers)) { responseData = [...responseData, ...response.customers]; const totalResults = response.total; hasNextPage = totalResults > (pageNumber + 1) * 100; if (limit > 0 && responseData.length >= limit) { responseData = responseData.slice(0, limit); hasNextPage = false; break; } pageNumber++; } else { hasNextPage = false; } } for (const item of responseData) { returnData.push({ json: item, pairedItem: { item: i, input: 0 } }); } } catch (error) { let errorMessage = error.message; if (error.response && error.response.body) { const responseBody = error.response.body; if (typeof responseBody === 'object' && responseBody.message) { errorMessage = responseBody.message; } else if (typeof responseBody === 'string') { try { const parsedBody = JSON.parse(responseBody); if (parsedBody.message) { errorMessage = parsedBody.message; } } catch (e) { } } } if (this.continueOnFail()) { returnData.push({ json: { ...items[i].json, error: errorMessage, }, pairedItem: { item: i, input: 0 } }); continue; } throw new n8n_workflow_1.NodeOperationError(this.getNode(), errorMessage, { itemIndex: i }); } } } else if (operation === 'getConversations') { for (let i = 0; i < items.length; i++) { try { const chatbotId = this.getNodeParameter('chatbot_id', i); const limit = this.getNodeParameter('limit', i); const additionalFields = this.getNodeParameter('additionalFields', i, {}); let responseData = []; const qs = { size: 100, }; if (additionalFields.startDate) { const startDate = new Date(additionalFields.startDate); qs.startTimestamp = startDate.getTime().toString(); } if (additionalFields.endDate) { const endDate = new Date(additionalFields.endDate); qs.endTimestamp = endDate.getTime().toString(); } if (additionalFields.source) { qs.source = additionalFields.source; } if (additionalFields.leadId) { qs.leadId = additionalFields.leadId; } let hasNextPage = true; let pageNumber = 0; while (hasNextPage) { if (pageNumber > 0) { qs.start = (pageNumber * 100).toString(); } const endpoint = `/get-conversations/${chatbotId}`; const credentials = await this.getCredentials('chatDataApi'); const baseUrl = credentials.baseUrl; const baseUrlFormatted = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl; const fullUrl = `${baseUrlFormatted}/api/v2${endpoint}`; const response = await this.helpers.httpRequestWithAuthentication.call(this, 'chatDataApi', { url: fullUrl, method: 'GET', qs, headers: { 'Accept': 'application/json', 'Content-Type': 'application/json', }, json: true, ignoreHttpStatusErrors: true, }); if (response.status === 'error') { throw new n8n_workflow_1.NodeOperationError(this.getNode(), response.message, { itemIndex: i }); } if (response && response.conversations && Array.isArray(response.conversations)) { responseData = [...responseData, ...response.conversations]; const totalResults = response.total; hasNextPage = totalResults > (pageNumber + 1) * 100; if (limit > 0 && responseData.length >= limit) { responseData = responseData.slice(0, limit); hasNextPage = false; break; } pageNumber++; } else { hasNextPage = false; } } for (const item of responseData) { returnData.push({ json: item, pairedItem: { item: i, input: 0 } }); } } catch (error) { let errorMessage = error.message; if (error.response && error.response.body) { const responseBody = error.response.body; if (typeof responseBody === 'object' && responseBody.message) { errorMessage = responseBody.message; } else if (typeof responseBody === 'string') { try { const parsedBody = JSON.parse(responseBody); if (parsedBody.message) { errorMessage = parsedBody.message; } } catch (e) { } } } if (this.continueOnFail()) { returnData.push({ json: { ...items[i].json, error: errorMessage, }, pairedItem: { item: i, input: 0 } }); continue; } throw new n8n_workflow_1.NodeOperationError(this.getNode(), errorMessage, { itemIndex: i }); } } } else if (operation === 'appendMessage') { for (let i = 0; i < items.length; i++) { try { const chatbotId = this.getNodeParameter('chatbot_id', i); const conversationId = this.getNodeParameter('conversationId', i); const message = this.getNodeParameter('message', i); const senderType = this.getNodeParameter('senderType', i); if (!chatbotId) { throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Chatbot ID is required', { itemIndex: i }); } if (!conversationId) { throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Conversation ID is required', { itemIndex: i }); } const trimmedMessage = message.trim(); if (!trimmedMessage) { throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Message text is required and cannot be empty', { itemIndex: i }); } const apiRole = senderType === 'human' ? 'human' : 'assistant'; const body = { chatbotId, conversationId, message: trimmedMessage, role: apiRole, }; if (senderType === 'human') { const agentName = this.getNodeParameter('agentName', i, ''); const agentAvatar = this.getNodeParameter('agentAvatar', i, ''); if (agentName) { body.name = agentName; } if (agentAvatar) { body.avatar = agentAvatar; } } const filesData = this.getNodeParameter('files.fileValues', i, []); if (filesData.length > 0) { if (filesData.length > 3) { throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Maximum of 3 file attachments allowed', { itemIndex: i }); } for (const file of filesData) { if (!file.name || !file.type || !file.url) { throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Each file attachment must have name, type, and url', { itemIndex: i }); } } const files = filesData.map((file) => ({ name: file.name, type: file.type, url: file.url, })); body.files = files; } const credentials = await this.getCredentials('chatDataApi'); const baseUrl = credentials.baseUrl; const baseUrlFormatted = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl; const fullUrl = `${baseUrlFormatted}/api/v2/live-chat`; const response = await this.helpers.httpRequestWithAuthentication.call(this, 'chatDataApi', { url: fullUrl, method: 'POST', body, headers: { 'Accept': 'application/json', 'Content-Type': 'application/json', }, json: true, ignoreHttpStatusErrors: true, }); if (response.status === 'error') { throw new n8n_workflow_1.NodeOperationError(this.getNode(), response.message, { itemIndex: i }); } returnData.push({ json: { output: response, }, pairedItem: { item: i, input: 0 } }); } catch (error) { let errorMessage = error.message; if (error.response && error.response.body) { const responseBody = error.response.body; if (typeof responseBody === 'object' && responseBody.message) { errorMessage = responseBody.message; } else if (typeof responseBody === 'string') { try { const parsedBody = JSON.parse(responseBody); if (parsedBody.message) { errorMessage = parsedBody.message; } } catch (e) { } } } if (this.continueOnFail()) { returnData.push({ json: { ...items[i].json, error: errorMessage, }, pairedItem: { item: i, input: 0 } }); continue; } throw new n8n_workflow_1.NodeOperationError(this.getNode(), errorMessage, { itemIndex: i }); } } } } else if (resource === 'chatbot') { if (operation === 'updateBasePrompt') { for (let i = 0; i < items.length; i++) { try { const chatbotId = this.getNodeParameter('chatbot_id', i); const basePrompt = this.getNodeParameter('basePrompt', i); const body = { chatbotId, basePrompt, }; const credentials = await this.getCredentials('chatDataApi'); const baseUrl = credentials.baseUrl; const baseUrlFormatted = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl; const fullUrl = `${baseUrlFormatted}/api/v2/update-chatbot-settings`; const response = await this.helpers.httpRequestWithAuthentication.call(this, 'chatDataApi', { url: fullUrl, method: 'POST', body, headers: { 'Accept': 'application/json', 'Content-Type': 'application/json', }, json: true, ignoreHttpStatusErrors: true, }); if (response.status === 'error') { throw new n8n_workflow_1.NodeOperationError(this.getNode(), response.message, { itemIndex: i }); } const newItem = { json: { ...response, success: true, chatbotId, }, pairedItem: { item: i, input: 0 } }; returnData.push(newItem); } catch (error) { let errorMessage = error.message; if (error.response && error.response.body) { const responseBody = error.response.body; if (typeof responseBody === 'object' && responseBody.message) { errorMessage = responseBody.message; } else if (typeof responseBody === 'string') { try { const parsedBody = JSON.parse(responseBody); if (parsedBody.message) { errorMessage = parsedBody.message; } } catch (e) { } } } if (this.continueOnFail()) { returnData.push({ json: { ...items[i].json, error: errorMessage, }, pairedItem: { item: i, input: 0 } }); continue; } throw new n8n_workflow_1.NodeOperationError(this.getNode(), errorMessage, { itemIndex: i }); } } } else if (operation === 'retrainChatbot') { for (let i = 0; i < items.length; i++) { try { const chatbotId = this.getNodeParameter('chatbot_id', i); const sourceText = this.getNodeParameter('sourceText', i, ''); const qAndAsData = this.getNodeParameter('qAndAs.qAndAValues', i, []); const urlsData = this.getNodeParameter('urlsToScrape.urlValues', i, []); const scrapingOptions = this.getNodeParameter('options', i, {}); const qAndAs = qAndAsData.length ? qAndAsData.map((qa) => ({ question: qa.question, answer: qa.answer, })) : undefined; const urlsToScrape = urlsData.length ? urlsData.map((urlObj) => urlObj.url) : undefined; const body = { chatbotId, }; if (sourceText) { body.sourceText = sourceText; } if (qAndAs && qAndAs.length) { body.qAndAs = qAndAs; } if (Array.isArray(urlsToScrape) && urlsToScrape.length) { body.urlsToScrape = urlsToScrape; } if (Object.keys(scrapingOptions).length) { body.options = scrapingOptions; } const credentials = await this.getCredentials('chatDataApi'); const baseUrl = credentials.baseUrl; const baseUrlFormatted = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl; const fullUrl = `${baseUrlFormatted}/api/v2/retrain-chatbot`; const response = await this.helpers.httpRequestWithAuthentication.call(this, 'chatDataApi', { url: fullUrl, method: 'POST', body, headers: { 'Accept': 'application/json', 'Content-Type': 'application/json', }, json: true, ignoreHttpStatusErrors: true, }); if (response.status === 'error') { throw new n8n_workflow_1.NodeOperationError(this.getNode(), response.message, { itemIndex: i }); } const newItem = { json: { ...response, success: true, chatbotId, }, pairedItem: { item: i, input: 0 } }; returnData.push(newItem); } catch (error) { let errorMessage = error.message; if (error.response && error.response.body) { const responseBody = error.response.body; if (typeof responseBody === 'object' && responseBody.message) { errorMessage = responseBody.message; } else if (typeof responseBody === 'string') { try { const parsedBody = JSON.parse(responseBody); if (parsedBody.message) { errorMessage = parsedBody.message; } } catch (e) { } } } if (this.continueOnFail()) { returnData.push({ json: { ...items[i].json, error: errorMessage, }, pairedItem: { item: i, input: 0 } }); continue; } throw new n8n_workflow_1.NodeOperationError(this.getNode(), errorMessage, { itemIndex: i }); } } } else if (operation === 'getChatbotStatus') { for (let i = 0; i < items.length; i++) { try { const chatbotId = this.getNodeParameter('chatbot_id', i); const endpoint = `/chatbot/status/${chatbotId}`; const credentials = await this.getCredentials('chatDataApi'); const baseUrl = credentials.baseUrl; const baseUrlFormatted = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl; const fullUrl = `${baseUrlFormatted}/api/v2${endpoint}`; const response = await this.helpers.httpRequestWithAuthentication.call(this, 'chatDataApi', { url: fullUrl, method: 'GET', qs: {}, headers: { 'Accept': 'application/json', 'Content-Type': 'application/json', }, json: true, ignoreHttpStatusErrors: true, }); if (response.status === 'error') { throw new n8n_workflow_1.NodeOperationError(this.getNode(), response.message, { itemIndex: i }); } returnData.push({ json: response, pairedItem: { item: i, input: 0 } }); } catch (error) { let errorMessage = error.message; if (error.response && error.response.body) { const responseBody = error.response.body; if (typeof responseBody === 'object' && responseBody.message) { errorMessage = responseBody.message; } else if (typeof responseBody === 'string') { try { const parsedBody = JSON.parse(responseBody); if (parsedBody.message) { errorMessage = parsedBody.message; } } catch (e) { } } } if (this.continueOnFail()) { returnData.push({ json: { ...items[i].json, error: errorMessage, }, pairedItem: { item: i, input: 0 } }); continue; } throw new n8n_workflow_1.NodeOperationError(this.getNode(), errorMessage, { itemIndex: i }); } } } else if (operation === 'createChatbot') { for (let i = 0; i < items.length; i++) { try { const chatbotName = this.getNodeParameter('chatbotName', i); const model = this.getNodeParameter('model', i); const sourceText = this.getNodeParameter('sourceText', i, ''); const urlsData = this.getNodeParameter('urlsToScrape.urlValues', i, []); const urlsToScrape = urlsData.length ? urlsData.map((urlObj) => urlObj.url) : undefined; const body = { chatbotName, model, }; if (sourceText) { body.sourceText = sourceText; } if (Array.isArray(urlsToScrape) && urlsToScrape.length) { body.urlsToScrape = urlsToScrape; } if (model === 'custom-model') { const customBackend = this.getNodeParameter('customBackend', i, ''); const bearer = this.getNodeParameter('bearer', i, ''); if (customBackend) { body.customBackend = customBackend; } if (bearer) { body.bearer = bearer; } } const credentials = await this.getCredentials('chatDataApi'); const baseUrl = credentials.baseUrl; const baseUrlFormatted = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl; const fullUrl = `${baseUrlFormatted}/api/v2/create-chatbot`; const response = await this.helpers.httpRequestWithAuthentication.call(this, 'chatDataApi', { url: fullUrl, method: 'POST', body, headers: { 'Accept': 'application/json', 'Content-Type': 'application/json', }, json: true, ignoreHttpStatusErrors: true, }); if (response.status === 'error') { throw new n8n_workflow_1.NodeOperationError(this.getNode(), response.message, { itemIndex: i }); } returnData.push({ json: response, pairedItem: { item: i, input: 0 } }); } catch (error) { let errorMessage = error.message; if (error.response && error.response.body) { const responseBody = error.response.body; if (typeof responseBody === 'object' && responseBody.message) { errorMessage = responseBody.message; } else if (typeof responseBody === 'string') { try { const parsedBody = JSON.parse(responseBody); if (parsedBody.message) { errorMessage = parsedBody.message; } } catch (e) { } } } if (this.continueOnFail()) { returnData.push({ json: { ...items[i].json, error: errorMessage, }, pairedItem: { item: i, input: 0 } }); continue; } throw new n8n_workflow_1.NodeOperationError(this.getNode(), errorMessage, { itemIndex: i }); } } } } return [returnData.length ? returnData : items]; } } exports.ChatData = ChatData; //# sourceMappingURL=ChatData.node.js.map