Facebook Messanger Bot Webhook issue - javascript

I received this message
Your Webhooks subscription callback URL has not been accepting
updates.
We've noticed that your Webhooks subscription for callback URL
https://trololo.herokuapp.com/bot has not been accepting updates
for at least 16 minutes. Please verify that your callback server is
functioning so you may continue to receive updates. If you need to
update your callback URL, see
https://developers.facebook.com/docs/graph-api/reference/app/subscriptions#update
If your callback URL continues to fail to accept updates for 8 hours
straight, we will disable your subscription. To reactivate the
subscription, make a POST request with the same parameters, and it
will be reactivated.
This code is executed on the server
app.post('/bot', function (req, res) {
console.log('post bot: ' + req);
var messaging_events = req.body.entry[0].messaging;
for (var i = 0; i < messaging_events.length; i++) {
var event = req.body.entry[0].messaging[i];
var sender = event.sender.id;
if (event.message && event.message.text) {
text = event.message.text;
console.log('text received: ' + text);
sendTextMessage(sender, "Text received, echo: "+ text.substring(0, 200));
}
}
res.sendStatus(200);
});
But it fails because req.body is undefined. The req params is also no json because it makes this error:
TypeError: Converting circular structure to JSON
req only shows [object Object] and I have no idea whats inside the object. .toString isn't working either.
I made the complete guide twice. I think the issue comes from the part were the facebook page should connect to the facebook app. I do this with curl -ik -X POST "https://graph.facebook.com/v2.6/me/subscribed_apps?access_token=<mytoken>" Please help. Any response is greatly appreciated.
Here is a demo log

I think it's a dependency problem... maybe you're missing the json body parser body-parser
If you look at comments on program sample on node-wit/examples/messenger.js, you will see that you need install some deps:
in your project directory, try:
npm install body-parser express request
And look at: https://www.youtube.com/watch?v=zFO1cRr5-qY ... I think they resolved exactly this issue and others that you may find.

Related

"redirect_uri_mismatch" when sending authentication code to GoogleAPI

I am having trouble with the authentication process for the GoogleAPI. In the end I want to be able to read the users steps using the GoogleFit API and then store that value in a database. Currently I'm using restdb.io and executing javascript in codehooks.
The documentation from Google that I am following can be found here, clicking on the HTTP/REST option in the code examples. At the moment I am at step 5: I have gotten the users authentication code and stored it in the database. Now I have to POST the code along with some other parameters and get the access and refresh tokens.
If the POST is successful (from what I understand) I should get back a 200-OK message that the request was valid. Google will then POST a JSON body with the access and refresh token to the redirect_uri that I have specified in my GoogleAPI credentials page and the initial request. At redirect_uri I have to handle the request and save the two values.
The problem is that I receive a redirect_uri_mismatch - Bad Request message from Google as a response when executing the request. I get it at the log.debug("ERROR HERE: " + [...]); in the code below:
async function mainFunction(){
const authCode = THIS_IS_MY_AUTHENTICATION_CODE;
try {
var answer = await postRequestToGoogle(authCode);
//do stuff with response from Google
} catch (error) {
//do stuff
}
}
async function postRequestToGoogle(authCode){
//body for the request
const params = "code=" + authCode + "&" +
"client_id=THIS_IS_MY_CLIENT_ID" + "&" +
"client_secret=THIS_IS_MY_CLIENT_SECRET" + "&" +
"redirect_uri=THIS_IS_MY_REDIRECT_URI" + "&" +
"grant_type=authorization_code";
try{
const result = await fetch('https://oauth2.googleapis.com/token', {
method: 'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: params})
.then(res => {
log.debug("ERROR HERE: " + JSON.stringify(res.json()));
return res.json();
})
//return JSON back main function
return result;
}catch(error){
//do stuff
}
}
I looked up the error message and tried some things:
Copy and pasted multiple different Authorized redirect URI from the GoogleAPI credentials page into the code to make sure that there is no problem with
http/https
www/no www
trailing slashes
typos or capitalization
Waited for changes to be processed by Google (read that it can more than 30min)
Changed all the other parameters to see if the redirect_uri is actually the problem
If code is changed the message is invalid_grant - Bad Request
If client_id is changed the message is invalid_client - The OAuth client was not found
If client_secret is changed the message is invalid_client - Unauthorized
If the grant_type is changed the message is unsupported_grant_type - Invalid grant_type
That's why I think the issue is the redirect_uri, but it's unclear to me how since I copy&pasted it. Something that came to mind was that maybe the value of redirect_uri gets changed when it's read by Google? Or maybe when the request is being put together? Do some characters have to be replaced?
I tried to analyze the request with Wireshark but didn't think about the fact that it's HTTPS so I would have I would have to decrypt it.. Is that something I should look into?
Thank you for taking the time to read all of this! If you have any advice please let me know :)
Update 16.11.20:
I have created a new OAuth 2.0 Client ID and used the new id/secret in my request. The resulting message the same as before. I will wait and try again tomorrow to see if maybe Google needs some more time. Then I'll try to delete all current IDs and start with a fresh GoogleAPI project.
Update 19.11.20:
Creating a new OAuth 2.0 Client ID did not resolve my problem, neither did creating a whole new GoogleAPI project and adding those credentials into the request. I am in contact with the developers of restdb.io and have asked them to add the Google Auth Library: Node.js Client to the list of supported Node.js packages. Hopefully that will help, I will give it a try as soon as it can be used :)
Update 02.12.20:
No progress so far, but I'm optimistic that the developers will add the package soon. I will post a final update as soon as I am done with this project.

