Facebook Messenger: How to send multiple messages with nodejs - node.js

I just want to send a messages to all the subscribers with nodejs.
This is my code ( I have hidden the PSID below ):
app.get('/helloguys', function (req, res) {
var messageData = {
batch: [
{recipient: {id: "..."}},{recipient: {id: "..."}}
],
message: {
text: "Hi guys :)",
metadata: "DEVELOPER_DEFINED_METADATA"
}
};
request({
uri: 'https://graph.facebook.com/v2.6/me/messages',
qs: { access_token: token },
method: 'POST',
json: messageData
}, function (error, response, body) {
if (!error && response.statusCode == 200) {
console.log("Ok", response.statusCode);
} else {
console.error("Failed calling Send API", response.statusCode, response.statusMessage, body.error);
}
});
res.send('Hi :)')
})
I get this in the nodejs console:
Ok 200
but users don't receive the message.
Why ?
EDIT for Lix:
body:
2017-10-18T13:38:43.538998+00:00 app[web.1]: [ { code: 400,
2017-10-18T13:38:43.538999+00:00 app[web.1]: headers: [Object],
2017-10-18T13:38:43.538999+00:00 app[web.1]: body: '{"error":{"message":"Unsupported get request. Please read the Graph API documentation at https:\\/\\/developers.facebook.com\\/docs\\/graph-api","type":"GraphMethodException","code":100,"error_subcode":33,"fbtrace_id":"Dd6+kHN7Tl+"}}' },
EDIT for CBroe:
var messageData = {
batch: [
{method:"POST", message: "Hello", recipient: {id: "1552389158161227"}},{method:"POST", message: "Hello", recipient: {id: "1419003191530571"}}
]
};
It doesn't work
EDIT for CBroe 2:
app.get('/helloguys', function (req, res) {
var batch = [
{method:"POST", body: "message=Test status update&recipient=..."},
{method:"POST", body: "message=Test status update&recipient=..."}
];
request({
uri: 'https://graph.facebook.com/v2.6/me/messages',
qs: { access_token: token },
method: 'POST',
json: batch
}, function (error, response, body) {
if (!error && response.statusCode == 200) {
console.log("ok", response.statusCode, response.statusMessage, response);
res.send('hi')
} else {
console.error("Failed calling Send API", response.statusCode, response.statusMessage, body.error);
}
});
})
And now I get:
2017-10-18T15:36:05.981999+00:00 app[web.1]: Failed calling Send API 400 Bad Request { message: '(#100) The parameter recipient is required',
2017-10-18T15:36:05.982009+00:00 app[web.1]: type: 'OAuthException',
2017-10-18T15:36:05.982010+00:00 app[web.1]: code: 100,
2017-10-18T15:36:05.982011+00:00 app[web.1]: fbtrace_id: 'EJLQgP9UoMT' }

As per FB dev docs (they stated somewhere within the docs, and not very obvious)
Note the URLEncoding for the body param
Also, multiple POST requests (batched requests):
While GET and DELETE operations must only have a relative_url and a method field, POST and PUT operations may contain an optional body field.
And >>
This should be formatted as a raw HTTP POST body string, similar to a URL query string.
Also, this type of request should be made as multipart/form-data.
Then, batch request requirements are:
(1) to be multipart/form-data;
(2) consist of URLEncoding strings in 'body' parameter;
(3) batch request should be raw HTTP POST body string.
Node.js request module could send form-data (through form-data module). See docs
So, your code should be like this >>
app.get('/helloguys', function (req, res) {
var batchUrl = 'https://graph.facebook.com';
var r = request.post(batchUrl, function(error, response, body) {
if (error) {return console.log("error\n", error)};
console.log("successfull\n", body) //but fb sends error in body message, so check body.error for any errors
});
var form = r.form();
var multipleMessages = [];
var message = "message=" + encodeURIComponent(JSON.stringify(
{
"text": "​Hi guys :)"
}
));
//loop throught user IDs (PSIDs)
for (var i=0; i<users; i++) {
var recipient = "recipient=" + encodeURIComponent(JSON.stringify({"id": users[i].id}));
var batchMessage = {
"method": "POST",
"relative_url":"v2.6/me/messages",
"body": recipient + "&" + message
};
multipleMessages.push(batchMessage);
}
form.append("access_token", token)
form.append("batch", JSON.stringify(multipleMessages));
res.send('Hi :)')
})

Try to move res.send('Hi') inside your request callback:
function (error, response, body) {
if (!error && response.statusCode == 200) {
console.log("Ok", response.statusCode);
res.send('Hi');
} else {
console.error("Failed calling Send API", response.statusCode, response.statusMessage, body.error);
}
});

Related

node.js + request => response showing junk response

