How can I integrate my MS text bot program written in NodeJS to skype bot? - node.js

I'd like to develop a skype bot that would take user name as input and say hello username in the opposite char case based on the user input. In brief, if the user types his name as james, my bot would respond to him as Hello JAMES. The program runs fine, however I am finding it ambiguous to integrate my textbot program to skype bot.
Here's my code:
var builder = require('botbuilder');
var helloBot = new builder.TextBot();
helloBot.add('/', [
function (session, args, next) {
if (!session.userData.name) {
session.beginDialog('/profile');
} else {
next();
}
},
function (session, results) {
session.send('Hello %s!', session.userData.name);
}
]);
helloBot.add('/profile', [
function (session) {
builder.Prompts.text(session, 'Hi! What is your name?');
},
function (session, results) {
if(results.response == results.response.toUpperCase())
{
//console.log("in if");
session.userData.name = results.response.toLowerCase();
}
else
{
//console.log("else");
session.userData.name = results.response.toUpperCase();
}
session.endDialog();
}
]);
console.log("Hi!");
helloBot.listenStdin();
The output would be like :
bot : Hi
user: Hello.
bot : What is your name?
user: james.
bot : Hello JAMES.

To create a chat bot compatible with Skype, use the UniversalBot type instead of TextBot. You can find sample code that demonstrates how to send different card types in BotBuilder-Samples/Node/cards-RichCards.
To configure your bot to work with Skype, login to the Bot Portal at https://dev.botframework.com and register your bot. After your bot is registered, go to 'My bots', click on your bot name, and you will see the 'Channels' section with Skype and WebChat enabled by default. Under 'Test link', click the 'Add to Skype' button. This will redirect you to the Skype website where it will ask you to confirm that you want to add the Skype bot to your Skype contacts.
For more information on Skype bots check out the Getting Started Guide.

Related

Direct Messaging custom slack bot built on node.js

