Ending conversation - node.js

My bot (using MS BotFramework) is supposed to be hearing the conversation stream. If someone mentions 'chatbot' it should say 'Here I am!', otherwise stays quiet. It seems to be very simple and maybe it is but I am having a hard time trying to implementing it. Here is what I have:
bot.add('/', function(session) {
if (someoneSaidChatbot) {
session('Here I am!")
} else {
// session.reset(), maybe? No!
// session.endDialog() then? Uh...nope.
// nothing? Hmmm. negative
}
});
So, nothing works. If I leave there the bot just hangs and it stops listening to the stream or answering commands.
Any thoughts?

This code ends a dialog when someone types "chatbot" as part of the utterance. Is this what you are looking for?
bot.add('/', function (session) {
if (session.message.text.search("chatbot") >= 0) {
session.endDialog("Here I am");
}
});

I'd like to suggest use endConversationAction() to register a Bots Global Actions
bot.endConversationAction(
'enddialog', //dialog Id
'Here I am', //message
{ matches: /^.*chatbot/i } //match pattern
);
since this is global action, anytime when bot heard "Chatbot", it will say "Here I am" , if there are some dialog in stack, your proposed solution might not work.

It may also depend on which channel you're using. Some channels don't offer the ability for the Bot to listen to all of the messages in the conversation.

Related

'reloadAction' in Microsoft Bot Framework 3.15 for Node.js is not passing on 'dialogArgs'

I'm following the example from the Bot Framework pages, under 'Handle User Actions' (https://learn.microsoft.com/en-us/azure/bot-service/nodejs/bot-builder-nodejs-dialog-actions?view=azure-bot-service-3.0)
// Order dinner.
bot.dialog('orderDinner', [
function(session, args, next){
if(args && args.isReloaded){
// Reload action was triggered.
}
session.send("Lets order some dinner!");
builder.Prompts.choice(session, "Dinner menu:", dinnerMenu);
}
//...other waterfall steps...
])
// Once triggered, will restart the dialog.
.reloadAction('startOver', 'Ok, starting over.', {
matches: /^start over$/i,
dialogArgs: {
isReloaded: true;
}
});
and after reloading the dialog args.isReloadedis always undefined. That is, it doesn't seem that the framework is passing through what is put in dialogArgs. Any clues as to what I might be missing? I'm using v 3.15 (or rather, the people for whom I'm working are using 3.15) -- was this something that was introduced in a later version 3, that is, after 3.5? Or is something just going wrong?
Any help much appreciated!
Tried the code with the specified version and is working correctly. There is an errant ";" in your code (which is also in the docs) that should be removed and may be the culprit. Change the following line to the below.
Hope of help!
dialogArgs: {
isReloaded: true
}

How to prevent google action from closing the conversation if there is no intent match?

whenever default fallback intent is triggered 3 times in a row conversation is getting closed with the response, my test app left the conversation. How can i prevent this from happenning and also only exit from the action only when user wants to exit from the action.
The Actions on Google docs mention a conv.data.fallbackCount object, which you can read about in the No-match reprompting subsection:
app.intent('Default Fallback Intent', (conv) => {
conv.data.fallbackCount++;
// Provide two prompts before ending game
if (conv.data.fallbackCount === 1) {
conv.contexts.set(DONE_YES_NO_CONTEXT, 5);
conv.ask('Are you done playing Number Genie?');
} else {
conv.close(`Since I'm still having trouble, so I'll stop here. ` +
`Let’s play again soon.`);
}
});
Although it's arguably better conversation design to leave this variable alone -- thereby letting the conversation close when the counter increments to three -- you could try resetting conv.data.fallbackCount manually, like:
conv.data.fallbackCount = 0;
At least right now with the new Google Action you can just redirect the user to the current scene again on a NO_MATCH intent.
Basically in your webhook just set:
webhookResponseJson.scene.next.name = webhookRequestJson.scene.name

how to move to other section in script

I'm building a bot using gupshup.io using the scripting way ... but handling some things in default.js file as mentioned in the docs
I'm trying in a handler function to check if the event.message equals specific string to go to another section in the script
can anybody please help ?
thanks a lot
So to achieve that you can create a child state to go another section and just set options.next_state to that state. I mean suppose you have a script like this
[main]
inputParser:Welcome to New Bot.
thisFlow:
This is a output of this flow.
callAnotherFlow:
:call default.anotherFlow
[anotherFlow]
This is another flow.[[Wow, No]]
Wow
Thanks
No
Oh!
So in case if the message is 'another flow' you want the second flow to begin. So in the input parser you can create something like.
module.exports.main = {
inputParser: (options, event, context, callback)=>{
if(event.message.toLowerCase() === "another flow"){
options.next_state = 'callAnotherFlow';
}else{
options.next_state = 'thisFlow';
}
callback(options, event, context);
}
}
I think this is what you are looking for.

Server state and users in a Meteor app, how to create state?

I have a Meteor application where I use RiveScript, a chatbot module for Node. The module can save some aspects of user input. My issue is that when I run the module on server, the state is not saved for one user, but for all users. How would I go about creating a state for each user?
One method would be to create a new bot for each user like so:
let RiveScript = require('rivescript');
let users = {};
Meteor.onConnection(connection => {
users[connection.id] = new RiveScript({utf8: true});
users[connection.id].bot.loadDirectory('directory/',
() => {
users[connection.id].bot.sortReplies();
}
);
connection.onClose(() => {
delete users[connection.id]
})
});
However, in terms of memory management this can cause an issue. Are there any commonly used patterns in this regard?
I am not familiar with Meteor nor RiveScript, so I hope I'm answering your question.
If you want to keep a certain state for each conversation, e.g.
Chat #1 : the bot is waiting for the user to answer a particular question
Chat #2 : the bot is waiting for a command
...
Why don't you use a simple array mapping a conversation identifier (or in your case connection.id, I'm guessing) to its current state?
Example:
// Just to simulate an enumeration
var States = {WAITING: 0, WAITING_XXX_CONFIRMATION: 1, ...}
var state = [];
Meteor.onConnection(connection => {
state[connection.id] = States.WAITING;
});
// Somewhere else, e.g. in response to a command
if (state[connection.id] == WAITING_XXX_CONFIRMATION && input === 'yes') {
// do something
// reset the state
set[connection.id] = WAITING;
}
You could then keep track of the state of every conversation, and act accordingly. You could also wrap the state management inside an object to make it more reusable and nice to use (e.g. StateManager, to be able to make calls such as StateManager.of(chatId).set(newState).
Hope this helps.

Chrome extension delay condition

I have created a chrome extension which does something after its button is clicked.
However I dont want it be abused so I need the its code to be executed after some time.
How can I surround this code with a timeout in order to achieve this?
Thank you for reading me!
chrome.tabs.getSelected(null,function(tab) {
var Mp=tab.url.substring(0,23);
if(Mp=='https://www.example.com')
{
onWindowLoad();
chrome.extension.onMessage.addListener(function(request, sender) {
if (request.action == "getSource")
{
...Working here
}
});
}
else
{
message.innerHTML='<span style="color: #f00">This is not a valid page</span>';
}
});
function onWindowLoad()
{
var message = document.querySelector('#message');
chrome.tabs.executeScript(null, {file: "getPagesSource.js"});
}
I had to make a compromise so just after the getSelected I added the following line:
chrome.browserAction.disable(tab.Id);
It disables the action button thus it cant be clicked while the script sends the data to the server, as with this extension I grab the tab url in order to store it in my database.
After the ajax response and adding the following
if(xhr.readyState==4)
{
message.innerHTML=xhr.responseText;
chrome.browserAction.enable(tab.Id); /////<---THAT LINE
}
the button gets ready again to be clicked.
I couldnt find the way to add a specific delay in seconds, this way seems stupid but its working, as the response's delay from my server is enough for switching the 2 states of the action button.
With this, however another problem came up, which Ill write in different question.

Resources