Can't we use anything other than displayText from webhook response - webhooks

I am new to api.ai and I was doing the webhook implementation. I've noticed that only the "speech" or "displayText" from webhook response is shown to the user. Is there any technique to use any other params from the response?
I would be glad, if anyone tell me how could I format the response text like making it bold, change font etc.
Thank you!

Note that if the client you are sending the response to (such as Facebook Messenger) does not support special formats such as bold, this is an exercise in futility.
That said, there are many richer types of responses you can send than just plain text, and if you want to do this programmatically rather than build rich responses in API.ai, I'd suggest injecting your custom server side solution between the client and API.ai rather than have it at the end of the process.
In other words:
Client interface <-> Custom solution <-> API.ai
rather than
Client <-> API.ai <-> Custom fulfillment
This gives you more customization and fulfillment options, including building entirely custom response/prompt logic without even hitting the API.ai endpoint, or further editing API returns after they are processed, for example appending a database query result to the text of an API.ai fulfillment.
Assuming you have a setup like this, in node.js a solution for sending more advanced payloads than text to Facebook Messenger would look like this:
//Send gif or image reply
function sendGifMessage(recipientId) {
var messageData = {
recipient: {
id: recipientId
},
message: {
attachment: {
type: "image",
payload: {
url: config.SERVER_URL + "FILE LOCATION"
}
}
}
};
callSendAPI(messageData);
}
// Send custom payload buttons
function sendButtonMessage(recipientId, text, buttons) {
var messageData = {
recipient: {
id: recipientId
},
message: {
attachment: {
type: "template",
payload: {
template_type: "button",
text: text,
buttons: buttons
}
}
}
};
callSendAPI(messageData);
}
// Send quickReply buttons
function sendQuickReply(recipientId, text, replies, metadata) {
var messageData = {
recipient: {
id: recipientId
},
message: {
text: text,
metadata: isDefined(metadata)?metadata:'',
quick_replies: replies
}
};
callSendAPI(messageData);
}
function callSendAPI(messageData) {
request({
uri: 'https://graph.facebook.com/v2.6/me/messages',
qs: {
access_token: config.FB_PAGE_TOKEN
},
method: 'POST',
json: messageData
}, function (error, response, body) {
if (!error && response.statusCode == 200) {
var recipientId = body.recipient_id;
var messageId = body.message_id;
if (messageId) {
console.log("Successfully sent message with id %s to recipient %s",
messageId, recipientId);
} else {
console.log("Successfully called Send API for recipient %s",
recipientId);
}
} else {
console.error("Failed calling Send API", response.statusCode, response.statusMessage, body.error);
}
});
}
Hope that helps

Related

How to send FCM push notification to multiple devices using google apis?

I want to send push notification to multiple devices at once. Can i pass array of tokens?
Is it possible to do using google api? Please help me with this.
request(
{
method: 'POST',
uri:
'https://fcm.googleapis.com/v1/projects/projectId/messages:send',
headers: {
'content-type': 'application/json',
Authorization: `Bearer ${token}`,
'apns-priority': 'high',
content_available: true
},
body: {
message: {
token: token,
notification: {
body: 'This is an FCM notification message!',
title: 'FCM Title'
},
android: {
notification: {
sound: 'default'
}
}
}
},
json: true
},
async function(error, response, body) {
if (error) {
console.log(error);
}
console.log(body);
}
);
If you want to make the POST requests by yourself, you can prefer to:
1) Use the legacy HTTP server protocol. With that you will be able to use the "registration_ids" field which expects an array of token strings in POST body. Docs here.
2) Stick to HTTP v1 API that you're using right now, but since "token" field is expecting only string, you can first subscribe your users to a specific topic and use that topic in "topic" field in POST body.
Additionally, you may prefer to use Admin SDK to send batch notifications. You can check for further here.

FCM delivers duplicated copies of Push Notifications

