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
JavaScript
"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