Node.js Facebook messenger chatbot - sender PSID is not defined - node.js

i developed a chatbot with nodejs and deployed it to heroku. but the webhook is not working properly since its gets an error saying sender PSID is not defined. what should I do? I need help from experts.. I haven't used wit.ai in my project but only node.js. and here i haven't posted post backs handlings as its too long!
my controllers.js as below.. (messages are in Sinhalese language)
import dotenv from 'dotenv';
dotenv.config();
import request from 'request';
const PAGE_ACCESS_TOKEN = process.env.PAGE_ACCESS_TOKEN;
const MY_VERIFY_TOKEN = process.env.MY_VERIFY_TOKEN;
let test = (req, res) => {
return res.send("hello again")
}
let getWebhook = (req, res) => {
// Your verify token. Should be a random string.
let VERIFY_TOKEN = MY_VERIFY_TOKEN
// Parse the query params
let mode = req.query['hub.mode'];
let token = req.query['hub.verify_token'];
let challenge = req.query['hub.challenge'];
// Checks if a token and mode is in the query string of the request
if (mode && token) {
// Checks the mode and token sent is correct
if (mode === 'subscribe' && token === VERIFY_TOKEN) {
// Responds with the challenge token from the request
console.log('WEBHOOK_VERIFIED');
res.status(200).send(challenge);
} else {
// Responds with '403 Forbidden' if verify tokens do not match
res.sendStatus(403);
}
}
}
let postWebhook = (req, res) => {
let body = req.body;
// Parse the request body from the POST
// Check the webhook event is from a Page subscription
if (body.object === 'page') {
// Iterate over each entry - there may be multiple if batched
body.entry.forEach(function (entry) {
// Gets the body of the webhook event
let webhook_event = entry.messaging[0];
console.log(webhook_event);
// Get the sender PSID
let sender_psid = webhook_event.sender.id;
console.log('Sender PSID: ' + sender_psid);
});
// Return a '200 OK' response to all events
res.status(200).send('EVENT_RECEIVED');
} else {
// Return a '404 Not Found' if event is not from a page subscription
res.sendStatus(404);
}
}
// Handles messages events
function handleMessage(sender_psid, received_message) {
let response;
// Checks if the message contains text
if (received_message.text) {
// Create the payload for a basic text message, which
// will be added to the body of our request to the Send API
response = {
"text": `ආයුබෝවන්! ඔබ මේ සම්බන්ද වන්නේ chatbot IN සේවාව වෙතයි.!ඔබට මේ පිළිබද වැඩිදුර දැනගැනීමට අවශ්‍යද?`,
"quick_replies":[
{
"content_type":"text",
"title":"Yes",
"payload":"<POSTBACK_PAYLOAD>",
},{
"content_type":"text",
"title":"No",
"payload":"<POSTBACK_PAYLOAD>",
}
]
}
}
}
// Send the response message
callSendAPI(sender_psid, response);
// Sends response messages via the Send API
function callSendAPI(sender_psid, response) {
// Construct the message body
let request_body = {
"recipient": {
"id": sender_psid
},
"message": response
}
// Send the HTTP request to the Messenger Platform
request({
"uri": "https://graph.facebook.com/v11.0/me/messages",
"qs": { "access_token": PAGE_ACCESS_TOKEN },
"method": "POST",
"json": request_body
}, (err, res, body) => {
if (!err) {
console.log('message sent!')
} else {
console.error("Unable to send message:" + err);
}
});
}
module.exports = {
test: test,
getWebhook: getWebhook,
postWebhook: postWebhook
}
Thanks!

Related

In React 18, when I am sending data to nodejs server, it is sending two request and receiving two response from server

This is the front-end code which is used for sending access token to server site.
useEffect(() => {
const getProducts = async () => {
try {
const url = `http://localhost:5000/product?email=${user.email}`
const { data } = await axios.get(url, {
headers: {
authorization: localStorage.getItem('accessToken')
}
});
setProducts(data);
} catch (err) {
const status = err.response.status;
if (status === 401 || status === 403) {
signOut(auth);
navigate('/login');
localStorage.removeItem('accessToken')
toast.error(err.response?.data?.message);
}
}
}
getProducts();
}, [user.email]);
This is server site express code for response. Why every time it is receiving two request and sending two response?
app.get('/product', verifyToken, async (req, res) => {
const decoded = req.decoded?.email;
const queryEmail = req.query?.email;
if (decoded === queryEmail) {
const query = { email: queryEmail };
const cursor = medicineCollection.find(query);
const products = await cursor.toArray();
res.send(products);
} else {
res.status(403).send({ message: "Forbidden Access" })
}
})
Maybe you take user.email in a state which is updating somehow so that's why useEffect is calling again and giving you twice response.

Twitter Account Activity API in Firebase Function

