fix(whatsapp.gblib): Fix broadcasts.

This commit is contained in:
Rodrigo Rodriguez 2024-06-29 09:09:50 -03:00
parent 0e2586ba0c
commit b43e179172
2 changed files with 111 additions and 104 deletions

View file

@ -2700,4 +2700,34 @@ export class SystemKeywords {
ChatServices.userSystemPrompt[user.userSystemId] = text; ChatServices.userSystemPrompt[user.userSystemId] = text;
} }
public async setMemoryContext({pid, input, output, erase}){
const { min, user, params } = await DialogKeywords.getProcessInfo(pid);
let memory;
if (erase || !ChatServices.memoryMap[user.userSystemId]) {
memory = new BufferWindowMemory({
returnMessages: true,
memoryKey: 'chat_history',
inputKey: 'input',
k: 2
});
ChatServices.memoryMap[user.userSystemId] = memory;
} else {
memory = ChatServices.memoryMap[user.userSystemId];
}
if (memory)
await memory.saveContext(
{
input: input
},
{
output: output
}
);
}
} }

View file

@ -65,13 +65,11 @@ import { GBUtil } from '../../../src/util.js';
import { GBLogEx } from './GBLogEx.js'; import { GBLogEx } from './GBLogEx.js';
import { DialogKeywords } from '../../basic.gblib/services/DialogKeywords.js'; import { DialogKeywords } from '../../basic.gblib/services/DialogKeywords.js';
/** /**
* Provides basic services for handling messages and dispatching to back-end * Provides basic services for handling messages and dispatching to back-end
* services like NLP or Search. * services like NLP or Search.
*/ */
export class GBConversationalService { export class GBConversationalService {
public async getNewMobileCode() { public async getNewMobileCode() {
throw new Error('Method removed.'); throw new Error('Method removed.');
} }
@ -322,7 +320,8 @@ export class GBConversationalService {
const filename = url.substring(url.lastIndexOf('/') + 1); const filename = url.substring(url.lastIndexOf('/') + 1);
await min.whatsAppDirectLine.sendFileToDevice(mobile, url, filename, caption); await min.whatsAppDirectLine.sendFileToDevice(mobile, url, filename, caption);
} else { } else {
GBLogEx.info(min, GBLogEx.info(
min,
`Sending ${url} as file attachment not available in this channel ${step.context.activity['mobile']}...` `Sending ${url} as file attachment not available in this channel ${step.context.activity['mobile']}...`
); );
await min.conversationalService.sendText(min, step, url); await min.conversationalService.sendText(min, step, url);
@ -341,9 +340,9 @@ export class GBConversationalService {
} }
public async sendEvent(min: GBMinInstance, step: GBDialogStep, name: string, value: Object): Promise<any> { public async sendEvent(min: GBMinInstance, step: GBDialogStep, name: string, value: Object): Promise<any> {
if (step.context.activity.channelId !== 'msteams' && if (step.context.activity.channelId !== 'msteams' && step.context.activity.channelId !== 'omnichannel') {
step.context.activity.channelId !== 'omnichannel') { GBLogEx.info(
GBLogEx.info(min, min,
`Sending event ${name}:${typeof value === 'object' ? JSON.stringify(value) : value ? value : ''} to client...` `Sending event ${name}:${typeof value === 'object' ? JSON.stringify(value) : value ? value : ''} to client...`
); );
const msg = MessageFactory.text(''); const msg = MessageFactory.text('');
@ -357,23 +356,18 @@ export class GBConversationalService {
// tslint:disable:no-unsafe-any due to Nexmo. // tslint:disable:no-unsafe-any due to Nexmo.
public async sendSms(min: GBMinInstance, mobile: string, text: string): Promise<any> { public async sendSms(min: GBMinInstance, mobile: string, text: string): Promise<any> {
let botNumber = min.core.getParam<string>(min.instance, 'Bot Number', null); let botNumber = min.core.getParam<string>(min.instance, 'Bot Number', null);
if (botNumber) { if (botNumber) {
GBLogEx.info(min, `Sending SMS from ${botNumber} to ${mobile} with text: '${text}'.`); GBLogEx.info(min, `Sending SMS from ${botNumber} to ${mobile} with text: '${text}'.`);
const accountSid = process.env.TWILIO_ACCOUNT_SID; const accountSid = process.env.TWILIO_ACCOUNT_SID;
const authToken = process.env.TWILIO_AUTH_TOKEN; const authToken = process.env.TWILIO_AUTH_TOKEN;
const client = twilio(null, authToken, { accountSid: accountSid }); const client = twilio(null, authToken, { accountSid: accountSid });
const msg = await client.messages.create({
const msg = await client.messages
.create({
body: text, body: text,
from: '+' + botNumber, from: '+' + botNumber,
to: '+' + mobile to: '+' + mobile
}) });
GBLogEx.info(min, `SMS sent, return: ${msg.sid}.`); GBLogEx.info(min, `SMS sent, return: ${msg.sid}.`);
} }
@ -429,8 +423,9 @@ export class GBConversationalService {
public async sendToMobile(min: GBMinInstance, mobile: string, message: any, conversationId) { public async sendToMobile(min: GBMinInstance, mobile: string, message: any, conversationId) {
GBLogEx.info(min, `Sending message ${message} to ${mobile}...`); GBLogEx.info(min, `Sending message ${message} to ${mobile}...`);
return min.whatsAppDirectLine ? await min.whatsAppDirectLine.sendToDevice(mobile, message, conversationId) : return min.whatsAppDirectLine
await this.sendSms(min, mobile, message); ? await min.whatsAppDirectLine.sendToDevice(mobile, message, conversationId)
: await this.sendSms(min, mobile, message);
} }
public static async getAudioBufferFromText(text): Promise<string> { public static async getAudioBufferFromText(text): Promise<string> {
@ -544,27 +539,24 @@ export class GBConversationalService {
} }
public static getIBMAudioModelNameFromLocale = locale => { public static getIBMAudioModelNameFromLocale = locale => {
const locales = { const locales = {
"ar": "ar-MS_BroadbandModel", ar: 'ar-MS_BroadbandModel',
"zh": "zh-CN_BroadbandModel", zh: 'zh-CN_BroadbandModel',
"nl": "nl-NL_BroadbandModel", nl: 'nl-NL_BroadbandModel',
"en": "en-US_BroadbandModel", en: 'en-US_BroadbandModel',
"fr": "fr-FR_BroadbandModel", fr: 'fr-FR_BroadbandModel',
"de": "de-DE_BroadbandModel", de: 'de-DE_BroadbandModel',
"it": "it-IT_BroadbandModel", it: 'it-IT_BroadbandModel',
"ja": "ja-JP_BroadbandModel", ja: 'ja-JP_BroadbandModel',
"ko": "ko-KR_BroadbandModel", ko: 'ko-KR_BroadbandModel',
"pt": "pt-BR_BroadbandModel", pt: 'pt-BR_BroadbandModel',
"es": "es-ES_BroadbandModel" es: 'es-ES_BroadbandModel'
}; };
const languageCode = locale.substring(0, 2); const languageCode = locale.substring(0, 2);
return locales[languageCode] || "en-US_BroadbandModel"; return locales[languageCode] || 'en-US_BroadbandModel';
}; };
public async playMarkdown(min: GBMinInstance, answer: string, channel: string, step: GBDialogStep, mobile: string) {
public async playMarkdown(min: GBMinInstance, answer: string, channel: string,
step: GBDialogStep, mobile: string) {
const sec = new SecService(); const sec = new SecService();
const user = await sec.getUserFromSystemId(mobile ? mobile : step.context.activity.from.id); const user = await sec.getUserFromSystemId(mobile ? mobile : step.context.activity.from.id);
@ -649,58 +641,57 @@ export class GBConversationalService {
} }
public async fillAndBroadcastTemplate(min: GBMinInstance, mobile: string, text) { public async fillAndBroadcastTemplate(min: GBMinInstance, mobile: string, text) {
if (text.startsWith('broadcastx')) {
await this.sendToMobile(min, mobile, { name: text }, null);
} else {
let isMedia =
text.toLowerCase().endsWith('.jpg') ||
text.toLowerCase().endsWith('.jpeg') ||
text.toLowerCase().endsWith('.png');
let isMedia = text.toLowerCase().endsWith('.jpg') || text.toLowerCase().endsWith('.jpeg') let image = !isMedia ? /(.*)\n/gim.exec(text)[0].trim() : text;
|| text.toLowerCase().endsWith('.png');
let image = !isMedia ?
/(.*)\n/gmi.exec(text)[0].trim() :
text;
const gbaiName = DialogKeywords.getGBAIPath(min.botId); const gbaiName = DialogKeywords.getGBAIPath(min.botId);
const fileUrl = urlJoin(process.env.BOT_URL, 'kb', gbaiName, `${min.botId}.gbkb`, 'images', image); const fileUrl = urlJoin(process.env.BOT_URL, 'kb', gbaiName, `${min.botId}.gbkb`, 'images', image);
let urlImage = image.startsWith('http') let urlImage = image.startsWith('http') ? image : fileUrl;
? image
: fileUrl;
if (!isMedia) { if (!isMedia) {
text = text.substring(image.length + 1).trim(); text = text.substring(image.length + 1).trim();
text = text.replace(/\n/g, "\\n"); text = text.replace(/\n/g, '\\n');
} }
let data: any = { let data: any = {
name: isMedia ? 'broadcast_notext' : 'broadcast1', components: [ name: isMedia ? 'broadcast_notext' : 'broadcast1',
components: [
{ {
type: "header", type: 'header',
parameters: [ parameters: [
{ {
type: "image", type: 'image',
image: { image: {
link: urlImage, link: urlImage
} }
}, }
], ]
} }
] ]
}; };
if (!isMedia) { if (!isMedia) {
data.components.push({ data.components.push({
type: "body", type: 'body',
parameters: [ parameters: [
{ {
type: "text", type: 'text',
text: text, text: text
} }
] ]
}); });
} }
GBLogEx.info(min, `Sending answer file to mobile: ${mobile}. Header: ${urlImage}`);
await this.sendToMobile(min, mobile, data, null); await this.sendToMobile(min, mobile, data, null);
}
GBLogEx.info(min, `Sending answer file to mobile: ${mobile}. Header: ${urlImage}`);
} }
// tslint:enable:no-unsafe-any // tslint:enable:no-unsafe-any
@ -944,7 +935,8 @@ export class GBConversationalService {
return false; return false;
} }
GBLogEx.info(min, GBLogEx.info(
min,
`NLP called: ${intent}, entities: ${nlp.entities.length}, score: ${score} > required (nlpScore): ${instanceScore}` `NLP called: ${intent}, entities: ${nlp.entities.length}, score: ${score} > required (nlpScore): ${instanceScore}`
); );
@ -965,7 +957,6 @@ export class GBConversationalService {
await step.replaceDialog(`/${intent}`, step.activeDialog.state.options); await step.replaceDialog(`/${intent}`, step.activeDialog.state.options);
return true; return true;
} }
GBLogEx.info(min, `NLP NOT called: score: ${score} > required (nlpScore): ${instanceScore}`); GBLogEx.info(min, `NLP NOT called: score: ${score} > required (nlpScore): ${instanceScore}`);
@ -1003,7 +994,6 @@ export class GBConversationalService {
} }
public async translate(min: GBMinInstance, text: string, language: string): Promise<string> { public async translate(min: GBMinInstance, text: string, language: string): Promise<string> {
const translatorEnabled = () => { const translatorEnabled = () => {
if (min.instance.params) { if (min.instance.params) {
const params = JSON.parse(min.instance.params); const params = JSON.parse(min.instance.params);
@ -1051,14 +1041,13 @@ export class GBConversationalService {
return Promise.reject(new Error(msg)); return Promise.reject(new Error(msg));
} }
} else { } else {
let url = urlJoin( let url = urlJoin(endPoint, 'translate');
endPoint, url +=
'translate'); '?' +
url += "?" +
new URLSearchParams({ new URLSearchParams({
'api-version': '3.0', 'api-version': '3.0',
to: language to: language
}).toString() }).toString();
let options = { let options = {
method: 'POST', method: 'POST',
@ -1078,8 +1067,7 @@ export class GBConversationalService {
if (results[0]) { if (results[0]) {
return results[0].translations[0].text; return results[0].translations[0].text;
} } else {
else {
return text; return text;
} }
} catch (error) { } catch (error) {
@ -1157,10 +1145,7 @@ export class GBConversationalService {
const group = step.context.activity['group']; const group = step.context.activity['group'];
const groupSpell = group ? await min.core.getParam( const groupSpell = group ? await min.core.getParam(min.instance, 'Group Spell', false) : false;
min.instance,
'Group Spell',
false) : false;
if (textProcessed !== text && group && groupSpell) { if (textProcessed !== text && group && groupSpell) {
await min.whatsAppDirectLine.sendToDevice(group, `Spell: ${text}`); await min.whatsAppDirectLine.sendToDevice(group, `Spell: ${text}`);
@ -1168,24 +1153,17 @@ export class GBConversationalService {
// Detects user typed language and updates their locale profile if applies. // Detects user typed language and updates their locale profile if applies.
let locale = user.locale ? user.locale : min.core.getParam( let locale = user.locale
min.instance, ? user.locale
'Default User Language', : min.core.getParam(min.instance, 'Default User Language', GBConfigService.get('DEFAULT_USER_LANGUAGE'));
GBConfigService.get('DEFAULT_USER_LANGUAGE'));
const detectLanguage =
min.core.getParam(
min.instance,
'Language Detector',
false) != false;
const detectLanguage = min.core.getParam(min.instance, 'Language Detector', false) != false;
if (text.indexOf(' ') !== -1 && detectLanguage) { if (text.indexOf(' ') !== -1 && detectLanguage) {
locale = await min.conversationalService.getLanguage(min, text); locale = await min.conversationalService.getLanguage(min, text);
if (user.locale != locale) { if (user.locale != locale) {
user = await sec.updateUserLocale(user.userId, locale); user = await sec.updateUserLocale(user.userId, locale);
await min.conversationalService.sendText(min, await min.conversationalService.sendText(min, step, `Changed language to: ${locale}`);
step, `Changed language to: ${locale}`);
} }
} }
@ -1221,7 +1199,6 @@ export class GBConversationalService {
GBLog.verbose(`Translated text(prompt): ${text}.`); GBLog.verbose(`Translated text(prompt): ${text}.`);
} }
if (step.activeDialog.state.options['kind'] === 'file') { if (step.activeDialog.state.options['kind'] === 'file') {
return await step.prompt('attachmentPrompt', {}); return await step.prompt('attachmentPrompt', {});
} else { } else {
await this.sendText(min, step, text); await this.sendText(min, step, text);