Is there a way to mock a property on a request object

I have a Javascript REST api endpoint defined using swagger. In my controller, I am logging the IP address from the incoming request.
This is functioning just fine but now I am trying to add Jest tests for coverage and each time I run my test I am getting an error thrown
module.exports.execute = async function execute (req, res) {
try {
log.info("Start processing request from client IP="+req.connection.remoteAddress);
... do some stuff
log.info("Finished processing request from client IP="+req.connection.remoteAddress);
} catch(err) {
log.error("Error caught in Address controller =>" + err.message);
utils.writeJson(res, err.message, 500);
}
};
When I execute my tests, I am getting Error caught in controller =>Cannot read property 'remoteAddress' of undefined
When I comment out the lines that call req.connection.remoteAddress, all is good and I get coverage but not for those 2 lines.
I am guessing the issue is that the req.connection.remoteAddress is a property and not a function.
Is there a way I can mock the response from this call to return a statis string like 1.1.1.1 ?
Any help is appreciated
After thinking about the question in the first comment from #Will Alexander, I added this (second line) and now all is good. Thank you Will
let mockReq = _.set({},'swagger.params.entity.value', JSON.stringify({ fail: false}));
mockReq.connection = _.set({},'remoteAddress', '1.1.1.1');

Twitter Bot Node.js and Twit Package

PROBLEM
So im trying to create a twitter bot and everything was going fine until i tried to auto reply to users who follow me.
I'am learning and was watching from this tutorial Coding Train Twitter Bot(LINK) but i seem to get this error(PHOTO) even tho i did everything exactly the same.
Im Using:
Node.js
NPM
Windows CMD Command Prompt
Sublime Text 3
Importing Packages
var Twit = require('twit');
var Keys = require('./private_auth_keys');
var T = new Twit(Keys);
Stream Setup.
I belive the bug is somewhere in the stream part but i dont get it... i did everything the same as the video. Maybe twitter blocked this from their API? idk what im talking about, but any feedback would be awesome.
var stream = T.stream('user');
stream.on('follow', followed);
function followed(eventMsg) {
console.log("New Follower Reply Sent!");
var Name = eventMsg.source.name;
var screenName = eventMsg.source.screen_name;
tweetIt('Heyyy .#' + screenName + ' thanks for the follow! Do you like memes? #RateThatMeme');
}
Reply/Tweet Function
function tweetIt(txt) {
var tweet = {
status: txt
}
T.post('statuses/update', tweet, tweeted);
function tweeted(err, data, response) {
if (err) {
console.log("oof! Something went wrong!");
} else {
console.log("Tweet sent successfully!");
}
}
}
Error Message
events.js:167
throw er; // Unhandled 'error' event
^
Error: Bad Twitter streaming request: 401
at Object.exports.makeTwitError (C:\Users\admin\Desktop\Projects Code Train\node\node2\node_modules\twit\lib\helpers.js:74:13)....etc
Twitter user streams were retired in August so this code will no longer work as is.
401 status code means you are not unauthenticated - there should be additional WWW-Authenticate header in response that will tell you more.
I think twitter API changed since this tutorial was recorded and you have to do a bit more now to be able to access it, this is probably a reason for 401 status. as far as I can see, the author moved to mastodon with this tutorial lately because of that.

