I'm doing a service to warn me of possible errors that can occur on my server , my doubt is , after I send a message as I finalize the execution or the way it is presenting the image below normal? For to complete the task I have to take a ctrl + c
code:
var util = require('util');
var TelegramBot = require('node-telegram-bot-api');
var token = '237907874:AAG8hK1lPWi1WRlqQT2';
var bot = new TelegramBot(token, {polling: true});
var millisecondsToWait = 5000;
robot = {
"alert": function teste(message) {
var toId = '-103822200';
var resp = util.format('alerta: %s', message);
bot.sendMessage(toId, resp);
}
}
robot.alert(process.argv[2]);
in cmd i execute this code
node.exe bot.js 'text send'
this is image
Looks like some error occurs but not captured:
var robot = { // Don't forget about var :)
"alert": function teste(message) {
var toId = '-103822200';
var resp = util.format('alerta: %s', message);
bot.sendMessage(toId, resp)
.catch(function(error){ // Catch possible error
console.error(error);
});
}
}
Related
I have a problem with my nodejs code and the connection to the official whatsapp business api.
The bot connects the webhook correctly, the messages arrive to the server correctly but the code I have implemented to make it respond is not being effective, I checked the code from top to bottom but I can't find the fault.
I leave you the codes so you have more context:
whatsappController.js:
const fs = require("fs");
const myConsole = new console.Console(fs.createWriteStream("./logs.txt"));
const whatsappService = require("../services/whatsappService")
const VerifyToken = (req, res) => {
try {
var accessToken = "456E7GR****************************";
var token = req.query["hub.verify_token"];
var challenge = req.query["hub.challenge"];
if(challenge != null && token != null && token == accessToken){
res.send(challenge);
}
else{
res.status(400).send();
}
} catch(e) {
res.status(400).send();
}
}
const ReceivedMessage = (req, res) => {
try {
var entry = (req.body["entry"])[0];
var changes = (entry["changes"])[0];
var value = changes["value"];
var messageObject = value["messages"];
if(typeof messageObject != "undefined"){
var messages = messageObject[0];
var text = GetTextUser(messages);
var number = messages["from"];
myConsole.log("Message: " + text + " from: " + number);
whatsappService.SendMessageWhatsApp("The user say: " + text, number);
myConsole.log(messages);
myConsole.log(messageObject);
}
res.send("EVENT_RECEIVED");
}catch(e) {
myConsole.log(e);
res.send("EVENT_RECEIVED");
}
}
function GetTextUser(messages){
var text = "";
var typeMessage = messages["type"];
if(typeMessage == "text"){
text = (messages["text"])["body"];
}
else if(typeMessage == "interactive"){
var interactiveObject = messages["interactive"];
var typeInteractive = interactiveObject["type"];
if(typeInteractive == "button_reply"){
text = (interactiveObject["button_reply"])["title"];
}
else if(typeInteractive == "list_reply"){
text = (interactiveObject["list_reply"])["title"];
}else{
myConsole.log("sin mensaje");
}
}else{
myConsole.log("sin mensaje");
}
return text;
}
module.exports = {
VerifyToken,
ReceivedMessage
}
The second file is whatsappService which I make the connection with the api using the token and I also send the format of the message I want to send when I receive a hello for example...
const https = require("https");
function SendMessageWhatsApp(textResponse, number){
const data = JSON.stringify({
"messaging_product": "whatsapp",
"recipient_type": "individual",
"to": number,
"type": "text",
"text": {
"preview_url": false,
"body": textResponse
}
});
const options = {
host:"graph.facebook.com",
path:"/v15.0/1119744*************/messages",
method:"POST",
body:data,
headers: {
"Content-Type":"application/json",
Authorization:"Bearer EAAWNbICfuWEBAK5ObPbD******************************************************"
}
};
const req = https.request(options, res => {
res.on("data", d=> {
process.stdout.write(d);
});
});
req.on("error", error => {
console.error(error);
});
req.write(data);
req.end();
}
module.exports = {
SendMessageWhatsApp
};
Then I declare the routes for the get (to check token) and post (to receive and reply to messages) methods:
const expres = require("express");
const router = expres.Router();
const whatsappController = require("../controllers/whatsappControllers");
router
.get("/", whatsappController.VerifyToken)
.post("/", whatsappController.ReceivedMessage)
module.exports = router;
Last but not least the index file for the code to run correctly:
const express = require("express");
const apiRoute = require("./routes/routes");
const app = express();
const PORT = process.env.PORT || 3000
app.use(express.json());
app.use("/whatsapp", apiRoute);
app.listen(PORT, () => (console.log("El puerto es: " + PORT)));
I should clarify that I did the tests with Postman and they were all successful, it responds and receives messages correctly, finally I did the tests by uploading the bot to the Azure service and it works without problem until it has to answer/replicate the user's message.
The bot is not responding to the user when he talks to it but everything arrives correctly to the server and it processes it with a 200 response. I attach the evidence that there is no problem in the reception.
Finally I must say that in the meta platform I have everything configured as specified by the same platform, I have already configured the api to answer the messages through the webhooks and everything is correct, I just can't get the bot to answer correctly.
The bot is hosted in the Azure service.
Solved: some numbers have a problema with the api of WAB in my country (Argentina) the phone numbers start in +54 9 11. The problem is the 9 in the phone number, and this have a conflict in the servers of meta, Solution quit number 9 to numbers of this country and the message will send to user.
How to send bot response based on user session in NodeJS.
I have created a sample NodeJS application using botframework and connecting to IBM watson to process the user query to get the appropriate response and sending back the response with 10secs delay.
I have generate the ngrok URL and configured it bot framework for web channel. When i test this in mutipl browsers simulataneously , i am getting the same response for all , not based on the user session and user request.
It's giving the latest request processed response to everyuser. I have copied the sample nodejs code below.
Can someone please look into my code and suggest me on how to send the response based on user session/conversationID?
NodeJS sample code :
'use strict';
var restify = require('restify');
var builder = require('botbuilder');
var Conversation = require('watson-developer-cloud/conversation/v1');
require('dotenv').config({silent: true});
var server = restify.createServer();
var contexts = { CandidateID : "89798" , Location : "USA" }
var workspace= 'XXXXXXXXXXXXXXXX';
let name,id,message,addr,watson;
var savedAddress;
server.listen(process.env.port || process.env.PORT || 3000, function () {
console.log('%s listening to %s', server.name, server.url);
});
// Create the service wrapper
var conversation = new Conversation({
username: 'XXXXXXXXXXXXXXXX',
password: 'XXXXXXXXXXXXXXXX',
url: 'https://gateway.watsonplatform.net/conversation/api',
version_date: 'XXXXXXXXXXXXXXXX'
});
// setup bot credentials
var connector = new builder.ChatConnector({
appId: 'XXXXXXXXXXXXXXXX',
appPassword: 'XXXXXXXXXXXXXXXX'
});
var bot = new builder.UniversalBot(connector,);
server.post('/api/messages', connector.listen());
// root dialog
bot.dialog('/', function (session, args) {
name = session.message.user.name;
id = session.message.user.id;
message = session.message.text;
savedAddress = session.message.address;
var payload = {
workspace_id: workspace,
context: contexts,
input: {
text: session.message.text
}
};
var conversationContext = {
workspaceId: workspace,
watsonContext: contexts
};
if (!conversationContext) {
conversationContext = {};
}
payload.context = conversationContext.watsonContext;
conversation.message(payload, function(err, response) {
if (err) {
console.log(err);
session.send(err);
} else {
console.log(JSON.stringify(response, null, 2));
conversationContext.watsonContext = response.context;
watson = response.output.text;
}
});
console.log(message);
setTimeout(() => {
startProactiveDialog(savedAddress);
}, 10000);
});
// handle the proactive initiated dialog
bot.dialog('/survey', function (session, args, next) {
if (session.message.text === "done") {
session.send("Great, back to the original conversation");
session.endDialog();
} else {
session.send(id + ' ' + watson);
}
});
// initiate a dialog proactively
function startProactiveDialog(address) {
bot.beginDialog(address, "*:/survey");
}
You need to make sure it passes back and forth all of the system context for that user's session. Our botkit middleware essentially does this for you.
https://github.com/watson-developer-cloud/botkit-middleware
It looks like that you are leveraging the sample at https://github.com/Microsoft/BotBuilder-Samples/tree/master/Node/core-proactiveMessages/startNewDialog Sending a dialog-based proactive message to specific user.
The sample is just for reference, it only saves the latest conversion at it only declare one variable savedAddress, each time the new user comes in, the new seession address will assign to savedAddress and cover the old value.
You can try to define an object to save user addresses for quick test:
var savedAddress = {};
bot.dialog('/', function (session, args) {
savedAddress[session.message.address.id] = session.message.address;
var message = 'Hey there, I\'m going to interrupt our conversation and start a survey in a few seconds.';
session.send(message);
message = 'You can also make me send a message by accessing: ';
message += 'http://localhost:' + server.address().port + '/api/CustomWebApi';
session.send(message);
setTimeout(() => {
startProactiveDialog(savedAddress[session.message.address.id]);
}, 5000);
});
For production stage, you can leverage Redis or some other cache storage to store this address list.
Hope it helps.
I am new to Microsoft Bot Framework. Earlier I was using Gupshup to build my bots. Gupshup had designed the workflow in a very nice manner. I had used api.ai NLP engine with Gupshup. I want to switch and try MS Bot Framework now with api.ai.
Below is my Gupshup's code:
function MessageHandler(context, event) {
sendMessageToApiAi({
message : event.message,
sessionId : new Date().getTime() +'api',
nlpToken : "74c04b2c16284c738a8dbcf6bb343f",
callback : function(res){
if(JSON.parse(res).result.parameters.Ent_1=="Hello"){
context.sendResponse("Hello");
}
}
},context);
};
function sendMessageToApiAi(options,botcontext) {
var message = options.message; // Mandatory
var sessionId = options.sessionId || ""; // optinal
var callback = options.callback;
if (!(callback && typeof callback == 'function')) {
return botcontext.sendResponse("ERROR : type of options.callback should be function and its Mandatory");
}
var nlpToken = options.nlpToken;
if (!nlpToken) {
if (!botcontext.simpledb.botleveldata.config || !botcontext.simpledb.botleveldata.config.nlpToken) {
return botcontext.sendResponse("ERROR : token not set. Please set Api.ai Token to options.nlpToken or context.simpledb.botleveldata.config.nlpToken");
} else {
nlpToken = botcontext.simpledb.botleveldata.config.nlpToken;
}
}
var query = '?v=20150910&query='+ encodeURIComponent(message) +'&sessionId='+context.simpledb.roomleveldata.session+'&timezone=Asia/Calcutta&lang=en '
var apiurl = "https://api.api.ai/api/query"+query;
var headers = { "Authorization": "Bearer " + nlpToken};
botcontext.simplehttp.makeGet(apiurl, headers, function(context, event) {
if (event.getresp) {
callback(event.getresp);
} else {
callback({})
}
});
}
I have started off with MS bot Framework and linked with api.ai. Below is my code:
var builder = require('botbuilder');
var restify = require('restify');
var apiairecognizer = require('api-ai-recognizer');
var request = require('request');
//=========================================================
// Bot Setup
//=========================================================
// 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
var connector = new builder.ChatConnector({
appId: "8c9f2d7b-dfa6-4116-ac45-po34eeb1d25c",
appPassword: "7CCO8vBGtdcTr9PoiUVy98tO"
});
server.post('/api/messages', connector.listen());
var bot = new builder.UniversalBot(connector);
var recognizer = new apiairecognizer("74c04b2c16284c738a8dbcf6bb343f");
var intents = new builder.IntentDialog({
recognizers: [recognizer]
});
bot.dialog('/',intents);
intents.matches('Flow_1',function(session, args){
var fulfillment = builder.EntityRecognizer.findEntity(args.entities, 'fulfillment');
if (fulfillment){
var speech = fulfillment.entity;
session.send(speech);
console.log("Inside fulfillment");
}else{
session.send('Sorry...not sure how to respond to that');
}
});
intents.matches('Intro',function(session, args){
var fulfillment = builder.EntityRecognizer.findEntity(args.entities, 'fulfillment');
if (fulfillment){
var speech = fulfillment.entity;
session.send(speech);
}else{
session.send('Sorry...not sure how to respond to that');
}
});
intents.matches('Default Fallback Intent',function(session, args){
var fulfillment = builder.EntityRecognizer.findEntity(args.entities, 'fulfillment');
if (fulfillment){
var speech = fulfillment.entity;
session.send(speech);
}else{
session.send('Sorry...not sure how to respond to that');
}
});
Now here is what I want to achieve:
JSON.parse(res).result.parameters.Ent_1 was a easy of parsing and getting the paramerters. How can I achieve something similar to that in Bot Framework? Do I have to construct a function sendMessageToApiAi() or is there a different way to achieve in MS Bot Framework?
Actually, Gupshup's template doesn't care about the intent which is sending the response. The template just gets the response from the API call and allows you to parse the response as desired.
Now in MSbot framework, if you want to get the value of Ent_1 then you can use the below sample code considering Flow_1 is the intent which will contain the entity Ent_1
intents.matches('Flow_1',function(session, args){
var fulfillment = builder.EntityRecognizer.findEntity(args.entities, 'Ent_1');
if (fulfillment){
var speech = fulfillment.entity;
session.send(speech);
console.log("Inside fulfillment");
}else{
session.send('Sorry...not sure how to respond to that');
}
});
You can also go through this blog which will help.
I have GRPC server running using openssl - static way and I am trying to connect to server using nodejs client
I do not see any error but I do not see its connecting to server either.
Please share if you have any sample.
Please refer code below:
var rootCertPath = path.join('.','.', 'server-root.PEM');
var privateCertPath = path.join('.','.', 'server-private.PEM');
var domainCertPath = path.join('.','.', 'server-domain.PEM');
var rootCert = fs.readFileSync(rootCertPath);
var privateCert = fs.readFileSync(privateCertPath);
var domainCert = fs.readFileSync(domainCertPath);
var buf1 = new Buffer('rootCert');
var buf2 = new Buffer('privateCert');
var buf3 = new Buffer('domainCert');
var chat_proto = grpc.load("Chat.proto").com.company.grpc;
var client = new chat_proto.ChatService('https://servervip:443',grpc.credentials.createSsl(buf1,buf2,buf3));
Chat.proto
syntax = "proto3";
// Service definition.
service ChatService {
// Sends a chat
rpc chat(stream ChatMessage) returns (stream ChatMessageFromServer) {}
}
// The request message containing the user's name.
message ChatMessage {
string name = 1;
string message = 2;
}
// The response message containing the greetings
message ChatMessageFromServer {
string name = 1;
string message = 2;
}
//Code to make a request
var username = process.argv[2];
var stdin = process.openStdin();
function main() {
console.log("starting");
console.log(client); // prints { '$channel': Channel {} }
var chat=client.chat();
chat.on('data', function(msg) {
console.log(msg.name + ': ' + msg.message);
console.log("after message");
});
stdin.addListener('data',function(input) {
chat.write({ name: username, message: input.toString().trim()
});
});
}
main();
so good new is - below thing worked for me
var rootCertPath = path.join('.','.', 'roots.PEM');
var rootCert = fs.readFileSync(rootCertPath);
var chat_proto = grpc.load("Chat.proto").com.americanexpress.grpc.chat;
var client = new chat_proto.ChatService('servervip:443',grpc.credentials.createSsl(rootCert));
Looks like an issue with the cert - I used the default roots.PEM in grpc client and it worked for me. will look internally to have correct root of my servervip CA certificate chain.
Thanks all for your support
I have a situation where I have about 50 listeners on 50 'direct' exchanges. The client and the server are in javascript (node.js) . It is using the node-amqp from postwait .
Things work fairly well at low frequency of messages. Once the message frequency increases ~ 5000 messages per minute then there is a buffer copy error being shown in amqp.js
From what I could trace the max_frame_size in amqp.js is fixed to 131072 .
I just tried to double the value from 128k to 256k . But doing so causes the node.js to silently fail without starting up. There is no error message. I am assuming that I also have to change the corresponding value (max_frame) in the rabbit.config file.
Do I have to do anything else to increase this value . Any other suggestions will also be appreciated.
I have attached the minimal code to simulate the error . Run the commands below in 2 windows to simulate the error
node engine-so-client.js -c 200 -p 12000
node server-so.js
File server-so.js
var util= require('util')
var amqp = require('amqp');
var express = require ('express')
function httpServer(exchange) {
console.log("In httpServer start %s",exchange.name);
var port;
app = express.createServer();
app.get('/message/:routingKey/:message',function(req,res) {
exchange.publish(req.params.routingKey,{'d' : req.params.message});
res.send('Published the message '+req.params.message+'\n');
});
app.get('/register/:socket/:routingKey',function(req,res) {
var queue1 = conn.queue('',
{autoDelete: false, durable: true, exclusive: true},
function() {
console.log("Queue1 Callback");
queue1.subscribe(
function(message) {
console.log("subscribe Callback for "+req.params.routingKey + " " + message.d);
});
console.log("Queue Callback Binding with "+req.params.routingKey);
queue1.bind(exchange.name,req.params.routingKey);
});
res.send('Started the socket at '+req.params.socket+'\n');
});
app.listen(3000);
app.use(express.logger());
console.log('Started server on port %s', app.address().port);
}
function setup() {
console.log("Setup");
var exchange = conn.exchange('cf2-demo',
{'type': 'direct', durable: false}, function() {
var queue = conn.queue('',
{autoDelete: false, durable: true, exclusive: true},
function() {
console.log("Queue Callback Binding with test key");
queue.bind(exchange.name,'testKey');
});
queue.on('queueBindOk',
function() { httpServer(exchange); });
});
console.log("Completed setup %s", exchange.name);
}
var conn = amqp.createConnection({host:'localhost',
login:'guest',
password:'guest'},
{defaultExchangeName: "cf2-demo"});
conn.on('ready',setup);
File engine-so-client.js
var program = require('commander.js');
var util = require('util');
var http = require('http');
program
.version('0.0.1')
.option('-h, --host <host>', 'Host running server', String,'localhost')
.option('-p, --port <port>', 'Port to open to connect messages on',Number,12000)
.option('-k, --key <key>,', 'Routing Key to be used',String,'key1')
.option('-c, --count <count>','Iteration count',Number,50)
.option('-m, --mesg <mesg>','Message prefix',String,'hello')
.option('-t, --timeout', 'Timeout in ms between message posts')
.parse(process.argv);
function setup(host,port,key,mesg) {
var client = http.createClient(3000, host);
var request = client.request('GET','/register/'+port+"/"+key);
request.end();
request.on('response', function(response) {
response.on('data', function(chunk) {
postMessage(host,port,key,mesg,1);
});
});
}
function postMessage(host,port,key,mesg,count) {
var timeNow = new Date().getTime();
var mesgNow = mesg+"-"+count+"-"+port;
console.log("Type: Sent Mesg, Message: %s, Time: %s",mesgNow,timeNow);
var client1 = http.createClient(3000, host);
var request1 = client1.request('GET','/message/'+key+"/"+mesgNow);
request1.end();
count++;
if (count <100) {
setTimeout( function() { postMessage(host,port,key,mesg,count); }, 1000 );
}
}
var port = program.port;
var host = program.host;
var key = program.key;
var mesg = program.mesg;
var count = program.count;
var keys = ['key1','key2','key3','key4','key5'];
var messages = ['hello','world','good','morning','bye'];
var start=port;
for (i=0; i<count; i++) {
var index = i%keys.length;
var socket = start + i;
setup(host,socket,keys[index],messages[index]);
}
Error attached
buffer.js:494
throw new Error('sourceEnd out of bounds');
^
Error: sourceEnd out of bounds
at Buffer.copy (buffer.js:494:11)
at frame (/home/hvram/programs/node_modules/node-amqp/amqp.js:170:10)
at header (/home/hvram/programs/node_modules/node-amqp/amqp.js:160:14)
at frameEnd (/home/hvram/programs/node_modules/node-amqp/amqp.js:205:16)
at frame (/home/hvram/programs/node_modules/node-amqp/amqp.js:172:14)
at header (/home/hvram/programs/node_modules/node-amqp/amqp.js:160:14)
at frameEnd (/home/hvram/programs/node_modules/node-amqp/amqp.js:205:16)
at frame (/home/hvram/programs/node_modules/node-amqp/amqp.js:172:14)
at header (/home/hvram/programs/node_modules/node-amqp/amqp.js:160:14)
at frameEnd (/home/hvram/programs/node_modules/node-amqp/amqp.js:205:16)