Wit.ai How to add dynamic Quick Replies - node.js

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.

Related

How to add a contact to ActiveCampaign using API v1 contact_sync/contact_add

I am having trouble adding a contact to ActiveCampaign. I read a post in here: How to add a contact to a list in ActiveCampaign API v3 and am using v1 of the API. I used their contact_sync documentation to the best of my availability.
I'm developing using Gatsby/React --> GitHub --> Netlify, using a lamda function for the POST request.
Here is my axios POST:
{
method: 'post',
url: 'https://ACCOUNT.api-us1.com/admin/api.php?api_key=xxxxxxxxxxxx&api_action=contact_sync&api_output=json',
headers: { 'Content-Type': 'Content-Type: application/x-www-form-urlencoded' },
body: {
email: 'email#email.com',
first_name: 'John'
}
}
And received the following response:
{
result_code: 0,
result_message: 'Could not add contact; missing email address',
result_output: 'json'
}
I'm talking to their endpoint. I just can't figure out how to feed the endpoint the email address?
Does anyone have a working example they would be kind enough to share? Guidance of any kind would be greatly appreciated!
I wanted to make sure to close this and share my answer.
Thanks so much to #reza jafari for his comment in this post where he brought to my attention the code window on the right margin of Postman where you can choose the language/server from a dropdown and it provides the correctly formatted response.
(I don't have enough reputation to upvote #reza's response so wanted to acknowledge it here.)
I was able to get my post working in Postman, and this little trick squared me away. I'll go ahead and post my solution to close this post.
const axios = require("axios")
const qs = require("qs")
exports.handler = async function (event) {
const { email, first_name } = JSON.parse(event.body)
const data = qs.stringify({
email: email,
first_name: first_name,
tags: '"api"',
"p[1]": "1",
})
const config = {
method: "post",
url: "https://ACCOUNT.api-us1.com/admin/api.php?api_key=xxxxxxxxx&api_action=contact_sync&api_output=json",
headers: {
"Api-Token":
"xxxxxxxxx",
"Content-Type": "application/x-www-form-urlencoded",
},
data: data,
}
try {
const response = await axios(config)
return {
statusCode: 200,
body: JSON.stringify(response.data),
}
} catch (err) {
return {
statusCode: 500,
body: JSON.stringify(err),
}
}
}

How to respond to message from the Bot Framework (Direct Line Client)?

I want to create a dialog with the bot framework. My steps:
Create a new Conversation using the Direct Line API (Works without problems) (Clientside)
The following Dialog gets triggered in the Bot framework (Serverside):
bot.dialog('*:notification', [
function (session, args) {
builder.Prompts.text(session, args)
},
function (session, results) {
logger.info('Results', results)
}])
I want to send a reply to the incoming Message (Clientside)
method:'post',
url:'conversations/' + conversationId + '/activities',
headers:{
'Authorization': 'Bearer' + token
}
body:{
replyToId: replyToId,
type:'message',
from: {
id:'myId'
},
text: 'Some simple text',
textFormat: 'plain'
}
conversationId: I use the one i recieved when i created the conversation
token: I use the one i recieved when i created the conversation
replyToId: The one from the activity Object
Actual Result:
The Botframework does not recognize that this is the reply to the message send and triggers the default handler.
Expected Result:
The Bot Framework triggers the second step of the Dialog.
For the first thing, your dialog '*:notification' don't have a triggerAction, you can for example modify your dialog like this:
bot.dialog('*:notification', [
function (session, args) {
builder.Prompts.text(session, args)
},
function (session, results) {
logger.info('Results', results)
}]).triggerAction({matches: /^notification/i});
Then you may use DL to send message from your client side to your bot and trigger this dialog like this:
method:'post',
url:'conversations/' + conversationId + '/activities',
headers:{
'Authorization': 'Bearer' + token
}
body:{
type:'message',
from: {
"id": "1234",
"firstname": "fname",
"lastname": "lname"
},
text: 'notification',
textFormat: 'plain'
}

Facebook Messenger Bot - How to use NodeJS to get User Information?

