I have written a dummy bot using the latest botbuilder version : 3.4.4. My sample code is:
var server = restify.createServer();
server.listen(config.port,config.ip,function () {
try{
console.log('%s listening to %s', server.name, server.url);
console.log("Welcome to Banker Bot!!!!");
}
catch(err){
console.log("Server already in Use" + err);
}
});
var connector = new builder.ChatConnector({
appId: config.MICROSOFT_APP_ID,
appPassword: config.MICROSOFT_APP_PASSWORD
});
var bot = new builder.UniversalBot(connector);
server.post('/api/messages', connector.listen());
var recognizer = new builder.LuisRecognizer(config.model);
bot.dialog('/', [
function (session) {
session.beginDialog('/askName');
},
function (session, results) {
session.send('Hello %s!', results.response);
}
]);
bot.dialog('/askName', [
function (session) {
builder.Prompts.text(session, 'Hi! What is your name?');
},
function (session, results) {
session.endDialogWithResult(results);
}
]);
I am trying to talk to my bot using emulator. I am able to connect to bot as I get : "ChatConnector: Message Received" when I type anything, then I get a session.error(). Please guide me as to where I am going wrong. I am completely novice to chatbot and nodejs.
Thanks in advance
In your code you are calling results.response in session.send('Hello %s!', results.response); but here when I have run code results is undefined hence it goes in session.err dialog.
Related
i am following this tutorial regardign saving data to database using mqtt to mysql sensor to mysql via mqtt where i am at the app_mqtt.js part where i try to follow the exact same thing to create the js file but when i try to run it via python, it shows an error of :
File "app_mqtt.js", line 1
var mqtt = require('mqtt');
^
SyntaxError: invalid syntax
I have already the mqtt via npm i mqtt and npm install mqtt --save yet it still have such an error, i really need help in this. Thank you.
var mqtt = require('mqtt');
var Topic = '#'; //subscribe to all topics
var Broker_URL = 'mqtt://192.168.1.123';
var options = {
clientId: 'MyMQTT',
port: 1883,
keepalive : 60
};
var client = mqtt.connect(Broker_URL, options);
client.on('connect', mqtt_connect);
client.on('reconnect', mqtt_reconnect);
client.on('error', mqtt_error);
client.on('message', mqtt_messsageReceived);
client.on('close', mqtt_close);
function mqtt_connect()
{
console.log("Connecting MQTT");
client.subscribe(Topic, mqtt_subscribe);
}
function mqtt_subscribe(err, granted)
{
console.log("Subscribed to " + Topic);
if (err) {console.log(err);}
}
function mqtt_reconnect(err)
{
console.log("Reconnect MQTT");
if (err) {console.log(err);}
client = mqtt.connect(Broker_URL, options);
}
function mqtt_error(err)
{
console.log("Error!");
if (err) {console.log(err);}
}
function after_publish()
{
//do nothing
}
function mqtt_messsageReceived(topic, message, packet)
{
console.log('Topic=' + topic + ' Message=' + message);
}
function mqtt_close()
{
console.log("Close MQTT");
}
As per your code , it shows fine.
1) Try to restart the server.
2) check your code to this code
npm i mqtt --save
var mqtt = require('mqtt')
var client = mqtt.connect('mqtt://{Your connection string}')
client.on('connect', function () {
client.subscribe('presence', function (err) {
if (!err) {
client.publish('presence', 'Hello mqtt')
}
})
})
client.on('message', function (topic, message) {
// message is Buffer
console.log(message.toString())
client.end()
})
3) At last , re-install the package.
Note: If still issue , please share your code. So I can debug it.
I am very new to bot builder. I need to use LUIs intents and then eventually call azure-search to search the intent.
However, below is my code. In the Aco-Saerch intent, I want to extract the intent from the user's message and then want to pass to the query in the azure-search.
In the dialog SearchDialog, waterfall functions are not proceeding after the first function. Can anyone help me out whats wrong here.
I am trying the use the azure search code and libraries from this git-hub shared code: Realstate azure search node js code
In future, I want to add QnA recognizer too. Aim is : search the query in qnA base, if found, return else, use the LUIS to find out the intent and then pass it the azure search.
var util = require('util');
var _ = require('lodash');
var builder = require('botbuilder');
var restify = require('restify');
/// <reference path="../SearchDialogLibrary/index.d.ts" />
var SearchLibrary = require('../SearchDialogLibrary');
var AzureSearch = require('../SearchProviders/azure-search');
// Setup Restify Server
var server = restify.createServer();
server.listen(process.env.port || process.env.PORT || 3978, function () {
console.log('%s listening to %s', server.name, server.url);
});
// Create chat bot and listen for messages
var connector = new builder.ChatConnector({
appId: process.env.MICROSOFT_APP_ID,
appPassword: process.env.MICROSOFT_APP_PASSWORD
});
server.post('/api/messages', connector.listen());
// Bot Storage: Here we register the state storage for your bot.
// Default store: volatile in-memory store - Only for prototyping!
// We provide adapters for Azure Table, CosmosDb, SQL Azure, or you can implement your own!
// For samples and documentation, see: https://github.com/Microsoft/BotBuilder-Azure
var inMemoryStorage = new builder.MemoryBotStorage();
const LuisModelUrl = 'https://westeurope.api.cognitive.microsoft.com/luis/v2.0/apps/180a9aaa-9d67-4d40-b3d3-121917f4dbb8?subscription-key=39155bb750dc4b2abd84d410d80fce21&timezoneOffset=0&q=';
var recognizer = new builder.LuisRecognizer(LuisModelUrl);
// Bot with main dialog that triggers search and display its results
var bot = new builder.UniversalBot(connector, function (session, args) {
session.send('You reached the default message handler. You said \'%s\'.', session.message.text);
}).set('storage', inMemoryStorage);
bot.recognizer(recognizer);
bot.dialog('GreetingDialog',
(session) => {
session.send('You reached the Greeting intent. You said \'%s\'.', session.message.text);
session.endDialog();
}
).triggerAction({
matches: 'Greeting'
})
bot.dialog('HelpDialog',
(session) => {
session.send('You reached the Help intent. You said \'%s\'.', session.message.text);
session.endDialog();
}
).triggerAction({
matches: 'Help'
})
bot.dialog('CancelDialog',
(session) => {
session.send('You reached the Cancel intent. You said \'%s\'.', session.message.text);
session.endDialog();
}
).triggerAction({
matches: 'Cancel'
})
bot.dialog('SearchDialog', [
function (session, args) {
var intent = args.intent;
var title = builder.EntityRecognizer.findEntity(intent.entities, 'businessterm');
console.log(title.entity);
session.send('You reached the Search.Aco intent. You enquire for the entitiy \'%s\'.', title.entity);
},
function (session, args, results) {
// Trigger Search
console.log("Inside the SearchLibrary.begin");
SearchLibrary.begin(session);
console.log("after the SearchLibrary.begin");
},
function (session, args, results) {
// Process selected search results
session.send(
'Done! For future reference, you selected these properties: %s',
args.selection.map(function (i) { return i.key; }).join(', '));
}
]).triggerAction({
matches: 'Search.Aco'
});
var azureSearchClient = AzureSearch.create('aco-intel2', '4105C6676D0CDD9B2E7891952B9E9E00', 'azureblob-index');
var jobsResultsMapper = SearchLibrary.defaultResultsMapper(jobToSearchHit);
// Register Search Dialogs Library with bot
bot.library(SearchLibrary.create({
multipleSelection: true,
search: function (query) { return azureSearchClient.search(query).then(jobsResultsMapper); },
refiners: ['people', 'content', 'location']
}));
// Maps the AzureSearch Job Document into a SearchHit that the Search Library can use
function jobToSearchHit(acosearch) {
console.log("inside jobToSearchHit");
console.log("inside acosearch.DocUrl" + acosearch.DocUrl + "-------" + acosearch.metadata_storage_name);
return {
key: acosearch.id,
title: acosearch.metadata_storage_name,
description: acosearch.content.substring(0, 100)+"...",
documenturl:acosearch.DocUrl,
imageUrl: acosearch.imageurl
};
}
Your dialog isn't advancing as there is nothing for it to act on. Thus, it reaches the end of the first function with nowhere to move on to. You have a few options. You can:
You can include a prompt or button (i.e. some sort of action) to move the dialog along. Ex:
bot.dialog('SearchDialog', [
function (session, args) {
var intent = args.intent;
var title = builder.EntityRecognizer.findEntity(intent.entities, 'businessterm');
console.log(title.entity);
session.send('You reached the Search.Aco intent. You enquire for the entitiy \'%s\'.', title.entity);
builder.Prompts.choice(session, "Start search?", "Yes|No", { listStyle: builder.ListStyle["button"] });
},
function (session, args, results) {
// Trigger Search
console.log("Inside the SearchLibrary.begin");
SearchLibrary.begin(session);
console.log("after the SearchLibrary.begin");
}
You can marry the first and second function. However, again, you will need something to move the dialog along from the search function to the search results function.
bot.dialog('SearchDialog', [
function (session, args) {
var intent = args.intent;
var title = builder.EntityRecognizer.findEntity(intent.entities, 'businessterm');
console.log(title.entity);
session.send('You reached the Search.Aco intent. You enquire for the entitiy \'%s\'.', title.entity);
// Trigger Search
console.log("Inside the SearchLibrary.begin");
SearchLibrary.begin(session);
console.log("after the SearchLibrary.begin");
},
function (session, args, results) {
// Process selected search results
session.send(
'Done! For future reference, you selected these properties: %s',
args.selection.map(function (i) { return i.key; }).join(', '));
}
]).triggerAction({
matches: 'Search.Aco'
});
You can make the search function a separate dialog that is initiated at the end of the first dialog function and, once completes, returns and continues the original dialog.
bot.dialog('SearchDialog', [
function (session, args) {
var intent = args.intent;
var title = builder.EntityRecognizer.findEntity(intent.entities, 'businessterm');
console.log(title.entity);
session.send('You reached the Search.Aco intent. You enquire for the entitiy \'%s\'.', title.entity);
session.beginDialog('/searchAzure');
},
function (session, args, results) {
// Process selected search results
session.send(
'Done! For future reference, you selected these properties: %s',
args.selection.map(function (i) { return i.key; }).join(', '));
}
]).triggerAction({
matches: 'Search.Aco'
});
bot.dialog('/searchAzure', [
function (session) {
// Trigger Search
console.log("Inside the SearchLibrary.begin");
SearchLibrary.begin(session);
console.log("after the SearchLibrary.begin");
session.endDialog();
}
]);
I'm currently building a chatbot with Azure's Bot service. I use a NLU-Bot, mixed with a waterfall flow, because dependent on the intent I want to get some specific information.
Therefore I match the intent1 and want to
var intents = new builder.IntentDialog({ recognizers: [recognizer] })
.matches('intent1', (session, args, results) =>{
session.beginDialog("getRequiredInformations");
session.send("I received your information");
})
bot.dialog('getRequiredInformations', [
(session) =>{
var levels = ['Beginner', 'Intermediate', 'Expert'];
builder.Prompts.choice(session, "What's your level ?", levels, { listStyle: builder.ListStyle.button, maxRetries: 0 });
},
(session, results) => {
session.conversationData.level = results.response.entity;
}
]);
What I want to do is to wait until we received the answer from the getRequiredInformations dialog and then continue with the original dialog containing the recognized intent. With the code above the session.send("I received your information");is sent before the user entered an answer.
I also tried with bot.beginDialogAction('getRequiredInformations', 'getRequiredInformations'); but I think it's not possible to call this inside the dialog.
How am I able to achieve this?
Found there several misstakes in your code snippet, please refer the following modification:
bot.dialog('intent1', [(session, args, next) => {
session.beginDialog("getRequiredInformations");
}, (session, args, next) => {
session.send("I received your information");
session.send(session.conversationData.level)
}]).triggerAction({
matches: 'intent1'
})
bot.dialog('getRequiredInformations', [
(session) => {
var levels = ['Beginner', 'Intermediate', 'Expert'];
builder.Prompts.choice(session, "What's your level ?", levels, {
listStyle: builder.ListStyle.button,
maxRetries: 0
});
},
(session, results) => {
session.conversationData.level = results.response.entity;
session.endDialog();
}
]);
But this means there is not really an opportunity to wait for the dialog to finish like a callback or anything, I need to do this with a waterfall?
If I understand correct, you can try to use the following code snippet to enable the luis recognizer only if there is no dialog in stack.
var recognizer = new builder.LuisRecognizer(luisAppUrl)
.onEnabled(function (context, callback) {
var enabled = context.dialogStack().length == 0;
callback(null, enabled);
});
Move the send to next waterfall step of the intent1 dialog. I think this should work.
var intents = new builder.IntentDialog({ recognizers: [recognizer] })
.matches('intent1', [(session, args, results) =>{
session.beginDialog("getRequiredInformations");
}, (session, args, results) =>{
session.send("I received your information");
}]);
matches method takes IWaterfallStep or IWaterfallStep[]. More info here.
I'm building a SlackBot with NodeJS.
I'm currently using this library slackbots, but the problem is that after the initialization, the bot does not appear in the Apps category, but it's inside SlackBot and every time I type a message it returns an error message:
I'm sorry, I don't understand! Sometimes I have an easier time with a few simple keywords. Or you can head to our wonderful Help Center for more assistance!
On the other side, when I send a message to a user I can see the bot I have set up:
How can I make the bot Hugo separated from the SlackBot inside Slack?
That's how I set it up:
var SlackBot = require('slackbots');
var bot = new SlackBot({
token: process.env.SLACK_TOKEN,
name: 'Hugo'
});
function get() {
return bot;
}
exports.get = function() {
return bot;
}
exports.send_message = function(user_ref, message) {
bot.postMessage(user_ref, message).then((data) => {
return data;
});
}
exports.get_users = function() {
var user_list = get().getUsers();
return user_list;
}
And this is how I send the test message:
var bot = require('./modules/bot.js');
bot.get().on('message', function(data) {
console.log("#######################################"); // -> debug only
console.log(data);
console.log("#######################################");
bot.send_message('USER_ID', 'test response');
});
I’m making a basic Twitter bot that will search Tweets for a certain word and reply to them.
The problem is that it replies to both Tweets and Retweets, but I want it to reply to Tweets only. How can I filter the Retweets from the stream?
I tried { track: 'hello -filter:retweets'} and it didn’t work.
console.log('The bot is starting');
var ntwitter = require('ntwitter');
var bot = new ntwitter({
consumer_key: '---',
consumer_secret: '---',
access_token_key: '---',
access_token_secret: '---'
});
var callback = function handleError(error) {
if (error) {
console.error('response status:', error.statusCode);
console.error('data:', error.data);
}
};
function startStreaming() {
bot.stream('statuses/filter', { track: 'hello'}, function(stream) {
console.log('Listening for Tweets...');
stream.on('data', function(tweet) {
if (tweet.text.match(/hello/)) {
bot.updateStatus('#' + tweet.user.screen_name + 'hello' , {in_reply_to_status_id: tweet.id_str} , callback);
console.log("done")
}
});
});
}
startStreaming();
Check for retweeted_status
stream.on('data', function (tweet) {
if (!tweet.retweeted_status) {
//...
I also wrote a tiny twitter like bot, maybe it helps you:
https://github.com/abimelex/twivorite