How can i connect Luis to Node.js - node.js

This is my first time working with node.js and i have to connect it to Luis, what i tried to do so far is a simple example available in the docs where the bot repeats what the user says and it gave an error as i seemingly am linking LUIS to node.js badly although I referred to the docs https://learn.microsoft.com/en-us/azure/cognitive-services/luis/luis-nodejs-tutorial-build-bot-framework-sample
precisely
// app.js - register LUIS endpoint API
var recognizer = new builder.LuisRecognizer(process.env.LUIS_MODEL_URL);
bot.recognizer(recognizer)
;
My code
var restify = require('restify');
var builder = require('botbuilder');
var http = require('http');
var recognizer = new builder.LuisRecognizer(MY_PATH_TO_LUIS_HTTP);
bot.recognizer(recognizer);
// 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 connector for communicating with the Bot Framework Service
var connector = new builder.ChatConnector({
appId: MY_ID,
appPassword:MY_PASS
});
// Listen for messages from users
server.post('/api/messages', connector.listen());
// Receive messages from the user and respond by echoing each message back (prefixed with 'You said:')
var bot = new builder.UniversalBot(connector, function (session) {
session.send("You said: %s", session.message.text);
});
So again what i'm trying to do is connect the Luis successfully to node.js then run the output in the cmd and test it in the bot framework channel emulator.
Kindly note that i have tested the code without adding
var http = require('http');
var recognizer = new builder.LuisRecognizer(MY_PATH_TO_LUIS_HTTP);
bot.recognizer(recognizer);
at first and it worked fine and i know that what i set in LuiS is different than what this node.js should do(repeat my words) but I'm just still getting a feel of how to link things.
Edit : I got this error
so i went to the command line and used this command npm install --save recognizer then imported to my code above by adding var recognizer = require ('recognizer');
still not working.

You are going in the right direction. The main issue is that you are doing
bot.recognizer before bot is declared :) (you are doing it at the bottom of the code)
Also, I believe that what it's missing is defining the intents methods that will handle the responses from LUIS.
You might want to check the following resources:
Recognize intents and entities with LUIS
The intelligence-LUIS Node.js sample

Related

Why am I getting: AskSdk.Request verification failed Error, Missing Certificate for the skill request?

I got a self hosted skill in Cloud Foundry, that uses Node js, Typescript and Express.
The code looks like this:
const app: express.Application = express()
// Skill entry point
const skill = application.getSkillBuilder.createSkillForWebService()
const adapter = new ExpressAdapter(skill, config.global.verifySignature, config.global.verifyTimestamp)
const PORT = app.listen(process.env.PORT || config.global.port)
app.post("/", adapter.getRequestHandlers())
const listener = app.listen(PORT, function () {
const { address, port } = listener.address() as AddressInfo
logger.debug("%s listening to %s%s", app.name, address, port)
})
So when I deploy into a lower environment and a new instance of the Express adapter is created, I pass false for verify signature and verify timestamp.
And it works when I test it on an Alexa device and on the Alexa developers console.
And when I deploy it into production and a new instance of the Express adapter is created, I pass true for the verify signature and verify timestamp.
And I get this error: AskSdk.Request verification failed Error, Missing Certificate for the skill request
Am I missing something in my code??
Do I need to upload the certificate in the Developers console??
Thanks in advance for your help

POST 500 Error Bot Emulator Localhost for IIS hosted Bot

