new(basic.gblib): GPT replacing ALLEN NLP Reading Comp.
This commit is contained in:
parent
218bcd1b3e
commit
681d20c5fe
10 changed files with 138 additions and 103 deletions
|
@ -327,7 +327,7 @@ export class AdminDialog extends IGBDialog {
|
||||||
let sec = new SecService();
|
let sec = new SecService();
|
||||||
const member = step.context.activity.from;
|
const member = step.context.activity.from;
|
||||||
const user = await sec.ensureUser(
|
const user = await sec.ensureUser(
|
||||||
min.instance.instanceId,
|
min,
|
||||||
member.id,
|
member.id,
|
||||||
member.name,
|
member.name,
|
||||||
'',
|
'',
|
||||||
|
|
|
@ -1220,7 +1220,7 @@ export class DialogKeywords {
|
||||||
let user = await sec.getUserFromSystemId(fromOrDialogName);
|
let user = await sec.getUserFromSystemId(fromOrDialogName);
|
||||||
if (!user) {
|
if (!user) {
|
||||||
user = await sec.ensureUser(
|
user = await sec.ensureUser(
|
||||||
min.instance.instanceId,
|
min,
|
||||||
fromOrDialogName,
|
fromOrDialogName,
|
||||||
fromOrDialogName,
|
fromOrDialogName,
|
||||||
null,
|
null,
|
||||||
|
|
|
@ -328,6 +328,10 @@ export class GBMinService {
|
||||||
if (!Fs.existsSync(dir)) {
|
if (!Fs.existsSync(dir)) {
|
||||||
mkdirp.sync(dir);
|
mkdirp.sync(dir);
|
||||||
}
|
}
|
||||||
|
dir = `work/${gbai}/users`;
|
||||||
|
if (!Fs.existsSync(dir)) {
|
||||||
|
mkdirp.sync(dir);
|
||||||
|
}
|
||||||
|
|
||||||
// Loads Named Entity data for this bot.
|
// Loads Named Entity data for this bot.
|
||||||
|
|
||||||
|
@ -956,7 +960,7 @@ export class GBMinService {
|
||||||
|
|
||||||
const member = context.activity.from;
|
const member = context.activity.from;
|
||||||
const sec = new SecService();
|
const sec = new SecService();
|
||||||
const user = await sec.ensureUser(instance.instanceId, member.id, member.name, '', 'web', member.name, null);
|
const user = await sec.ensureUser(min, member.id, member.name, '', 'web', member.name, null);
|
||||||
const userId = user.userId;
|
const userId = user.userId;
|
||||||
const params = user.params ? JSON.parse(user.params) : {};
|
const params = user.params ? JSON.parse(user.params) : {};
|
||||||
|
|
||||||
|
@ -1351,7 +1355,7 @@ export class GBMinService {
|
||||||
memberId = member.id;
|
memberId = member.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
let user = await sec.ensureUser(min.instance.instanceId, memberId, member.name, '', 'web', member.name, email);
|
let user = await sec.ensureUser(min, memberId, member.name, '', 'web', member.name, email);
|
||||||
|
|
||||||
const userId = user.userId;
|
const userId = user.userId;
|
||||||
const params = user.params ? JSON.parse(user.params) : {};
|
const params = user.params ? JSON.parse(user.params) : {};
|
||||||
|
|
|
@ -88,7 +88,7 @@ export class FeedbackDialog extends IGBDialog {
|
||||||
if (args && args.to) {
|
if (args && args.to) {
|
||||||
// An user from Teams willing to transfer to a WhatsApp user.
|
// An user from Teams willing to transfer to a WhatsApp user.
|
||||||
|
|
||||||
await sec.ensureUser(min.instance.instanceId, args.to, 'Name', '', 'whatsapp', 'Name', null);
|
await sec.ensureUser(min, args.to, 'Name', '', 'whatsapp', 'Name', null);
|
||||||
|
|
||||||
await sec.assignHumanAgent(min, args.to, profile.userSystemId);
|
await sec.assignHumanAgent(min, args.to, profile.userSystemId);
|
||||||
await min.conversationalService.sendText(
|
await min.conversationalService.sendText(
|
||||||
|
|
|
@ -137,7 +137,7 @@ export class GoogleChatDirectLine extends GBService {
|
||||||
message.ack();
|
message.ack();
|
||||||
|
|
||||||
const sec = new SecService();
|
const sec = new SecService();
|
||||||
const user = await sec.ensureUser(this.min.instance.instanceId, from, from, '', 'googlechat', fromName, from);
|
const user = await sec.ensureUser(this.min, from, from, '', 'googlechat', fromName, from);
|
||||||
|
|
||||||
await sec.updateConversationReferenceById(user.userId, threadName);
|
await sec.updateConversationReferenceById(user.userId, threadName);
|
||||||
|
|
||||||
|
|
|
@ -32,14 +32,35 @@
|
||||||
|
|
||||||
import { GBMinInstance } from 'botlib';
|
import { GBMinInstance } from 'botlib';
|
||||||
import OpenAI from "openai";
|
import OpenAI from "openai";
|
||||||
import { ChatGPTAPIBrowser, getOpenAIAuth } from 'chatgpt'
|
import { OpenAIChat } from 'langchain/llms/openai';
|
||||||
|
import { CallbackManager } from 'langchain/callbacks';
|
||||||
|
import { ChatPromptTemplate, HumanMessagePromptTemplate, SystemMessagePromptTemplate } from 'langchain/prompts';
|
||||||
|
import { LLMChain } from 'langchain/chains';
|
||||||
|
import { BufferWindowMemory } from 'langchain/memory';
|
||||||
import { CollectionUtil } from 'pragmatismo-io-framework';
|
import { CollectionUtil } from 'pragmatismo-io-framework';
|
||||||
import { DialogKeywords } from '../../basic.gblib/services/DialogKeywords.js';
|
import { DialogKeywords } from '../../basic.gblib/services/DialogKeywords.js';
|
||||||
import Path from 'path';
|
import Path from 'path';
|
||||||
import * as Fs from 'fs';
|
import * as Fs from 'fs';
|
||||||
|
import { HNSWLib } from 'langchain/vectorstores/hnswlib';
|
||||||
|
import { GuaribasSubject } from '../../kb.gbapp/models/index.js';
|
||||||
|
import { GBConfigService } from '../../core.gbapp/services/GBConfigService.js';
|
||||||
|
|
||||||
export class ChatServices {
|
export class ChatServices {
|
||||||
|
|
||||||
|
private static async getRelevantContext(
|
||||||
|
vectorStore: HNSWLib,
|
||||||
|
sanitizedQuestion: string,
|
||||||
|
numDocuments: number
|
||||||
|
): Promise<string> {
|
||||||
|
const documents = await vectorStore.similaritySearch(sanitizedQuestion, numDocuments);
|
||||||
|
return documents
|
||||||
|
.map((doc) => doc.pageContent)
|
||||||
|
.join(', ')
|
||||||
|
.trim()
|
||||||
|
.replaceAll('\n', ' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static async sendMessage(min: GBMinInstance, text: string) {
|
public static async sendMessage(min: GBMinInstance, text: string) {
|
||||||
let key;
|
let key;
|
||||||
if (process.env.OPENAI_KEY) {
|
if (process.env.OPENAI_KEY) {
|
||||||
|
@ -112,4 +133,85 @@ export class ChatServices {
|
||||||
// });
|
// });
|
||||||
// return chatCompletion.choices[0].message.content;
|
// return chatCompletion.choices[0].message.content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static async answerByGPT(min: GBMinInstance,
|
||||||
|
query: string,
|
||||||
|
searchScore: number,
|
||||||
|
subjects: GuaribasSubject[]
|
||||||
|
) {
|
||||||
|
|
||||||
|
if (!process.env.OPENAI_KEY) {
|
||||||
|
return { answer: undefined, questionId: 0 };
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const contextVectorStore = min['vectorStore'];
|
||||||
|
const question = query.trim().replaceAll('\n', ' ');
|
||||||
|
const context = await this.getRelevantContext(contextVectorStore, question, 1);
|
||||||
|
|
||||||
|
const systemPrompt = SystemMessagePromptTemplate.fromTemplate(
|
||||||
|
`You are $${min.botId}`);
|
||||||
|
|
||||||
|
const contentLocale = min.core.getParam(
|
||||||
|
min.instance,
|
||||||
|
'Default Content Language',
|
||||||
|
GBConfigService.get('DEFAULT_CONTENT_LANGUAGE')
|
||||||
|
);
|
||||||
|
|
||||||
|
const chatPrompt = ChatPromptTemplate.fromPromptMessages([
|
||||||
|
systemPrompt,
|
||||||
|
HumanMessagePromptTemplate.fromTemplate(`Answer in ${contentLocale}.
|
||||||
|
You have access to the context (RELEVANTDOCS) provided by the user.
|
||||||
|
|
||||||
|
When answering think about whether the question in RELEVANTDOCS, but never mention
|
||||||
|
to user about the source.
|
||||||
|
Don’t justify your answers. Don't refer to yourself in any of the created content.
|
||||||
|
Don´t prefix RESPONSE: when answering the user.
|
||||||
|
RELEVANTDOCS: {context}
|
||||||
|
|
||||||
|
QUESTION: """{input}"""
|
||||||
|
|
||||||
|
`),
|
||||||
|
]);
|
||||||
|
const windowMemory = new BufferWindowMemory({
|
||||||
|
returnMessages: false,
|
||||||
|
memoryKey: 'immediate_history',
|
||||||
|
inputKey: 'input',
|
||||||
|
k: 2,
|
||||||
|
});
|
||||||
|
|
||||||
|
const callbackManager = CallbackManager.fromHandlers({
|
||||||
|
// This function is called when the LLM generates a new token (i.e., a prediction for the next word)
|
||||||
|
async handleLLMNewToken(token: string) {
|
||||||
|
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const llm = new OpenAIChat({
|
||||||
|
streaming: true,
|
||||||
|
callbackManager,
|
||||||
|
modelName: 'gpt-3.5-turbo',
|
||||||
|
});
|
||||||
|
|
||||||
|
const chain = new LLMChain({
|
||||||
|
prompt: chatPrompt,
|
||||||
|
memory: windowMemory,
|
||||||
|
llm,
|
||||||
|
});
|
||||||
|
|
||||||
|
const response = await chain.call({
|
||||||
|
input: question,
|
||||||
|
context,
|
||||||
|
history: '',
|
||||||
|
immediate_history: '',
|
||||||
|
});
|
||||||
|
if (response) {
|
||||||
|
|
||||||
|
return { answer: response.text, questionId: 0 };
|
||||||
|
}
|
||||||
|
|
||||||
|
return { answer: undefined, questionId: 0 };
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -132,7 +132,7 @@ export class AskDialog extends IGBDialog {
|
||||||
let sec = new SecService();
|
let sec = new SecService();
|
||||||
const member = step.context.activity.from;
|
const member = step.context.activity.from;
|
||||||
const user = await sec.ensureUser(
|
const user = await sec.ensureUser(
|
||||||
min.instance.instanceId,
|
min,
|
||||||
member.id,
|
member.id,
|
||||||
member.name,
|
member.name,
|
||||||
'',
|
'',
|
||||||
|
@ -187,7 +187,7 @@ export class AskDialog extends IGBDialog {
|
||||||
let answer: GuaribasAnswer = null;
|
let answer: GuaribasAnswer = null;
|
||||||
const member = step.context.activity.from;
|
const member = step.context.activity.from;
|
||||||
const sec = new SecService();
|
const sec = new SecService();
|
||||||
let user = await sec.ensureUser(min.instance.instanceId, member.id, member.name, '', 'web', member.name, null);
|
let user = await sec.ensureUser(min, member.id, member.name, '', 'web', member.name, null);
|
||||||
|
|
||||||
const minBoot = GBServer.globals.minBoot as any;
|
const minBoot = GBServer.globals.minBoot as any;
|
||||||
|
|
||||||
|
@ -436,7 +436,7 @@ export class AskDialog extends IGBDialog {
|
||||||
let sec = new SecService();
|
let sec = new SecService();
|
||||||
const member = step.context.activity.from;
|
const member = step.context.activity.from;
|
||||||
const user = await sec.ensureUser(
|
const user = await sec.ensureUser(
|
||||||
min.instance.instanceId,
|
min,
|
||||||
member.id,
|
member.id,
|
||||||
member.name,
|
member.name,
|
||||||
'',
|
'',
|
||||||
|
|
|
@ -34,28 +34,22 @@
|
||||||
|
|
||||||
import Path from 'path';
|
import Path from 'path';
|
||||||
import Fs from 'fs';
|
import Fs from 'fs';
|
||||||
import { OpenAIChat } from 'langchain/llms/openai';
|
|
||||||
import { CallbackManager } from 'langchain/callbacks';
|
|
||||||
import urlJoin from 'url-join';
|
import urlJoin from 'url-join';
|
||||||
import asyncPromise from 'async-promises';
|
import asyncPromise from 'async-promises';
|
||||||
import walkPromise from 'walk-promise';
|
import walkPromise from 'walk-promise';
|
||||||
import { SearchClient } from '@azure/search-documents';
|
import { SearchClient } from '@azure/search-documents';
|
||||||
import Excel from 'exceljs';
|
import Excel from 'exceljs';
|
||||||
import getSlug from 'speakingurl';
|
import getSlug from 'speakingurl';
|
||||||
import { ChatPromptTemplate, HumanMessagePromptTemplate, SystemMessagePromptTemplate } from 'langchain/prompts';
|
|
||||||
import { LLMChain } from 'langchain/chains';
|
|
||||||
import { GBServer } from '../../../src/app.js';
|
import { GBServer } from '../../../src/app.js';
|
||||||
import { HNSWLib } from 'langchain/vectorstores/hnswlib';
|
|
||||||
import { JSONLoader } from 'langchain/document_loaders/fs/json';
|
import { JSONLoader } from 'langchain/document_loaders/fs/json';
|
||||||
import { TextLoader } from 'langchain/document_loaders/fs/text';
|
import { TextLoader } from 'langchain/document_loaders/fs/text';
|
||||||
import { PDFLoader } from 'langchain/document_loaders/fs/pdf';
|
import { PDFLoader } from 'langchain/document_loaders/fs/pdf';
|
||||||
import { DocxLoader } from 'langchain/document_loaders/fs/docx';
|
import { DocxLoader } from 'langchain/document_loaders/fs/docx';
|
||||||
import { EPubLoader } from 'langchain/document_loaders/fs/epub';
|
import { EPubLoader } from 'langchain/document_loaders/fs/epub';
|
||||||
import { CSVLoader } from 'langchain/document_loaders/fs/csv';
|
import { CSVLoader } from 'langchain/document_loaders/fs/csv';
|
||||||
import { RecursiveCharacterTextSplitter } from 'langchain/text_splitter';
|
|
||||||
import { BufferWindowMemory } from 'langchain/memory';
|
|
||||||
import { Document } from 'langchain/document';
|
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
|
import { RecursiveCharacterTextSplitter } from 'langchain/text_splitter';
|
||||||
|
import { Document } from 'langchain/document';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
GBDialogStep,
|
GBDialogStep,
|
||||||
|
@ -85,6 +79,8 @@ import { GBAdminService } from '../../admin.gbapp/services/GBAdminService.js';
|
||||||
import { GBVMService } from '../../basic.gblib/services/GBVMService.js';
|
import { GBVMService } from '../../basic.gblib/services/GBVMService.js';
|
||||||
import { DialogKeywords } from '../../basic.gblib/services/DialogKeywords.js';
|
import { DialogKeywords } from '../../basic.gblib/services/DialogKeywords.js';
|
||||||
import { GBMinService } from '../../core.gbapp/services/GBMinService.js';
|
import { GBMinService } from '../../core.gbapp/services/GBMinService.js';
|
||||||
|
import { ChatServices } from '../../gpt.gblib/services/ChatServices.js';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Result for quey on KB data.
|
* Result for quey on KB data.
|
||||||
|
@ -365,7 +361,7 @@ export class KBService implements IGBKBService {
|
||||||
returnedScore: ${returnedScore} < required (searchScore): ${searchScore}`
|
returnedScore: ${returnedScore} < required (searchScore): ${searchScore}`
|
||||||
);
|
);
|
||||||
|
|
||||||
return await this.answerByGPT(min,
|
return await ChatServices.answerByGPT(min,
|
||||||
query,
|
query,
|
||||||
searchScore,
|
searchScore,
|
||||||
subjects
|
subjects
|
||||||
|
@ -374,86 +370,8 @@ export class KBService implements IGBKBService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async getRelevantContext(
|
|
||||||
vectorStore: HNSWLib,
|
|
||||||
sanitizedQuestion: string,
|
|
||||||
numDocuments: number
|
|
||||||
): Promise<string> {
|
|
||||||
const documents = await vectorStore.similaritySearch(sanitizedQuestion, numDocuments);
|
|
||||||
return documents
|
|
||||||
.map((doc) => doc.pageContent)
|
|
||||||
.join(', ')
|
|
||||||
.trim()
|
|
||||||
.replaceAll('\n', ' ');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public async answerByGPT(min: GBMinInstance,
|
|
||||||
query: string,
|
|
||||||
searchScore: number,
|
|
||||||
subjects: GuaribasSubject[]
|
|
||||||
) {
|
|
||||||
const contextVectorStore = min['vectorStore'];
|
|
||||||
const question = query.trim().replaceAll('\n', ' ');
|
|
||||||
const context = await this.getRelevantContext(contextVectorStore, question, 1);
|
|
||||||
|
|
||||||
const systemPrompt = SystemMessagePromptTemplate.fromTemplate(
|
|
||||||
"You are General Bots");
|
|
||||||
|
|
||||||
const chatPrompt = ChatPromptTemplate.fromPromptMessages([
|
|
||||||
systemPrompt,
|
|
||||||
HumanMessagePromptTemplate.fromTemplate(`Answer in pt-br.
|
|
||||||
You have access to the context (RELEVANTDOCS) provided by the user.
|
|
||||||
|
|
||||||
When answering think about whether the question in RELEVANTDOCS, but never mention
|
|
||||||
to user about the source.
|
|
||||||
Don’t justify your answers. Don't refer to yourself in any of the created content.
|
|
||||||
Don´t prefix RESPONSE: when answering the user.
|
|
||||||
RELEVANTDOCS: {context}
|
|
||||||
|
|
||||||
QUESTION: """{input}"""
|
|
||||||
|
|
||||||
`),
|
|
||||||
]);
|
|
||||||
const windowMemory = new BufferWindowMemory({
|
|
||||||
returnMessages: false,
|
|
||||||
memoryKey: 'immediate_history',
|
|
||||||
inputKey: 'input',
|
|
||||||
k: 2,
|
|
||||||
});
|
|
||||||
|
|
||||||
const callbackManager = CallbackManager.fromHandlers({
|
|
||||||
// This function is called when the LLM generates a new token (i.e., a prediction for the next word)
|
|
||||||
async handleLLMNewToken(token: string) {
|
|
||||||
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const llm = new OpenAIChat({
|
|
||||||
streaming: true,
|
|
||||||
callbackManager,
|
|
||||||
modelName: 'gpt-3.5-turbo',
|
|
||||||
});
|
|
||||||
|
|
||||||
const chain = new LLMChain({
|
|
||||||
prompt: chatPrompt,
|
|
||||||
memory: windowMemory,
|
|
||||||
llm,
|
|
||||||
});
|
|
||||||
|
|
||||||
const response = await chain.call({
|
|
||||||
input: question,
|
|
||||||
context,
|
|
||||||
history: '',
|
|
||||||
immediate_history: '',
|
|
||||||
});
|
|
||||||
if (response) {
|
|
||||||
|
|
||||||
return { answer: response.text, questionId: 0 };
|
|
||||||
}
|
|
||||||
|
|
||||||
return { answer: undefined, questionId: 0 };
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public async getSubjectItems(instanceId: number, parentId: number): Promise<GuaribasSubject[]> {
|
public async getSubjectItems(instanceId: number, parentId: number): Promise<GuaribasSubject[]> {
|
||||||
|
|
|
@ -1,16 +1,18 @@
|
||||||
import { GBServer } from '../../../src/app.js';
|
|
||||||
import { ConversationReference } from 'botbuilder';
|
import { ConversationReference } from 'botbuilder';
|
||||||
import { GBLog, GBMinInstance, GBService, IGBInstance } from 'botlib';
|
import { GBLog, GBMinInstance, GBService, IGBInstance } from 'botlib';
|
||||||
import { CollectionUtil } from 'pragmatismo-io-framework';
|
import { CollectionUtil } from 'pragmatismo-io-framework';
|
||||||
import { GuaribasUser } from '../models/index.js';
|
import { GuaribasUser } from '../models/index.js';
|
||||||
import { FindOptions } from 'sequelize';
|
import { FindOptions } from 'sequelize';
|
||||||
|
import { DialogKeywords } from '../../../packages/basic.gblib/services/DialogKeywords.js';
|
||||||
|
import * as Fs from 'fs';
|
||||||
|
import mkdirp from 'mkdirp';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Security service layer.
|
* Security service layer.
|
||||||
*/
|
*/
|
||||||
export class SecService extends GBService {
|
export class SecService extends GBService {
|
||||||
public async ensureUser(
|
public async ensureUser(
|
||||||
instanceId: number,
|
min: GBMinInstance,
|
||||||
userSystemId: string,
|
userSystemId: string,
|
||||||
userName: string,
|
userName: string,
|
||||||
address: string,
|
address: string,
|
||||||
|
@ -26,9 +28,18 @@ export class SecService extends GBService {
|
||||||
|
|
||||||
if (!user) {
|
if (!user) {
|
||||||
user = GuaribasUser.build();
|
user = GuaribasUser.build();
|
||||||
|
const gbaiPath = DialogKeywords.getGBAIPath(min.botId);
|
||||||
|
|
||||||
|
const dir = `work/${gbaiPath}/users/${userSystemId}`;
|
||||||
|
if (!Fs.existsSync(dir)) {
|
||||||
|
mkdirp.sync(dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
user.instanceId = instanceId;
|
user.instanceId = min.instance.instanceId;
|
||||||
user.userSystemId = userSystemId;
|
user.userSystemId = userSystemId;
|
||||||
user.userName = userName;
|
user.userName = userName;
|
||||||
user.displayName = displayName;
|
user.displayName = displayName;
|
||||||
|
|
|
@ -472,7 +472,7 @@ export class WhatsappDirectLine extends GBService {
|
||||||
});
|
});
|
||||||
|
|
||||||
const sec = new SecService();
|
const sec = new SecService();
|
||||||
const user = await sec.ensureUser(this.min.instance.instanceId, from, fromName, '', 'whatsapp', fromName, null);
|
const user = await sec.ensureUser(this.min, from, fromName, '', 'whatsapp', fromName, null);
|
||||||
const locale = user.locale ? user.locale : 'pt';
|
const locale = user.locale ? user.locale : 'pt';
|
||||||
|
|
||||||
if (answerText) {
|
if (answerText) {
|
||||||
|
@ -1083,7 +1083,7 @@ export class WhatsappDirectLine extends GBService {
|
||||||
}
|
}
|
||||||
const botId = getKeyByValue(WhatsappDirectLine.botGroups, group);
|
const botId = getKeyByValue(WhatsappDirectLine.botGroups, group);
|
||||||
if ((botId && user.instanceId !== this.min.instance.instanceId) || !user) {
|
if ((botId && user.instanceId !== this.min.instance.instanceId) || !user) {
|
||||||
user = await sec.ensureUser(this.min.instance.instanceId, id, senderName, '', 'whatsApp', senderName, null);
|
user = await sec.ensureUser(this.min, id, senderName, '', 'whatsApp', senderName, null);
|
||||||
}
|
}
|
||||||
if (botId) {
|
if (botId) {
|
||||||
activeMin = GBServer.globals.minInstances.filter(p => p.instance.botId === botId)[0];
|
activeMin = GBServer.globals.minInstances.filter(p => p.instance.botId === botId)[0];
|
||||||
|
@ -1122,7 +1122,7 @@ export class WhatsappDirectLine extends GBService {
|
||||||
// start dialog if any is specified in Config.xlsx.
|
// start dialog if any is specified in Config.xlsx.
|
||||||
|
|
||||||
if (user === null || user.hearOnDialog) {
|
if (user === null || user.hearOnDialog) {
|
||||||
user = await sec.ensureUser(activeMin.instance.instanceId, id, senderName, '', 'whatsapp', senderName, null);
|
user = await sec.ensureUser(activeMin, id, senderName, '', 'whatsapp', senderName, null);
|
||||||
|
|
||||||
const startDialog = user.hearOnDialog
|
const startDialog = user.hearOnDialog
|
||||||
? user.hearOnDialog
|
? user.hearOnDialog
|
||||||
|
|
Loading…
Add table
Reference in a new issue