new(all): TRUE multicloud.
This commit is contained in:
parent
3f9e3b040e
commit
3299683268
12 changed files with 1397 additions and 143 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -29,3 +29,4 @@ package-lock.json
|
|||
yarn-lock.json
|
||||
logo.svg
|
||||
screenshot.png
|
||||
data.db
|
||||
|
|
1248
directline-3.0-local.json
Normal file
1248
directline-3.0-local.json
Normal file
File diff suppressed because one or more lines are too long
|
@ -39,6 +39,7 @@ import { GBAdminService } from '../../admin.gbapp/services/GBAdminService.js';
|
|||
import urlJoin from 'url-join';
|
||||
import { GBServer } from '../../../src/app.js';
|
||||
import { GBLogEx } from '../../core.gbapp/services/GBLogEx.js';
|
||||
import sharp from 'sharp';
|
||||
|
||||
/**
|
||||
* Image processing services of conversation to be called by BASIC.
|
||||
|
|
|
@ -341,6 +341,7 @@ export class GBConversationalService {
|
|||
}
|
||||
|
||||
public async sendEvent(min: GBMinInstance, step: GBDialogStep, name: string, value: Object): Promise<any> {
|
||||
|
||||
if (step.context.activity.channelId !== 'msteams' && step.context.activity.channelId !== 'omnichannel') {
|
||||
GBLogEx.info(
|
||||
min,
|
||||
|
|
|
@ -140,10 +140,7 @@ export class GBMinService {
|
|||
this.deployer = deployer;
|
||||
}
|
||||
|
||||
|
||||
public async enableAPI(min: GBMinInstance) {
|
||||
|
||||
}
|
||||
public async enableAPI(min: GBMinInstance) {}
|
||||
|
||||
/**
|
||||
* Constructs a new minimal instance for each bot.
|
||||
|
@ -175,7 +172,7 @@ export class GBMinService {
|
|||
instances,
|
||||
(async instance => {
|
||||
try {
|
||||
GBLog.info(`Mounting ${instance.botId}...`)
|
||||
GBLog.info(`Mounting ${instance.botId}...`);
|
||||
await this['mountBot'](instance);
|
||||
} catch (error) {
|
||||
GBLog.error(`Error mounting bot ${instance.botId}: ${error.message}\n${error.stack}`);
|
||||
|
@ -234,7 +231,7 @@ export class GBMinService {
|
|||
/**
|
||||
* Unmounts the bot web site (default.gbui) secure domain, if any.
|
||||
*/
|
||||
public async unloadDomain(instance: IGBInstance) { }
|
||||
public async unloadDomain(instance: IGBInstance) {}
|
||||
|
||||
/**
|
||||
* Mount the instance by creating an BOT Framework bot object,
|
||||
|
@ -242,7 +239,6 @@ export class GBMinService {
|
|||
* installing all BASIC artifacts from .gbdialog and OAuth2.
|
||||
*/
|
||||
public async mountBot(instance: IGBInstance) {
|
||||
|
||||
// Build bot adapter.
|
||||
|
||||
const { min, adapter, conversationState } = await this.buildBotAdapter(
|
||||
|
@ -331,7 +327,9 @@ export class GBMinService {
|
|||
const receiver = async (req, res) => {
|
||||
await this.receiver(req, res, conversationState, min, instance, GBServer.globals.appPackages);
|
||||
};
|
||||
const url = `/api/messages/${instance.botId}`;
|
||||
let url = `/api/messages/${instance.botId}`;
|
||||
GBServer.globals.server.post(url, receiver);
|
||||
url = `/api/messages`;
|
||||
GBServer.globals.server.post(url, receiver);
|
||||
GBServer.globals.server.get(url, (req, res) => {
|
||||
if (req.query['hub.mode'] === 'subscribe') {
|
||||
|
@ -426,35 +424,35 @@ export class GBMinService {
|
|||
|
||||
// Setups official handler for WhatsApp.
|
||||
|
||||
GBServer.globals.server.all(`/${min.instance.botId}/whatsapp`, async (req, res) => {
|
||||
GBServer.globals.server
|
||||
.all(`/${min.instance.botId}/whatsapp`, async (req, res) => {
|
||||
if (req.query['hub.mode'] === 'subscribe') {
|
||||
const val = req.query['hub.verify_token'];
|
||||
|
||||
if (val === process.env.META_CHALLENGE) {
|
||||
res.send(req.query['hub.challenge']);
|
||||
res.status(200);
|
||||
GBLogEx.info(min, `Meta callback OK. ${JSON.stringify(req.query)}`);
|
||||
} else {
|
||||
res.status(401);
|
||||
}
|
||||
res.end();
|
||||
|
||||
if (req.query['hub.mode'] === 'subscribe') {
|
||||
const val = req.query['hub.verify_token'];
|
||||
|
||||
if (val === process.env.META_CHALLENGE) {
|
||||
res.send(req.query['hub.challenge']);
|
||||
res.status(200);
|
||||
GBLogEx.info(min, `Meta callback OK. ${JSON.stringify(req.query)}`);
|
||||
} else {
|
||||
res.status(401);
|
||||
return;
|
||||
}
|
||||
res.end();
|
||||
|
||||
return;
|
||||
}
|
||||
let whatsAppDirectLine = min.whatsAppDirectLine;
|
||||
|
||||
let whatsAppDirectLine = min.whatsAppDirectLine;
|
||||
// Not meta, multiples bots on root bot.
|
||||
|
||||
// Not meta, multiples bots on root bot.
|
||||
if (!req.body.object) {
|
||||
const to = req.body.To.replace(/whatsapp\:\+/gi, '');
|
||||
whatsAppDirectLine = WhatsappDirectLine.botsByNumber[to];
|
||||
}
|
||||
|
||||
if (!req.body.object) {
|
||||
const to = req.body.To.replace(/whatsapp\:\+/gi, '');
|
||||
whatsAppDirectLine = WhatsappDirectLine.botsByNumber[to];
|
||||
}
|
||||
|
||||
await whatsAppDirectLine.WhatsAppCallback(req, res, whatsAppDirectLine.botId);
|
||||
}).bind(min);
|
||||
await whatsAppDirectLine.WhatsAppCallback(req, res, whatsAppDirectLine.botId);
|
||||
})
|
||||
.bind(min);
|
||||
|
||||
GBDeployer.mountGBKBAssets(`${botId}.gbkb`, botId, `${botId}.gbkb`);
|
||||
}
|
||||
|
@ -510,9 +508,7 @@ export class GBMinService {
|
|||
* on https://<gbhost>/<BotId>/token URL.
|
||||
*/
|
||||
private handleOAuthTokenRequests(server: any, min: GBMinInstance, instance: IGBInstance) {
|
||||
|
||||
server.get(`/${min.instance.botId}/token`, async (req, res) => {
|
||||
|
||||
let tokenName = req.query['value'];
|
||||
if (!tokenName) {
|
||||
tokenName = '';
|
||||
|
@ -535,9 +531,7 @@ export class GBMinService {
|
|||
if (tokenName) {
|
||||
const code = req?.query?.code;
|
||||
|
||||
let url = urlJoin(
|
||||
host,
|
||||
tenant, 'oauth/token');
|
||||
let url = urlJoin(host, tenant, 'oauth/token');
|
||||
let buff = new Buffer(`${clientId}:${clientSecret}`);
|
||||
const base64 = buff.toString('base64');
|
||||
|
||||
|
@ -549,14 +543,14 @@ export class GBMinService {
|
|||
'Content-Type': 'application/x-www-form-urlencoded'
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
'grant_type': 'authorization_code',
|
||||
'code': code
|
||||
grant_type: 'authorization_code',
|
||||
code: code
|
||||
})
|
||||
};
|
||||
const result = await fetch(url, options);
|
||||
|
||||
if (result.status != 200) {
|
||||
throw new Error(`handleOAuthTokenRequests error: ${result.status}: ${result.statusText}.`)
|
||||
throw new Error(`handleOAuthTokenRequests error: ${result.status}: ${result.statusText}.`);
|
||||
}
|
||||
|
||||
const text = await result.text();
|
||||
|
@ -564,24 +558,31 @@ export class GBMinService {
|
|||
|
||||
// Saves token to the database.
|
||||
|
||||
await this.adminService.setValue(instance.instanceId,
|
||||
`${tokenName}accessToken`, token['accessToken'] ? token['accessToken'] : token['access_token']);
|
||||
await this.adminService.setValue(instance.instanceId,
|
||||
`${tokenName}refreshToken`, token['refreshToken'] ? token['refreshToken'] : token['refresh_token']);
|
||||
await this.adminService.setValue(
|
||||
instance.instanceId,
|
||||
`${tokenName}accessToken`,
|
||||
token['accessToken'] ? token['accessToken'] : token['access_token']
|
||||
);
|
||||
await this.adminService.setValue(
|
||||
instance.instanceId,
|
||||
`${tokenName}refreshToken`,
|
||||
token['refreshToken'] ? token['refreshToken'] : token['refresh_token']
|
||||
);
|
||||
|
||||
await this.adminService.setValue(instance.instanceId,
|
||||
`${tokenName}expiresOn`, token['expiresOn'] ?
|
||||
token['expiresOn'].toString() :
|
||||
new Date(Date.now() + (token['expires_in'] * 1000)).toString());
|
||||
await this.adminService.setValue(
|
||||
instance.instanceId,
|
||||
`${tokenName}expiresOn`,
|
||||
token['expiresOn']
|
||||
? token['expiresOn'].toString()
|
||||
: new Date(Date.now() + token['expires_in'] * 1000).toString()
|
||||
);
|
||||
await this.adminService.setValue(instance.instanceId, `${tokenName}AntiCSRFAttackState`, null);
|
||||
|
||||
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
const authenticationContext = new AuthenticationContext.AuthenticationContext(
|
||||
urlJoin(
|
||||
tokenName ? host : min.instance.authenticatorAuthorityHostUrl,
|
||||
tokenName ? tenant : min.instance.authenticatorTenant)
|
||||
tokenName ? tenant : min.instance.authenticatorTenant
|
||||
)
|
||||
);
|
||||
const resource = 'https://graph.microsoft.com';
|
||||
|
||||
|
@ -595,26 +596,24 @@ export class GBMinService {
|
|||
tokenName ? clientSecret : instance.marketplacePassword,
|
||||
async (err, token) => {
|
||||
if (err) {
|
||||
|
||||
const msg = `handleOAuthTokenRequests: Error acquiring token: ${err}`;
|
||||
|
||||
GBLog.error(msg);
|
||||
res.send(msg);
|
||||
|
||||
} else {
|
||||
|
||||
// Saves token to the database.
|
||||
|
||||
await this.adminService.setValue(instance.instanceId, `${tokenName}accessToken`, token['accessToken']);
|
||||
await this.adminService.setValue(instance.instanceId, `${tokenName}refreshToken`, token['refreshToken']);
|
||||
await this.adminService.setValue(instance.instanceId, `${tokenName}expiresOn`, token['expiresOn'].toString());
|
||||
await this.adminService.setValue(
|
||||
instance.instanceId,
|
||||
`${tokenName}expiresOn`,
|
||||
token['expiresOn'].toString()
|
||||
);
|
||||
await this.adminService.setValue(instance.instanceId, `${tokenName}AntiCSRFAttackState`, null);
|
||||
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
}
|
||||
// Inform the home for default .gbui after finishing token retrival.
|
||||
|
||||
|
@ -633,8 +632,9 @@ export class GBMinService {
|
|||
min.instance.authenticatorTenant,
|
||||
'/oauth2/authorize'
|
||||
);
|
||||
authorizationUrl = `${authorizationUrl}?response_type=code&client_id=${min.instance.marketplaceId
|
||||
}&redirect_uri=${urlJoin(process.env.BOT_URL, min.instance.botId, 'token')}`;
|
||||
authorizationUrl = `${authorizationUrl}?response_type=code&client_id=${
|
||||
min.instance.marketplaceId
|
||||
}&redirect_uri=${urlJoin(process.env.BOT_URL, min.instance.botId, 'token')}`;
|
||||
GBLogEx.info(min, `HandleOAuthRequests: ${authorizationUrl}.`);
|
||||
res.redirect(authorizationUrl);
|
||||
});
|
||||
|
@ -651,7 +651,6 @@ export class GBMinService {
|
|||
botId = GBConfigService.get('BOT_ID');
|
||||
}
|
||||
|
||||
|
||||
// Loads by the botId itself or by the activationCode field.
|
||||
|
||||
let instance = await this.core.loadInstanceByBotId(botId);
|
||||
|
@ -678,7 +677,8 @@ export class GBMinService {
|
|||
instanceId: instance.instanceId,
|
||||
botId: botId,
|
||||
theme: theme,
|
||||
webchatToken: webchatTokenContainer.token,
|
||||
//webchatToken: webchatTokenContainer.token,
|
||||
domain: 'http://localhost:3978/directline',
|
||||
speechToken: speechToken,
|
||||
conversationId: webchatTokenContainer.conversationId,
|
||||
authenticatorTenant: instance.authenticatorTenant,
|
||||
|
@ -690,10 +690,7 @@ export class GBMinService {
|
|||
paramLogoImageType: this.core.getParam(instance, 'Logo Image Type', null),
|
||||
logo: this.core.getParam(instance, 'Logo', null),
|
||||
color1: this.core.getParam(instance, 'Color1', null),
|
||||
color2: this.core.getParam(instance, 'Color2', null),
|
||||
|
||||
|
||||
|
||||
color2: this.core.getParam(instance, 'Color2', null)
|
||||
})
|
||||
);
|
||||
} else {
|
||||
|
@ -752,8 +749,10 @@ export class GBMinService {
|
|||
*/
|
||||
private async buildBotAdapter(instance: any, sysPackages: IGBPackage[], appPackages: IGBPackage[]) {
|
||||
// MSFT stuff.
|
||||
const uri = 'http://localhost:3978';
|
||||
|
||||
const adapter = new BotFrameworkAdapter({
|
||||
clientOptions: { baseUri: uri },
|
||||
appId: instance.marketplaceId ? instance.marketplaceId : GBConfigService.get('MARKETPLACE_ID'),
|
||||
appPassword: instance.marketplacePassword
|
||||
? instance.marketplacePassword
|
||||
|
@ -802,7 +801,6 @@ export class GBMinService {
|
|||
GBServer.globals.minBoot = min;
|
||||
GBServer.globals.minBoot.instance.marketplaceId = GBConfigService.get('MARKETPLACE_ID');
|
||||
GBServer.globals.minBoot.instance.marketplacePassword = GBConfigService.get('MARKETPLACE_SECRET');
|
||||
|
||||
}
|
||||
|
||||
if (min.instance.facebookWorkplaceVerifyToken) {
|
||||
|
@ -860,8 +858,7 @@ export class GBMinService {
|
|||
|
||||
await min.whatsAppDirectLine.setup(true);
|
||||
} else {
|
||||
if (min !== minBoot && minBoot.instance.whatsappServiceKey
|
||||
&& min.instance.webchatKey) {
|
||||
if (min !== minBoot && minBoot.instance.whatsappServiceKey && min.instance.webchatKey) {
|
||||
min.whatsAppDirectLine = new WhatsappDirectLine(
|
||||
min,
|
||||
min.botId,
|
||||
|
@ -1087,7 +1084,10 @@ export class GBMinService {
|
|||
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}...`);
|
||||
GBLogEx.info(
|
||||
min,
|
||||
`Auto start (teams) dialog is now being called: ${startDialog} for ${min.instance.botId}...`
|
||||
);
|
||||
await GBVMService.callVM(startDialog.toLowerCase(), min, step, pid);
|
||||
}
|
||||
}
|
||||
|
@ -1095,7 +1095,8 @@ export class GBMinService {
|
|||
|
||||
// Required for F0 handling of persisted conversations.
|
||||
|
||||
GBLogEx.info(min,
|
||||
GBLogEx.info(
|
||||
min,
|
||||
`Input> ${context.activity.text} (type: ${context.activity.type}, name: ${context.activity.name}, channelId: ${context.activity.channelId})`
|
||||
);
|
||||
|
||||
|
@ -1104,7 +1105,6 @@ export class GBMinService {
|
|||
|
||||
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) {
|
||||
|
@ -1133,7 +1133,8 @@ export class GBMinService {
|
|||
) {
|
||||
min['conversationWelcomed'][step.context.activity.conversation.id] = true;
|
||||
|
||||
GBLogEx.info(min,
|
||||
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);
|
||||
|
@ -1147,7 +1148,6 @@ export class GBMinService {
|
|||
} else if (context.activity.type === 'message') {
|
||||
// Processes messages activities.
|
||||
|
||||
|
||||
await this.processMessageActivity(context, min, step, pid);
|
||||
} else if (context.activity.type === 'event') {
|
||||
// Processes events activities.
|
||||
|
@ -1155,8 +1155,9 @@ export class GBMinService {
|
|||
await this.processEventActivity(min, user, context, step);
|
||||
}
|
||||
} catch (error) {
|
||||
const msg = `ERROR: ${error.message} ${error.stack} ${error.error ? error.error.body : ''} ${error.error ? (error.error.stack ? error.error.stack : '') : ''
|
||||
}`;
|
||||
const msg = `ERROR: ${error.message} ${error.stack} ${error.error ? error.error.body : ''} ${
|
||||
error.error ? (error.error.stack ? error.error.stack : '') : ''
|
||||
}`;
|
||||
GBLog.error(msg);
|
||||
|
||||
await min.conversationalService.sendText(
|
||||
|
@ -1170,7 +1171,17 @@ export class GBMinService {
|
|||
};
|
||||
|
||||
try {
|
||||
await adapter['processActivity'](req, res, handler);
|
||||
if (process.env.STORAGE_FILE) {
|
||||
const context = adapter['createContext'](req);
|
||||
context['_activity'] = context.activity.body;
|
||||
await handler(context);
|
||||
// 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.');
|
||||
|
@ -1209,7 +1220,10 @@ export class GBMinService {
|
|||
const startDialog = min.core.getParam(min.instance, 'Start Dialog', null);
|
||||
if (startDialog && !min['conversationWelcomed'][step.context.activity.conversation.id]) {
|
||||
user.welcomed = true;
|
||||
GBLogEx.info(min, `Auto start (web 2) dialog is now being called: ${startDialog} for ${min.instance.instanceId}...`);
|
||||
GBLogEx.info(
|
||||
min,
|
||||
`Auto start (web 2) dialog is now being called: ${startDialog} for ${min.instance.instanceId}...`
|
||||
);
|
||||
await GBVMService.callVM(startDialog.toLowerCase(), min, step, pid);
|
||||
}
|
||||
} else if (context.activity.name === 'updateToken') {
|
||||
|
@ -1263,7 +1277,6 @@ export class GBMinService {
|
|||
}
|
||||
|
||||
private async handleUploads(min, step, user, params, autoSave) {
|
||||
|
||||
// Prepare Promises to download each attachment and then execute each Promise.
|
||||
|
||||
if (
|
||||
|
@ -1294,7 +1307,6 @@ export class GBMinService {
|
|||
GBServer.globals.files[handle] = gbfile;
|
||||
|
||||
if (!min.cbMap[user.userId] && autoSave) {
|
||||
|
||||
const result = await t['internalAutoSave']({ min: min, handle: handle });
|
||||
await min.conversationalService.sendText(
|
||||
min,
|
||||
|
@ -1303,12 +1315,9 @@ export class GBMinService {
|
|||
);
|
||||
|
||||
return;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return gbfile;
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
await this.sendActivity('Error uploading file. Please,start again.');
|
||||
}
|
||||
|
@ -1399,10 +1408,8 @@ export class GBMinService {
|
|||
const userId = user.userId;
|
||||
const params = user.params ? JSON.parse(user.params) : {};
|
||||
|
||||
|
||||
let message: GuaribasConversationMessage;
|
||||
if (process.env.PRIVACY_STORE_MESSAGES === 'true') {
|
||||
|
||||
// Adds message to the analytics layer.
|
||||
|
||||
const analytics = new AnalyticsService();
|
||||
|
@ -1420,7 +1427,6 @@ export class GBMinService {
|
|||
userId,
|
||||
context.activity.text
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1439,7 +1445,8 @@ export class GBMinService {
|
|||
) {
|
||||
await sec.setParam(userId, 'welcomed', 'true');
|
||||
min['conversationWelcomed'][step.context.activity.conversation.id] = true;
|
||||
GBLogEx.info(min,
|
||||
GBLogEx.info(
|
||||
min,
|
||||
`Auto start (4) dialog is now being called: ${startDialog} for ${min.instance.instanceId}...`
|
||||
);
|
||||
await GBVMService.callVM(startDialog.toLowerCase(), min, step, pid);
|
||||
|
@ -1500,21 +1507,18 @@ export class GBMinService {
|
|||
} else {
|
||||
// Removes unwanted chars in input text.
|
||||
|
||||
|
||||
step.context.activity['originalText'] = context.activity.text;
|
||||
const text = await GBConversationalService.handleText(min, user, step, context.activity.text);
|
||||
step.context.activity['originalText']
|
||||
step.context.activity['originalText'];
|
||||
step.context.activity['text'] = text;
|
||||
|
||||
|
||||
if (notes && text && text !== "") {
|
||||
if (notes && text && text !== '') {
|
||||
const sys = new SystemKeywords();
|
||||
await sys.note({ pid, text });
|
||||
await step.context.sendActivity('OK.');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Checks for bad words on input text.
|
||||
|
||||
const hasBadWord = wash.check(step.context.activity.locale, text);
|
||||
|
@ -1549,7 +1553,7 @@ export class GBMinService {
|
|||
}
|
||||
} else {
|
||||
if (min.cbMap[userId] && min.cbMap[userId].promise === '!GBHEAR') {
|
||||
min.cbMap[userId].promise = step.context.activity['originalText'];;
|
||||
min.cbMap[userId].promise = step.context.activity['originalText'];
|
||||
}
|
||||
|
||||
// If there is a dialog in course, continue to the next step.
|
||||
|
@ -1557,8 +1561,9 @@ export class GBMinService {
|
|||
try {
|
||||
await step.continueDialog();
|
||||
} catch (error) {
|
||||
const msg = `ERROR: ${error.message} ${error.stack} ${error.error ? error.error.body : ''} ${error.error ? (error.error.stack ? error.error.stack : '') : ''
|
||||
}`;
|
||||
const msg = `ERROR: ${error.message} ${error.stack} ${error.error ? error.error.body : ''} ${
|
||||
error.error ? (error.error.stack ? error.error.stack : '') : ''
|
||||
}`;
|
||||
GBLog.error(msg);
|
||||
await min.conversationalService.sendText(
|
||||
min,
|
||||
|
@ -1601,7 +1606,6 @@ export class GBMinService {
|
|||
}
|
||||
|
||||
public async ensureAPI() {
|
||||
|
||||
const mins = GBServer.globals.minInstances;
|
||||
|
||||
function getRemoteId(ctx: Koa.Context) {
|
||||
|
@ -1611,14 +1615,11 @@ export class GBMinService {
|
|||
const close = async () => {
|
||||
return new Promise(resolve => {
|
||||
if (GBServer.globals.server.apiServer) {
|
||||
GBServer.globals.server.apiServer.close(
|
||||
cb => {
|
||||
resolve(true);
|
||||
GBLogEx.info(0, 'Reloading General Bots API...');
|
||||
}
|
||||
);
|
||||
}
|
||||
else {
|
||||
GBServer.globals.server.apiServer.close(cb => {
|
||||
resolve(true);
|
||||
GBLogEx.info(0, 'Reloading General Bots API...');
|
||||
});
|
||||
} else {
|
||||
resolve(true);
|
||||
GBLogEx.info(0, 'Loading General Bots API...');
|
||||
}
|
||||
|
@ -1629,11 +1630,9 @@ export class GBMinService {
|
|||
|
||||
let proxies = {};
|
||||
await CollectionUtil.asyncForEach(mins, async min => {
|
||||
|
||||
let dialogs = {};
|
||||
await CollectionUtil.asyncForEach(Object.values(min.scriptMap), async script => {
|
||||
|
||||
dialogs[script] = async (data) => {
|
||||
dialogs[script] = async data => {
|
||||
let sec = new SecService();
|
||||
const user = await sec.ensureUser(
|
||||
min,
|
||||
|
@ -1649,7 +1648,6 @@ export class GBMinService {
|
|||
if (script === 'start') {
|
||||
pid = GBVMService.createProcessInfo(user, min, 'api', null);
|
||||
|
||||
|
||||
const client = await new SwaggerClient({
|
||||
spec: JSON.parse(Fs.readFileSync('directline-3.0.json', 'utf8')),
|
||||
requestInterceptor: req => {
|
||||
|
@ -1668,7 +1666,7 @@ export class GBMinService {
|
|||
ret = pid;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
const proxy = {
|
||||
|
@ -1686,10 +1684,10 @@ export class GBMinService {
|
|||
pingSendTimeout: null,
|
||||
keepAliveTimeout: null,
|
||||
listeners: {
|
||||
unsubscribed(subscriptions: number): void { },
|
||||
subscribed(subscriptions: number): void { },
|
||||
disconnected(remoteId: string, connections: number): void { },
|
||||
connected(remoteId: string, connections: number): void { },
|
||||
unsubscribed(subscriptions: number): void {},
|
||||
subscribed(subscriptions: number): void {},
|
||||
disconnected(remoteId: string, connections: number): void {},
|
||||
connected(remoteId: string, connections: number): void {},
|
||||
messageIn(...params): void {
|
||||
params.shift();
|
||||
},
|
||||
|
@ -1699,16 +1697,8 @@ export class GBMinService {
|
|||
}
|
||||
};
|
||||
|
||||
GBServer.globals.server.apiServer = createKoaHttpServer(
|
||||
GBVMService.API_PORT,
|
||||
getRemoteId, { prefix: `api/v3` });
|
||||
|
||||
createRpcServer(
|
||||
proxies,
|
||||
GBServer.globals.server.apiServer,
|
||||
opts
|
||||
);
|
||||
GBServer.globals.server.apiServer = createKoaHttpServer(GBVMService.API_PORT, getRemoteId, { prefix: `api/v3` });
|
||||
|
||||
createRpcServer(proxies, GBServer.globals.server.apiServer, opts);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
<link rel="stylesheet" type="text/css" href="/themes/{theme}/css/App.css" />
|
||||
<link rel="stylesheet" type="text/css" href="/themes/{theme}/css/SideBarMenu.css" />
|
||||
|
||||
<script src="https://cdn.botframework.com/botframework-webchat/latest/webchat.js"></script>
|
||||
<script src="./js/webchat.js"></script>
|
||||
<title>{title} - General Bots Community Edition</title>
|
||||
|
||||
<style>
|
||||
|
|
2
packages/default.gbui/public/js/webchat.js
Normal file
2
packages/default.gbui/public/js/webchat.js
Normal file
File diff suppressed because one or more lines are too long
|
@ -168,9 +168,18 @@ class GBUIApp extends React.Component {
|
|||
let _this_ = this;
|
||||
window['botchatDebug'] = true;
|
||||
|
||||
const line = new DirectLine({
|
||||
const line = instanceClient.webchatToken ?
|
||||
new DirectLine({
|
||||
token: instanceClient.webchatToken
|
||||
});
|
||||
}):
|
||||
new DirectLine({
|
||||
domain: instanceClient.domain,
|
||||
secret: null,
|
||||
token: null,
|
||||
webSocket: false // defaults to true
|
||||
});
|
||||
|
||||
;
|
||||
_this_.setState({ line: line });
|
||||
|
||||
line.connectionStatus$.subscribe(connectionStatus => {
|
||||
|
|
|
@ -36,6 +36,7 @@ class ChatPane extends React.Component {
|
|||
render() {
|
||||
return (
|
||||
<Chat
|
||||
|
||||
ref={(chat) => { this.chat = chat; }}
|
||||
botConnection={this.props.botConnection}
|
||||
user={{ id: "webUser@gb", name: "You" }}
|
||||
|
|
|
@ -31,7 +31,8 @@
|
|||
'use strict';
|
||||
|
||||
import { GBMinInstance } from 'botlib';
|
||||
import { OpenAIClient } from '@azure/openai';
|
||||
import OpenAI from 'openai';
|
||||
|
||||
import { AzureKeyCredential } from '@azure/core-auth';
|
||||
import { DialogKeywords } from '../../basic.gblib/services/DialogKeywords';
|
||||
import Path from 'path';
|
||||
|
@ -45,7 +46,6 @@ import { GBLogEx } from '../../core.gbapp/services/GBLogEx';
|
|||
* Image processing services of conversation to be called by BASIC.
|
||||
*/
|
||||
export class ImageServices {
|
||||
|
||||
public async getImageFromPrompt({ pid, prompt }) {
|
||||
const { min, user, params } = await DialogKeywords.getProcessInfo(pid);
|
||||
|
||||
|
@ -55,11 +55,12 @@ export class ImageServices {
|
|||
|
||||
if (azureOpenAIKey) {
|
||||
// Initialize the Azure OpenAI client
|
||||
const client = new OpenAIClient(azureOpenAIEndpoint, new AzureKeyCredential(azureOpenAIKey));
|
||||
|
||||
const client = new OpenAI({ apiKey: azureOpenAIKey, baseURL: azureOpenAIEndpoint });
|
||||
|
||||
// Make a request to the image generation endpoint
|
||||
|
||||
const response = await client.getImageGeneration(azureOpenAIImageModel, {
|
||||
const response = await client.images.generate({
|
||||
prompt: prompt,
|
||||
n: 1,
|
||||
size: '1024x1024'
|
||||
|
@ -75,7 +76,7 @@ export class ImageServices {
|
|||
|
||||
GBLogEx.info(min, `BASIC: DALL-E image generated at ${url}.`);
|
||||
|
||||
return {localName, url};
|
||||
return { localName, url };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -85,12 +85,10 @@ export class WhatsappDirectLine extends GBService {
|
|||
public botId: string;
|
||||
public botNumber: string;
|
||||
public min: GBMinInstance;
|
||||
private directLineSecret: string;
|
||||
private locale: string = 'pt-BR';
|
||||
provider: any;
|
||||
INSTANCE_URL = 'https://api.maytapi.com/api';
|
||||
private customClient: any;
|
||||
private groupId;
|
||||
|
||||
constructor(
|
||||
min: GBMinInstance,
|
||||
|
@ -104,13 +102,12 @@ export class WhatsappDirectLine extends GBService {
|
|||
super();
|
||||
|
||||
this.min = min;
|
||||
this.botId = botId;
|
||||
this.directLineSecret = directLineSecret;
|
||||
this.botId = botId;
|
||||
this.whatsappServiceKey = whatsappServiceKey;
|
||||
this.whatsappServiceNumber = whatsappServiceNumber;
|
||||
this.whatsappServiceUrl = whatsappServiceUrl;
|
||||
this.provider = whatsappServiceKey === 'internal' ? 'GeneralBots' : 'meta';
|
||||
this.groupId = groupId;
|
||||
|
||||
}
|
||||
|
||||
public static async asyncForEach(array, callback) {
|
||||
|
@ -121,6 +118,7 @@ export class WhatsappDirectLine extends GBService {
|
|||
|
||||
public async setup(setUrl: boolean) {
|
||||
const client = await new SwaggerClient({
|
||||
url: 'http://127.0.0.1:3978/api/messages', // TODO:
|
||||
spec: JSON.parse(Fs.readFileSync('directline-3.0.json', 'utf8')),
|
||||
requestInterceptor: req => {
|
||||
req.headers['Authorization'] = `Bearer ${this.min.instance.webchatKey}`;
|
||||
|
|
12
src/app.ts
12
src/app.ts
|
@ -100,6 +100,7 @@ export class GBServer {
|
|||
GBServer.globals.wwwroot = null;
|
||||
GBServer.globals.entryPointDialog = null;
|
||||
GBServer.globals.debuggers = [];
|
||||
GBServer.globals.users = [];
|
||||
GBServer.globals.indexSemaphore = new Mutex();
|
||||
|
||||
server.use(bodyParser.json());
|
||||
|
@ -121,17 +122,16 @@ export class GBServer {
|
|||
});
|
||||
|
||||
process.on('unhandledRejection', (err, p) => {
|
||||
|
||||
let bypass = false;
|
||||
let res = err['response'];
|
||||
if (res) {
|
||||
if (res?.body?.error?.message?.startsWith('Failed to send activity: bot timed out')){
|
||||
bypass = true;
|
||||
if (res?.body?.error?.message?.startsWith('Failed to send activity: bot timed out')) {
|
||||
bypass = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(!bypass){
|
||||
GBLogEx.error(0,`GBREJECTION: ${GBUtil.toYAML(err)} ${GBUtil.toYAML(p)}`);
|
||||
if (!bypass) {
|
||||
GBLogEx.error(0, `GBREJECTION: ${GBUtil.toYAML(err)} ${GBUtil.toYAML(p)}`);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -179,6 +179,8 @@ export class GBServer {
|
|||
if (GBConfigService.get('STORAGE_SERVER')) {
|
||||
azureDeployer = await AzureDeployerService.createInstance(deployer);
|
||||
await core.initStorage();
|
||||
} else if (GBConfigService.get('STORAGE_FILE')) {
|
||||
await core.initStorage();
|
||||
} else {
|
||||
runOnce = true;
|
||||
[GBServer.globals.bootInstance, azureDeployer] = await core['createBootInstanceEx'](
|
||||
|
|
Loading…
Add table
Reference in a new issue