I'm sending an event request to Google Analytics server-side using a POST request to https://www.google-analytics.com/collect from Python/Flask (via the requests library). I'm testing it by looking at the real-time events page.
If I try my request on the GA Hit Builder, it works perfectly.
If I paste the request directly into my browser with the URL parameters, it works perfectly.
If I post from my app, I get a status 200, suggesting it has worked, but nothing appears in the live events view.
If I post from my app to /debug/collect I get this response, which looks OK to me, but nothing in the live events view:
{
"hitParsingResult": [ {
"valid": true,
"parserMessage": [ ],
"hit": "/debug/collect?v=1\u0026tid=UA-18542058-16\u0026cid=ax5b51b5beaa4f0\u0026t=event\u0026ec=Tasks\u0026ea=View task\u0026el=25\u0026ev=0"
} ],
"parserMessage": [ {
"messageType": "INFO",
"description": "Found 1 hit in the request."
} ]
}
The request is: https://www.google-analytics.com/debug/collect
v=1&tid=UA-18542058-16&cid=ax5b51b5beaa4f0&t=event&ec=Tasks&ea=View+task&el=25&ev=0.
I cannot figure out what I'm doing wrong here. Any ideas?
Try to specify dl (document location URL) parameter in the hit or both dh (document host name) and dp (document path) parameters:
https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters?hl=it#dl
Alternative disable any filter in the view and the tick to exclude bots.
Related
I have an issue related to access_token which I've received from a React Native app. The React Native app uses the expo-facebook library and when the pop-up of authentication disappears the token is created and sent to the backend API. The token is created by logInWithReadPermissionsAsync method.
const { type, token, expirationDate, permissions, declinedPermissions, graphDomain } =
await Facebook.logInWithReadPermissionsAsync({
permissions: ["public_profile", "email"],
});
I see that the server received this token on http://localhost:8000/api/rest-auth/facebook/ endpoint and sends it to the Facebook endpoint verify. The problem occurs on the response from Facebook. I expect that it should be valid by Facebook, but it seems that something went wrong.
HTTP 400 Bad Request
Allow: POST, OPTIONS
Content-Type: application/json
Vary: Accept
{
"non_field_errors": [
"Incorrect value."
],
"code": 400,
"message": "Bad Request"
}
An access token that I generate in Graph API Explorer is shorter (when I use it, it works in the backend app) than the token which is generated in the React Native expo app. Why are these two tokens different? And why doesn't it work as I am expecting?
I discovered where the issue was. I knew that the issue is was in the token, a good direction was a response from Facebook.
{"error":{"message":"Invalid appsecret_proof provided in the API argument","type":"GraphMethodException","code":100}}.
After that, I realized that probably something is wrong with React Native Expo. Expo-facebook doesn't react when you even pass the app id, it used the wrong APP ID which was defined in the expo environment(APP_ID=1696089354000816). App-id was set in settings and also in the
await Facebook.initializeAsync({
appId: '<APP_ID>',
});".
So the main issue was that I relied on an access_token that didn't belong to my app.
I am trying to build a very light weight static website with a form using a serverless architecture:
User populates the form with login info
Submit action routes to AWS API Gateway which then triggers AWS Lambda Python function which logs the user in to 3rd party site, gets some data and saves it to s3
Once the data is saved, I would like to provide a download button for the data back to the user at the client
I've tried to do this using a 302 redirect in API Gateway both with and without lambda proxy integration so that I could redirect the user to a different webpage that pulls their data from s3.
Using proxy integration I get an Internal Server Error every time.
Without it I just get the json response back to the user instead of an actual redirect.
Here is the python code for the response in my lambda function (this json is what comes back to the user currently instead of taking them to the url https://example.com):
return {
"isBase64Encoded": False,
"statusCode": 302,
"headers": {
"Location": "https://example.com"
},
"multiValueHeaders": {},
"body": "Success!!!"
}
I added the "Location" header to the Method Response in API Gateway and mapped it to integration.response.headers.location in the Integration Response (when I tried without lambda proxy).
No success with any of this though.
With proxy its an internal server error that only happens from the html form (doesn't happen when testing in api gateway console or lambda console), and without proxy it doesn't redirect to the value in the Location header, just prints the json to the url of the api.
Any help, guidance or suggestions is much appreciated!
Thanks for your time.
Sharing how I figured this out in case someone else ever runs into a similar issue.
I was getting an Internal Server error when using Lambda Proxy Integration because of the way I was parsing my event variable from API Gateway.
Assuming your API Gateway is configured to Lambda Proxy Integration and that your Lambda function is written in python, the below code should result in a successful 302 Redirect when triggered from a static s3 http form:
import urllib.parse
from furl import furl
def lambda_handler(event, context):
body = urllib.parse.unquote(event["body"])
furledBody = furl("/abc?" + body)
parameter1 = furledBody.args["parameter1"]
parameter2 = furledBody.args["parameter2"]
parameter3 = furledBody.args["parameter3"]
#Do stuff with body parameters
return {
"isBase64Encoded": False,
"statusCode": 302,
"headers": {
"Location": "https://example.com"
}
"multiValueHeaders": {},
"body": ""
}
This however is not the design I went with for my use case of providing the data my lambda function downloaded back to the client for the user to download.
Instead I configured my lambda response to contain html that automatically rendered at the client as a response to the http form request. Within the html I include S3 pre-signed URLs that were generated earlier in the lambda:
import boto3
s3 = boto3.client('s3')
presignedURL = s3.generate_presigned_url('get_object',{'Bucket': '[insert bucket name]', 'Key': '[insert key aka file name including the full path]'}, 500, 'GET'}
responseBody = (
"<html>"
"<head></head>"
"<body>"
"<a href=\"" + presignedURL + "\"download><button>Download</button></a>"
"</body>"
"</html>")
return {
"isBase64Encoded": False,
"statusCode": 200,
"headers": {
"Content-Type": "text/html"
}
"multiValueHeaders": {},
"body": responseBody
}
I am writing a Python script to edit an Excel spreadsheet that lives in SharePoint. We have Office 365 for Business. I am using Microsoft Graph API.
I registered the Python app with Microsoft Azure Active Directory (AD) and added the following 2 (app-only) permissions for Graph API: (1) Read and write files in all site collections (preview) and (2) Read directory data. (I had our company administrator register the app for me.)
My Python script uses the requests library to send REST requests:
import json
import requests
MSGRAPH_URI = 'https://graph.microsoft.com'
VERSION = 'v1.0'
def requestAccessToken(tenant_id, app_id, app_key):
MSLOGIN_URI = 'https://login.microsoftonline.com'
ACCESS_TOKEN_PATH = 'oauth2/token'
GRANT_TYPE = 'client_credentials'
endpoint = '{0}/{1}/{2}'.format(MSLOGIN_URI, tenant_id, ACCESS_TOKEN_PATH)
headers = {'Content-Type': 'Application/Json'}
data = {
'grant_type': GRANT_TYPE,
'client_id': app_id,
'client_secret': app_key,
'resource': MSGRAPH_URI
}
access_token = response.json()['access_token']
return access_token
def getWorkbookID(access_token, fileName):
endpoint = '{0}/{1}/me/drive/root/children'.format(MSGRAPH_URI, VERSION)
headers = {
'Content-Type': 'Application/Json',
'Authorization': 'Bearer {}'.format(access_token)
}
response = requests.get(endpoint, headers=headers)
print response.text
assert response.status_code == 200
items = response.json()['value']
workbook_id = None
for item in items:
if item['name'] == fileName:
workbook_id = item['id']
return workbook_id
access_token = requestAccessToken(TENANT_ID, APP_ID, APP_KEY)
workbook_id = getWorkbookID(access_token, WORKBOOK_FILENAME)
The Python app successfully requests and receives an access_token from the Microsoft server. The access token starts like this
eyJ0eXAiOiJKV1QiLCJub25jZSI6...
Then it requests a list of my files in getWorkbookID():
GET https://graph.microsoft.com/v1.0/me/drive/root/children
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJub25jZSI6...
This is the response to that REST request:
{
"error": {
"code": "InternalServerError",
"message": "Object reference not set to an instance of an object.",
"innerError": {
"request-id": "aa97a822-7ac5-4986-8ac0-9852146e149a",
"date": "2016-12-26T22:13:54"
}
}
}
Note that I successfully get a list of my files when I request it via Graph Explorer (https://graph.microsoft.io/en-us/graph-explorer).
EDIT:
Changed the title from "Microsoft Graph API Returns Object reference not set to an instance of an object" to "Azure AD "scope" Missing from Access Token Response".
Changed the "me" in the uri of the GET request to "myOrganization", after reading this: graph.microsft.io/en-us/docs/overview/call_api
That is,
GET https://graph.microsoft.com/v1.0/myOrganization/drive/root/children
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJub25jZSI6...
Now get the following response.
{
"error": {
"code": "AccessDenied",
"message": "Either scp or roles claim need to be present in the token.",
"innerError": {
"request-id": "bddb8c51-535f-456b-b43e-5cfdf32bd8a5",
"date": "2016-12-28T22:39:25"
}
}
}
Looking at an example in graph.microsoft.io/en-us/docs/authorization/app_authorization, I see that the access token response body contains a "scope" property that lists the permissions granted for the app during the app's registration. However, the access token response I receive from the server does not have the "scope" property. Here is what my access token response looks like.
{
"token_type":"Bearer",
"expires_in":"3599",
"ext_expires_in":"0",
"expires_on":"1482968367",
"not_before":"1482964467",
"resource":"https://graph.microsoft.com",
"access_token":"eyJ0eXAiOiJKV..."
}
Questions:
I had the administrator register the app in Azure AD and check the boxes for the Microsoft Graph API application permissions needed. Apparently that is not enough. What else is needed? Why are the permissions not in the access token response body?
What is the correct URI for the GET request? Is "MyOrganization" the correct value in the URI?
Thanks all for your responses. After more research, I found the answer to my question.
The original problem: "Microsoft Graph API Returns Object reference not set to an instance of an object"
The request
GET https://graph.microsoft.com/v1.0/me/drive/root/children
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJub25jZSI6...
gets the response
{
"error": {
"code": "InternalServerError",
"message": "Object reference not set to an instance of an object.",
"innerError": {
"request-id": "aa97a822-7ac5-4986-8ac0-9852146e149a",
"date": "2016-12-26T22:13:54"
}
}
}
As #SriramDhanasekaran-MSFT noted, /me refers to the currently signed-in user. In our case, we do not have a signed-in user, so we cannot use /me. Instead, we can either use /myOrganization or nothing, it is optional.
The updated problem: "Azure AD "scope" Property Missing from Access Token Response"
The updated (replaces /me with /myOrganization) request
GET https://graph.microsoft.com/v1.0/myOrganization/drive/root/children
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJub25jZSI6...
gets the response
{
"error": {
"code": "AccessDenied",
"message": "Either scp or roles claim need to be present in the token.",
"innerError": {
"request-id": "bddb8c51-535f-456b-b43e-5cfdf32bd8a5",
"date": "2016-12-28T22:39:25"
}
}
}
As #SriramDhanasekaran-MSFT and #DanKershaw-MSFT mentioned, the reason why the access_token response was missing the scope property is that the permissions had not been "granted" in Azure AD by the administrator.
However, the solution that #SriramDhanasekaran-MSFT provided:
https://login.microsoftonline.com/common/oauth2/authorize?client_id=&response_type=code&redirect_uri=http://localhost&resource=https://graph.microsoft.com&prompt=consent
doesn't help me because my app doesn't have a redirect uri. The solution to granting the permissions is simpler than that: simply have the administrator login in to Azure AD and click the "Grant Permissions" link to grant the permissions.
Additionally, /myOrganization/driver/root/children lists the contents of the administrator's drive. As #PeterPan-MSFT noted, to list a different user's drive, replace /myOrganization with /users/<user-id>.
Success:
My application can now edit my Excel spreadsheets online, without the intervention of a human user. Contrary to what #PeterPan-MSFT stated, this is possible with Graph API and there is no need to download the Excel spreadsheet and edit offline.
Summary:
There were two problems: (1) using /me and (2) the application permissions had not been granted in Azure AD by the administrator.
Since client_credential token flow is being used (i.e., there is no authenticated user context), any request with /me is not valid as /me refers to current signed-in user. Please try with delegated token if you to access files in user's drive.
To access root drive in Sharepoint, request url is /drive/root/children (myorganization is optional).
With regards to missing claims, admin has to consent the app. You can force consent by asking the admin to access the below url (replace with that of your app's)
https://login.microsoftonline.com/common/oauth2/authorize?client_id=&response_type=code&redirect_uri=http://localhost&resource=https://graph.microsoft.com&prompt=consent
As #juunas said, the first error information below should be the NULL exception in .NET which be caused at the server end, but also not an API bug or a permission issue.
error": {
"code": "InternalServerError",
"message": "Object reference not set to an instance of an object.",
You can refer to the SO thread to know this case which seems to update for backend, please try again later.
To explain for the second error when you changed the option me to myOrganization in the Graph API url, as #SriramDhanasekaran-MSFT, it's accessing files for the current user or a specified user with <user-id> instead of me.
However, based on my understanding, you want to edit an Excel spreadsheet lived in SharePoint for your orgnization, it seems to be not suitable via using Graph APIs. Per my experience, it should be done via using the APIs of OneDrive for Business to copy the Excel file to local to edit & upload to overwrite it, please refer to the dev documents for OneDrive and try to use the API for drive resource.
Hope it helps.
I am trying to develop a app which will post on user's Facebook page.
Steps I followed are:
1.Created a fb App, with permission : manage_pages and publish_actions
2.Redirected user to 'https://www.facebook.com/dialog/oauth
With parameters:
client_id=FACEBOOK_APP_ID
redirect_uri=FACEBOOK_REDIRECT_URL
scope=manage_pages,publish_actions
Where user allowed app against each permissions
3.On call back url (FACEBOOK_REDIRECT_URL), cought CODE sent by facebook api
4.Now I sent get request to url = https://graph.facebook.com/oauth/access_token with parameters:
'client_id':FACEBOOK_APP_ID
'redirect_uri':FACEBOOK_REDIRECT_URL
'client_secret':FACEBOOK_SECRET_KEY,
'code':CODE
from respose sent by facebook, I filtered TOKEN
5.sent get request to url = https://graph.facebook.com/me/accounts. with parameters:
'access_token':TOKEN
from response I received, I saved page id as PAGE_ID, page_token as PAGE_TOKEN
6.I tried to post something on user's facebook page, I sent post request to url = https://graph.facebook.com/PAGE_ID/feed , with parameters:
'access_token':TOKEN'
'message': MESSAGE_TEXT,
Snap! in response I received:
{
"error": {
"message": "(#200) The user hasn't authorized the application to perform this action",
"type": "OAuthException",
"code": 200
}
}
I couldn't figure out What mistake I am committing, Do I need to get my app reviewed before posting ? If yes, How can I test my app?
I also tried this by creating a test user. I got the same error.
Thanks to #dhana,
In order to Post on a facebook page, App need manage_pages and publish_action app centre permission, and manage_pages , publish_action and status_update scope while requesting
url = https://www.facebook.com/dialog/oauth?\
client_id='+FACEBOOK_APP_ID+'&\
redirect_uri=' +FACEBOOK_REDIRECT_URL+'&\
scope=manage_pages,publish_actions,status_update
I'm trying to make my first facebook tab app with django.
I did some resarch and found out that fandjago is the best.
So I'm using it , but when I try to require users to authorize I use the decorator
facebook_authorization_required
see : https://fandjango.readthedocs.org/en/latest/usage/authorization.html
I get the following error :
{
"error": {
"message": "Invalid redirect_uri: Given URL is not allowed by the Application configuration.",
"type": "OAuthException",
"code": 191
}
}
with this url:
https://graph.facebook.com/oauth/authorize?scope=publish_stream%2C+publish_actions%2C+user_photos&redirect_uri=https%3A%2F%2Fwww.facebook.com%2Fpages%2FWissals-testing%2F368147096656989%3Fid%3D368147096656989%26sk%3Dapp_269443246412431&client_id=269443246412431
This is my redirect uri :
facebook_redirect_uri = "https://www.facebook.com/pages/mypage-testing/36814709662989?id=36814709686989&sk=app_26944328962431"
Please tell me what I am doing wrong, I searched all topics related to th eissu but couldn't figure it out
EDITED
It worked,I had to add my url in my app configuration "Valid OAuth redirect URIs"
But the problem now is that it gets me out of my app to that url, although I need it to stay on the app!!
I'm taking a guess here,
you might need to set FANDJANGO_AUTHORIZATION_DENIED_VIEW to fully contain your canvas url
I finlly solved it
I had to add the same url of my facebook_redirect_uri to my app settings in facebook, advanced tab, field named : Valid OAuth redirect URIs
The URL to redirect to after the user clicks a button in the dialog. The URL you specify must be a URL of with the same Base Domain as specified in your app's settings,
A Canvas URL of the form
https://apps.facebook.com/YOUR_APP_NAMESPACE
or a Page Tab URL of the form
https://www.facebook.com/PAGE_USERNAME/app_YOUR_APP_ID