Node JS HTTP Server request.on('data') event failure

I am working on a NodeACS app in which I have to send xml as request from Java HTTP client and to receive response after some manipulation. The Java HTTP Client is working fine so far but the issue is with Node JS file. The req.on('data'...) event is not firing in my case.
Following is the code of my JS file:
function index(req, res) {
console.log(req.headers); //Its getting printed on console
req.on('data', function (data) {
console.log("Inside 1"); //Not printed on console
....REST OF THE CODE....
});
req.on('end', function () {
res.writeHead(200);
res.end();
});
}
In the above code after getting request the index function is called and printing the output for console.log(req.headers); but as mentioned above the script is not running after that. Please help me out What am I missing in this.
For testing I have installed cURL on my system and sending POST request to server using cURL request using following command:
curl -X POST -d #output.xml http://localhost:7788/
Can you confirm you aren't consuming the body prior to this? If the body has been consumed already by another middleware like body-parser you would need to restream the body via something like connect-restreamer. If it were consumed, the data event would not be emitted.
If that checks out, check to see if the "end" event is being emitted. Could be a sign of the content-length header being set to the wrong value.

Sails.js to client using sails.sockets.join and sails.sockets.broadcast doesn't return info to the client

I'm attempting to create a one to one chat using Sails.js and sails.io.js on the client side.
I can get the io.socket.get and io.socket.post to work, but I haven't been able to receive anything from either sails.sockets.broadcast or Model.publish as instructed here:
Personalized chat using Sails.js
or here
Sails.js + socket.io: Sending messages from server to clients
Server Side Code:
UserController.js
module.exports = {
listen: function(req, res) {
console.log("about to join " + userId);
sails.sockets.join(req.socket, req.param('userId'));
}
};
From: http://beta.sailsjs.org/#/documentation/reference/sails.sockets/sails.sockets.join.html
MessageController.js
// Some code to get userId and message model here
console.log("about to broadcast on " + userId);
sails.sockets.broadcast(userId, 'conversation_message', message);
// Did not JSONify the message model, not sure if I need to?
From: http://beta.sailsjs.org/#/documentation/reference/sails.sockets/sails.sockets.broadcast.html
Client Side Code:
// Some code to get userId...
io.socket.get('/user/listen', {
userId: userId
}, function() {
io.socket.on('conversation_message', function(message) {
console.log("we have a message");
});
});
When I hit the route that triggers the broadcast with userId, nothing is sent to this client code to log we have a message. Any ideas?
I have tried the Model.subscribe / Model.publish methods as well with no luck--same issue.
Update: The listen function doesn't actually return -- as someone suggested in a comment that they later deleted. Adding res.send(200); to the end of the listen function was enough to make it work.
If that person would add their comment again as an answer I'll accept it.
(That was me. I thought my comment might of been not worthwhile because i reread your post and you said you had the get working so I thought I was wrong. My comment was something to the effect below, but I don't remember verbatim)
Have you checked to make sure the you are actually getting a response on the client-side listen? What log statements are you actually getting throughout your code? Put a console.log('get user listen') or something inside of the Client-side socket.get.

Categories

Resources