问题
I am developing a bot that is connected to our client application using Direct Line using botbuilder JS V4. for some reasons, messages are sent with a wrong order to the bot. For example:
User: hello
Bot: How can I help you?
- Bot: Hi, I am a robot.
As a solution, I added a delay of two seconds between messages in many of my bot's dialogues.
What is the right way to do that? And is this the recommended way to fix this issue?
Using setTimeout()
async greetUser(step) {
...
await step.context.sendActivity(firstReply);
setTimeout(() => {
await step.context.sendActivity(secondReply);
}, 2000);
}
Using sleep()
const sleep = require("util").promisify(setTimeout);
async greetUser(step) {
...
await step.context.sendActivity(firstReply);
await sleep(2000);
await step.context.sendActivity(secondReply);
}
After adding many of sleep() functions, I noticed that the bot performance is affected. The bot wasn't responding in production enivrement. and it thows this error:
[onTurnErrorStack]: Error
at new RestError (D:\home\site\wwwroot\node_modules\@azure\ms-rest-js\dist\msRest.node.js:1397:28)
at D:\home\site\wwwroot\node_modules\@azure\ms-rest-js\dist\msRest.node.js:1849:37
at <anonymous>
at process._tickDomainCallback (internal/process/next_tick.js:228:7)
[onTurnError]: {"statusCode":401,"request":{"streamResponseBody":false,"url":"https://directline.botframework.com/v3/conversations/DxjYZQsdv16sdULAsaIn8iQ-h/activities/DxjYZQ65dffgsaIn8iQ-h%7C0000000","method":"POST","headers":{"_
Any suggestions to resolve this issue?
回答1:
If you are using the default BotFrameworkAdapter
, you could also use the delay
ActivityType. This will add a delay without extra code (source).
You could also give sendActivities
method a try, according to the documentation this will also keep the order.
The activities will be sent one after another in the order in which they're received. A response object will be returned for each sent activity. For message
activities this will contain the ID of the delivered message.
async greetUser(step) {
await step.context.sendActivities([
{ type: 'message', text: 'First reply' },
{ type: 'delay', value: 2000 },
{ type: 'message', text: 'Second reply' }
]);
}
回答2:
I had a similar issue where I was logging transcripts and the response would overwrite the request. I found a simple for loop that allowed me to set a ms delay and it worked great for me. The wait function is:
async wait(milliseconds) {
var start = new Date().getTime();
for (var i = 0; i < 1e7; i++) {
if ((new Date().getTime() - start) > milliseconds) {
break;
}
}
}
So you should be able to call it like this:
async greetUser(step) {
...
await step.context.sendActivity(firstReply);
await this.wait(2000);
await step.context.sendActivity(secondReply);
}
Now this seems very similar to sleep function, which I do not have any experience with. I haven't had any issues with it and it is getting called twice per turn to log both the request and the response, though my delay is only 250ms, not 2000.
I would be interested to know if there is a better way to introduce conversation delay.
Edit: As mentioned in comments below, awaiting a Promise would be a better solution. But leaving the original answer here in case it is beneficial to someone. Inside async function, it seems that await new Promise(resolve => setTimeout(resolve,2000));
would provide same results without the drawbacks.
来源:https://stackoverflow.com/questions/58233171/how-to-make-a-delay-between-two-messages-in-bot-framework-node-js