I am working with Outlook Webhook Subscriptions and working on QA server.
According to the Microsoft Graph documentation, we need to send the request to get the webhook notification. I am using Python 3 request module for this.
I am sending the following data but getting the error. I can't figure out where I am going wrong in the process.
url="https://graph.microsoft.com/v1.0/subscriptions"
header={
'Content-Type': 'application/json',
'Authorization':"Bearer "+ "valid access token"
}
data={
"changeType": "created,updated",
"notificationUrl": "https://qa.example.com/get_webhook",
"resource": "/me/mailfolders('inbox')/messages",
"expirationDateTime": "2018-12-11T11:00:00.0000000Z"
}
response=requests.post(url, headers=header, data=data)
After executing the above lines I am getting the following <400> response
'{\r\n "error": {\r\n "code": "BadRequest",\r\n "message":
"Unable to read JSON request payload. Please ensure Content-Type
header is set and payload is of valid JSON format.",\r\n
"innerError": {\r\n "request-id": "3a15ba2f-a055-4f33-a3f8-
f1f40cdb2d64",\r\n "date": "2018-12-10T06:51:32"\r\n }\r\n
}\r\n}'
To post as JSON, you need to json property rather than the data property (i.e. json={"key": "value"}:
url="https://graph.microsoft.com/v1.0/subscriptions"
header={
'Content-Type': 'application/json',
'Authorization':"Bearer "+ "valid access token"
}
data={
"changeType": "created,updated",
"notificationUrl": "https://qa.example.com/get_webhook",
"resource": "/me/mailfolders('inbox')/messages",
"expirationDateTime": "2018-12-11T11:00:00.0000000Z"
}
response=requests.post(url, headers=header, json=data)
You can use:
import json
response=requests.post(url, headers=header, data=json.dumps(data))
I am getting Http 500 error whenever i am calling the QnAMaker Api with Metadata(strictFilter) body. Am I not following any instruction before calling Apis?
QnA maker api is working perfectly if I am not adding strictFilter in the Api request body.
api request details:
URL: https://qnamaker endpoint/qnamaker/knowledgebases/KBID/generateAnswer
Method: POST
content-type: application/json
Authorization: EndpointKey Key
Body:
{
"question": "hi",
"top": 3,
"strictFilters": [
{
"name": "category",
"value": "pears"
}
]
}
I have even read the Microsoft documentation
Still no luck for me here.
QnaMaker Response Error with StrictFilter screenshot
I am trying to import vapid push subscriptions into firebase. I found some solution in https://developers.google.com/instance-id/reference/server#import_push_subscriptions. It thew following error. Please help me regarding this.
POST : https://iid.googleapis.com/v1/web/iid
Headers :
Content-Type:application/json
Authorization:key=MY_SERVER_KEY
BODY:
{
"endpoint" : "https://fcm.googleapis.com/fcm/send/my_sub_key",
"keys" : {
"p256dh" : "hidden_key",
"auth" : "hidden_auth"
}
}
}
Response:
"error": { "code": 401, "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.", "status": "UNAUTHENTICATED" }
I post this request:
POST https://login.microsoftonline.com:443/{my-tennant-here}/oauth2/v2.0/token HTTP/1.1
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded
client_id={client id here}
&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default
&client_secret={client secret here}
&grant_type=client_credentials
This returns:
{
"token_type": "Bearer",
"expires_in": 3599,
"ext_expires_in": 0,
"access_token": "eyJ0eX......
}
I have decoded the token using jwt.io and it definitely is not empty. It contains 14 claims. aud, iss, tid etc...
I then use the access token in this request
GET https://graph.microsoft.com/v1.0/users
Athorization: Bearer eyJ0eX...
I then get a 401 Unauthorized with this body:
{
"error": {
"code": "InvalidAuthenticationToken",
"message": "Access token is empty.",
"innerError": {
"request-id": "",
"date": "2018-08-14T15:41:44"
}
}
}
Expected result was a 200 Ok with a body containing a list of users
Does this simply mean that my app is Unauthorized, and the error message is just misleading (access token is empty)?
Or have I done something wrong?
Update:
I have noted that the although the token does contain claims it does not have a scope claim which seems a bit weird to me. I would assume that it had the User.Read.All scope. The application (client id/client secret) should have this permission.
The claims in the token I receive have the following claims:
aud: "https://graph.microsoft.com",
iss: "https://sts.windows.net/my tennant id",
iat: timestamp
nbf: timestamp
exp: timestamp
aio: looks like some kind of signature
app_displayname: "the expected app name"
appid: "the expected appid"
appidacr: "1"
idp: "https://sts.windows.net/...."
oid: "GUID"
sub: "GUID"
tid: "my tennant id"
uti: "value"
ver: 1.0
The Authorization header was misspelled.
So "Access token is empty" probably actually meant not present or even "No authorization header in request".
For me, my issue was that I had put a linebreak between the request url and the Authorization header, making it the body instead.
Wrong:
GET https://graph.microsoft.com/v1.0/users
Authorization: Bearer {{token}}
Correct:
GET https://graph.microsoft.com/v1.0/users
Authorization: Bearer {{token}}
A stupid mistake, but easy to overlook - if you get to this post you have probably done a silly mistake like OP (typo) or this. Look through your request syntax again!
One URL works while the other doesn't.
This works:
endpoint = "https://graph.microsoft.com/v1.0/reports/getOffice365ActiveUserDetail%28period%3D%27D7%27%29"
headers = {"Authorization": 'Bearer ' + access_token_gmc}
response = requests.get(endpoint, headers=headers)
But this one doesn't:
endpoint = "https://graph.microsoft.com/v1.0//users/myuserid/calendars"
headers = {"Authorization": 'Bearer ' + access_token_gmc}
response = requests.get(endpoint, headers=headers)
Please make sure the spellings are correct.
I was getting the same error in my angular application where I use MSAL.
And it was all because of the wrong API scope provided in the MSALAngularConfigFactory. I was having the environment as preceding.
export const environment = {
production: false,
clientId: 'clientid',
redirectUrl: 'http://localhost:4200',
graphApiUrl: 'https://graph.microsoft.com/v1.0',
graphGetUserImage: '/me/photo/$value',
protectedResourceMap: [
['http://localhost:65498/api', ['api.access']],
['https://graph.microsoft.com/beta', ['user.read']]
] as [string, string[]][],
authority: 'https://login.microsoftonline.com/organizations'
};
As you can see that I have given https://graph.microsoft.com/beta in the protectedResourceMap, which is wrong. Instead, we should give https://graph.microsoft.com/v1.0/. So here is the correct environment.
export const environment = {
production: false,
clientId: 'clientid',
redirectUrl: 'http://localhost:4200',
graphApiUrl: 'https://graph.microsoft.com/v1.0',
graphGetUserImage: '/me/photo/$value',
protectedResourceMap: [
['http://localhost:65498/api', ['api.access']],
['https://graph.microsoft.com/v1.0/', ['user.read']]
] as [string, string[]][],
authority: 'https://login.microsoftonline.com/organizations'
};
And I use it in the app.module.ts as below.
function MSALAngularConfigFactory(): MsalAngularConfiguration {
return {
popUp: false,
protectedResourceMap: environment.protectedResourceMap,
};
}
For User.Read.All scope you can't have a user consent. It must be admin consent. It looks like you may have missed consenting your app using an admin account.
To do this hit:
GET https://login.microsoftonline.com/{tenant}/adminconsent
?client_id=6731de76-14a6-49ae-97bc-6eba6914391e
&state=12345
&redirect_uri=http://localhost/myapp/permissions
Then get an access token and you should get the scopes the admin has consented users for.
I'm trying to create a subscription to receive notification about changes to Office365 Calendar. I have already worked with Outlook Notitication API but having a problem with Microsoft Grap API
I try to create a subscription using Http Post to https://graph.microsoft.com/beta/subscriptions with header and body:
Header: Content-Type: application/json; Authorization : Bearer {accessToke}
Body:
{
"resource": "me/calendars",
"notificationUrl": "sample notification url",
"changeType": "Created",
}
In my notification url, i've setup to send a response with the value of validation token when receveving a validation request
Finally, the result i received:
{
"error": {
"code": "ExtensionError",
"message": "There was an error processing a storage extension.",
"innerError": {
"request-id": "6c563931-511d-415d-9c04-c07f25d45b1f",
"date": "2016-03-20T08:10:32"
}
}
}
I wonder what I'm doing wrong or that's a internal error of MS Grap API. Can anyone help me? Thank in advance
The correct resource to use for calendar events is "me/events". We'll try to get a better error message in future.