I am using the node.js + request for send HTTP request to URL. I required the JSON response, but I get junk character.
Here is my node.js code
var request = require('request');
var post_data = { UserName: "xxxxx", Password: "xxxxx" };
var post_options = {
url: 'http://xxxxxxx.info/api/CoreUser/cognitoLogin',
method: 'POST',
form: post_data,
headers: {
'AppID': 'zNiphaJww8e4qYEwJ96g555HTAAbAXdj',
'OAuth': 'xxxxxxxxxxxxxxxxxx',
//'User-Agent': 'Super Agent/0.0.1',
'Content-Type': 'application/json;charset=UTF-8',
}
};
// Set up the request
request(post_options, function (error, response, body) {
console.log(response.statusCode);
if (!error && response.statusCode == 200) {
console.log("200");
console.log(response);
}
});
But I received response in junk characters.
I need result in jSON format, What is wrong in this request?
I found the issue, reason is that API response send in gZip format. Here is the change we have to made here. Just enable gzip: true that resolve the things.
var request = require('request');
var post_data = { UserName: "xxxxx", Password: "xxxxx" };
var post_options = {
url: 'http://xxxxxxx.info/api/CoreUser/cognitoLogin',
method: 'POST',
gzip: true,
form: post_data,
headers: {
'AppID': 'zNiphaJww8e4qYEwJ96g555HTAAbAXdj',
'OAuth': 'xxxxxxxxxxxxxxxxxx',
//'User-Agent': 'Super Agent/0.0.1',
'Content-Type': 'application/json;charset=UTF-8',
}
};
// Set up the request
request(post_options, function (error, response, body) {
console.log(response.statusCode);
if (!error && response.statusCode == 200) {
console.log("200");
console.log(response);
}
});
You are missing { json: true } in request call
request(post_options, { json: true }, function (error, response, body) {
console.log(response.statusCode);
if (!error && response.statusCode == 200) {
console.log("200");
console.log(response);
}
});

Node JS Request Printing nothing in console

