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
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.
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);
}
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
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)
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");
}
}
});
}
});