Open Graph Action POST fails when called thru a google app engine based unpaid instance - google-app-engine

urlopen fails with a 500 code and '{"error_code":1,"error_msg":"An unknown error occurred"}' error from Facebook when posting an Open Graph Action. I can get the code to work with other posts (e.g. posting a comment on a status using the graph API works fine). I can also get this action-post to work using curl. So this seems like a urllib2.urlopen issue when posting a form-data with a URL as one of the values.
Graph api post that works with curl :
curl -F 'access_token=nnnnnn' -F 'object=https://abc.com/123' \
'https://graph.facebook.com/me/namespace:action' -k
Same Graph api post thru urllib2 which gives the error :
from urllib2 import urlopen, Request, URLError
request = Request (url='http://graph.facebook.com/me/namespace:action';,
data = urllib.urlencode(
{'object':'https://abc.com/123',
'access_token':'nnnnnnnn'
},
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
)
response = urlopen (request)
What could I be doing wrong ? (I am new to urllib2.urlopen. Btw, I originally tried urlfetch.fetch thru the urlfetch python module. That did not work either). I am using this thru goole app engine.

After a fair amount of digging/trial-error, finally managed to solve this.
This is not an issue with urllib urlopen, but more of a Google App Engine nuance where when an action post on an open Graph URL is called - it causes Facebook to trigger a 'get' on the Object URL (synchronously).
So essentially the get is being called on app engine app while an active instance is already calling the FB graph URL. I am currently using an unpaid instance and this is causing an unexpected behavior such that FB to fails the OG post (I see the get on the logs going thru successfully, while the active post, so not sure what causes FB to fail - anybody with an insight, please share).
I got around this by 'taskqueue'ing urlopen/OG-action-post - and when this is called the second time (FB apparently caches the object the first time) it succeeds.
If anybody needs more details, get in touch and am more than happy to save you all the time and pain that I have already gone thru..

Related

Modify HTTP Method for Request in Browser

i am Learning Python and at the moment i am experimenting with the request Module.
What i did so far:
This is the API Documentation for the Endpoint i used:
https://trackapi.nutritionix.com/docs/#/default/post_v2_natural_exercise
And this is the associated Python Code:
EXERCISES_ENDPOINT = "https://trackapi.nutritionix.com/v2/natural/exercise"
header = {
"x-app-id": APP_ID,
"x-app-key": API_KEY
}
body = {
"query": "Ran 2 miles and walked for 3Km."
}
response = requests.post(url=EXERCISES_ENDPOINT, headers=header, json=body)
The corresponding http Request URL should be:
https://trackapi.nutritionix.com/v2/natural/exercise?Ran%202%20miles%20and%20walked%20%20for%203Km.
My Problem is as follows:
In Python the code ist working perfectly fine and my response is as expected
If i use Postman, this works fine too, because in both -Python and Postman - i can specify my Request as a POST Method
But if i use the URL in my MS Edge Browser (and Chrome too) i get an Error: Cannot GET /v2/natural/exercise
The Header information are ok, because i told the Browser them per "ModHeader" Extension.
But why is my Browser doing a GET and not a POST and how can i change this with the developemant tools from MS Edge Browser.
Important for my learning is to know why the Browser do a GET??
Is the Browser only able to do GET in generel and the other Methods (POST, PUT, DELETE) are not possible in this way. But that makes no sense for me :)
Thanks a lot in advance
But why is my Browser doing a GET and not a POST
Presumably because you are trying the address into the address bar of the browser.
That is designed to make a GET request because there is nothing in the UI designed to collect any of the data needed to make another request type.
The usual way to make a POST request would be to provide a user interface for it in the form of an HTML <form>.

Microsoft Graph: Getting 400 Bad Request when trying to fetch mailboxSettings