I'm making an post call using the nodejs requests module. However, the console.log statements seems to be not working for either the error or the response.body that I am trying to get.
My POST request needs the following headers -
Accept : "application/json"
Content-Type : "application/json"
Authorization : Basic + Base64Encoded(username+password)
The post body is something like this
Body:
{
"arg_1" : "a_string_key"
, "arg_2" : "a_string"
, "arg_3" : "a_string"
, "arg_4" : "some_value"
, "arg_5" : "some_string"
, "arg_6" : "<yyyy-mm-dd>"
, "arg_7" : "<yyyy-mm-dd>"
}
My code does nothing but send a POST request and checks if the response.statusCode ==200
Here is what I am doing
var int_user = "username";
var int_pass = "password";
var encoding = "base64"
var auth = "Basic" + new Buffer(int_user + int_pass).toString(encoding);
var headers = {
"Accept": "application/json",
"Content-Type": "application/json",
"Authorization": auth
}
var options = {
url: 'URL_I_WANT',
// method: 'POST',
headers: headers,
body : {
"arg_1": "a_string_key",
"arg_2": "a_string",
"arg_3": "a_string",
"arg_4": "some_value",
"arg_5": "some_string",
"arg_6": "<yyyy-mm-dd>",
"arg_7": "<yyyy-mm-dd>"
},
json: true
}
console.log('Before request');
request.post(options, function(error, response) {
if (error) {
console.log(error);
}
try {
if (!error && response.statusCode == 200) {
console.log(response.body);
console.log('Success');
}
} catch (error) {
console.log(error)
}
});
console.log('After request');
The code runs without any glitch and I get the before and after request console statements. However the statements inside the requests do not appear in the console, which means my request is not going through. I am not able to understand this. Shouldn't an error come if there is an issue with the request itself? Any if the request is failing, why isn't the error printed out?
This could be because your node process is auto-closed and it will exit before the async request to finishes (haven't looked into it but it might be something configurable). I've seen such set-up on repl.it for example.
To overcome this(if not configurable), you could wrap your code in an async function and use the request-promise to call await request.
var request = require('request-promise-native');
var int_user = "username";
var int_pass = "password";
var encoding = "base64"
var auth = "Basic" + new Buffer(int_user + int_pass).toString(encoding);
var headers = {
"Accept": "application/json",
"Content-Type": "application/json",
"Authorization": auth
}
var options = {
url: 'https://google.com',
method: 'POST',
headers: headers,
body : {
"arg_1": "a_string_key",
"arg_2": "a_string",
"arg_3": "a_string",
"arg_4": "some_value",
"arg_5": "some_string",
"arg_6": "<yyyy-mm-dd>",
"arg_7": "<yyyy-mm-dd>"
},
json: true
};
console.log('Before request');
async function main() {
try {
const response = await request.post(options);
if (response.statusCode === 200) {
console.log(response.body);
console.log('Success');
process.exit();
}
console.log(`Bad statusCode:${response.statusCode}`);
}
catch (error) {
console.log(error);
}
}
main();
you can check-out the code below
a link to the code above, working on repl.it

Passing array or nested objects in body of request npm

I have to send some parameters of String type along with one array in my body.
But it throws me an error message:
First argument must be String or buffer
Here is my code:
var tokenList = JSON.parse(req.body.tokenList);
var mobParams = {
"tokens": tokenList,
"profile": "<myprofile>",
"notification": {
"title": req.body.title,
"message": req.body.text
}
};
request({
method: "POST",
url: 'https://api.ionic.io/push/notifications',
headers: {
"content-type": "application/json",
"authorization": "Bearer ********"
},
body: (mobParams)
}, function(error, response, body){
console.log('Ionic push error', error);
console.log('IOnic push res', response);
console.log('IOnic push body', body);
if(!error){
return res.send({
code: 1,
message: "success"
});
}else{
return res.send({
code: 0,
message: error
});
}
How can I pass my array inside this object to request npm?
Also, I would like to add that this implementation works pretty fine through front-end but I have separate codebase which requires me to hit multiple FCM requests i.e. in a loop. So I would be happy to have a solution as neither ionic push nor FCM push works
For the FCM push I am trying the code below :
let desktopParams = {
"notification": {
"title": 'Merchant Portal Notifications',
"body": req.body.text
// "click_action" : action
},
"to": '/topics/' + topic
};
request({
method: "POST",
json: true,
url: 'https://fcm.googleapis.com/fcm/send',
headers: {
"content-type": "application/json",
"authorization": "key=****"
},
body: desktopParams
}, function(error, response, body){
console.log('error', error);
console.log('response', response);
console.log('body', body);
//return body;
});
you should try stringifying your tokenList & req.body.text before you join it with with the string (try to log it and post the outcome so that people will have a better idea about the objects...):
var cho = [{name:'john',lname:'cena'},{name:'mary',lname:'jane'}];
var che = {list:[{name:'john',lname:'cena'},{name:'mary',lname:'jane'}],group:'people'}
var mobParams = {
"tokens":JSON.parse(JSON.stringify(cho)),
"profile": "<myprofile>",
"notification": {
"title": "Some title",
"message":JSON.parse(JSON.stringify(che))
}
};
console.log(JSON.stringify(mobParams));//----->{"tokens":[{"name":"john","lname":"cena"},{"name":"mary","lname":"jane"}],"profile":"<myprofile>","notification":{"title":"Some title","message":{"list":[{"name":"john","lname":"cena"},{"name":"mary","lname":"jane"}],"group":"people"}}}
var arr = [{name:'john',lname:'cena'},{name:'mary',lname:'jane'}]
var js = JSON.stringify(arr);
var blabla = {'item':'something',js}
console.log(blabla); //-----> Object {item: "something", js: "[{"name":"john","lname":"cena"},{"name":"mary","lname":"jane"}]"}
var js = JSON.parse(JSON.stringify(arr));
var blabla = {'item':'something',js}
console.log(blabla); //-----> Object {item: "something", js: Array(2)}
var js = JSON.parse(arr);
var blabla = {'item':'something',js}
console.log(blabla); //-----> "SyntaxError: Unexpected identifier"

Testing Auth0 API Patch Request

Trying to test Auth0 API patch request to modify user_metadata.
Using mocha and superagent for testing.
Get succeeds, but doing a patch with a userid and sending
.send({ "metadata": { "nickname": "Jill" } })
in the mocha testing file does not work.
router.patch('/:id', function(req, res, next) {
var options = {
method: 'PATCH',
url: 'https://mrides.auth0.com/api/v2/users/' + req.params.id,
headers: {
Authorization: "Bearer " + apiToken
},
data: req.body
}
request.patch(options, function(err, response, body) {
if(!err && response.statusCode == 200) {
res.send(JSON.parse(body))
} else {
res.status(500).send(err);
}
})
});
Error:
{
"statusCode": 400,
"error": "Bad Request",
"message": "Payload validation error: 'Expected type object but found type null'.",
"errorCode": "invalid_body"
}
Had seen this question:
Auth0 API Request
but it did not work when trying:
data: JSON.stringify(req.body)
Any help or links on how to propery modify user_metadata?
Have also been looking through Auth0 docs but no advancement yet.
change options following way:
var options = {
method: 'PATCH',
url: 'https://mrides.auth0.com/api/v2/users/' + req.params.id,
headers: {
Authorization: "Bearer " + apiToken
},
// change here
body: req.body
}
request.patch(options, function(err, response, body) {
if(!err && response.statusCode == 200) {
res.send(JSON.parse(body))
} else {
res.status(500).send(err);
}
})
};

Trying to post api request

I having problem with making a API call to an external site.
I need to send a POST request to http://api.turfgame.com/v4/users with headers Content-type: application/js. But when I run this code it only loads and nothing more.
var request = require('request');
var options = {
uri: 'http://api.turfgame.com/v4/users',
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: {
"name": "username"
}
};
request(options, function (error, response, body) {
if (!error && response.statusCode == 200) {
res.send(response.body);
}
});
The body need to be posted in json formate [{'name': 'username'}].
Can someone tell me what I have done wrong?
There are a few things wrong:
the address property in the "options" object should be "url" not
"uri"
you can use the "json" property instead of body
"res" is undefined in your response handler function
if you want the body to be an array, it needs to be surrounded in square brackets
here's a working sample that just logs the response:
var request = require('request');
var options = {
url: 'http://api.turfgame.com/v4/users',
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
json: [{
"name": "username"
}]
};
request(options, function (error, response, body) {
if (!error && response.statusCode == 200) {
console.log(response.body);
}
});

Resources