I am using fcm node modules to send push notifications. Tried to send to a group(group with one device token). And all it delivers duplicated copies(4 copies everytime) of the same push for a single alert. It was supposed to be delivered only one. I have used fcm-node (version: 1.2.1), fcm-push (version: 1.1.3) etc.
The nodejs code is as shown below:
Alerts.pushTry = function (cb) {
var serverKey = "abcd"; //put your server key here
var deviceToken = 'group_key'; // required
var FCM = require('fcm-node');
var message = { //this may vary according to the message type (single recipient, multicast, topic, et cetera)
to: deviceToken,
notification: {
title: 'Group 555 test'+ ((new Date()).getTime()),
body: 'Body of your push notification'
},
data: {
my_key: 'my value',
my_another_key: 'my another value'
}
};
fcm.send(message, function(err, response) {
console.log("sent");
if (err) {
console.log(err);
console.log("Something has gone wrong!");
cb(err);
} else {
console.log("Successfully sent with response: ", response);
cb(null, response);
}
});
};
Can anyone help me?
There are some open issues exists for the above mentioned node modules.. I have used the request module and connected the fcm push notification url directly without depending on these types of npm modules with open issues.
var request = require('request');
request({
url: 'fcm.googleapis.com/fcm/send',
method: "POST",
headers: { "content-type" : "application/json",
"Authorization": key=${constants.FCM_SERVER_KEY},
"project_id": constants.FCM_SENDER_ID, },
json: message
}, function(error, response, body) {
//You code
});

How to use facebook messenger send image API in Node js?

I'm building a facebook bot in nodejs with facebook messenger API. I'm trying to send a image from the bot by directly uploading the image file from the heroku server itself (not through URL) and it does not work.
Here is a error log from the console.
Failed calling Send API 400 Bad Request { message: '(#100) Incorrect
number of files uploaded. Must upload exactly one file.',type:
'OAuthException', code: 100,error_subcode: 2018005,fbtrace_id:
'E32ogm/ofxd' }
The official facebook document only contains an example in curl format and I'dont know how to replicate this curl into node format.
I've tested with curl and it worked like a charm.
curl \ -F 'recipient={"id":"recipientId"}' \ -F 'message={"attachment":{"type":"image", "payload":{}}}' \ -F 'filedata=#resource/pdf_img/sample.jpg;type=image/jpeg' \ "https://graph.facebook.com/v2.6/me/messages?access_token=PAGE_ACCESS_TOKEN"
This is my node implementation that seems to be problematic,
//file_loc = __dirname+"/resource/pdf_img/sample.jpg"
function sendImageMessage(recipientId, file_loc){
let fs = require('fs');
var readStream = fs.createReadStream(file_loc);
var messageData = {
recipient : {
id : recipientId
},
message : {
attachment : {
type : "image",
payload :{}
}
},
filedata:readStream
}
callSendAPI(messageData);
}
function callSendAPI(messageData) {
request({
uri: "https://graph.facebook.com/v2.6/me/messages",
qs: {access_token: process.env.PAGE_ACCESS_TOKEN},
method: "POST",
json: messageData
}, function(error, response, body) {
if (!error && response.statusCode == 200) {
var recipientId = body.recipient_id;
var messageId = body.message_id;
if (messageId) {
console.log("Successfully sent message with id %s to recipient %s",
messageId, recipientId);
} else {
console.log("Successfully called Send API for recipient %s",
recipientId);
}
} else {
console.error("Failed calling Send API", response.statusCode, response.statusMessage, body.error);
}
});
}
Please any help with fixing my node implementation or translating that curl in to node would be appreciated.
You can use forms /form-data/ in the request module (which has integrated module 'form-data').
But all requests needs to be stringified.
So, based on your example, the following should do the job >>
function sendImageMessage(recipientId, file_loc){
let fs = require('fs');
var readStream = fs.createReadStream(file_loc);
var messageData = {
recipient : {
id : recipientId
},
message : {
attachment : {
type : "image",
payload :{}
}
},
filedata:readStream
}
callSendAPI(messageData);
}
function callSendAPI(messageData) {
var endpoint = "https://graph.facebook.com/v2.6/me/messages?access_token=" + process.env.PAGE_ACCESS_TOKEN;
var r = request.post(endpoint, function(err, httpResponse, body) {
if (err) {return console.error("upload failed >> \n", err)};
console.log("upload successfull >> \n", body); //facebook always return 'ok' message, so you need to read error in 'body.error' if any
});
var form = r.form();
form.append('recipient', JSON.stringify(messageData.recipient));
form.append('message', JSON.stringify(messageData.message));
form.append('filedata', messageData.filedata); //no need to stringify!
}
Details here https://github.com/request/request#forms
I think sending variable messagedata as formdata would solve the problem.
var FormData = require('form-data');
var fs = require('fs');
var https = require('https');
function sendImageMessage(recipientId, file_loc){
var readStream = fs.createReadStream(file_loc);
var messageData = new FormData();
messageData.append('recipient', '{id:' +recipientId+ '}');
messageData.append('message', '{attachment :{type:"image", payload:{}}}');
messageData.append('filedata', readStream);
callSendAPI(messageData);
}
Secondly you need to change request a bit since now you are using formdata. I have done it using module https and so have changed the callSendAPI() code accordingly. You can find out how to send the formdata using request module.
function callSendAPI(messageData) {
var options = {
method: 'post',
host: 'graph.facebook.com',
path: '/v2.6/me/messages?access_token=' + pagetoken,
headers: messageData.getHeaders()
};
var request = https.request(options);
messageData.pipe(request);
request.on('error', function(error) {
console.log("Unable to send message to recipient %s", recipientId);
return;
});
request.on('response', function(res) {
if (res.statusMessage == "OK") {
console.log("Successfully sent message to recipient %s", recipientId);
} else {
console.log("Unable to send message to recipient %s", recipientId);
}
return;
});
}

