new(core.gbapp): New activationCode for multiple bot activation on the same channel.
This commit is contained in:
parent
1a2d1f3346
commit
d0c04ed676
7 changed files with 117 additions and 49 deletions
|
@ -43,4 +43,12 @@ ALTER TABLE dbo.GuaribasInstance ADD
|
||||||
translatorEndpoint nvarchar(64) NULL
|
translatorEndpoint nvarchar(64) NULL
|
||||||
GO
|
GO
|
||||||
|
|
||||||
|
# 1.7.9
|
||||||
|
|
||||||
|
ALTER TABLE dbo.GuaribasInstance ADD
|
||||||
|
activationCode nvarchar(16) NULL
|
||||||
|
GO
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
|
@ -40,13 +40,11 @@ const crypto = require('crypto');
|
||||||
import { WaterfallDialog } from 'botbuilder-dialogs';
|
import { WaterfallDialog } from 'botbuilder-dialogs';
|
||||||
import { GBMinInstance, IGBDialog, GBLog } from 'botlib';
|
import { GBMinInstance, IGBDialog, GBLog } from 'botlib';
|
||||||
import urlJoin = require('url-join');
|
import urlJoin = require('url-join');
|
||||||
import { GBConfigService } from '../../core.gbapp/services/GBConfigService';
|
|
||||||
import { GBDeployer } from '../../core.gbapp/services/GBDeployer';
|
import { GBDeployer } from '../../core.gbapp/services/GBDeployer';
|
||||||
import { GBImporter } from '../../core.gbapp/services/GBImporterService';
|
import { GBImporter } from '../../core.gbapp/services/GBImporterService';
|
||||||
import { Messages } from '../strings';
|
import { Messages } from '../strings';
|
||||||
import { GBAdminService } from '../services/GBAdminService';
|
import { GBAdminService } from '../services/GBAdminService';
|
||||||
import { CollectionUtil } from 'pragmatismo-io-framework';
|
import { CollectionUtil } from 'pragmatismo-io-framework';
|
||||||
import { GBConversationalService } from '../../core.gbapp/services/GBConversationalService';
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -54,6 +52,15 @@ import { GBConversationalService } from '../../core.gbapp/services/GBConversatio
|
||||||
*/
|
*/
|
||||||
export class AdminDialog extends IGBDialog {
|
export class AdminDialog extends IGBDialog {
|
||||||
|
|
||||||
|
|
||||||
|
public static isIntentYes(locale, utterance) {
|
||||||
|
return utterance.toLowerCase().match(Messages[locale].affirmative_sentences);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static isIntentNo(locale, utterance) {
|
||||||
|
return utterance.toLowerCase().match(Messages[locale].negative_sentences);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Setup dialogs flows and define services call.
|
* Setup dialogs flows and define services call.
|
||||||
*
|
*
|
||||||
|
@ -75,7 +82,7 @@ export class AdminDialog extends IGBDialog {
|
||||||
const locale = step.context.activity.locale;
|
const locale = step.context.activity.locale;
|
||||||
const prompt = Messages[locale].authenticate;
|
const prompt = Messages[locale].authenticate;
|
||||||
|
|
||||||
return await min.conversationalService.prompt (min, step, prompt);
|
return await min.conversationalService.prompt(min, step, prompt);
|
||||||
},
|
},
|
||||||
async step => {
|
async step => {
|
||||||
const locale = step.context.activity.locale;
|
const locale = step.context.activity.locale;
|
||||||
|
@ -84,7 +91,7 @@ export class AdminDialog extends IGBDialog {
|
||||||
if (sensitive === min.instance.adminPass) {
|
if (sensitive === min.instance.adminPass) {
|
||||||
await min.conversationalService.sendText(min, step, Messages[locale].welcome);
|
await min.conversationalService.sendText(min, step, Messages[locale].welcome);
|
||||||
|
|
||||||
return await min.conversationalService.prompt (min, step, Messages[locale].which_task);
|
return await min.conversationalService.prompt(min, step, Messages[locale].which_task);
|
||||||
} else {
|
} else {
|
||||||
await min.conversationalService.sendText(min, step, Messages[locale].wrong_password);
|
await min.conversationalService.sendText(min, step, Messages[locale].wrong_password);
|
||||||
|
|
||||||
|
@ -155,57 +162,96 @@ export class AdminDialog extends IGBDialog {
|
||||||
min.dialogs.add(
|
min.dialogs.add(
|
||||||
new WaterfallDialog('/publish', [
|
new WaterfallDialog('/publish', [
|
||||||
async step => {
|
async step => {
|
||||||
const botId = min.instance.botId;
|
if (step.activeDialog.state.options.confirm) {
|
||||||
|
return await step.next('sim');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const locale = step.context.activity.locale;
|
||||||
|
return await min.conversationalService.prompt(min, step, Messages[locale].publish_type_yes);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async step => {
|
||||||
const locale = step.context.activity.locale;
|
const locale = step.context.activity.locale;
|
||||||
await min.conversationalService.sendText(min, step, Messages[locale].working('Publishing'));
|
|
||||||
|
|
||||||
step.activeDialog.state.options.args = (step.options as any).args;
|
// If the user says yes, starts publishing.
|
||||||
let args = step.activeDialog.state.options.args.split(' ');
|
|
||||||
let filename = args[0];
|
|
||||||
const packages = [];
|
|
||||||
if (filename === null) {
|
|
||||||
await min.conversationalService.sendText(min, step, `Starting publishing for all bot packages...`);
|
|
||||||
packages.push(`${botId}.gbkb`);
|
|
||||||
packages.push(`${botId}.gbdialog`);
|
|
||||||
packages.push(`${botId}.gbot`);
|
|
||||||
packages.push(`${botId}.gbtheme`);
|
|
||||||
packages.push(`${botId}.gbapp`);
|
|
||||||
packages.push(`${botId}.gblib`);
|
|
||||||
} else {
|
|
||||||
await min.conversationalService.sendText(min, step, `Starting publishing for ${filename}...`);
|
|
||||||
packages.push(filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
if (AdminDialog.isIntentYes(locale, step.result)) {
|
||||||
|
|
||||||
await CollectionUtil.asyncForEach(packages, async packageName => {
|
let from = step.context.activity.from.id;
|
||||||
|
|
||||||
const cmd1 = `deployPackage ${process.env.STORAGE_SITE} /${process.env.STORAGE_LIBRARY}/${botId}.gbai/${packageName}`;
|
if (AdminDialog.canSendBroadcast(from)) {
|
||||||
|
|
||||||
if (await (deployer as any).getStoragePackageByName(min.instance.instanceId,
|
const botId = min.instance.botId;
|
||||||
packageName) !== null) { // TODO: Move to interface.
|
const locale = step.context.activity.locale;
|
||||||
const cmd2 = `undeployPackage ${packageName}`;
|
await min.conversationalService.sendText(min, step, Messages[locale].working('Publishing'));
|
||||||
await GBAdminService.undeployPackageCommand(cmd2, min);
|
|
||||||
|
step.activeDialog.state.options.args = (step.options as any).args;
|
||||||
|
let args = step.activeDialog.state.options.args.split(' ');
|
||||||
|
let filename = args[0];
|
||||||
|
const packages = [];
|
||||||
|
if (filename === null) {
|
||||||
|
await min.conversationalService.sendText(min, step, `Starting publishing for all bot packages...`);
|
||||||
|
packages.push(`${botId}.gbkb`);
|
||||||
|
packages.push(`${botId}.gbdialog`);
|
||||||
|
packages.push(`${botId}.gbot`);
|
||||||
|
packages.push(`${botId}.gbtheme`);
|
||||||
|
packages.push(`${botId}.gbapp`);
|
||||||
|
packages.push(`${botId}.gblib`);
|
||||||
|
} else {
|
||||||
|
await min.conversationalService.sendText(min, step, `Starting publishing for ${filename}...`);
|
||||||
|
packages.push(filename);
|
||||||
}
|
}
|
||||||
await GBAdminService.deployPackageCommand(min, cmd1, deployer);
|
|
||||||
if (packageName.endsWith('.gbkb')) {
|
try {
|
||||||
await min.conversationalService.sendText(min, step, 'Rebuilding my own index, wait a minute, please...');
|
|
||||||
await GBAdminService.rebuildIndexPackageCommand(min, deployer);
|
await CollectionUtil.asyncForEach(packages, async packageName => {
|
||||||
|
|
||||||
|
const cmd1 = `deployPackage ${process.env.STORAGE_SITE} /${process.env.STORAGE_LIBRARY}/${botId}.gbai/${packageName}`;
|
||||||
|
|
||||||
|
if (await (deployer as any).getStoragePackageByName(min.instance.instanceId,
|
||||||
|
packageName) !== null) { // TODO: Move to interface.
|
||||||
|
const cmd2 = `undeployPackage ${packageName}`;
|
||||||
|
await GBAdminService.undeployPackageCommand(cmd2, min);
|
||||||
|
}
|
||||||
|
await GBAdminService.deployPackageCommand(min, cmd1, deployer);
|
||||||
|
if (packageName.endsWith('.gbkb')) {
|
||||||
|
await min.conversationalService.sendText(min, step, 'Rebuilding my own index, wait a minute, please...');
|
||||||
|
await GBAdminService.rebuildIndexPackageCommand(min, deployer);
|
||||||
|
}
|
||||||
|
await min.conversationalService.sendText(min, step, `Finished publishing ${packageName}.`);
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
await min.conversationalService.sendText(min, step, error.message);
|
||||||
|
}
|
||||||
|
await min.conversationalService.sendText(min, step, Messages[locale].publish_success);
|
||||||
|
if (!step.activeDialog.state.options.confirm) {
|
||||||
|
return await step.replaceDialog('/ask', { isReturning: true });
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return await step.endDialog();
|
||||||
}
|
}
|
||||||
await min.conversationalService.sendText(min, step, `Finished publishing ${packageName}.`);
|
|
||||||
});
|
|
||||||
|
|
||||||
return await step.replaceDialog('/ask', { isReturning: true });
|
} else {
|
||||||
|
await min.conversationalService.sendText(min, step, Messages[locale].publish_must_be_admin);
|
||||||
} catch (error) {
|
}
|
||||||
await min.conversationalService.sendText(min, step, error.message);
|
|
||||||
}
|
}
|
||||||
await step.replaceDialog('/ask', { isReturning: true });
|
await min.conversationalService.sendText(min, step, Messages[locale].publish_canceled);
|
||||||
|
|
||||||
}]));
|
}]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the specified phone can receive a message by running
|
||||||
|
* the /broadcast command with specific phone numbers.
|
||||||
|
* @param phone Phone number to check (eg.: +5521900002233)
|
||||||
|
*/
|
||||||
|
public static canSendBroadcast(phone: string): Boolean {
|
||||||
|
const list = process.env.SECURITY_CAN_PUBLISH.split(';');
|
||||||
|
return list.includes(phone);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private static setupSecurityDialogs(min: GBMinInstance) {
|
private static setupSecurityDialogs(min: GBMinInstance) {
|
||||||
min.dialogs.add(
|
min.dialogs.add(
|
||||||
new WaterfallDialog('/setupSecurity', [
|
new WaterfallDialog('/setupSecurity', [
|
||||||
|
@ -213,14 +259,14 @@ export class AdminDialog extends IGBDialog {
|
||||||
const locale = step.context.activity.locale;
|
const locale = step.context.activity.locale;
|
||||||
const prompt = Messages[locale].enter_authenticator_tenant;
|
const prompt = Messages[locale].enter_authenticator_tenant;
|
||||||
|
|
||||||
return await min.conversationalService.prompt (min, step, prompt);
|
return await min.conversationalService.prompt(min, step, prompt);
|
||||||
},
|
},
|
||||||
async step => {
|
async step => {
|
||||||
step.activeDialog.state.authenticatorTenant = step.result;
|
step.activeDialog.state.authenticatorTenant = step.result;
|
||||||
const locale = step.context.activity.locale;
|
const locale = step.context.activity.locale;
|
||||||
const prompt = Messages[locale].enter_authenticator_authority_host_url;
|
const prompt = Messages[locale].enter_authenticator_authority_host_url;
|
||||||
|
|
||||||
return await min.conversationalService.prompt (min, step, prompt);
|
return await min.conversationalService.prompt(min, step, prompt);
|
||||||
},
|
},
|
||||||
async step => {
|
async step => {
|
||||||
step.activeDialog.state.authenticatorAuthorityHostUrl = step.result;
|
step.activeDialog.state.authenticatorAuthorityHostUrl = step.result;
|
||||||
|
|
|
@ -75,6 +75,9 @@ export class GuaribasInstance extends Model<GuaribasInstance>
|
||||||
@Column
|
@Column
|
||||||
public title: string;
|
public title: string;
|
||||||
|
|
||||||
|
@Column({ type: DataType.STRING(16) })
|
||||||
|
public activationCode: string;
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
public description: string;
|
public description: string;
|
||||||
|
|
||||||
|
|
|
@ -164,6 +164,7 @@ export class GBDeployer implements IGBDeployer {
|
||||||
accessToken, (application as any).id);
|
accessToken, (application as any).id);
|
||||||
instance.adminPass = GBAdminService.getRndPassword();
|
instance.adminPass = GBAdminService.getRndPassword();
|
||||||
instance.title = botId;
|
instance.title = botId;
|
||||||
|
instance.activationCode = instance.botId;
|
||||||
|
|
||||||
await this.core.saveInstance(instance);
|
await this.core.saveInstance(instance);
|
||||||
|
|
||||||
|
|
|
@ -145,11 +145,11 @@ export class GBMinService {
|
||||||
let activeMin;
|
let activeMin;
|
||||||
if (process.env.WHATSAPP_WELCOME_DISABLED !== "true") {
|
if (process.env.WHATSAPP_WELCOME_DISABLED !== "true") {
|
||||||
|
|
||||||
const toSwitchMin = GBServer.globals.minInstances.filter(p => p.instance.botId === text)[0];
|
const toSwitchMin = GBServer.globals.minInstances.filter(p => p.instance.activationCode === text)[0];
|
||||||
activeMin = toSwitchMin ? toSwitchMin : GBServer.globals.minBoot;
|
activeMin = toSwitchMin ? toSwitchMin : GBServer.globals.minBoot;
|
||||||
|
|
||||||
let sec = new SecService();
|
let sec = new SecService();
|
||||||
const instance = await this.core.loadInstanceByBotId(activeMin.botId);
|
|
||||||
let user = await sec.getUserFromSystemId(id);
|
let user = await sec.getUserFromSystemId(id);
|
||||||
|
|
||||||
if (user === null) {
|
if (user === null) {
|
||||||
|
|
|
@ -10,7 +10,12 @@ export const Messages = {
|
||||||
very_sorry_about_error: `I'm sorry to inform that there was an error which was recorded to be solved.`,
|
very_sorry_about_error: `I'm sorry to inform that there was an error which was recorded to be solved.`,
|
||||||
canceled: 'Canceled. If I can be useful, let me know how',
|
canceled: 'Canceled. If I can be useful, let me know how',
|
||||||
whats_email: "What's your E-mail address?",
|
whats_email: "What's your E-mail address?",
|
||||||
validation_enter_valid_email: "Please enter a valid e-mail."
|
validation_enter_valid_email: "Please enter a valid e-mail." ,
|
||||||
|
affirmative_sentences: /^(sim|s|positivo|afirmativo|claro|evidente|sem dúvida|confirmo|confirmar|confirmado|uhum)/i,
|
||||||
|
publish_must_be_admin: 'Seu telefone precisa estar com privilégios administrativos para realizar publicação.',
|
||||||
|
publish_success: 'Publicação realizada.',
|
||||||
|
publish_type_yes: 'Por favor, digite *Sim* para continuar com a publicação.',
|
||||||
|
publish_canceled: 'Publicação cancelada.',
|
||||||
},
|
},
|
||||||
'pt-BR': {
|
'pt-BR': {
|
||||||
show_video: 'Vou te mostrar um vídeo. Por favor, aguarde...',
|
show_video: 'Vou te mostrar um vídeo. Por favor, aguarde...',
|
||||||
|
@ -21,6 +26,11 @@ export const Messages = {
|
||||||
very_sorry_about_error: `Lamento, ocorreu um erro que já foi registrado para ser tratado.`,
|
very_sorry_about_error: `Lamento, ocorreu um erro que já foi registrado para ser tratado.`,
|
||||||
canceled: 'Cancelado, avise como posso ser útil novamente.',
|
canceled: 'Cancelado, avise como posso ser útil novamente.',
|
||||||
whats_email: "Qual seu e-mail?",
|
whats_email: "Qual seu e-mail?",
|
||||||
validation_enter_valid_email: "Por favor digite um email válido."
|
validation_enter_valid_email: "Por favor digite um email válido.",
|
||||||
|
affirmative_sentences: /^(sim|s|positivo|afirmativo|claro|evidente|sem dúvida|confirmo|confirmar|confirmado|uhum)/i,
|
||||||
|
publish_must_be_admin: 'Seu telefone precisa estar com privilégios administrativos para realizar publicação.',
|
||||||
|
publish_success: 'Publicação realizada.',
|
||||||
|
publish_type_yes: 'Por favor, digite *Sim* para continuar com a publicação.',
|
||||||
|
publish_canceled: 'Publicação cancelada.',
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Reference in a new issue