gpt4 book ai didi

javascript - 处理提醒对话框的答案

转载 作者:行者123 更新时间:2023-12-01 00:40:54 25 4
gpt4 key购买 nike

我想在向用户发送主动消息时启动“提醒对话框”。对话框已发布。但在处理答案时,它会返回主对话框。

目前我创建的机器人如下:

const conversationState = new ConversationState(mongoStorage);
const userState = new UserState(memoryStorage);

const bot = new DialogAndWelcomeBot(conversationState, userState, logger);

// Listen for incoming activities and route them to your bot main dialog.
server.post("/api/messages", (req, res) => {
adapter.use(new GraphQLMiddleware(bot.getAuthState()));

// Route received a request to adapter for processing
adapter.processActivity(req, res, async turnContext => {
await bot.run(turnContext);
});
});

并发送这样的主动消息:

await adapter.createConversation(conversationReferenceAdapted, bot.remind);

其中DialogAndWelcomeBot具有以下功能:

remind = async turnContext => {
const reminderDialog = new ReminderDialog(this.logger);
await reminderDialog.run(turnContext, this.dialogState);
await this.conversationState.saveChanges(turnContext, false);
await this.userState.saveChanges(turnContext, false);
};

但是,ReminderDialog 会正确触发(带有"is"和“否”按钮)。但是当我按下任何一个按钮时我得到:

[onTurnError]: Error: DialogContext.continue(): Can't continue dialog. A dialog with an id of 'ReminderDialog' wasn't found.

这让我怀疑它不知道原始流程中的ReminderDialog(通过实例化MainDialogDialogAndWelcomeBot的构造函数)并运行)。

关于如何解决这个问题有什么想法吗?

所需功能

我有一个询问有关用户的一些详细信息的主流程。可以通过向机器人发送任何短信来调用此流程。然后它会回复请求一些输入。

我尝试实现的流程是主要流程的替代流程。它应该与用户联系(例如每天)。因此,它应该开始一个(不同于主要的)对话,要求输入他运动的时间,然后确认。

简而言之:

  • 主流程:用户输入 hi -> 机器人回复“你的年龄” -> 用户输入 28 -> 机器人回复“好的,谢谢”

  • 主动流程:机器人询问用户“您今天运动了多长时间?” -> 用户输入 1 小时 -> 机器人回复“好的,1 小时正确吗?” -> 用户点击"is"按钮 -> 机器人回复“谢谢,明天见”

最佳答案

您将需要为此工作设置一个 cron 作业以及主动消息传递。幸运的是,您已经可以引用一些帖子来了解如何执行这两项操作。

cron 作业将允许您设置一天中执行主动消息的时间。此堆栈溢出post讨论如何创建一个可以与您的机器人一起运行的简单项目。或者,您也可以在 Azure Function 内运行 cron 作业。同样,它会按照设定的时间表调用您的主动消息 API。

关于主动消息,请查看此 Stack Overflow post这详细介绍了设置此服务。特定于该用户问题的某些要点不适用于您,可以忽略。这个sample BotBuilder-Samples 存储库中的内容也可以作为一个很好的引用点。

希望得到帮助!

<小时/>

[编辑]

以下是调用 API 发送主动消息的基本设置,该消息还会启动特定的对话流。显然,您需要进行更改以满足您的需求,但这应该会让您走上正确的道路。

简而言之,会针对您的机器人公开的 API 进行调用,其中包含 conversationId 作为参数。当调用 API 时,会创建一个 conversationReference 并用于发送英雄卡。 Hero 卡会询问用户是否接受过训练(是/否),并在用户响应时发送 PostBack。 PostBack 是通过中断方法在组件对话框中监视的触发器。当匹配成功后,“主动”对话框就会开始。当用户结束时,“主动”对话框将从堆栈中弹出,然后用户返回到对话停止的地方(如果他们在对话中)。

请注意,主动消息需要 token 和对话 ID。用户之前需要与机器人进行过对话,或者您需要事先通过机器人生成 token 和对话 ID,然后将其与用户的 Slack user.id 一起发送以开始。

索引.js

const conversationReferences = {};

const dialog = new MainDialog( 'MainDialog', userState, conversationState );
const bot = new WelcomeBot( conversationState, userState, dialog, conversationReferences );

