I try to get the image upload to facebook working... Unfortunately, the facebook graph API always returns the following error:
{ error: Objectcode: 324, message: "(#324) Requires upload file", type: "OAuthException" }
It seems that the picture data is not transfered correctly. The facebook docs tell me to use a multipart/form-data upload. (See here > Publishing)
I am using angular-easyfb as a wrapper for the faceebook sdk. What's the easiest way to get this thing working? My current code is:
var sharePhoto = function() {
ezfb.api("/me/photos",
"POST",
{
"source": content,
"message": "This is a test Photo"
},
function (response) {
console.log("shared", response);
if (response && !response.error) {
/* handle the result */
}
});
};
ezfb.getLoginStatus(function(response) {
if(response.status === 'connected') {
console.log("already conntected", response);
sharePhoto();
} else {
ezfb.login(function(response) {
// Do something with response.
console.log("FB",response);
sharePhoto();
}, {scope: 'public_profile,email,user_photos,publish_actions'});
}
});
The console-log is:
already conntected {status: "connected", authResponse: Object}
shared {error: {code: 324, message: "(#324) Requires upload file", type: "OAuthException"}}
My questions are:
Whats the expected format of my variable content? How do I need to
encode it?
Do I have to manipulate the request Headers of the request? How?
Thanks a lot for your help!
Edit: Console-Log added
Related
I am trying to develop a bot for FB Messenger and I'm always getting stuck with their documentation. Currently, I tried to add a Greeting Text and a Get_Started button in JavaScript, so I will be able to modify it easily. It seems like most of their documentation is in PHP or they just telling you to add it by sending a POST request using CURL, which worked for me, but again, it's not so modular.
I can't find proper documentation in JavaScript. and the only one is this:
https://www.techiediaries.com/build-messenger-bot-nodejs/
But I can't find the place where you actually call the greeting or get started functions.
there is also this https://github.com/fbsamples/original-coast-clothing
but I still can't find where they trigger the Greetings and the Get_Started postbacks. Only the json file where they store it /locales/en_US.json "profile".
My code currently has
// Accepts POST requests at /webhook endpoint
app.post('/webhook', (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) {
// Get the webhook event. entry.messaging is an array, but
// will only ever contain one event, so we get index 0
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);
// 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);
} else if (webhook_event.postback) {
handlePostback(sender_psid, webhook_event.postback);
}
});
// 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);
}
});
function setupGreetingText(res){
var messageData = {
"greeting":[
{
"locale":"default",
"text":"Greeting text for default local !"
}, {
"locale":"en_US",
"text":"Greeting text for en_US local !"
}
]};
request({
"uri": "https://graph.facebook.com/v2.6/me/messages",
"qs": { "access_token": process.env.PAGE_ACCESS_TOKEN },
"method": 'POST',
"headers": {'Content-Type': 'application/json'},
"form": messageData
},
function (error, response, body) {
if (!error && response.statusCode == 200) {
// Print out the response body
res.send(body);
} else {
// TODO: Handle errors
res.send(body);
}
});
}
but I still dont know how to trigger it.
Examples on the documentation look like this. This is how you break it down. Final result can be found below.
curl -X POST -H "Content-Type: application/json" -d '{
"get_started": {"payload": "<postback_payload>"}
}' "https://graph.facebook.com/v2.6/me/messenger_profile?access_token=<PAGE_ACCESS_TOKEN>"
Third word is the type of request you'll send and should be defined inside the method property.
Between the curly braces, is how the content inside the json property should be formatted.
The link on the last line is the link you should provide to the uri property minus the query part ?access_token=<PAGE_ACCESS_TOKEN>
SendAPI's uri is https://graph.facebook.com/v8.0/me/messages (you're using this)
MessengerProfileAPI's uri is https://graph.facebook.com/v2.6/me/messenger_profile (use this instead)
In the end, your request function should look something like this:
request(
{
"uri": "https://graph.facebook.com/v2.6/me/messenger_profile",
"qs": { "access_token": process.env.PAGE_ACCESS_TOKEN },
"method": "POST",
"json": {
"get_started": {"payload": "start"}
},
},
(err) => {
if (!err) {
console.log('request sent!');
} else {
console.error("Unable to send message:" + err);
}
}
);
Even though its been almost 3 months since this question has been asked. I hope this will still come useful.
Was struggling and frustrated as you trying to implement the examples on facebook for developers documentation but I finally got to understand it after some looking and observation at other developers webhook on github.
I'm trying the Wikipedia client login flow depicted in the API:Login docs, but something wrong happens:
1) I correctly get a token raised with the HTTP GET https://en.wikipedia.org/w/api.php?action=query&meta=tokens&type=login&format=json
and I get a valid logintoken string.
2.1) I then try the clientlogin like:
HTTP POST /w/api.php?action=clientlogin&format=json&lgname=xxxx&lgtoken=xxxx%2B%5C
and the POST BODY was
{
"lgpassword" : "xxxxx",
"lgtoken" : "xxxxx"
}
But I get an error:
{
"error": {
"code": "notoken",
"info": "The \"token\" parameter must be set."
},
"servedby": "mw1228"
}
If I try to change lgtoken to token I get the same result.
2.2) I have then tried the old method i.e. action=login and passing the body, but it does not work, since it gives me back another login token: HTTP POST https://en.wikipedia.org/w/api.php?action=login&format=json&lgname=xxxx
and the same POST BODY
I then get
{
"warnings": {}
},
"login": {
"result": "NeedToken",
"token": "xxxxx+\\"
}
where the docs here states that
NeedToken if the lgtoken parameter was not provided or no session was active (e.g. your cookie handling is broken).
but I have passed the lgtoken in the json body as showed.
I'm using Node.js and the built-in http module, that is supposed to pass and keep session Cookies in the right way (with other api it works ok).
I have found a similar issue on a the LrMediaWiki client here.
[UPDATE]
This is my current implementation:
Wikipedia.prototype.loginUser = function (username, password) {
var self = this;
return new Promise((resolve, reject) => {
var cookies = self.cookies({});
var headers = {
'Cookie': cookies.join(';'),
'Accept': '*/*',
'User-Agent': self.browser.userAgent()
};
// fetch login token
self.api.RequestGetP('/w/api.php', headers, {
action: 'query',
meta: 'tokens',
type: 'login',
format: 'json'
})
.then(response => { // success
if (response.query && response.query.tokens && response.query.tokens['logintoken']) {
self.login.logintoken = response.query.tokens['logintoken'];
self.logger.info("Wikipedia.login token:%s", self.login);
return self.api.RequestPostP('/w/api.php', headers, {
action: 'login',
format: 'json',
lgname: username
},
{
lgpassword: password,
lgtoken: self.login.logintoken
});
} else {
var error = new Error('no logintoken');
return reject(error);
}
})
.then(response => { // success
return resolve(response);
})
.catch(error => { // error
self.logger.error("Wikipedia.login error%s\n%#", error.message, error.stack);
return reject(error);
});
});
}//loginUser
where this.api is a simple wrapper of the Node.js http, the source code is available here and the api signatures are like:
Promise:API.RequestGetP(url,headers,querystring)
Promise:API.RequestPostP(url,headers,querystring,body)
If the currently accepted answer isn't working for someone, the following method will definitely work. I've used the axios library to send requests. Any library can be used but the key lies in formatting the body and headers correctly.
let url = "https://test.wikipedia.org/w/api.php";
let params = {
action: "query",
meta: "tokens",
type: "login",
format: "json"
};
axios.get(url, { params: params }).then(resp => {
let loginToken = resp.data.query.tokens.logintoken
let cookie = resp.headers["set-cookie"].join(';');
let body = {
action: 'login',
lgname: 'user_name',
lgpassword: 'password',
lgtoken: loginToken,
format: 'json'
}
let bodyData = new URLSearchParams(body).toString();
axios.post(url, bodyData, {
headers: {
Cookie: cookie,
}
}).then(resp => {
// You're now logged in!
// You'll have to add the following cookie in the headers again for any further requests that you might make
let cookie = resp.headers["set-cookie"].join(';')
console.log(resp.data)
})
})
And you should be seeing a response like
{
login: { result: 'Success', lguserid: 0000000, lgusername: 'Username' }
}
The second post request was where I got stuck for several hours, trying to figure out what was wrong. You need to send the data in an encoded form by using an API like URLSearchParams, or by just typing up the body as a string manually yourself.
I think from what you are saying you have lgtoken and lgname in the URL you are using, and then lgpassword and lgtoken (again!) in a JSON-encoded POST body.
This is not how the Mediawiki API works.
You submit it all as POST parameters. JSON is never involved, except when you ask for the result to come back in that format. I can't help you fix your code as you don't provide it, but that's what you need to do. (If you edit your question with your code, I'll do my best to help you.)
After seeing your code, I'll presume (without knowing the detail of your code) that you want something like this:
return self.api.RequestPostP('/w/api.php', headers, {
action: 'login',
format: 'json',
lgname: username,
lgpassword: password,
lgtoken: self.login.logintoken
});
i am trying to send four points of data to a spread sheet from a website i am developing. name, email, subject, message.
function loadClient() {
gapi.client.setApiKey(myapikey);
return gapi.client.load("https://content.googleapis.com/discovery/v1/apis/sheets/v4/rest")
.then(function() {
console.log("GAPI client loaded for API");
}, function(error) {
console.error("Error loading GAPI client for API");
});
}
// Make sure the client is loaded before calling this method.
function execute() {
return gapi.client.sheets.spreadsheets.values.append({
"spreadsheetId": mysheetid,
"range": "a1",
"includeValuesInResponse": "false",
"insertDataOption": "INSERT_ROWS",
"responseDateTimeRenderOption": "SERIAL_NUMBER",
"responseValueRenderOption": "FORMATTED_VALUE",
"valueInputOption": "RAW",
"resource": {
"values": [
[
"test#text.com",
"jimmy clarke",
"subject",
"this is a test email"
]
]
}
})
.then(function(response) {
// Handle the results here (response.result has the parsed body).
console.log("Response", response);
}, function(error) {
console.error("Execute error", error);
});
}
gapi.load("client");
</script>
i expected it to send the data to the google sheet without error.
it tells me that this can only be sent using oauth.
i would prefer not to use oauth. my main pain point is that when i look at the (google made) templates it allows for the use of the api key, though when i run the code i recieve and i receive this error
Object {
result: {…},
body: "{\n \"error\":
{\n \"code\": 401,\n \"message\": \"Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.\",\n \"status\": "UNAUTHENTICATED\"\n }\n}\n", headers: {…}, status: 401, statusText: "Unauthorized" }
Could i have made a mistake in setting it up?
May have found the answer i believe it is due to the fact that i left the
spread sheet as private, which would require the use of the oauth.
The user will click on a button that will invoke the Parse Cloud function sendText()
I've tried both Live Twilio and Testing Twilio accSID and authToken
I first initialize my Twilio by:
var Twilio = require('twilio');
Twilio.initialize('accountSid', 'authToken'); //put in my corresponding <<
then I set the Parse function by:
Parse.Cloud.define('sendText', function(request, response) {
Twilio.sendSMS({
From: '+1234567890', //From Number
To: "+0987654321", //To Number
Body: "Start using Parse and Twilio!" //Message <<
}, {
success: function(httpResponse) { response.success("SMS sent!"); },
error: function(httpResponse) { response.error("Uh oh, something went wrong"); }
});
}
It would be great to have someone tell me if something here is wrong or if there are other approaches in sending SMS through Twilio via Parse Cloud.
On the SMS Summary on Twilio, it does not even know any SMS being sent out.
Going on...
The button that calls this cloud function is:
<button type="button" class="page-scroll btn btn-xl" onclick="saveData()">CONFIRM</button>
and the js function that is called saveData() is:
function saveData() {
booking.save({
something: something,
}, {
success: function (booking) {
window.location.href = 'final.php';
Parse.Cloud.run('sendText',
{
something: something
});
},
error: function (booking, error) {
alert('Failed to save');
}
});
}
NO ERROR LOG
Twilio developer evangelist here.
You seem to be using an old Parse module which is no longer supported by us. The new module however uses a newer version of our Node module.
Some documentation for it can be found here
It also has some sample code to do what you're trying to do.
// Require and initialize the Twilio module with your credentials
var client = require('twilio')('ACCOUNT_SID', 'AUTH_TOKEN');
// Send an SMS message
client.sendSms({
to:'+0987654321',
from: '+1234567890',
body: 'Hello world!'
}, function(err, responseData) {
if (err) {
console.log(err);
} else {
console.log(responseData.from);
console.log(responseData.body);
}
}
);
I think you will find your SMS will be sent using this version of the code. Notice how the initialization is different.
I have a simple facebook app, when I click a button with javascript function, I show me Post was successful! Action ID: 685335521499641, but not appear on the timeline. Also, when I go to Open Graph -> Stories for check, my meta tags is not functioning right, only the image if I change it. I get the POST code from Get Code with some change on it.
I read many comments, but nothing for my issue. So how can I make it right ?
The function is:
FB.api('/me/the_name:action_type', 'post', {
photo: "http://samples.ogp.me/XXXXXXXXXXXXXXXX",
image: "http://path_to_my_image.jpg",
title: "The sample photo",
description: "Just for test !!!",
},
function(response) {
var msg = 'Error occured';
if (!response || response.error) {
if (response.error) {
console.log(response.error);
msg += "\n\nType: "+response.error.type+"\n\nMessage:"+response.error.message;
}
alert(msg);
}
else {
alert('Post was successful! Action ID: ' + response.id);
}
}
);
The case may be that, you have not submitted the actions for the approval yet.
But you can check the story in the Activity log in your timeline. Or, directly with this url: https://www.facebook.com/me/activity/RESPONSE_ID
Once approved, the stories will appear in the news feed.
If someone have the same issue like mine, think I success, it's work for me for now.
So first generate new own object with https://developers.facebook.com/tools/object-browser , with correct App: and Object Owner:, mine was http://samples.ogp.me/XXXXXXXXXXXXXXXX (from Get Code). In there put only the URL (may be and title), where the meta tags are, it will get the meta tags for this URL.
So it will be 1st version.
FB.api('/me/the_name:action_type',
'post',
{
photo: "http://The_URL_with meta_tags",
image: "http://path_to_my_image.jpg",
title: "The simple photo",
description: "Just for test !!!",
},
function(response) {
... see above ...
}
});
2nd version: Allow the User Messages and User Generated Photos if will want big image and comment.
FB.api('/me/the_name:action_type?image[0][url]=http://path_to_my_image.jpg&image[0][user_generated]=true',
'post',
{
photo: "http://The_URL_with meta_tags",
message: "a simple message will appear above the image" ,
},
function(response) {
... see above ...
}
});
I don't know this is the right way, but hope to help if someone have the same issue, it will be for a guide. (if is OK go for submit in Review Status)