I have used IIS to locally host my bot like so: https: //localhost/MyBot. Currently when I try to connect to my bot in the bot emulator I get a POST 500 error, and am unable to send messages. I am new to this and most documentation for publishing a bot to a local server is limited. I can however successfully open this link from my browser.
Am I experiencing this error because I don't have the https: //localhost/Bridget/api/messages directory/url? I tried creating Virtual Directories in IIS but that did not help solve my problem. Do I need tunneling software? Is there a simple tutorial for deploying a bot locally using IIS and connecting to it via the bot emulator?
Here is the error I see in the emulator:
Bot Emulator Error
Using ngrok tunneling software this is what I see:
NGROK Bot Emulator Error
Here is the code that processing incoming POST messages:
/// <summary>
/// POST: api/Messages
/// Receive a message from a user and reply to it
/// </summary>
public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
{
if (activity.Type == ActivityTypes.Message)
{
// Strip any #mentions
Mention[] m = activity.GetMentions();
for (int x = 0; x < m.Length; x++)
{
if (m[x].Mentioned.Id == activity.Recipient.Id)
{
if (m[x].Text != null)
{
activity.Text = activity.Text.Replace(m[x].Text, "");
}
}
}
await stateClient.BotState.SetUserDataAsync(activity.ChannelId, activity.From.Id, userData);
await Conversation.SendAsync(activity, () => new Dialogs.RootDialog());
}
else if (activity.Type == ActivityTypes.Invoke)
{
// Some Code...
}
else
{
HandleSystemMessage(activity);
}
var response = Request.CreateResponse(HttpStatusCode.OK);
return response;
}
Am I experiencing this error because I don't have the https: //localhost/Bridget/api/messages directory/url?
Both your screenshots show you trying to connect to /api/messages, which you say you don't have, so naturally, you are going to get an error.
Please post the portion of your bot code to show where you are listening for the messages. For example, a NodeJS bot would have something like:
var server = restify.createServer();
server.listen(process.env.port || process.env.PORT || 3978, () => {
console.log('%s listening to %s', server.name, server.url);
});
var connector = new builder.ChatConnector({
appId: process.env.MICROSOFT_APP_ID,
appPassword: process.env.MICROSOFT_APP_PASSWORD
});
var bot = new builder.UniversalBot(connector);
server.post('/api/messages', connector.listen());
The last line shows the connecting listening for message at /api/messages in the current application (being run by NodeJS using the restify library). What does your's have?
I fixed the issue, it was because IIS was not allowing POST requests. All I did was go to Request filtering and added the verb POST:
IIS POST Fix

Can't receive redis data from socket io

