feat(DialogKeywords): integrate MinIO client for file handling in gbcluster mode
Some checks failed
GBCI / build (push) Failing after 3h14m23s
Some checks failed
GBCI / build (push) Failing after 3h14m23s
This commit is contained in:
parent
7035c6799f
commit
d2851aabd6
1 changed files with 210 additions and 201 deletions
|
@ -496,15 +496,14 @@ export class GBMinService {
|
||||||
|
|
||||||
if (!req.body.object) {
|
if (!req.body.object) {
|
||||||
|
|
||||||
if (req.body.To){
|
if (req.body.To) {
|
||||||
|
|
||||||
const to = req.body.To.replace(/whatsapp\:\+/gi, '');
|
const to = req.body.To.replace(/whatsapp\:\+/gi, '');
|
||||||
whatsAppDirectLine = WhatsappDirectLine.botsByNumber[to];
|
whatsAppDirectLine = WhatsappDirectLine.botsByNumber[to];
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
const minBoot = GBServer.globals.minBoot as GBMinInstance;
|
||||||
const minBoot = GBServer.globals.minBoot as GBMinInstance;
|
whatsAppDirectLine = minBoot.whatsAppDirectLine;
|
||||||
whatsAppDirectLine = minBoot.whatsAppDirectLine;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -744,8 +743,8 @@ export class GBMinService {
|
||||||
|
|
||||||
if (GBConfigService.get('GB_MODE') !== 'legacy') {
|
if (GBConfigService.get('GB_MODE') !== 'legacy') {
|
||||||
const url =
|
const url =
|
||||||
process.env.BOT_URL ||
|
process.env.BOT_URL ||
|
||||||
`http://localhost:${GBConfigService.get('PORT')}`;
|
`http://localhost:${GBConfigService.get('PORT')}`;
|
||||||
|
|
||||||
config['domain'] = urlJoin(url, 'directline', botId);
|
config['domain'] = urlJoin(url, 'directline', botId);
|
||||||
|
|
||||||
|
@ -841,7 +840,7 @@ export class GBMinService {
|
||||||
|
|
||||||
// The minimal bot is built here.
|
// The minimal bot is built here.
|
||||||
|
|
||||||
const min = new GBMinInstance();
|
const min = new GBMinInstance();
|
||||||
|
|
||||||
// Setups default BOT Framework dialogs.
|
// Setups default BOT Framework dialogs.
|
||||||
|
|
||||||
|
@ -1080,58 +1079,6 @@ export class GBMinService {
|
||||||
try {
|
try {
|
||||||
const conversationReference = JSON.stringify(TurnContext.getConversationReference(context.activity));
|
const conversationReference = JSON.stringify(TurnContext.getConversationReference(context.activity));
|
||||||
user = await sec.updateConversationReferenceById(user.userId, conversationReference);
|
user = await sec.updateConversationReferenceById(user.userId, conversationReference);
|
||||||
|
|
||||||
const auth = min.core.getParam(min.instance, 'Enable Authentication', null);
|
|
||||||
|
|
||||||
if (auth && await t.find({pid: pid, "users.csv", `key={member.id}`})){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// First time processing.
|
|
||||||
|
|
||||||
if (!params.loaded) {
|
|
||||||
if (step.context.activity.channelId !== 'msteams') {
|
|
||||||
await min.conversationalService.sendEvent(min, step, 'loadInstance', {});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Default params.
|
|
||||||
|
|
||||||
await sec.setParam(userId, 'loaded', true);
|
|
||||||
await sec.setParam(userId, 'subjects', '[]');
|
|
||||||
await sec.setParam(userId, 'cb', null);
|
|
||||||
await sec.setParam(userId, 'welcomed', 'false');
|
|
||||||
await sec.setParam(userId, 'maxLines', 100);
|
|
||||||
await sec.setParam(userId, 'translatorOn', true);
|
|
||||||
await sec.setParam(userId, 'wholeWord', true);
|
|
||||||
await sec.setParam(userId, 'theme', 'white');
|
|
||||||
await sec.setParam(userId, 'maxColumns', 40);
|
|
||||||
|
|
||||||
// This same event is dispatched either to all participants
|
|
||||||
// including the bot, that is filtered bellow.
|
|
||||||
|
|
||||||
if (context.activity.from.id !== min.botId) {
|
|
||||||
// Creates a new row in user table if it does not exists.
|
|
||||||
if (process.env.PRIVACY_STORE_MESSAGES === 'true') {
|
|
||||||
// Stores conversation associated to the user to group each message.
|
|
||||||
|
|
||||||
const analytics = new AnalyticsService();
|
|
||||||
await analytics.createConversation(user);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
await sec.updateConversationReferenceById(userId, conversationReference);
|
|
||||||
|
|
||||||
if (step.context.activity.channelId !== 'msteams') {
|
|
||||||
const service = new KBService(min.core.sequelize);
|
|
||||||
const data = await service.getFaqBySubjectArray(min.instance.instanceId, 'faq', undefined);
|
|
||||||
await min.conversationalService.sendEvent(min, step, 'play', {
|
|
||||||
playerType: 'bullet',
|
|
||||||
data: data.slice(0, 10)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let conversationId = step.context.activity.conversation.id;
|
let conversationId = step.context.activity.conversation.id;
|
||||||
|
|
||||||
let pid = GBMinService.pidsConversation[conversationId];
|
let pid = GBMinService.pidsConversation[conversationId];
|
||||||
|
@ -1149,164 +1096,226 @@ export class GBMinService {
|
||||||
GBMinService.pidsConversation[conversationId] = pid;
|
GBMinService.pidsConversation[conversationId] = pid;
|
||||||
step.context.activity['pid'] = pid;
|
step.context.activity['pid'] = pid;
|
||||||
|
|
||||||
const notes = min.core.getParam(min.instance, 'Notes', null);
|
const auth = min.core.getParam(min.instance, 'Enable Authentication', null);
|
||||||
if (await this.handleUploads(min, step, user, params, notes != null)) {
|
|
||||||
return;
|
|
||||||
|
|
||||||
|
if (auth) {
|
||||||
|
const res = await t.find({ pid: pid, handle: "users.csv", args: [`key={member.id}`] });
|
||||||
|
|
||||||
|
if (!res) {
|
||||||
|
await min.conversationalService.sendText(
|
||||||
|
min,
|
||||||
|
step,
|
||||||
|
'Sorry, not authorized.'
|
||||||
|
);
|
||||||
|
res.end();
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Required for MSTEAMS handling of persisted conversations.
|
|
||||||
|
|
||||||
if (step.context.activity.channelId === 'msteams') {
|
// First time processing.
|
||||||
if (step.context.activity.attachments && step.context.activity.attachments.length > 1) {
|
|
||||||
const file = context.activity.attachments[0];
|
|
||||||
const credentials = new MicrosoftAppCredentials(
|
|
||||||
min.instance.marketplaceId,
|
|
||||||
min.instance.marketplacePassword
|
|
||||||
);
|
|
||||||
const botToken = await credentials.getToken();
|
|
||||||
const headers = { Authorization: `Bearer ${botToken}` };
|
|
||||||
const data = await t.getByHttp({
|
|
||||||
pid: 0,
|
|
||||||
url: file.contentUrl,
|
|
||||||
headers,
|
|
||||||
username: null,
|
|
||||||
ps: null,
|
|
||||||
qs: null
|
|
||||||
});
|
|
||||||
const packagePath = GBUtil.getGBAIPath(min.botId);
|
|
||||||
const folder = `work/${path}/cache`;
|
|
||||||
const filename = `${GBAdminService.generateUuid()}.png`;
|
|
||||||
|
|
||||||
await fs.writeFile(urlJoin(folder, filename), data);
|
if (!params.loaded) {
|
||||||
step.context.activity.text = urlJoin(
|
if (step.context.activity.channelId !== 'msteams') {
|
||||||
GBServer.globals.publicAddress,
|
await min.conversationalService.sendEvent(min, step, 'loadInstance', {});
|
||||||
`${min.instance.botId}`,
|
|
||||||
'cache',
|
|
||||||
filename
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(await sec.getParam(user, 'welcomed'))) {
|
|
||||||
const startDialog = min.core.getParam(min.instance, 'Start Dialog', null);
|
|
||||||
if (startDialog) {
|
|
||||||
await sec.setParam(userId, 'welcomed', 'true');
|
|
||||||
GBLogEx.info(
|
|
||||||
min,
|
|
||||||
`Auto start (teams) dialog is now being called: ${startDialog} for ${min.instance.botId}...`
|
|
||||||
);
|
|
||||||
|
|
||||||
await GBVMService.callVM(startDialog.toLowerCase(), min, step, 0);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Answer to specific BOT Framework event conversationUpdate to auto start dialogs.
|
// Default params.
|
||||||
// Skips if the bot is talking.
|
|
||||||
|
|
||||||
const startDialog = min.core.getParam(min.instance, 'Start Dialog', null);
|
await sec.setParam(userId, 'loaded', true);
|
||||||
|
await sec.setParam(userId, 'subjects', '[]');
|
||||||
|
await sec.setParam(userId, 'cb', null);
|
||||||
|
await sec.setParam(userId, 'welcomed', 'false');
|
||||||
|
await sec.setParam(userId, 'maxLines', 100);
|
||||||
|
await sec.setParam(userId, 'translatorOn', true);
|
||||||
|
await sec.setParam(userId, 'wholeWord', true);
|
||||||
|
await sec.setParam(userId, 'theme', 'white');
|
||||||
|
await sec.setParam(userId, 'maxColumns', 40);
|
||||||
|
|
||||||
if (context.activity.type === 'installationUpdate') {
|
// This same event is dispatched either to all participants
|
||||||
GBLogEx.info(min, `Bot installed on Teams.`);
|
// including the bot, that is filtered bellow.
|
||||||
} else if (context.activity.type === 'conversationUpdate' &&
|
|
||||||
context.activity.membersAdded.length > 0) {
|
|
||||||
// Check if a bot or a human participant is being added to the conversation.
|
|
||||||
|
|
||||||
const member = context.activity.membersAdded[0];
|
if (context.activity.from.id !== min.botId) {
|
||||||
if (context.activity.membersAdded[0].id === context.activity.recipient.id) {
|
// Creates a new row in user table if it does not exists.
|
||||||
GBLogEx.info(min, `Bot added to conversation, starting chat...`);
|
if (process.env.PRIVACY_STORE_MESSAGES === 'true') {
|
||||||
|
// Stores conversation associated to the user to group each message.
|
||||||
|
|
||||||
// Calls onNewSession event on each .gbapp package.
|
const analytics = new AnalyticsService();
|
||||||
|
await analytics.createConversation(user);
|
||||||
await CollectionUtil.asyncForEach(appPackages, async e => {
|
|
||||||
await e.onNewSession(min, step);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Auto starts dialogs if any is specified.
|
|
||||||
|
|
||||||
if (!startDialog && !(await sec.getParam(user, 'welcomed'))) {
|
|
||||||
// Otherwise, calls / (root) to default welcome users.
|
|
||||||
|
|
||||||
await step.beginDialog('/');
|
|
||||||
} else {
|
|
||||||
if (
|
|
||||||
!GBMinService.userMobile(step) &&
|
|
||||||
!min['conversationWelcomed'][step.context.activity.conversation.id]
|
|
||||||
) {
|
|
||||||
|
|
||||||
const pid = GBVMService.createProcessInfo(user, min, step.context.activity.channelId, null, step);
|
|
||||||
step.context.activity['pid'] = pid;
|
|
||||||
|
|
||||||
min['conversationWelcomed'][step.context.activity.conversation.id] = true;
|
|
||||||
|
|
||||||
GBLogEx.info(
|
|
||||||
min,
|
|
||||||
`Auto start (web 1) dialog is now being called: ${startDialog} for ${min.instance.instanceId}...`
|
|
||||||
);
|
|
||||||
await GBVMService.callVM(startDialog.toLowerCase(), min, step, pid);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
GBLogEx.info(min, `Person added to conversation: ${member.name}`);
|
|
||||||
|
|
||||||
return;
|
await sec.updateConversationReferenceById(userId, conversationReference);
|
||||||
|
|
||||||
|
if (step.context.activity.channelId !== 'msteams') {
|
||||||
|
const service = new KBService(min.core.sequelize);
|
||||||
|
const data = await service.getFaqBySubjectArray(min.instance.instanceId, 'faq', undefined);
|
||||||
|
await min.conversationalService.sendEvent(min, step, 'play', {
|
||||||
|
playerType: 'bullet',
|
||||||
|
data: data.slice(0, 10)
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (context.activity.type === 'message') {
|
|
||||||
|
|
||||||
|
const notes = min.core.getParam(min.instance, 'Notes', null);
|
||||||
|
if (await this.handleUploads(min, step, user, params, notes != null)) {
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Required for MSTEAMS handling of persisted conversations.
|
||||||
|
|
||||||
|
if (step.context.activity.channelId === 'msteams') {
|
||||||
|
if (step.context.activity.attachments && step.context.activity.attachments.length > 1) {
|
||||||
|
const file = context.activity.attachments[0];
|
||||||
|
const credentials = new MicrosoftAppCredentials(
|
||||||
|
min.instance.marketplaceId,
|
||||||
|
min.instance.marketplacePassword
|
||||||
|
);
|
||||||
|
const botToken = await credentials.getToken();
|
||||||
|
const headers = { Authorization: `Bearer ${botToken}` };
|
||||||
|
const data = await t.getByHttp({
|
||||||
|
pid: 0,
|
||||||
|
url: file.contentUrl,
|
||||||
|
headers,
|
||||||
|
username: null,
|
||||||
|
ps: null,
|
||||||
|
qs: null
|
||||||
|
});
|
||||||
|
const packagePath = GBUtil.getGBAIPath(min.botId);
|
||||||
|
const folder = `work/${path}/cache`;
|
||||||
|
const filename = `${GBAdminService.generateUuid()}.png`;
|
||||||
|
|
||||||
|
await fs.writeFile(urlJoin(folder, filename), data);
|
||||||
|
step.context.activity.text = urlJoin(
|
||||||
|
GBServer.globals.publicAddress,
|
||||||
|
`${min.instance.botId}`,
|
||||||
|
'cache',
|
||||||
|
filename
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(await sec.getParam(user, 'welcomed'))) {
|
||||||
|
const startDialog = min.core.getParam(min.instance, 'Start Dialog', null);
|
||||||
|
if (startDialog) {
|
||||||
|
await sec.setParam(userId, 'welcomed', 'true');
|
||||||
|
GBLogEx.info(
|
||||||
|
min,
|
||||||
|
`Auto start (teams) dialog is now being called: ${startDialog} for ${min.instance.botId}...`
|
||||||
|
);
|
||||||
|
|
||||||
|
await GBVMService.callVM(startDialog.toLowerCase(), min, step, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Answer to specific BOT Framework event conversationUpdate to auto start dialogs.
|
||||||
|
// Skips if the bot is talking.
|
||||||
|
|
||||||
|
const startDialog = min.core.getParam(min.instance, 'Start Dialog', null);
|
||||||
|
|
||||||
|
if (context.activity.type === 'installationUpdate') {
|
||||||
|
GBLogEx.info(min, `Bot installed on Teams.`);
|
||||||
|
} else if (context.activity.type === 'conversationUpdate' &&
|
||||||
|
context.activity.membersAdded.length > 0) {
|
||||||
|
// Check if a bot or a human participant is being added to the conversation.
|
||||||
|
|
||||||
|
const member = context.activity.membersAdded[0];
|
||||||
|
if (context.activity.membersAdded[0].id === context.activity.recipient.id) {
|
||||||
|
GBLogEx.info(min, `Bot added to conversation, starting chat...`);
|
||||||
|
|
||||||
|
// Calls onNewSession event on each .gbapp package.
|
||||||
|
|
||||||
|
await CollectionUtil.asyncForEach(appPackages, async e => {
|
||||||
|
await e.onNewSession(min, step);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Auto starts dialogs if any is specified.
|
||||||
|
|
||||||
|
if (!startDialog && !(await sec.getParam(user, 'welcomed'))) {
|
||||||
|
// Otherwise, calls / (root) to default welcome users.
|
||||||
|
|
||||||
|
await step.beginDialog('/');
|
||||||
|
} else {
|
||||||
|
if (
|
||||||
|
!GBMinService.userMobile(step) &&
|
||||||
|
!min['conversationWelcomed'][step.context.activity.conversation.id]
|
||||||
|
) {
|
||||||
|
|
||||||
|
const pid = GBVMService.createProcessInfo(user, min, step.context.activity.channelId, null, step);
|
||||||
|
step.context.activity['pid'] = pid;
|
||||||
|
|
||||||
|
min['conversationWelcomed'][step.context.activity.conversation.id] = true;
|
||||||
|
|
||||||
|
GBLogEx.info(
|
||||||
|
min,
|
||||||
|
`Auto start (web 1) dialog is now being called: ${startDialog} for ${min.instance.instanceId}...`
|
||||||
|
);
|
||||||
|
await GBVMService.callVM(startDialog.toLowerCase(), min, step, pid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
GBLogEx.info(min, `Person added to conversation: ${member.name}`);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else if (context.activity.type === 'message') {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Required for F0 handling of persisted conversations.
|
// Required for F0 handling of persisted conversations.
|
||||||
|
|
||||||
GBLogEx.info(
|
GBLogEx.info(
|
||||||
|
min,
|
||||||
|
`Human: pid:${pid} ${context.activity.from.id} ${GBUtil.toYAML(WhatsappDirectLine.pidByNumber)} ${context.activity.text} (type: ${context.activity.type}, name: ${context.activity.name}, channelId: ${context.activity.channelId})`
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Processes messages activities.
|
||||||
|
|
||||||
|
await this.processMessageActivity(context, min, step, pid);
|
||||||
|
} else if (context.activity.type === 'event') {
|
||||||
|
// Processes events activities.
|
||||||
|
|
||||||
|
await this.processEventActivity(min, user, context, step);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
GBLog.error(`Receiver: ${GBUtil.toYAML(error)}`);
|
||||||
|
|
||||||
|
await min.conversationalService.sendText(
|
||||||
min,
|
min,
|
||||||
`Human: pid:${pid} ${context.activity.from.id} ${GBUtil.toYAML(WhatsappDirectLine.pidByNumber)} ${context.activity.text} (type: ${context.activity.type}, name: ${context.activity.name}, channelId: ${context.activity.channelId})`
|
step,
|
||||||
|
Messages[step.context.activity.locale].very_sorry_about_error
|
||||||
);
|
);
|
||||||
|
|
||||||
|
await step.beginDialog('/ask', { isReturning: true });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Processes messages activities.
|
try {
|
||||||
|
if (GBConfigService.get('GB_MODE') !== 'legacy') {
|
||||||
|
const context = adapter['createContext'](req);
|
||||||
|
context['_activity'] = context.activity.body;
|
||||||
|
await adapter['processActivity'](req, res, handler);
|
||||||
|
|
||||||
await this.processMessageActivity(context, min, step, pid);
|
// Return status
|
||||||
} else if (context.activity.type === 'event') {
|
res.status(200);
|
||||||
// Processes events activities.
|
|
||||||
|
|
||||||
await this.processEventActivity(min, user, context, step);
|
res.end();
|
||||||
|
} else {
|
||||||
|
await adapter['processActivity'](req, res, handler);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
GBLog.error(`Receiver: ${GBUtil.toYAML(error)}`);
|
if (error.code === 401) {
|
||||||
|
GBLog.error('Calling processActivity due to Signing Key could not be retrieved error.');
|
||||||
await min.conversationalService.sendText(
|
await adapter['processActivity'](req, res, handler);
|
||||||
min,
|
} else {
|
||||||
step,
|
GBLog.error(`Error processing activity: ${GBUtil.toYAML(error)}`);
|
||||||
Messages[step.context.activity.locale].very_sorry_about_error
|
throw error;
|
||||||
);
|
}
|
||||||
|
|
||||||
await step.beginDialog('/ask', { isReturning: true });
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (GBConfigService.get('GB_MODE') !== 'legacy') {
|
|
||||||
const context = adapter['createContext'](req);
|
|
||||||
context['_activity'] = context.activity.body;
|
|
||||||
await adapter['processActivity'](req, res, handler);
|
|
||||||
|
|
||||||
// Return status
|
|
||||||
res.status(200);
|
|
||||||
|
|
||||||
res.end();
|
|
||||||
} else {
|
|
||||||
await adapter['processActivity'](req, res, handler);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
if (error.code === 401) {
|
|
||||||
GBLog.error('Calling processActivity due to Signing Key could not be retrieved error.');
|
|
||||||
await adapter['processActivity'](req, res, handler);
|
|
||||||
} else {
|
|
||||||
GBLog.error(`Error processing activity: ${GBUtil.toYAML(error)}`);
|
|
||||||
throw error;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called to handle all event sent by .gbui clients.
|
* Called to handle all event sent by .gbui clients.
|
||||||
|
@ -1635,7 +1644,7 @@ export class GBMinService {
|
||||||
// Removes unwanted chars in input text.
|
// Removes unwanted chars in input text.
|
||||||
|
|
||||||
step.context.activity['originalText'] = context.activity.text;
|
step.context.activity['originalText'] = context.activity.text;
|
||||||
const text = context.activity.text;
|
const text = context.activity.text;
|
||||||
step.context.activity['originalText'];
|
step.context.activity['originalText'];
|
||||||
step.context.activity['text'] = text;
|
step.context.activity['text'] = text;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue