Start conversation with Wit.ai chat bot in node.js - javascript

I have created a story on wit.ai using the quickstart guide.
Now I want to make a conversation with my chat bot using node-wit in node.js.
I guess I should use https://github.com/wit-ai/node-wit#runactions to run the messages, but I'm not sure how to start a conversation that never ends. I need to send a message and then get the response from the chat bot until I break the conversation.
I have looked through the wit.ai examples, but I cannot find any example of how to start a simple conversation in node.js.
I use socket.io to transmit the messages between client and server, and I have tried to solve my problem with
let sessions = {};
const sessionId = new Date().toISOString();
sessions[sessionId] = { context: {} };
io.on('connection', function (socket) {
socket.on('new message', function (message) {
client.runActions(
sessionId,
message,
sessions[sessionId].context
).then((context) => {
console.log(context);
sessions[sessionId].context = context;
}).catch((err) => {
console.error('Error: ', err.stack || err);
});
});
});
and it seems to almost work. I can chat with my bot, but it messes up the stories by sometimes answering multiple times from different stories. I guess I should probably end the stories somehow?

You should try with this link
https://github.com/wit-ai/node-wit/blob/master/examples/quickstart.js
Just clone/download the whole node-wit module from git or npm-install.
Then just run the command node quickstart.js "wit-token".
wit-token == wit-app-token
it will work .

Have you checked this Facebook Messenger integration example. The quickstart.js includes an interactive mode this is why it may be confusing.

Look at the messenger.js example on how to use runActions and send messages back to Messenger.
I was successful in doing this, although I'm still working on stories.

Related

Unable to get Notify data using Noble

Can't receive any notifications sent from the Server peripheral.
I am using ESP32 as Server with the "BLE_notify" code that you can find in the Arduino app (File> Examples ESP32 BLE Arduino > BLE_notify).
With this code the ESP32 starts notifying new messages every second once a Client connects.
The client used is a Raspberry Pi with Noble node library installed on it (https://github.com/abandonware/noble). this is the code I am using.
noble.on('discover', async (peripheral) => {
console.log('found peripheral:', peripheral.advertisement);
await noble.stopScanningAsync();
await peripheral.connectAsync();
console.log("Connected")
try {
const services = await peripheral.discoverServicesAsync([SERVICE_UUID]);
const characteristics = await services[0].discoverCharacteristicsAsync([CHARACTERISTIC_UUID])
const ch = characteristics[0]
ch.on('read', function(data, isNotification) {
console.log(isNotification)
console.log('Temperature Value: ', data.readUInt8(0));
})
ch.on('data', function(data, isNotification) {
console.log(isNotification)
console.log('Temperature Value: ', data.readUInt8(0));
})
ch.notify(true, function(error) {
console.log(error)
console.log('temperature notification on');
})
} catch (e) {
// handle error
console.log("ERROR: ",e)
}
});
SERVICE_UUID and CHARACTERISTIC_UUID are obviously the UUIDs coded in the ESP32.
This code sort of works, it can find Services and Characteristics and it can successfully connect to the peripheral, but it cannot receive messages notifications.
I also tried an Android app that works as client, from that app I can get all the messages notified by the peripheral once connected to it. So there is something missing in the noBLE client side.
I think there is something wrong in the on.read/on.data/notify(true) callback methods. Maybe these are not the methods to receive notifications from Server?
I also tried the subscribe methods but still not working.
The official documentation is not clear. Anyone could get it up and running? Please help.
on.read/on.data/ are event listeners. There is nothing wrong with them. They are invoked when there is a certain event.
For example adding characteristic.read([callback(error, data)]); would have invoked the on.read.
From the source:
Emitted when:
Characteristic read has completed, result of characteristic.read(...)
Characteristic value has been updated by peripheral via notification or indication, after having been enabled with
characteristic.notify(true[, callback(error)])
I resolve using the following two envs NOBLE_MULTI_ROLE=1 and NOBLE_REPORT_ALL_HCI_EVENTS=1 (see the documentation https://github.com/abandonware/noble)

Why my bot showing info only in terminal?

I want to display player count on my Discord server like that:
Desired output
If I use the !players command
const Gamedig = require('gamedig');
Gamedig.query({
type: 'samp',
host: '91.121.87.14',
port: 9180
}).then((state) => {
console.log(state);
}).catch((error) => {
console.log("Server is offline");
});
I run my Discord bot with this code and it's showing me the info but only in the terminal I want like that:
Output example
I just want my bot to display player count like above in the pic
You need to tell your code to post a message in Discord.Try Discord Webhooks.
You use the lib "gamedig" which provides the following function:
node-GameDig is a game server query library, capable of querying for the status of almost any game or voice server.
(https://github.com/sonicsnes/node-gamedig)
Currently, the data read from "gamedig" is only output via the console.
In order to display the data in Discord like on your first screenshot, you have to talk to the Discord API (https://discord.com/developers/docs/intro)
The question is: "Why my bot showing info only in terminal?"
The answer is: Because you asked it only to console.log
I don't know your lib, but it seems it only returns data from the server.
Use discord.js to make a discord bot https://discord.js.org/#/
Hope it helped

Microsoft Bot Framework send message without having an user talk to the bot

I need to make a bot to send a message each ten minutes using Javascript. I'm using Microsoft Bot Framework, this is the entry code:
const restify = require('restify');
const botbuilder = require('botbuilder');
var adapter = new botbuilder.BotFrameworkAdapter({
appId: process.env.MicrosoftAppId,
appPassword: process.env.MicrosoftAppPassword
});
let server = restify.createServer();
server.listen(process.env.port || process.env.PORT || 3978, function () {
console.log(`\n${server.name} listening to ${server.url}`);
console.log(`\nGet Bot Framework Emulator: https://aka.ms/botframework-emulator`);
});
server.post('/api/messages', (req, res) => {
adapter.processActivity(req, res, async (turnContext) => {
if (turnContext.activity.type === 'message') {
const text = turnContext.activity.text;
await turnContext.sendActivity(`You just said: ${ text }`);
}
});
});
Basically that responds with "You just said: x" to whatever the person talking to the bot said.
What I need is the bot to be in group in Skype and send a message each ten minutes.
However, in my example, the server awaits for a POST to /api/messages, then it uses the adapter to process that request and fires the "sendActivity" method from the turnContext, which comes from the processActivity method.
How can I just send a message at a fixed interval, and ignore all messages/mentions.
What you want to do is called proactive messaging. You can have a look at this document and the sample it references to better understand how to do this.
If you want your proactive messages to be triggered by a timer then you can run the timer on a thread in your bot, though it's generally recommended to have the timer running externally.
To disable messaging for your bot, simply choose that option in your channel configuration. I'm not sure how you'll retrieve the conversation ID if you disable messaging, though.
If you still want your bot to receive messages but just don't want to reply to them, simply edit the part of your bot code that responds to the condition turnContext.activity.type === 'message'.
Please keep in mind that Skype bot features may become increasingly limited. You should see an official message in your Skype channel configuration that says:
As of October 31, 2019 the Skype channel will no longer be accepting new Bot registrations. Current Skype bots will continue to run uninterrupted.

RabbitMQ amqp.node integration with nodejs express

The official RabbitMQ Javascript tutorials show usage of the amqp.node client library
amqp.connect('amqp://localhost', function(err, conn) {
conn.createChannel(function(err, ch) {
var q = 'hello';
ch.assertQueue(q, {durable: false});
// Note: on Node 6 Buffer.from(msg) should be used
ch.sendToQueue(q, new Buffer('Hello World!'));
console.log(" [x] Sent 'Hello World!'");
});
});
However, I find it's hard to reuse this code elsewhere. In particular, I don't know how to exports the channel object since it's in a callback. For example in my NodeJs/Express App:
app.post('/posts', (req, res) => {
-- Create a new Post
-- Publish a message saying that a new Post has been created
-- Another 'newsfeed' server consume that message and update the newsfeed table
// How do I reuse the channel 'ch' object from amqp.node here
});
Do you guys have any guidance on this one? Suggestion of other libraries is welcomed (Since I'm starting out, ease of use is what I considered the most important)
amqp.node is a low-level API set that does minimal translation from AMQP to Node.js. It's basically a driver that should be used from a more friendly API.
If you want a DIY solution, create an API that you can export from your module and manage the connection, channel and other objects from within that API file.
But I don't recommend doing it yourself. It's not easy to get things right.
I would suggest using a library like Rabbot (https://github.com/arobson/rabbot/) to handle this for you.
I've been using Rabbot for quite some time now, and I really like the way it works. It pushes the details of AMQP off to the side and lets me focus on the business value of my applications and the messaging patterns that I need, to build featurs.
As explained in the comments, you could use the module.exports to expose the newly created channel. Of course this will be overridden each time you create a new channel, unless you want to keep an array of channels or some other data structure.
Assuming this is in a script called channelCreator.js:
amqp.connect('amqp://localhost', function(err, conn) {
conn.createChannel(function(err, ch) {
var q = 'hello';
ch.assertQueue(q, {durable: false});
//this is where you can export the channel object
module.exports.channel = ch;
//moved the sending-code to some 'external script'
});
});
In the script where you may want to use the "exported" channel:
var channelCreator = require("<path>/channelCreator.js");
//this is where you can access the channel object:
if(channelCreator.channel){
channelCreator.channel.sendToQueue('QueueName', new Buffer('This is Some Message.'));
console.log(" [x] Sent 'Message'");
}
Hope this helps.

Node.js and zmq

I have a strange issue with a basic pubsub application with node and zmq:
a client is publishing strings to a broker, the problem is that the broker only receives the first line. At network level I've noticed that only the first message is sent then the next calls to .send() function have no effect (no packets are sent) so I suppose the problem is in the client/publisher.
I used the example code provided in the official guide which works perfectly, the only difference in my code is that I use prototype to have a reusable structure.
(I didn't paste subscriber's code because is not relevant and took some other not relevant stuff out)
relevant part of the client/publisher:
Publisher = function(zmq, pport) {
this.logread = spawn('tail', ['-n0', '-f', '/var/log/auth.log']);
this.publisher = zmq.socket('req');
this.pport = pport;
};
Publisher.prototype.start = function() {
var self = this;
this.publisher.connect('tcp://127.0.0.1:' + this.pport);
this.logread.stdout.on('data', function(data){
self.publisher.send(data.toString());
console.log(data.toString());
});
};
relevant part of the broker:
Broker = function(zmq, bpport, bsport) {
this.server = zmq.socket('rep');
this.bpport = bpport;
this.bsport = bsport;
};
Broker.prototype.start = function() {
this.server.on('message', function(request) {
console.log(request.toString());
});
this.server.bind('tcp://127.0.0.1:' + this.bsport, function(err) {
if (err)
console.log(err);
});
};
You are talking about publish subscribe pattern, but in your code, you create a req socket, and in the broker a rep socket, which is for the request-reply pattern. The request-reply pattern is strictly need to send first, than receive, see the api docs docs, or read more from the guide
I suppose you should use pub socket on the client side, and a sub socket on the other side, but don't know what do you want to achieve, maybe a different pattern would fit your needs better.
so I'll answer my question:
the server must send a reply to the client, until then the client will not send more messages
server.send('OK');
I also suppose there is a different way to achieve this

Categories