server.post( '/api/message', async ( req, res ) => {
[...]
}

server.get( '/api/notify/:conversationID', async ( req, res ) => {
const { conversationID, query } = req.params;
const conversationReference = conversationReferences[ conversationID ];

await adapter.continueConversation( conversationReference, async turnContext => {
var reply = { type: ActivityTypes.Message };

const yesBtn = { type: ActionTypes.PostBack, title: 'Yes', value: 'Yes' };
const noBtn = { type: ActionTypes.PostBack, title: 'No', value: 'No' };

const card = CardFactory.heroCard(
'Have you trained today?',
null,
[ yesBtn, noBtn ]
);

reply.attachments = [ card ];

await turnContext.sendActivity( reply );
return { status: DialogTurnStatus.waiting };
} );


res.setHeader( 'Content-Type', 'text/html' );
res.writeHead( 200 );
res.write( '<html><body><h1>Proactive messages have been sent.</h1></body></html>' );
res.end();
} );

mainDialog.js

const { DialogSet } = require( 'botbuilder-dialogs' );
const { InterruptionDialog} = require( './interruptionDialog' );

const MAIN_WATERFALL_DIALOG = 'MainWaterfallDialog';
const ADAPTIVE_CARD = 'AdaptiveCard';

class MainDialog extends CancelAndHelpDialog {
constructor ( id, userState, conversationState ) {
this.mainId = id;
this.userState = userState;
this.conversationState = conversationState;
[...]
};

async run ( turnContext, accessor ) {
const dialogSet = new DialogSet( accessor );
this.id = this.mainId;
dialogSet.add( this );

const dialogContext = await dialogSet.createContext( turnContext );
const results = await dialogContext.continueDialog();
if ( results.status === DialogTurnStatus.empty ) {
return await dialogContext.beginDialog( this.id );
}
};

[...]
};

interruptionDialog.js

const { ProactiveDialog, PROACTIVE_DIALOG } = require( './proactiveDialog' );

class InterruptionDialog extends ComponentDialog {
constructor ( id ) {
super( id );
this.addDialog( new ConfirmPrompt( 'ConfirmPrompt' ) );
this.addDialog( new ProactiveDialog() );
}

async onBeginDialog ( innerDc, options ) {
const result = await this.interrupt( innerDc );
if ( result ) {
return result;
}
return await super.onBeginDialog( innerDc, options );
}

async onContinueDialog ( innerDc ) {
const result = await this.interrupt( innerDc );
if ( result ) {
return result;
}
return await super.onContinueDialog( innerDc );
}

async onEndDialog ( innerDc ) {
const result = await this.interrupt( innerDc );
if ( result ) {
return result;
}
return await super.onEndDialog( innerDc );
}

async interrupt ( innerDc, next ) {
if ( innerDc.context.activity.type === 'message' ) {
if ( activity.channelId === 'slack' && activity.channelData.Payload ) {
if ( activity.channelData.Payload.actions[ 0 ].name === 'postBack' ) {
return await innerDc.beginDialog( PROACTIVE_DIALOG );
}
}
}
}
}

module.exports.InterruptionDialog = InterruptionDialog;

proactiveDialog.js

const {
NumberPrompt,
ComponentDialog,
DialogTurnStatus,
WaterfallDialog
} = require( 'botbuilder-dialogs' );

const PROACTIVE_DIALOG = 'proactiveDialog';
const WATERFALL_DIALOG = 'WATERFALL_DIALOG';
const NUMBER_PROMPT = 'NUMBER_PROMPT';

class ProactiveDialog extends ComponentDialog {
constructor () {
super( PROACTIVE_DIALOG );

this.addDialog( new NumberPrompt( NUMBER_PROMPT ) );
this.addDialog( new WaterfallDialog( WATERFALL_DIALOG, [
this.didTrainStep.bind( this ),
this.trainingStep.bind( this )
] ) );
this.initialDialogId = WATERFALL_DIALOG;
}

async didTrainStep ( stepContext ) {
const activity = stepContext.context.activity;
const response = activity.channelData.Payload.actions[ 0 ].value.toLowerCase();
if ( response === 'yes' ) {
return await stepContext.prompt( NUMBER_PROMPT, 'Fantastic! How many minutes?' )
} else if ( response === 'no' ) {
await stepContext.context.sendActivity( 'Rubbish...serious rubbish.' )
}
return await stepContext.next();
}

async trainingStep ( stepContext ) {
const activity = stepContext.context.activity;
const stepResult = stepContext.result;
const textResponse = activity.text.toLowerCase();

if ( textResponse === 'no' ) {
await stepContext.context.sendActivity( "I would recommend at least 5-10 mins of training." )
} else
if ( typeof ( stepResult ) === 'number' && stepResult > 0 ) {
await stepContext.context.sendActivity( "I'll log that for you." );
} else if ( stepResult <= 0 ) {
await stepContext.context.sendActivity( "I can't log that value." )
}
return { status: DialogTurnStatus.complete }
}
}
module.exports.ProactiveDialog = ProactiveDialog;
module.exports.PROACTIVE_DIALOG = PROACTIVE_DIALOG;

关于javascript - 处理提醒对话框的答案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57715944/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com