diff --git a/src/api/integrations/chatbot/dify/services/dify.service.ts b/src/api/integrations/chatbot/dify/services/dify.service.ts index f59fd673..c467af7f 100644 --- a/src/api/integrations/chatbot/dify/services/dify.service.ts +++ b/src/api/integrations/chatbot/dify/services/dify.service.ts @@ -41,24 +41,15 @@ export class DifyService { return content.includes('imageMessage'); } - private async initNewSession( + private async sendMessageToBot( instance: any, - remoteJid: string, - dify: Dify, - settings: DifySetting, session: IntegrationSession, + settings: DifySetting, + dify: Dify, + remoteJid: string, + pushName: string, content: string, - pushName?: string, ) { - const data = await this.createNewSession(instance, { - remoteJid, - botId: dify.id, - }); - - if (data.session) { - session = data.session; - } - let endpoint: string = dify.apiUrl; if (dify.botType === 'chatBot') { @@ -104,66 +95,7 @@ export class DifyService { const message = response?.data?.answer; - const regex = /!?\[(.*?)\]\((.*?)\)/g; - - const result = []; - let lastIndex = 0; - - let match; - while ((match = regex.exec(message)) !== null) { - if (match.index > lastIndex) { - result.push({ text: message.slice(lastIndex, match.index).trim() }); - } - - result.push({ caption: match[1], url: match[2] }); - - lastIndex = regex.lastIndex; - } - - if (lastIndex < message.length) { - result.push({ text: message.slice(lastIndex).trim() }); - } - - for (const item of result) { - if (item.text) { - await instance.textMessage( - { - number: remoteJid.split('@')[0], - delay: settings?.delayMessage || 1000, - text: item.text, - }, - false, - ); - } - - if (item.url) { - await instance.mediaMessage( - { - number: remoteJid.split('@')[0], - delay: settings?.delayMessage || 1000, - mediatype: 'image', - media: item.url, - caption: item.caption, - }, - false, - ); - } - } - - await this.prismaRepository.integrationSession.update({ - where: { - id: session.id, - }, - data: { - status: 'opened', - awaitUser: true, - sessionId: response?.data?.conversation_id, - }, - }); - - sendTelemetry('/message/sendText'); - - return; + await this.sendMessageWhatsApp(instance, remoteJid, message, session, settings); } if (dify.botType === 'textGenerator') { @@ -209,66 +141,7 @@ export class DifyService { const message = response?.data?.answer; - const regex = /!?\[(.*?)\]\((.*?)\)/g; - - const result = []; - let lastIndex = 0; - - let match; - while ((match = regex.exec(message)) !== null) { - if (match.index > lastIndex) { - result.push({ text: message.slice(lastIndex, match.index).trim() }); - } - - result.push({ caption: match[1], url: match[2] }); - - lastIndex = regex.lastIndex; - } - - if (lastIndex < message.length) { - result.push({ text: message.slice(lastIndex).trim() }); - } - - for (const item of result) { - if (item.text) { - await instance.textMessage( - { - number: remoteJid.split('@')[0], - delay: settings?.delayMessage || 1000, - text: item.text, - }, - false, - ); - } - - if (item.url) { - await instance.mediaMessage( - { - number: remoteJid.split('@')[0], - delay: settings?.delayMessage || 1000, - mediatype: 'image', - media: item.url, - caption: item.caption, - }, - false, - ); - } - } - - await this.prismaRepository.integrationSession.update({ - where: { - id: session.id, - }, - data: { - status: 'opened', - awaitUser: true, - sessionId: response?.data?.conversation_id, - }, - }); - - sendTelemetry('/message/sendText'); - - return; + await this.sendMessageWhatsApp(instance, remoteJid, message, session, settings); } if (dify.botType === 'agent') { @@ -334,64 +207,7 @@ export class DifyService { const message = response?.data?.answer; - const regex = /!?\[(.*?)\]\((.*?)\)/g; - - const result = []; - let lastIndex = 0; - - let match; - while ((match = regex.exec(message)) !== null) { - if (match.index > lastIndex) { - result.push({ text: message.slice(lastIndex, match.index).trim() }); - } - - result.push({ caption: match[1], url: match[2] }); - - lastIndex = regex.lastIndex; - } - - if (lastIndex < message.length) { - result.push({ text: message.slice(lastIndex).trim() }); - } - - for (const item of result) { - if (item.text) { - await instance.textMessage( - { - number: remoteJid.split('@')[0], - delay: settings?.delayMessage || 1000, - text: item.text, - }, - false, - ); - } - - if (item.url) { - await instance.mediaMessage( - { - number: remoteJid.split('@')[0], - delay: settings?.delayMessage || 1000, - mediatype: 'image', - media: item.url, - caption: item.caption, - }, - false, - ); - } - } - - await this.prismaRepository.integrationSession.update({ - where: { - id: session.id, - }, - data: { - status: 'opened', - awaitUser: true, - sessionId: conversationId, - }, - }); - - sendTelemetry('/message/sendText'); + await this.sendMessageWhatsApp(instance, remoteJid, message, session, settings); }); reader.on('error', (error) => { @@ -443,73 +259,104 @@ export class DifyService { const message = response?.data?.data.outputs.text; - const regex = /!?\[(.*?)\]\((.*?)\)/g; - - const result = []; - let lastIndex = 0; - - let match; - while ((match = regex.exec(message)) !== null) { - if (match.index > lastIndex) { - result.push({ text: message.slice(lastIndex, match.index).trim() }); - } - - result.push({ caption: match[1], url: match[2] }); - - lastIndex = regex.lastIndex; - } - - if (lastIndex < message.length) { - result.push({ text: message.slice(lastIndex).trim() }); - } - - for (const item of result) { - if (item.text) { - await instance.textMessage( - { - number: remoteJid.split('@')[0], - delay: settings?.delayMessage || 1000, - text: item.text, - }, - false, - ); - } - - if (item.url) { - await instance.mediaMessage( - { - number: remoteJid.split('@')[0], - delay: settings?.delayMessage || 1000, - mediatype: 'image', - media: item.url, - caption: item.caption, - }, - false, - ); - } - } - - if (settings.keepOpen) { - await this.prismaRepository.integrationSession.update({ - where: { - id: session.id, - }, - data: { - status: 'closed', - }, - }); - } else { - await this.prismaRepository.integrationSession.delete({ - where: { - id: session.id, - }, - }); - } - - sendTelemetry('/message/sendText'); + await this.sendMessageWhatsApp(instance, remoteJid, message, session, settings); return; } + } + + private async sendMessageWhatsApp( + instance: any, + remoteJid: string, + message: string, + session: IntegrationSession, + settings: DifySetting, + ) { + const regex = /!?\[(.*?)\]\((.*?)\)/g; + + const result = []; + let lastIndex = 0; + + let match; + while ((match = regex.exec(message)) !== null) { + if (match.index > lastIndex) { + result.push({ text: message.slice(lastIndex, match.index).trim() }); + } + + result.push({ caption: match[1], url: match[2] }); + + lastIndex = regex.lastIndex; + } + + if (lastIndex < message.length) { + result.push({ text: message.slice(lastIndex).trim() }); + } + + for (const item of result) { + if (item.text) { + await instance.textMessage( + { + number: remoteJid.split('@')[0], + delay: settings?.delayMessage || 1000, + text: item.text, + }, + false, + ); + } + + if (item.url) { + await instance.mediaMessage( + { + number: remoteJid.split('@')[0], + delay: settings?.delayMessage || 1000, + mediatype: 'image', + media: item.url, + caption: item.caption, + }, + false, + ); + } + } + + if (settings.keepOpen) { + await this.prismaRepository.integrationSession.update({ + where: { + id: session.id, + }, + data: { + status: 'closed', + }, + }); + } else { + await this.prismaRepository.integrationSession.delete({ + where: { + id: session.id, + }, + }); + } + + sendTelemetry('/message/sendText'); + } + + private async initNewSession( + instance: any, + remoteJid: string, + dify: Dify, + settings: DifySetting, + session: IntegrationSession, + content: string, + pushName?: string, + ) { + const data = await this.createNewSession(instance, { + remoteJid, + botId: dify.id, + }); + + if (data.session) { + session = data.session; + } + + await this.sendMessageToBot(instance, session, settings, dify, remoteJid, pushName, content); return; } @@ -612,427 +459,7 @@ export class DifyService { return; } - let endpoint: string = dify.apiUrl; - - if (dify.botType === 'chatBot') { - endpoint += '/chat-messages'; - const payload: any = { - inputs: { - remoteJid: remoteJid, - pushName: pushName, - instanceName: instance.instanceName, - serverUrl: this.configService.get('SERVER').URL, - apiKey: this.configService.get('AUTHENTICATION').API_KEY.KEY, - }, - query: content, - response_mode: 'blocking', - conversation_id: session.sessionId === remoteJid ? undefined : session.sessionId, - user: remoteJid, - }; - - if (this.isImageMessage(content)) { - const contentSplit = content.split('|'); - - payload.files = [ - { - type: 'image', - transfer_method: 'remote_url', - url: contentSplit[1].split('?')[0], - }, - ]; - payload.query = contentSplit[2] || content; - } - - await instance.client.presenceSubscribe(remoteJid); - - await instance.client.sendPresenceUpdate('composing', remoteJid); - - const response = await axios.post(endpoint, payload, { - headers: { - Authorization: `Bearer ${dify.apiKey}`, - }, - }); - - await instance.client.sendPresenceUpdate('paused', remoteJid); - - const message = response?.data?.answer; - - const regex = /!?\[(.*?)\]\((.*?)\)/g; - - const result = []; - let lastIndex = 0; - - let match; - while ((match = regex.exec(message)) !== null) { - if (match.index > lastIndex) { - result.push({ text: message.slice(lastIndex, match.index).trim() }); - } - - result.push({ caption: match[1], url: match[2] }); - - lastIndex = regex.lastIndex; - } - - if (lastIndex < message.length) { - result.push({ text: message.slice(lastIndex).trim() }); - } - - for (const item of result) { - if (item.text) { - await instance.textMessage( - { - number: remoteJid.split('@')[0], - delay: settings?.delayMessage || 1000, - text: item.text, - }, - false, - ); - } - - if (item.url) { - await instance.mediaMessage( - { - number: remoteJid.split('@')[0], - delay: settings?.delayMessage || 1000, - mediatype: 'image', - media: item.url, - caption: item.caption, - }, - false, - ); - } - } - - await this.prismaRepository.integrationSession.update({ - where: { - id: session.id, - }, - data: { - status: 'opened', - awaitUser: true, - sessionId: response?.data?.conversation_id, - }, - }); - - sendTelemetry('/message/sendText'); - - return; - } - - if (dify.botType === 'textGenerator') { - endpoint += '/completion-messages'; - const payload: any = { - inputs: { - query: content, - remoteJid: remoteJid, - pushName: pushName, - instanceName: instance.instanceName, - serverUrl: this.configService.get('SERVER').URL, - apiKey: this.configService.get('AUTHENTICATION').API_KEY.KEY, - }, - response_mode: 'blocking', - conversation_id: session.sessionId === remoteJid ? undefined : session.sessionId, - user: remoteJid, - }; - - if (this.isImageMessage(content)) { - const contentSplit = content.split('|'); - - payload.files = [ - { - type: 'image', - transfer_method: 'remote_url', - url: contentSplit[1].split('?')[0], - }, - ]; - payload.inputs.query = contentSplit[2] || content; - } - - await instance.client.presenceSubscribe(remoteJid); - - await instance.client.sendPresenceUpdate('composing', remoteJid); - - const response = await axios.post(endpoint, payload, { - headers: { - Authorization: `Bearer ${dify.apiKey}`, - }, - }); - - await instance.client.sendPresenceUpdate('paused', remoteJid); - - const message = response?.data?.answer; - - const regex = /!?\[(.*?)\]\((.*?)\)/g; - - const result = []; - let lastIndex = 0; - - let match; - while ((match = regex.exec(message)) !== null) { - if (match.index > lastIndex) { - result.push({ text: message.slice(lastIndex, match.index).trim() }); - } - - result.push({ caption: match[1], url: match[2] }); - - lastIndex = regex.lastIndex; - } - - if (lastIndex < message.length) { - result.push({ text: message.slice(lastIndex).trim() }); - } - - for (const item of result) { - if (item.text) { - await instance.textMessage( - { - number: remoteJid.split('@')[0], - delay: settings?.delayMessage || 1000, - text: item.text, - }, - false, - ); - } - - if (item.url) { - await instance.mediaMessage( - { - number: remoteJid.split('@')[0], - delay: settings?.delayMessage || 1000, - mediatype: 'image', - media: item.url, - caption: item.caption, - }, - false, - ); - } - } - - await this.prismaRepository.integrationSession.update({ - where: { - id: session.id, - }, - data: { - status: 'opened', - awaitUser: true, - sessionId: response?.data?.conversation_id, - }, - }); - - sendTelemetry('/message/sendText'); - - return; - } - - if (dify.botType === 'agent') { - endpoint += '/chat-messages'; - const payload: any = { - inputs: { - remoteJid: remoteJid, - pushName: pushName, - instanceName: instance.instanceName, - serverUrl: this.configService.get('SERVER').URL, - apiKey: this.configService.get('AUTHENTICATION').API_KEY.KEY, - }, - query: content, - response_mode: 'streaming', - conversation_id: session.sessionId === remoteJid ? undefined : session.sessionId, - user: remoteJid, - }; - - if (this.isImageMessage(content)) { - const contentSplit = content.split('|'); - - payload.files = [ - { - type: 'image', - transfer_method: 'remote_url', - url: contentSplit[1].split('?')[0], - }, - ]; - payload.query = contentSplit[2] || content; - } - - await instance.client.presenceSubscribe(remoteJid); - - await instance.client.sendPresenceUpdate('composing', remoteJid); - - const response = await axios.post(endpoint, payload, { - headers: { - Authorization: `Bearer ${dify.apiKey}`, - }, - responseType: 'stream', - }); - - let completeMessage = ''; - let conversationId; - - const stream = response.data; - const reader = new Readable().wrap(stream); - - reader.on('data', (chunk) => { - const data = chunk.toString(); - const lines = data.split('\n'); - - lines.forEach((line) => { - if (line.startsWith('data: ')) { - const jsonString = line.substring(6); - try { - const event = JSON.parse(jsonString); - if (event.event === 'agent_message') { - completeMessage += event.answer; - conversationId = conversationId ?? event?.conversation_id; - } - } catch (error) { - console.error('Error parsing stream data:', error); - } - } - }); - }); - - reader.on('end', async () => { - await instance.client.sendPresenceUpdate('paused', remoteJid); - - await instance.textMessage( - { - number: remoteJid.split('@')[0], - delay: settings?.delayMessage || 1000, - text: completeMessage, - }, - false, - ); - - await this.prismaRepository.integrationSession.update({ - where: { - id: session.id, - }, - data: { - status: 'opened', - awaitUser: true, - sessionId: conversationId, - }, - }); - - sendTelemetry('/message/sendText'); - }); - - reader.on('error', (error) => { - console.error('Error reading stream:', error); - }); - - return; - } - - if (dify.botType === 'workflow') { - endpoint += '/workflows/run'; - const payload: any = { - inputs: { - query: content, - remoteJid: remoteJid, - pushName: pushName, - instanceName: instance.instanceName, - serverUrl: this.configService.get('SERVER').URL, - apiKey: this.configService.get('AUTHENTICATION').API_KEY.KEY, - }, - response_mode: 'blocking', - conversation_id: session.sessionId === remoteJid ? undefined : session.sessionId, - user: remoteJid, - }; - - if (this.isImageMessage(content)) { - const contentSplit = content.split('|'); - - payload.files = [ - { - type: 'image', - transfer_method: 'remote_url', - url: contentSplit[1].split('?')[0], - }, - ]; - payload.inputs.query = contentSplit[2] || content; - } - - await instance.client.presenceSubscribe(remoteJid); - - await instance.client.sendPresenceUpdate('composing', remoteJid); - - const response = await axios.post(endpoint, payload, { - headers: { - Authorization: `Bearer ${dify.apiKey}`, - }, - }); - - await instance.client.sendPresenceUpdate('paused', remoteJid); - - const message = response?.data?.data.outputs.text; - - const regex = /!?\[(.*?)\]\((.*?)\)/g; - - const result = []; - let lastIndex = 0; - - let match; - while ((match = regex.exec(message)) !== null) { - if (match.index > lastIndex) { - result.push({ text: message.slice(lastIndex, match.index).trim() }); - } - - result.push({ caption: match[1], url: match[2] }); - - lastIndex = regex.lastIndex; - } - - if (lastIndex < message.length) { - result.push({ text: message.slice(lastIndex).trim() }); - } - - for (const item of result) { - if (item.text) { - await instance.textMessage( - { - number: remoteJid.split('@')[0], - delay: settings?.delayMessage || 1000, - text: item.text, - }, - false, - ); - } - - if (item.url) { - await instance.mediaMessage( - { - number: remoteJid.split('@')[0], - delay: settings?.delayMessage || 1000, - mediatype: 'image', - media: item.url, - caption: item.caption, - }, - false, - ); - } - } - - if (settings.keepOpen) { - await this.prismaRepository.integrationSession.update({ - where: { - id: session.id, - }, - data: { - status: 'closed', - }, - }); - } else { - await this.prismaRepository.integrationSession.delete({ - where: { - id: session.id, - }, - }); - } - - sendTelemetry('/message/sendText'); - - return; - } + await this.sendMessageToBot(instance, session, settings, dify, remoteJid, pushName, content); return; } diff --git a/src/api/integrations/chatbot/openai/services/openai.service.ts b/src/api/integrations/chatbot/openai/services/openai.service.ts index 0fe8d2b7..f0ff66f3 100644 --- a/src/api/integrations/chatbot/openai/services/openai.service.ts +++ b/src/api/integrations/chatbot/openai/services/openai.service.ts @@ -22,6 +22,194 @@ export class OpenaiService { private readonly logger = new Logger('OpenaiService'); + private async sendMessageToBot(instance: any, openaiBot: OpenaiBot, remoteJid: string, content: string) { + const systemMessages: any = openaiBot.systemMessages; + + const messagesSystem: any[] = systemMessages.map((message) => { + return { + role: 'system', + content: message, + }; + }); + + const assistantMessages: any = openaiBot.assistantMessages; + + const messagesAssistant: any[] = assistantMessages.map((message) => { + return { + role: 'assistant', + content: message, + }; + }); + + const userMessages: any = openaiBot.userMessages; + + const messagesUser: any[] = userMessages.map((message) => { + return { + role: 'user', + content: message, + }; + }); + + const messageData: any = { + role: 'user', + content: [{ type: 'text', text: content }], + }; + + if (this.isImageMessage(content)) { + const contentSplit = content.split('|'); + + const url = contentSplit[1].split('?')[0]; + + messageData.content = [ + { type: 'text', text: contentSplit[2] || content }, + { + type: 'image_url', + image_url: { + url: url, + }, + }, + ]; + } + + const messages: any[] = [...messagesSystem, ...messagesAssistant, ...messagesUser, messageData]; + + await instance.client.presenceSubscribe(remoteJid); + + await instance.client.sendPresenceUpdate('composing', remoteJid); + + const completions = await this.client.chat.completions.create({ + model: openaiBot.model, + messages: messages, + max_tokens: openaiBot.maxTokens, + }); + + await instance.client.sendPresenceUpdate('paused', remoteJid); + + const message = completions.choices[0].message.content; + + return message; + } + + private async sendMessageToAssistant( + instance: any, + openaiBot: OpenaiBot, + remoteJid: string, + pushName: string, + fromMe: boolean, + content: string, + threadId: string, + ) { + const messageData: any = { + role: fromMe ? 'assistant' : 'user', + content: [{ type: 'text', text: content }], + }; + + if (this.isImageMessage(content)) { + const contentSplit = content.split('|'); + + const url = contentSplit[1].split('?')[0]; + + messageData.content = [ + { type: 'text', text: contentSplit[2] || content }, + { + type: 'image_url', + image_url: { + url: url, + }, + }, + ]; + } + + await this.client.beta.threads.messages.create(threadId, messageData); + + if (fromMe) { + sendTelemetry('/message/sendText'); + return; + } + + const runAssistant = await this.client.beta.threads.runs.create(threadId, { + assistant_id: openaiBot.assistantId, + }); + + await instance.client.presenceSubscribe(remoteJid); + + await instance.client.sendPresenceUpdate('composing', remoteJid); + + const response = await this.getAIResponse(threadId, runAssistant.id, openaiBot.functionUrl, remoteJid, pushName); + + await instance.client.sendPresenceUpdate('paused', remoteJid); + + const message = response?.data[0].content[0].text.value; + + return message; + } + + private async sendMessageWhatsapp( + instance: any, + session: IntegrationSession, + remoteJid: string, + settings: OpenaiSetting, + message: string, + ) { + const regex = /!?\[(.*?)\]\((.*?)\)/g; + + const result = []; + let lastIndex = 0; + + let match; + while ((match = regex.exec(message)) !== null) { + if (match.index > lastIndex) { + result.push({ text: message.slice(lastIndex, match.index).trim() }); + } + + result.push({ caption: match[1], url: match[2] }); + + lastIndex = regex.lastIndex; + } + + if (lastIndex < message.length) { + result.push({ text: message.slice(lastIndex).trim() }); + } + + for (const item of result) { + if (item.text) { + await instance.textMessage( + { + number: remoteJid.split('@')[0], + delay: settings?.delayMessage || 1000, + text: item.text, + }, + false, + ); + } + + if (item.url) { + await instance.mediaMessage( + { + number: remoteJid.split('@')[0], + delay: settings?.delayMessage || 1000, + mediatype: 'image', + media: item.url, + caption: item.caption, + }, + false, + ); + } + } + + await this.prismaRepository.integrationSession.update({ + where: { + id: session.id, + }, + data: { + status: 'opened', + awaitUser: true, + }, + }); + + sendTelemetry('/message/sendText'); + } + public async createAssistantNewSession(instance: InstanceDto, data: any) { if (data.remoteJid === 'status@broadcast') return; @@ -80,111 +268,17 @@ export class OpenaiService { session = data.session; } - const messageData: any = { - role: fromMe ? 'assistant' : 'user', - content: [{ type: 'text', text: content }], - }; - - if (this.isImageMessage(content)) { - const contentSplit = content.split('|'); - - const url = contentSplit[1].split('?')[0]; - - messageData.content = [ - { type: 'text', text: contentSplit[2] || content }, - { - type: 'image_url', - image_url: { - url: url, - }, - }, - ]; - } - - await this.client.beta.threads.messages.create(data.session.sessionId, messageData); - - if (fromMe) { - sendTelemetry('/message/sendText'); - return; - } - - const runAssistant = await this.client.beta.threads.runs.create(data.session.sessionId, { - assistant_id: openaiBot.assistantId, - }); - - await instance.client.presenceSubscribe(remoteJid); - - await instance.client.sendPresenceUpdate('composing', remoteJid); - - const response = await this.getAIResponse( - data.session.sessionId, - runAssistant.id, - openaiBot.functionUrl, + const message = await this.sendMessageToAssistant( + instance, + openaiBot, remoteJid, pushName, + fromMe, + content, + session.sessionId, ); - await instance.client.sendPresenceUpdate('paused', remoteJid); - - const message = response?.data[0].content[0].text.value; - - const regex = /!?\[(.*?)\]\((.*?)\)/g; - - const result = []; - let lastIndex = 0; - - let match; - while ((match = regex.exec(message)) !== null) { - if (match.index > lastIndex) { - result.push({ text: message.slice(lastIndex, match.index).trim() }); - } - - result.push({ caption: match[1], url: match[2] }); - - lastIndex = regex.lastIndex; - } - - if (lastIndex < message.length) { - result.push({ text: message.slice(lastIndex).trim() }); - } - - for (const item of result) { - if (item.text) { - await instance.textMessage( - { - number: remoteJid.split('@')[0], - delay: settings?.delayMessage || 1000, - text: item.text, - }, - false, - ); - } - - if (item.url) { - await instance.mediaMessage( - { - number: remoteJid.split('@')[0], - delay: settings?.delayMessage || 1000, - mediatype: 'image', - media: item.url, - caption: item.caption, - }, - false, - ); - } - } - - await this.prismaRepository.integrationSession.update({ - where: { - id: session.id, - }, - data: { - status: 'opened', - awaitUser: true, - }, - }); - - sendTelemetry('/message/sendText'); + await this.sendMessageWhatsapp(instance, session, remoteJid, settings, message); return; } @@ -395,109 +489,17 @@ export class OpenaiService { const threadId = session.sessionId; - const messageData: any = { - role: fromMe ? 'assistant' : 'user', - content: [{ type: 'text', text: content }], - }; + const message = await this.sendMessageToAssistant( + instance, + openaiBot, + remoteJid, + pushName, + fromMe, + content, + threadId, + ); - if (this.isImageMessage(content)) { - const contentSplit = content.split('|'); - - const url = contentSplit[1].split('?')[0]; - - messageData.content = [ - { type: 'text', text: contentSplit[2] || content }, - { - type: 'image_url', - image_url: { - url: url, - }, - }, - ]; - } - - await this.client.beta.threads.messages.create(threadId, messageData); - - if (fromMe || session?.status === 'paused') { - sendTelemetry('/message/sendText'); - return; - } - - const runAssistant = await this.client.beta.threads.runs.create(threadId, { - assistant_id: openaiBot.assistantId, - additional_instructions: `WhatsappApiInfo: - Name: ${pushName} - RemoteJid: ${remoteJid} - `, - }); - - await instance.client.presenceSubscribe(remoteJid); - - await instance.client.sendPresenceUpdate('composing', remoteJid); - - const response = await this.getAIResponse(threadId, runAssistant.id, openaiBot.functionUrl, remoteJid, pushName); - - await instance.client.sendPresenceUpdate('paused', remoteJid); - - const message = response?.data[0].content[0].text.value; - - const regex = /!?\[(.*?)\]\((.*?)\)/g; - - const result = []; - let lastIndex = 0; - - let match; - while ((match = regex.exec(message)) !== null) { - if (match.index > lastIndex) { - result.push({ text: message.slice(lastIndex, match.index).trim() }); - } - - result.push({ caption: match[1], url: match[2] }); - - lastIndex = regex.lastIndex; - } - - if (lastIndex < message.length) { - result.push({ text: message.slice(lastIndex).trim() }); - } - - for (const item of result) { - if (item.text) { - await instance.textMessage( - { - number: remoteJid.split('@')[0], - delay: settings?.delayMessage || 1000, - text: item.text, - }, - false, - ); - } - - if (item.url) { - await instance.mediaMessage( - { - number: remoteJid.split('@')[0], - delay: settings?.delayMessage || 1000, - mediatype: 'image', - media: item.url, - caption: item.caption, - }, - false, - ); - } - } - - await this.prismaRepository.integrationSession.update({ - where: { - id: session.id, - }, - data: { - status: 'opened', - awaitUser: true, - }, - }); - - sendTelemetry('/message/sendText'); + await this.sendMessageWhatsapp(instance, session, remoteJid, settings, message); return; } @@ -549,133 +551,16 @@ export class OpenaiService { }); session = data.session; + const creds = data.creds; this.client = new OpenAI({ apiKey: creds.apiKey, }); - const systemMessages: any = openaiBot.systemMessages; + const message = await this.sendMessageToBot(instance, openaiBot, remoteJid, content); - const messagesSystem: any[] = systemMessages.map((message) => { - return { - role: 'system', - content: message, - }; - }); - - const assistantMessages: any = openaiBot.assistantMessages; - - const messagesAssistant: any[] = assistantMessages.map((message) => { - return { - role: 'assistant', - content: message, - }; - }); - - const userMessages: any = openaiBot.userMessages; - - const messagesUser: any[] = userMessages.map((message) => { - return { - role: 'user', - content: message, - }; - }); - - const messageData: any = { - role: 'user', - content: [{ type: 'text', text: content }], - }; - - if (this.isImageMessage(content)) { - const contentSplit = content.split('|'); - - const url = contentSplit[1].split('?')[0]; - - messageData.content = [ - { type: 'text', text: contentSplit[2] || content }, - { - type: 'image_url', - image_url: { - url: url, - }, - }, - ]; - } - - const messages: any[] = [...messagesSystem, ...messagesAssistant, ...messagesUser, messageData]; - - await instance.client.presenceSubscribe(remoteJid); - - await instance.client.sendPresenceUpdate('composing', remoteJid); - - const completions = await this.client.chat.completions.create({ - model: openaiBot.model, - messages: messages, - max_tokens: openaiBot.maxTokens, - }); - - await instance.client.sendPresenceUpdate('paused', remoteJid); - - const message = completions.choices[0].message.content; - - const regex = /!?\[(.*?)\]\((.*?)\)/g; - - const result = []; - let lastIndex = 0; - - let match; - while ((match = regex.exec(message)) !== null) { - if (match.index > lastIndex) { - result.push({ text: message.slice(lastIndex, match.index).trim() }); - } - - result.push({ caption: match[1], url: match[2] }); - - lastIndex = regex.lastIndex; - } - - if (lastIndex < message.length) { - result.push({ text: message.slice(lastIndex).trim() }); - } - - for (const item of result) { - if (item.text) { - await instance.textMessage( - { - number: remoteJid.split('@')[0], - delay: settings?.delayMessage || 1000, - text: item.text, - }, - false, - ); - } - - if (item.url) { - await instance.mediaMessage( - { - number: remoteJid.split('@')[0], - delay: settings?.delayMessage || 1000, - mediatype: 'image', - media: item.url, - caption: item.caption, - }, - false, - ); - } - } - - await this.prismaRepository.integrationSession.update({ - where: { - id: session.id, - }, - data: { - status: 'opened', - awaitUser: true, - }, - }); - - sendTelemetry('/message/sendText'); + await this.sendMessageWhatsapp(instance, session, remoteJid, settings, message); return; } @@ -789,127 +674,9 @@ export class OpenaiService { apiKey: creds.apiKey, }); - const systemMessages: any = openaiBot.systemMessages; + const message = await this.sendMessageToBot(instance, openaiBot, remoteJid, content); - const messagesSystem: any[] = systemMessages.map((message) => { - return { - role: 'system', - content: message, - }; - }); - - const assistantMessages: any = openaiBot.assistantMessages; - - const messagesAssistant: any[] = assistantMessages.map((message) => { - return { - role: 'assistant', - content: message, - }; - }); - - const userMessages: any = openaiBot.userMessages; - - const messagesUser: any[] = userMessages.map((message) => { - return { - role: 'user', - content: message, - }; - }); - - const messageData: any = { - role: 'user', - content: [{ type: 'text', text: content }], - }; - - if (this.isImageMessage(content)) { - const contentSplit = content.split('|'); - - const url = contentSplit[1].split('?')[0]; - - messageData.content = [ - { type: 'text', text: contentSplit[2] || content }, - { - type: 'image_url', - image_url: { - url: url, - }, - }, - ]; - } - - const messages: any[] = [...messagesSystem, ...messagesAssistant, ...messagesUser, messageData]; - - await instance.client.presenceSubscribe(remoteJid); - - await instance.client.sendPresenceUpdate('composing', remoteJid); - - const completions = await this.client.chat.completions.create({ - model: openaiBot.model, - messages: messages, - max_tokens: openaiBot.maxTokens, - }); - - await instance.client.sendPresenceUpdate('paused', remoteJid); - - const message = completions.choices[0].message.content; - - const regex = /!?\[(.*?)\]\((.*?)\)/g; - - const result = []; - let lastIndex = 0; - - let match; - while ((match = regex.exec(message)) !== null) { - if (match.index > lastIndex) { - result.push({ text: message.slice(lastIndex, match.index).trim() }); - } - - result.push({ caption: match[1], url: match[2] }); - - lastIndex = regex.lastIndex; - } - - if (lastIndex < message.length) { - result.push({ text: message.slice(lastIndex).trim() }); - } - - for (const item of result) { - if (item.text) { - await instance.textMessage( - { - number: remoteJid.split('@')[0], - delay: settings?.delayMessage || 1000, - text: item.text, - }, - false, - ); - } - - if (item.url) { - await instance.mediaMessage( - { - number: remoteJid.split('@')[0], - delay: settings?.delayMessage || 1000, - mediatype: 'image', - media: item.url, - caption: item.caption, - }, - false, - ); - } - } - - await this.prismaRepository.integrationSession.update({ - where: { - id: session.id, - }, - data: { - status: 'opened', - awaitUser: true, - }, - }); - - sendTelemetry('/message/sendText'); + await this.sendMessageWhatsapp(instance, session, remoteJid, settings, message); return; }