Wit.ai How to add dynamic Quick Replies

Here is the sentence from the Wit.ai doc : https://wit.ai/docs/recipes#categorize-the-user-intent
How to add dynamic Quick Replies
If you want to programmically create Quick Replies, you will need to
use a Bot Executes to trigger a function on your side that will create
these Quick Replies.
Ok, I can do that easily !
You can then store them in your context. In the
send function on your side, if you have them in the context you will
send them with the bot’s answer.
Can someone translate this last sentence for me because I don't understand what I shroud do. I want to add dynamic Quick Replies in my Node.js bot With Wit.ai
Thank you
I'm doing something like this for my bots using Wit.ai for Facebook Messenger.
In my action I store my dynamic quick replies in context:
myAction({ context, text, entities }) {
context.quick_replies = [
{
title: 'Option A',
content_type: 'text',
payload: 'empty'
},
{
title: 'Option B',
content_type: 'text',
payload: 'empty'
},
]
}
And then in send() I attach any quick replies to my text message:
send(req, res) {
await textMessage(messenger_id, res.text, req.context.quick_replies)
}
Where textMessage() looks something like this:
export async function textMessage(recipientId, text, quick_replies = null) {
const messageData = {
recipient: { id: recipientId },
message: {
quick_replies: quick_replies,
text: text
}
}
await request({
url: 'https://graph.facebook.com/v2.6/me/messages',
qs: { access_token: FB_PAGE_TOKEN },
method: 'POST',
json: messageData
})
}
Basically, I create and attach the quick replies on my own.
If you have static quick replies in Wit.ai, then you will get them in send() in this format: res.quickreplies = ['Yes', 'No'] and then you can format and attach these options.

Wit.ai: How to send a message when confidence below a certain level?

I'm playing around with the Wit.ai Facebook Messenger Example (https://github.com/wit-ai/node-wit/blob/master/examples/messenger.js)
Is there a way to send a preset response when the user's message is not understood. I was thinking along the lines of some way of stopping the Wit conversation when the confidence is below a certain threshold.
Any help greatly appreciated. Thanks.
You can use the Wit API directly and skip the ui all together if you want more fine control.
function getIntent(message) {
var serviceResult = {};
var url = 'https://api.wit.ai/message?v=20161006&q='+message;
var options = {
uri: url,
qs: {},
method: 'POST',
headers: {},
auth: {'bearer': process.env.WIT_TOKEN},
json: true
};
request(options, function(error, response, body) {
if(!error) {
serviceResult.result = "success";
// Check for entities
if(body.entities.contact) {
serviceResult.entity = body.entities.contact[0].value;
serviceResult.entityConfidence = body.entities.contact[0].confidence;
}
// Check for intent
if(body.entities.intent) {
serviceResult.intent = body.entities.intent[0].value;
serviceResult.intentConfidence = body.entities.intent[0].confidence;
}
}
else {
serviceResult.result = "fail";
}
});
}
Your bot can decide what it wants to do based on the confidence value.

Resources