get_started button sends messaging_postbacks callbacks thrice - node.js

Hi I am using nodejs and developing a bot on facebook messenger platform. I have my webhook subscribed only to messages and messaging_postbacks events. However, when I test the bot, it seems to send callback three times. This is my webhook code
server.post('/', (req, res, next) => {
let postback = req.body.entry[0].messaging[0].postback;
if (postback.payload === 'Greet User'){
console.log(postback);
}
}
When I test my bot, the postback object gets printed thrice as below.
{ payload: 'Greet User', title: 'Get Started' }
{ payload: 'Greet User', title: 'Get Started' }
{ payload: 'Greet User', title: 'Get Started' }
Any help how to avoid it? I read in some of the posts here that I should deselect message_reads and message_deliveries subscriptions. But I do not have those selected anyways. Not sure what else I am missing? Please help me.

I have found the problem after some more searching on the net and debugging it myself. In case, if others reading this might be interested to know, the issue was I was not sending back 200 status back to facebook. I found the hint regarding the need to do that in this stack overflow post.
Facebook webhook making multiple calls for the same message?
After sending the 200 response, I m not getting this issue. So relieved :)

Related

slack how to know if bot recently posted

I am using botkit, i have a bot that responses to a certain word.
But i don't want the bot to response if it recently did so.
Currently i am using channels.history method to retrieve 4 recent messages then find the bot id, if its there it won't reply. This is not pretty, i've been searching for useful methods to use but i can't find any. I just want to find out if the bot recently posted or not and do actions base on it.
const targetBotID = 'GKALXJCM6'
bot.api.channels.history({
channel: message.channel,
latest: message.ts,
count: 4,
inclusive: 1,
}, function(err, response) {
if(err) { bot.reply(message, 'Something is wrong with me, check log if there is??'); }
if(response){
const recentPostFound = response.messages.filter(function (member) {
return member.user === targetBotID;
});
if(recentPostFound){
return bot.reply();
}
return bot.reply(answer) // Answer if no matching id found
}
});
I can see two solutions to your issue:
Record previous actions of your bot in some kind of app context (e.g. database). Then you can verify each time if your bot already answered.
Consider using Events API instead of loading the chat history each time. Then your bot gets exactly one event request for each new message in a channel and you can be sure that your bot will only react once.

Botbuilder - How to ignore user response without exiting prompt dialog

I have a multipatform bot (node.js through Azure Botframework) that uses a series of prompts to play a game with the user.
In group mode, such as on Kik or Slack, it waits for responses addressed to the bot.
However, I haven't found a way to simply ignore a message that doesn't address the bot. The solution I found ages ago was to simply reply with a new blank prompt:
builder.Prompts.text(session, "");
And this worked fine. However recently Slack must have changed something, because now this causes an error and the bot restarts.
How do I make the bot ignore certain responses without ending the dialog?
If suggesting a duplicate, please ensure it actually addresses this issue. Many other questions allow for the dialog to end, however this would interrupt the game.
You can setup middleware, as mentioned by Gary, that intercepts incoming messages and only processes it if the bot is #mentioned:
bot.use({
botbuilder: function (session, next) {
var message = session.message;
var botMri = message.address.bot.id.toLowerCase();
var botAtMentions = message.entities && message.entities.filter(
(entity) => (entity.type === "mention") && (entity.mentioned.id.toLowerCase() === botMri));
if (botAtMentions && botAtMentions.length) {
next();
}
},
send: function (event, next) {
next();
}
})

Chatbot messages do not show up in Facebook Messenger chat heads

I am developing a chatbot for Facebook Messenger using Microsoft Bot Framework. The bot sends the user proactive messages (reminders). Unfortunately, for some reason the messages never show up in a chat head (the Android widget for conversations), nor pop up a chat head if it wasn't present on the screen before. It does happen for other chatbots (Jarvis, for example).
This is the code that sends the reminders:
Reminder.find({ next_reminder: { $lte: new Date() } }, (err, res) => {
if (err !== null) {
return console.error(err);
}
res.forEach(reminder => {
// Build a notification message and address it to user who created the reminder
const msg = new builder.Message().text('...');
bot.beginDialog(reminder.user_address, '*:/sendReminder', {message: msg, nudnik: nudnik});
});
});
};
};
I have also tried bot.send(msg, () => ....) and session.beginDialog('sendReminder', msg). However, there is still no indication from Messenger when the message is received. What could go wrong here?
OK, I figured it out! Apparently, the default notification setting for a Facebook message is not to show a notification. To change it, in NodeJS you should add channel-specific data to the message with the following code:
msg = msg.sourceEvent({
facebook:
{notification_type: 'REGULAR'}
});
You can discover more in official documentation by Microsoft (here and here) and also in this Github discussion.

How can i make my bot ask a statement, wait for the response of that statement

Is there any way i can ask my bot a question and make it wait for a response to that particular question so i could do some more things on that particular message?
Yes, there are examples in the botkit readme. copy pasting :
controller.hears(['question me'], 'message_received',function(bot,message) {
// start a conversation to handle this response.
bot.startConversation(message,function(err,convo) {
convo.ask('How are you?',function(response,convo) {
convo.say('Cool, you said: ' + response.text);
convo.next();
});
})
})

Twilio: Hangup a call in an existing conference, ERROR 20404

Following situation:
Someone called my Twilio Number
Twilio requested my url
Caller gets into a conference (don't starts until a second person join)
TwiML makes call to a Mobile
The Moblie dont accept the call
=> no second Person enters the conference so it wont stop and the caller is stuck there.
My solution is to end the whole call if this happens, I already know where to place the endCall function so this is not my problem. The function looks like this (You'll find it in the twilio API too):
client.calls(accountSid).update({
status: "completed"
}, function(err, call) {
if(err){
console.log(err);
}
});
My programm logic is fine, I see that this function is called at the right place but I receive this Error:
{ status: 404,
message: 'The requested resource /2010-04-01/Accounts/AC/Calls/AC.json was not found',
code: 20404,
moreInfo: 'https://www.twilio.com/docs/errors/20404' }
I already red whats at the moreInfo url but I disqualify
the solutions there. Maybe you have an idea whats the problem with this.
Twilio developer evangelist here.
You are almost all the way there. Your problem is that you are using your accountSid when trying to update the call's status.
You need to get hold of the callSid of the original call. You will find the callSid in the parameters that you receive in the incoming webhook when the person calls your Twilio number.
app.post('/calls', function(req, res, next) {
var callSid = req.body.CallSid;
// store callSid somewhere for use later
// return TwiML to set up conference and dial your mobile number
});
You'll need to save that callSid and then use it at this point later when you want to hangup the call.
client.calls(callSid).update({
status: "completed"
}, function(err, call) {
if(err){
console.log(err);
}
});
Let me know if this helps at all.

Resources