I'm building a realtime visualization using redis as pubsub messenger between python and node. There's a python script always running which sets a redis hash with hmset. That side of the app is working fine, if I enter the following example command: "HGETALL 'sellers-80183917'" in a redis client I end up getting the proper data.
The problem is in the js side. I'm using socketio and redis nodejs libraries to listen to the redis instance and publish the results online through a d3js viz.
I run the following code with node:
var express = require('express');
var app = express();
var redis = require('redis');
app.use(express.static(__dirname + '/public'));
var http = require('http').Server(app);
var io = require('socket.io')(http);
var sredis = require('socket.io-redis');
io.adapter(sredis({ host: 'localhost', port: 6379 }));
redisSubscriber = redis.createClient(6379, 'localhost', {});
redisSubscriber.on('message', function(channel, message) {
io.emit(channel, message);
});
app.get('/sellers/:seller_id', function(req, res){
var seller_id = req.params.seller_id;
redisSubscriber.subscribe('sellers-'.concat(seller_id));
res.render( 'seller.ejs', { seller:seller_id } );
});
http.listen(3000, '127.0.0.1', function(){
console.log('listening on *:3000');
});
And this is the relevant part of the seller.ejs file that's receiving the user requests and outputting the viz:
var socket = io('http://localhost:3000');
var stats;
var seller_key = 'sellers-'.concat(<%= seller %>);
socket.on(seller_key, function(msg){
stats = [];
console.log('Im in');
var seller = $.parseJSON(msg);
var items = seller['items'];
for(item in items) {
var item_data = items[item];
stats.push({'title': item_data['title'], 'today_visits': item_data['today_visits'], 'sold_today': item_data['sold_today'], 'conversion_rate': item_data['conversion_rate']});
}
setupData(stats);
});
The problem is that the socket_on() method never receives anything and I don't see where the problem is as everything seems to be working fine besides this.
I think that you might be confused as to what Pub/Sub in Redis actually is. It's not a way to listen to changes on hashes; you can have a Pub/Sub channel called sellers-1, and you can have a hash with the key sellers-1, but those are unrelated to each other.
As documented here:
Pub/Sub has no relation to the key space.
There is a thing called keyspace notifications that can be used to listen to changes in the key space (through Pub/Sub channels); however, this feature isn't enabled by default because it'll take up more resources.
Perhaps an easier method would be to publish a message after the HMSET, so any subscribers would know that the hash got changed (they would then retrieve the hash contents themselves, or the published message would contain the relevant data).
This brings us to the next possible issue: you only have one subscriber connection, redisSubscriber.
From what I understand from the Node.js Redis driver, calling .subscribe() on such a connection would remove any previous subscriptions in favor of the new one. So if you were previously subscribed to the sellers-1 channel and subscribe to sellers-2, you wouldn't be receiving messages from the sellers-1 channel anymore.
You can listen on multiple channels by either passing an array of channels, or by passing them as a arguments:
redisSubscriber.subscribe([ 'sellers-1', 'sellers-2', ... ])
// Or:
redisSubscriber.subscribe('sellers-1', 'sellers-2', ... )
You would obviously have to track each "active" seller subscription. Either that, or create a new connection for each subscription, which also isn't ideal.
It's probably a better idea to have a single Pub/Sub channel on which all changes would get published, instead of a separate channel for each seller.
Finally: if your seller id's aren't hard to guess (for instance, if it's based on an incremental integer value), it would be trivial for someone to write a client that would make it possible to listen in on any seller channel they'd like. It might not be a problem, but it is something to be aware of.

Skype Bot responding with empty body

I'm trying to get a Skype bot up and running based off of the echo example but I'm struggling to make a successful POST to my app. When I send a post to /v1/chat I get back a status of 201 (successful creation), and nothing in the body. My console.log does not print anything either, which leads me to believe that the botService.on('personalMessage', ...) function is not being run. Does anyone have any insight into how these POST requests should be formatted? I cannot seem to find anything in the documentation.
My code:
const fs = require('fs');
const restify = require('restify');
const skype = require('skype-sdk');
const botService = new skype.BotService({
messaging: {
botId: '28:<bot’s id="ID176db9ab-e313-4d76-a60c-bc2a280e9825">',
serverUrl : "https://apis.skype.com",
requestTimeout : 15000,
appId: process.env.APP_ID,
appSecret: process.env.APP_SECRET
}
});
botService.on('contactAdded', (bot, data) => {
console.log('contact added');
bot.reply('Hello ${data.fromDisplayName}!', true);
});
botService.on('personalMessage', (bot, data) => {
console.log('message incoming');
console.log(data);
bot.reply('Hey ${data.from}. Thank you for your message: "${data.content}".', true);
});
const server = restify.createServer();
server.post('/v1/chat', skype.messagingHandler(botService));
const port = process.env.PORT || 8080;
server.listen(port);
console.log('Listening for incoming requests on port ' + port);
Final Edit & Solution: I think the problem caused by Heroku somehow(it could be something with their free tier ,1 dyno). After some effort, I uploaded the program to Azure, and it is now working perfectly.
Potential Solution: You need to change the server address in the server.post command. If you run your program in "https:\www.yourwebsite.com/v1/chat" , you need to modify this;
server.post('/v1/chat', skype.messagingHandler(botService));
to this;
server.post('https:\\www.yourwebsite.com/v1/chat', skype.messagingHandler(botService));
Of course, don't forget to specify your app id, bot id, and app secret. If you don't have one, you need to generate a password in your Skype application page.
I have the exact problem with the OP. I followed the tutorial, and it doesn't specify how to modify our code to comply with our server. So, after running the program it only returns this;
{"code":"ResourceNotFound","message":"/ does not exist"}
In the Echo example in the Skype Bot Webpage; it says;
"We'll assume the bot's URL for messaging was set to https://echobot.azurewebsites.net/v1/chat during registration."
Make sure that Procfile and worker processes are setup.
My bot is working fine on heroku itself

Trying to use Socket.IO namespaces causes 404 polling error

When I use Socket.IO to connect like normal/default
var client = io.connect('http://localhost:466/');
It works/connects just fine. No errors in console.
However, when I want to try connecting to a namespace like so
var client = io('/adm').connect('http://localhost:466/');
I get the following errors
The admin namepsace is created on the server
//start server
var server = require('socket.io').listen(466);
//admin namespace
var adm = server.of('/adm');
adm.on('connection', function(client){
console.log('adm connection');
});
The issue was that I was trying
var client = io('/adm').connect('http://localhost:466/');
instead of
var client = io.connect('http://localhost:466/adm');
Which I find odd, because the documentation seemed to recommend the first method.
http://socket.io/docs/rooms-and-namespaces/#custom-namespaces

Resources