Everything appears to be working in the console for GET: CRCToken, the webhook is registered, account is authorized, etc.
But POST is not returning anything from Twitter regardless of what I do - favorite, tweet, DM.
Am I approaching this the right way or should I be using something like Twitter-Autohook in my firebase function instead?
exports.twitterMessage = functions.https.onRequest((req, res) => {
switch (req.method) {
case 'GET':
getTwitter(req, res);
break;
case 'POST':
postTwitter(req, res);
break;
default:
res.status(410).json({ message: "Unsupported Request Method" });
break;
}
});
function createCrcResponseToken(crcToken) {
const hmac = crypto.createHmac("sha256", myToken).update(crcToken).digest("base64");
return `sha256=${hmac}`;
}
function getTwitter(req, res) {
const crcToken = req.query.crc_token;
if (crcToken) {
console.log("CRC: " + crcToken)
res.status(200).send({
response_token: createCrcResponseToken(crcToken)
});
} else {
console.error("crc_token missing from request.");
response.sendStatus(400);
}
}
function postTwitter(req, res) {
console.log("received event", req.body);
res.sendStatus(200);
}

commerce coinbase wbhook payload error nodejs

getting error "Error occured Invalid payload provided. No JSON object could be decoded"
i am using below code for webhook
exports.paymentHandler = async (req, res) => {
const rawBody = req.rawBody;
const signature = req.headers['x-cc-webhook-signature'];
console.log("rawbody ",rawBody)
try {
const event = Webhook.verifyEventBody(rawBody, signature, webhookSecret);
functions.logger.info(event);
if (event.type === 'charge:pending') {
// TODO
// user paid, but transaction not confirm on blockchain yet
console.log("pending payment");
}
if (event.type === 'charge:confirmed') {
// TODO
// all good, charge confirmed
console.log("charge confirme");
}
if (event.type === 'charge:failed') {
// TODO
// charge failed or expired
console.log("charge failed");
}
res.send(`success ${event.id}`);
} catch (error) {
console.log(error);
res.status(400).send("failure");
}
};
what could be the possible reason?
For Node.js app to get rawBody from Coinbase use this code.
//server file
//app.use(bodyParser.json())
app.use(bodyParser.json({
verify: (req, res, buf) => {
req.rawBody = buf
}
}))
Now the raw body is available on req.rawBody and the JSON parsed data is available on req.body.
Usage:
const payloadRaw = req.rawBody

Applying asynchronous functions to facebook chatbot messages in specific order

I'm doing a chatbot for facebook and I have a problem with the order of sending messages
I send in the chat:
-Hi
The bot responds in the console:
-Hello!
-How can I help you?
but in the chat responds like this:
-How can I help you?
-Hello!
I tried to apply async and await, but it didn't work.
let postWebhook = (req, res) => {
// Parse the request body from the POST
let body = req.body;
// Check the webhook event is from a Page subscription
if (body.object === 'page') {
// Iterate over each entry - there may be multiple if batched
body.entry.forEach(function (entry) {
// Gets the body of the webhook event
let webhook_event = entry.messaging[0];
// Get the sender PSID
let sender_psid = webhook_event.sender.id;
// Check if the event is a message or postback and
// pass the event to the appropriate handler function
if (webhook_event.message) {
handleMessage(sender_psid, webhook_event.message);
}
});
// Return a '200 OK' response to all events
res.status(200).send('EVENT_RECEIVED');
}};
let handleMessage = async (sender_psid, received_message) => {
let response;
if (received_message.text) {
addUrl(`url/facebook?mensage=${received_message.text}&usuario=${user}&session=${sender_psid}&origem=${chanel}`)
.then(res => res.json())
.then(async json => {
for (var i = 0; i < json.length; i++) {
console.log(json[i].text || json[i].title)
response = {json[i].text || json [i] tittle}
await callSendAPI(sender_psid, response) //function to verify user and send message
}
})
await callSendAPI(sender_psid, response);
}
};
How can I ensure the correct order?
Well you can simplify this way:
const callSendAPII = (sender_psid, response) => {
return new Promise((resolve, reject) => {
let request_body = {
"recipient": {
"id": sender_psid
},
"message": response
}
request({
uri: 'https://graph.facebook.com/v12.0/me/messages',
qs: {"access_token": MY_IG_PAGE_TOKEN},
method: 'POST',
json: request_body,
}, (error, response, body) => {
if (error) {
reject(error);
} else {
resolve(response);
}
});
})
now just apply await in the calling function:
await callSendAPII(sender_psid, response)

Async await issue in nodejs

I am trying to send messages to mobile numbers using message bird API, i have completed the coding part but its not sending the messages, even i can see i have sent messages and being delivered in my message bird profile. I came to know that this issue can be due to not using async and await. Here is my code,
api.get('/sendmessage', function (req, res) {
var id = req.headers.authorization;
if (req.session.id) {
var userid = req.session.user[0].id;
var username = userInfo.find({ id: userid }, function (err, user) {
if (err) { res.send("New Error: " + err); }
else {
if (!_.isEmpty(user)) {
var contact = user[0].contact;
var messagebird = require('messagebird')('ACCESS_KEY_API'); // Api for testing
var params = {
'originator': 'MessageBird',
'recipients': [
contact
],
'body': 'Hello, world!'
};
messagebird.messages.create(params, function (err, response) {
if (err) {
return console.log("Error sent to Console: " + err);
}
else {
console.log(response);
return res.send(response);
}
});
}
else {
res.send("No Results");
}
}
});
}
});

Resources