I have built a slack bot using the slack/bots apis in node.js: https://slack.dev/bolt-js/tutorial/getting-started
Currently, it is working fine when I type <bot> help in a channel I have set up for using webhooks. I am trying to run those same commands in a DM with the bot using the app.event('app_mention',...) method but it is not working. its like the message doesn't register in a DM with the bot for some reason but it works in a public channel. code snippet below:
app.event('app_mention', async ({ event, client}) => {
console.log(event);
const text = event.text;
const parentMessageId = event.ts;
const eventChannel = event.channel;
if (text.includes("help")) {
console.log(event);
try {
await client.chat.postMessage({
channel: eventChannel,
text: helpMessage,
thread_ts: parentMessageId
});
} catch (err) {
console.error(err);
}
I should have permissions set up correctly as well. I basically have all the permissions that I can add for the bot
The documentation of the app_mention api specifically mentions that this event does not work with DMs.
Messages sent to your app in direct message conversations are not
dispatched via app_mention, whether the app is explicitly mentioned or
otherwise. Subscribe to message.im events to receive messages directed
to your bot user in direct message conversations.
Check here : https://api.slack.com/events/app_mention

disable qna recognizer when inside a dialog

I am using Luis and QnA maker, qna maker is now interupting a waterfall prompt. I have disabled the Luis prompt with code below, how can I to do same for the qna recognizer?
var recognizer = new
builder.LuisRecognizer(LuisModelUrl).onEnabled(function (context,
callback) {
var enabled = context.dialogStack().length == 0;
callback(null, enabled);
});
bot.recognizer(recognizer);
bot.recognizer(qnaRecognizer);
console.log(recognizer);
eg: What part of the toilet is broken? (1. Cistern, 2. Pipe, or 3. Seat)
Anything except an exact match gets picked up by qna sentiment which replaces the dialog stack
Thanks
You shouldn't have to disable either one for the code to work. I suspect the problem is in your dialog flow. Below is an example of how to construct the dialog portion of your bot. When I ran this, the logger middleware shows QnA is matching on the inputs I feed, but the bot is dictating the conversation because of the code.
var luisrecognizer = new builder.LuisRecognizer(LuisModelUrl);
var qnarecognizer = new cognitiveservices.QnAMakerRecognizer({
knowledgeBaseId: process.env.QnAKnowledgebaseId,
authKey: process.env.QnAAuthKey || process.env.QnASubscriptionKey,
endpointHostName: process.env.QnAEndpointHostName
});
var basicQnAMakerDialog = new cognitiveservices.QnAMakerDialog({
recognizers: [qnarecognizer],
defaultMessage: 'No match! Try changing the query terms!',
qnaThreshold: 0.3
});
bot.recognizer(luisrecognizer);
bot.recognizer(basicQnAMakerDialog);
bot.dialog('/', basicQnAMakerDialog);
bot.dialog('GreetingDialog',[
(session) => {
session.send('You reached the Greeting intent. You said \'%s\'.',
session.message.text);
builder.Prompts.text(session, "What is your name?");
},
(session, results) => {
session.userData.name = results.response;
session.send("Glad you could make it, " + session.userData.name);
builder.Prompts.text(session, "Ask me something!");
},
(session, results) => {
session.conversationData.question = results.response;
session.send(session.conversationData.question + " is an interesting topic!")
session.endDialog();
}
]).triggerAction({
matches: 'Greeting'
})
In the following image, LUIS brings me to the Greeting intent when I type "I'm happy [to be here]" which I have trained in the LUIS app. The bot dialog takes over asking me questions and storing the answers. Even though I'm making statements that QnA or LUIS should respond to neither is doing so. The conversation follows the code.
Had Qna taken over it would have responded to "What are you" with some text about QnA Maker. Similarly, "help" would have produced responses from either QnA or LUIS as I have topics/intents for both, respectively.

How to add Get Started button in the typing bar using bot builder sdk for node.js

I am using bot builder sdk for node.js to create a chatbot. Also connected it to facebook channel. I am using the following code to greet the user:
var bot = new builder.UniversalBot(connector, [
(session, result, next) => {
let text = '';
switch(session.message.address.channelId) {
case 'facebook':
text = 'Hi ' + session.message.user.name + ' !';
break;
default:
text = 'Hi !';
}
session.sendTyping();
session.say(text);
next();
},
(session, say) => {
}
]);
The above code works fine, but I want to add "Get Started" button in the typing bar to invoke the above code. Note that this button appears only once. Please find image of the typing bar below:
Is there a way to achieve this using bot builder sdk for node.js ?
Thanks
Although one can certainly add a button to start any activity with the bot, but that will limit the bots potential to only one customizable channel, i.e. WebChat.
I think there are better 2 alternative ways to get the desired functionality which will work across many channels.
First
I would suggest to add a conversation update event. Code goes in the botbuilder's middleware. Here is a sample code from the docs.
bot.on('conversationUpdate', function (message) {
if (message.membersAdded && message.membersAdded.length > 0) {
// Say hello
var txt = "Send me a Hi";
var reply = new builder.Message()
.address(message.address)
.text(txt);
bot.send(reply);
});
What this will do is make the bot send a message Send me a Hi to the user, if it determines this is a first time visitor. This will give the visitor enough cue to send the bot Hi by typing it. Although he can enter whatever he wants, but this will result in the invocation of the 1st dialog configured which in this case is the will be the dialog which you have posted in question.
Second
You can mark some dialog to be invoked automatically if your bot has never encountered this visitor. Here is the sample code...
var bot = new builder.UniversalBot(connector);
bot.dialog('firstRun', function (session) {
session.userData.firstRun = true;
session.send("Hello...").endDialog();
}).triggerAction({
onFindAction: function (context, callback) {
// Only trigger if we've never seen user before
if (!context.userData.firstRun) {
// Return a score of 1.1 to ensure the first run dialog wins
callback(null, 1.1);
} else {
callback(null, 0.0);
}
}
});
Here we have split the bot creation and dialog registration in 2 steps. And while registering the firstRun dialog, we have provided it the triggerAction that if the visitor is new, then trigger this dialog.
Both of these approaches do not use adding some extra buttons and it is up to the bot either to educate him on sending some message which in turn will start the 1st dialog or directly start some dialog.
For more info on conversationEvent you can refer to this page
I tried the above options, but they didn't seem to be working for facebook messenger. But I found a solution to add the Get Started button into the typing bar of the messenger. For that we need to use the Facebook Graph API and not the bot builder sdk.
https://graph.facebook.com/v2.6/me/messenger_profile?access_token=<PAGE_ACCESS_TOKEN>
{
"get_started":{
"payload":"Get Started"
}
}
The above API call will add the button for you to get the conversation started.
Thanks all for the help!!

dialogs in botframework using LUIS.ai

I have a piece of code that works perfectly on my local bot, and weird when integrated with LUIS. It's a simple dialogue that redirects to another dialog:
// Modelo de datos cargado en luis.ai
var recognizer = new builder.LuisRecognizer(process.env.LUIS_MODEL_URL);
bot.recognizer(recognizer);
//first intent, greeting intent to say hi to the user
bot.dialog('greetings', [
function (session) {
var greetings = ["¡Hola!", "Bonjour amigo!", "zdravstvuyte! (Así se dice hola en ruso)"];
var pickAGreeting = function () {
var rnd_greeting = greetings[Math.floor(Math.random() * 4)];
return rnd_greeting;
};
session.send(pickAGreeting(), session.message.text);
builder.Prompts.text(session, 'What can I do for you about Office?');
},
function (session, results) {
var user_response = results.response;
session.beginDialog('getProductoOffice', user_response);
}
]).triggerAction({
matches: 'greetings',
onInterrupted: function (session) {
session.send('Can I help you with something?');
}
});
bot.dialog('getProductoOffice', [
function (session, args) {
session.send('Welcome to O365 help!', session.message.text);
...
And the bot does this:
[me]: Hola
[bot]: ¡Hola!
[bot]: What can I do for you about Office?
[me]: Tell me about Skype
[bot]: Can I help you with something?
The weird thing is that after prompting me about Office, it never enters the "function (session, results)" and goes directly into the interrupted dialogue code.
This piece of code works perfectly without LUIS integration and moves correctly between dialogues.
The dialog was interrupted every time I entered an utterance recognized by LUIS because of the triggerAction behavior.
To disable the recognizer when a task is running I had to use the method onEnabled in the recognizer as follows:
var recognizer = new builder.LuisRecognizer('<model>').onEnabled(function (context, callback) {
var enabled = context.dialogStack().length == 0;
callback(null, enabled);
});
This won't interrupt the dialog stack and the recognizer will work only when there is no conversation running.

Trigger a specific dialog in Bot via Directline API

I'm working on breaking my bot repo into 2 separate repos
A repo to purely handle bot logic
A repo to handle custom chat via directline
Currently , we have a feature where we can trigger the bot to start a specific dialog if its mentioned as a parameter in the URL. So something like
https://foo.com/?param=bar
would trigger the bar dialog
This is the code that handles it
function(userId, conversationId, params, token){
return new Promise((resolve, reject)=>{
var _directlineAddress = {
bot: {"id":config.BOT.ID, "name": config.BOT.HANDLE},
channelId: "directline",
serviceUrl: config.BOT.DIRECTLINE_URL,
useAuth: true,
user:{"id": userId},
"conversation": {"id": conversationId}
}
if(params.options){
var _re = /^\?(\w+)*=(\w+)*/
var _programType = _re.exec(params.options);
if (_programType[1] === "foo") {
var _dialogId = "*:/foo";
}
else {
var _dialogId = "*:/" + _programType[1];
}
} else {
var _dialogId = "*:/";
var _specialParams = {"sessionId":token};
}
bot.beginDialog(_directlineAddress, _dialogId, _specialParams, function(err){
else{
resolve();
}
});
})
};
Since i'm splitting the directline from the bot logic , i will no longer be having access to the bot object. therefore bot.beginDialog would not work here
Is there a way i can trigger the dialog by posting to the Directline API?
No. With Direct Line you will be able to send messages to the bot. I guess that a way to go here will be to define a convention message that you will send via Direct Line and that the bot logic will know that it will have to start a dialog based on it.

Resources