I have followed this tutorial and have implemented Microsoft login via OAuth and Azure. Also, I have fetched data from Microsoft Graph to store in my database.
Here is a code sample to fetch data using Microsoft Graph:
$graph = new Graph();
$graph->setAccessToken($accessToken->getToken());
$user = $graph->createRequest('GET', '/me?$select=id,displayName,givenName,surName,mail,mobilePhone,jobTitle,userPrincipalName')
->setReturnType(Model\User::class)
->execute();
The code works fine and I get my desired data.
However, when I change the url from '/me?$select=id,displayName,givenName,surName,mail,mobilePhone,jobTitle,userPrincipalName' to '/me?$select=id,displayName,givenName,surName,mail,mobilePhone,jobTitle,userPrincipalName,mailboxSettings', I am getting this error:-
Error Code:- 400| Error Message:- Client error: `GET https://graph.microsoft.com/v1.0/me?$select=id,displayName,givenName,surName,mail,mobilePhone,jobTitle,userPrincipalName,mailboxSettings` resulted in a `400 Bad Request` response: { "error": { "code": "AuthenticationError", "message": "Error authenticating with resource", "innerErr (truncated...) | Error Location:- Line No. 113 in file C:\xampp7.2\htdocs\kaec\vendor\guzzlehttp\guzzle\src\Exception\RequestException.php
As you can see, I am getting the 400 Bad Request error only when I am adding 'mailboxSetttings' in the query string of the url.
Why am I getting this error? The tutorial itself has used 'mailboxSetttings' in their sample code?
PS: Two days ago, it worked absolutely fine when I used 'mailboxSetttings' in the query. But today, I am getting 400 - Bad Request.
Check if you have MailboxSettings.Read and MailboxSettings.ReadWrite permissions to be able to read, update, create, and delete your mailbox settings.
I agree with #user2250152 answer, at first I used an access token which doesn't with the scope of MailboxSettings.ReadWrite, and I called the api
'https://graph.microsoft.com/v1.0/me?$select=id,displayName,givenName,surName,mail,mobilePhone,jobTitle,userPrincipalName,mailboxSettings'
it returns 403 error(not the same as yours 400), I checked the api document and found that the 'mailboxSettings' property really exists but even I used beta version of the api I still can't find it in response. So I tried to add api permission when generate the access token, finally it worked for me.
I think you can debug your program to check if the access token you used to call the api has the scope of 'MailboxSettings.ReadWrite', just decode the token and you can see it in the claim "scp", because you said that your programs run absolutely fine before. So maybe you've added more other scopes(not belong to graph) when generate access token.

App Engine different response on browser vs postman

I have a nodejs express server running on app engine.
If i make a GET request to https://astral-pursuit-252600.appspot.com/users in the browser it works fine to say unauthorized (401).
If I do the same GET request in postman it returns 400 bad request.
Is there any obvious reason why this is occurring?
This is a known issue with postman. This tool sends certain headers by default that you cannot remove. App Engine does not like them for some reason. I had to use the Insomnia tool instead which does not include default headers.
The first thing that I can think about is that, in order to do an API call, you need to use an API key in your request. You should create one, after that you need to obtain an access token. Your requests should be send to an address like https://astral-pursuit-252600.appspot.com/users?key=YOUR_API_KEY and include in your request a header to contain the access token. Something like this : --header 'authorization: Bearer YOUR_ACCESS_TOKEN'.
In order to do that I do not think you need to change manually each request, but you need to change some POSTMAN settings. You can find here a guide with exactly what setting should be changed for this use case.
You can see more details about this topic and a more detailed guide for doing an API calls here.
In case this was not the issue, could you please provide me your POSTMAN settings? I am pretty sure this is about the way POSTMAN does the requests anyway.

JIRA Cloud REST API (OAuth 2.0) Error 403 on POST Requests

I am trying to connect my React app to the Jira Cloud API and can't seem to get past a 403 error.
My code currently does a Auth dance using OAuth 2.0 and returns the token and cloudid. I can use this to GET issues, however POST request (like creating an issue) return with 403. I have found here that this error is returned if the user does not have the necessary permission to access the resource or run the method.
I have ensured the user has the correct scope ([write: jira-work, read: jira-work]) and verified this is reflected in the user account (in their account > connect apps tab).
My app is not linked (via ApplicationLink) or installed (via Apps, Manage Apps), is this necessary to perform POST requests?
Here is a sample of my code:
fetch(`https://api.atlassian.com/ex/jira/${jira.cloudid}/rest/api/2/issue/`, {
method: "POST",
headers: {
"Content-Type": 'application/json',
"Authorization": `Bearer ${jira.token}`
},
body: JSON.stringify(data)
})
.then(...)
Neither api version 2 or 3 are working for this POST request. I have explored using Basic Auth however this fails due to CORS errors.
I have verified that the POST request does work in POSTMAN (using the cloudid and token).
---------------------------------------------------------------------------------------------------------------------------
UPDATE
After talking to Atlassian Staff, there is an issue within their API security:
"By trying the same thing you mentioned I think I found what the problem is. Your request likely fails with a ‘XSRF check failed’ in the browser.
I’ve already talked to one of our security engineers and we quickly dived into the implementation code to confirm why this not working and what would need to be changed on our side. We’ve also already opened a engineering ticket to get this addressed. This will likely take a few weeks to get addressed, but I’ll keep you posted if I hear any updates!"
The XSRF check failed was the main error for my 403 response. I'll post any updates I receive and answer the question when a resolution is found.
This has apparently been resolved. Follow the discussion here: https://community.developer.atlassian.com/t/jira-cloud-rest-api-oauth-2-0-error-403-on-post-requests/25621/4

Why is urlfetch throwing Download Errors when calling some Google services?

I've noticed that some Google services are blocking requests from App Engine servers, resulting in a urlfetch DownloadError. An example would be a feedproxy.google.com url (http://feedproxy.google.com/~r/blabbermouth/~3/cAk78LX4gJE/news.aspx, for example).
This occurs on all the apps I've tried it on, including app IDs I've never used for any kind of url fetching before. This behavior also doesn't occur on the local SDK. This leads me to believe that this is a result of using any GAE IP address when making the request.
The weird thing is that it results in the throwing of a DownloadError, instead of an error status_code in the successfully retrieved response. Using urlfetch or httplib locally works just fine, so this DownloadError I don't yet grok, or it's just a bug, in which case I'll file a ticket.
Without having a look at your code I will be guessing but since the URL that you are following is a going to redirect are you allowing redirects in your call? Note the follow_redirects=True
e.g. urlfetch.fetch(url, payload=None, method=GET, headers={}, allow_truncated=False, follow_redirects=True, deadline=None)
http://code.google.com/appengine/docs/python/urlfetch/fetchfunction.html

Resources