I have a bare bones chatbot in messenger set up and would like to expand on its potential functionality. The first thing I want to be able to do is access user info, mostly the users first name. I know this is possible, but as I am new to NodeJS I am not sure how to achieve this. I have not been able to find very many tutorials on chatbots past the intro stage. Any help is greatly appreciated!
Below is a link to an abbreviated version of my chatbot
This is the main bit of code that I think needs refining (see it below in the context of the rest of the bot)
function getName(event){
request({
url: "https://graph.facebook.com/v2.6/" + sender,
qs: {
access_token : token,
fields: "first_name"
},
method: "GET",
}, function(error, response, body) {
if(error){
console.log("error getting username")
} else{
var bodyObj = JSON.parse(body)
name = bodyObj.first_name
sendText(sender, "Hi, ")
sendText(sender, name)
sendText(sender, " whatsup?")
}
})
}
Chatbot Code
You can get the facebook user info by below code:
request({
url: "https://graph.facebook.com/v2.6/" + senderId + "?",
qs: {
access_token: config.FB_PAGE_ACCESS_TOKEN
},
headers: {
'Accept': 'application/json',
'Accept-Charset': 'utf-8',
'User-Agent': 'test-bot'
},
method: "GET",
json: true,
time: true
},
function(error, res, faceUserInfo) {
console.log("faceUserInfo", faceUserInfo)
}
);
Double check your access token is correct.
I also suggest you check the what the error message is
console.log("error getting username", error);
Sender is not defined in your function.
It is being passed into your other functions, or delcared in the scope of your post request handler.
Make sure sender is defined, and your code should work fine.
Add the below line to your getName function:
var sender = event.sender.id
Your variable name is not defined, should add let name=... and it works fine

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

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

Object property key is different within req.body than client-side (Express)

I'm a bit of a noob working on my first CRUD application (dream journal) using Node, Express, and MongoDB/Mongoose.
I'm creating a simple object based on a few user form inputs and then submitting a post request to the server, which in turn calls Mongoose.save().
The object I'm creating on the client side, however, is slightly different than the one that is being received by the server, and I'm at a complete loss as to why.
First I'm getting some values from a form and putting them in an object:
// within button click event handler
var dreamText = $('#dream-text').val().trim();
var dreamTags = ["tag 1", "tag 2", "tag 3"]; // for debugging
var dreamLucid = $('#dream-lucid').val() == 'Yes' ? true : false;
var dreamDate = $('#dream-date').val();
var dream = {
userID: 'test',
text: dreamText,
tags: dreamTags,
isLucid: dreamLucid,
dateCreated: dreamDate
};
Here a console.log of dream shows everything as it should be:
Object {userID: "test", text: "sample text", tags: Array[3], isLucid: false, dateCreated: "2016-08-08"}
From there I'm submitting a POST request with the dream object:
$.ajax({
type: 'POST',
url: '/new',
data: dream,
success: function(data){
console.log('dream saved');
}
});
Now on the server side, with Express and Mongoose, I'm attempting to save the object to a DB:
router.post('/', urlencodedParser, function(req, res) {
console.log(req.body);
var newDream = Dream(req.body).save(function(err, data){
if (err) {
throw error;
}
});
});
All the properties except tags are saving correctly, and a console.log of req.body yields:
{ userID: 'test',
text: 'sample text',
'tags[]': [ 'tag 1', 'tag 2', 'tag 3' ],
isLucid: 'false',
dateCreated: '2016-08-08' }
Any idea why the tags property on the client side is becoming 'tags[ ]' when it gets passed through the POST request?
I've tried both tags: Array and tags: [String] in my Mongoose Model, but the problem seems to be occurring before I ever call Mongoose.save.
By default, $.ajax() encodes a POST operation as application/x-www-form-urlencoded which does different things with arrays. You probably just want to send JSON so you can receive JSON on the server.
You can cause that to happen by manually turning your data into JSON and setting the content type appropriately:
$.ajax({
type: 'POST',
url: '/new',
data: JSON.stringify(dream),
contentType: "application/json",
success: function(data){
console.log('dream saved');
}
});
Then, you may also have to parse the JSON on the server side of things, either manually for this request or with some middleware like bodyParser.json().

Resources