I am trying to use Outlook's REST API in my python code to send an email in behalf of a user who already gives me his consent.
I was able to successfully send text emails using their /me/sendmail node with the following payload:
email_payload = {
"Message": {
"Subject": email_subject,
"Body": {
"ContentType": "Text",
"Content": email_body
},
"ToRecipients": [
{
"EmailAddress": {
"Address": to
}
}
]
}
}
However, when trying to add attachments (based on their documentation), I encounter some issues:
email_payload["Message"]["Attachments"] = [
{
"ContentType": "application/pdf",
"Name": "{0}".format("something.pdf"),
"ContentBytes": base64.b64encode(attachment.read())
}
]
Issues consist in 415 response status code with the following content:
{u'error': {u'message': u'A missing or empty content type header was found when trying to read a message. The content type header is required.', u'code': u'RequestBodyRead'}}
Couldn't find anything regarding this in their documentation. Hope somebody can enlighten me :)
For anyone else having such issues, here's the context and fix:
Initially, since I was sending only plain-text emails, my request header looked like this:
request_headers = {
'Authorization': "Bearer {0}".format(token),
}
And the actual request:
api_response = requests.post(
request_url,
json.dumps(body),
headers=request_headers
)
As you might have noticed I wasn't sending any content-type in my headers (not sure why), but everything went well so far up until when I decided to add attachments too.
Seems like if my request_headers would contain Content-Type too, everything would go well:
request_headers = {
'Authorization': 'Bearer {0}'.format(refreshed_token),
'Content-Type': 'application/json'
}
Related
I am attempting to post some data through REST API in Python.
data.json
{
"LastModifiedAt": "2020-12-21T20:19:45.335Z",
...
...
}
I am using following code to POST the data.
with open('data.json') as fh:
data = json.load(fh)
headers = {
'Content-Type': 'application/json',
'X-API-Key':'ABC=='
}
response = requests.post('https://myurl.net/api/v1/resource/int_key/endpoint', headers=headers,data=data)
I always get following as response status_code = 400
{
"ModelState": {
"line": [
"Unexpected character encountered while parsing value: L. Path '', line 0, position 0."
]
},
"Message": "The request is invalid."
}
How do I debug this? My URL is correct according to API documentation. Why does it return "Bad Request" status code?
I replaced data with json and it worked.
response = requests.post('https://myurl.net/api/v1/resource/int_key/endpoint', headers=headers,json=data)
I used Postman as suggested by AndroidDev to debug this.
I'm getting 'InvalidRegistration' error when I try to send a push notification to my Android device.
Header:
headers = {
'Content-Type': 'application/json',
'Authorization': 'key=' + serverToken,
{
Body:
body = {
"to": deviceToken,
"notification": {
"body": "Welcome to blabla",
"title": "Blabla trully loves you, did you know that?",
"priority": "high"
}
Response:
200
{'multicast_id': 6053848281333651847, 'success': 0, 'failure': 1, 'canonical_ids': 0, 'results': [{'error': 'NotRegistered'}]}
The idea is that I'm using Appium method driver.get_clipboard_text() to get a token which is already copied in device clipboard and store it in the following variable:
deviceToken = self.driver.get_clipboard_text()
Which I pass it to my JSON. Also, if I manually store the token in my variable it will successfully work and get the push notification on my device.
I've tried to use several formatting python types by using another variable where i store a previous one where I do call that method I mentioned from Appium, but without success.
Any thoughts?
In the Step Sending an Activity to the bot As per the documentation Here,
https://docs.botframework.com/en-us/restapi/directline3/#navtitle
I should pass this as the body content of the post request
{
"type": "message",
"from": {
"id": "user1"
},
"text": "hello"
}
I am using the following parameters to make POST request in python, but its not working.
msg = {"type": "message","channelId": "directline","conversation":{"id": str(convId)},"from":{"id": "test_user1"},"text": "hello"}
header = {"Authorization":"Bearer q1-Tr4sRrAI.cwA.BmE.n7xMxGl-QLoT7qvJ-tNIcwAd69V-KOn5see6ki5tmOM", "Content-Type":"application/json", "Content-Length": "512"}
send2 = "https://directline.botframework.com/v3/directline/conversations/"+str(convId)+"/activities"
rsa1 = requests.post(send2,data=msg, headers=header)
This gives me this error:
{
"error": {
"code": "MissingProperty",
"message": "Invalid or missing activities in HTTP body"
}
}
Before this step everything is working fine.
Edit 1: Even i added content-length as updated in the code, it gives the same error
Edit 2: If i changed the msg to json.dumps(msg)
rsa1 = requests.post(send2,data=json.dumps(msg), headers=header)
I get response:
{u'error': {u'message': u'Failed to send activity: bot returned an error', u'code': u'ServiceError'}}
{
"error": {
"code": "ServiceError",
"message": "Failed to send activity: bot returned an error"
}
}
The directline API is only not working, on skype client everything is working fine.
According to the code that you've posted, your request body looks like this:
{
"type": "message",
"channelId": "directline",
"conversation": {
"id": str(convId)
},
"from": {
"id": "test_user1"
},
"text": "hello"
}
I'd suspect that your error is caused by the fact that the conversation ID value that you're including in the request body is not surrounded with double quotes in the JSON that's sent over the wire.
For simplicity (and to eliminate the error you're receiving), I'd suggest that you try omitting the channelId property and the conversation property from the request body, as I don't believe that either of these properties are necessary (i.e., you are issuing the request to the Direct Line URI, so the Bot Framework knows that Direct Line is the channel, and the conversation ID is already being specified in the request URI). In other words, try this as your request body:
{
"type": "message",
"from": {
"id": "test_user1"
},
"text": "hello"
}
When passing a dictionary to data it gets urlencoded automatically, so the api returns an error as it expects json data.
You can either use the json lib, or preferably pass your dictionary to the json parameter.
Using json.dumps :
rsa1 = requests.post(send2, data=json.dumps(msg), headers=header)
Using requests only :
rsa1 = requests.post(send2, json=msg, headers=header)
Also you don't have to add "Content-Length" in header and if you use the second example you don't have to add "Content-Type" either.
I am building a small flask app to handle automatic deployment for another project I am working on.
This involves setting a gcloud firewall rule using googleapis.
I have followed the below documentation.
https://cloud.google.com/compute/docs/reference/latest/firewalls/insert
When I make my POST call in the following manner.
headers = {
'Authorization': 'Bearer {}'.format(access_token)
}
name = unique_identifier + "-rule"
payload = {
"kind": "compute#firewall",
"name": name,
"sourceRanges": [
"0.0.0.0/0"
],
"sourceTags": [
unique_identifier
],
"allowed": [
{
"IPProtocol": "tcp",
"ports": [
port_number
]
}
]
}
data = json.dumps(payload)
r = requests.post("https://www.googleapis.com/compute/v1/projects/apollo-rocket-chat/global/firewalls?key={MY_API_KEY}", data=data, headers=headers)
where port_number and unique_idenifier are strings. access_token is retrieved using a service account I have set. I am confident that the token is good, since I can make a GET call to a protected resource using the token.
I am using python 3.5.
The response to this POST is the following.
{
"error": {
"errors": [
{
"domain": "global",
"reason": "required",
"message": "Required field 'resource' not specified"
}
],
"code": 400,
"message": "Required field 'resource' not specified"
}
}
The error message is claiming that I am missing a field, although I have all the required fields that are specified at the link below.
https://cloud.google.com/compute/docs/reference/latest/firewalls/insert#request-body
What exactly am I doing wrong?
Figured it out. I removed.
data = json.dumps(payload)
and changed
r = requests.post("https://www.googleapis.com/compute/v1/projects/apollo-rocket-chat/global/firewalls?key={MY_API_KEY}", data=data, headers=headers)
to
r = requests.post("https://www.googleapis.com/compute/v1/projects/apollo-rocket-chat/global/firewalls?key={MY_API_KEY}", json=data, headers=headers)
I am trying to send a request to Linkedin's rest share api. I have been receiving this error message:
{
"errorCode": 0,
"message": "Can not parse JSON share document.\nRequest body:\n\nError:\nnull",
"requestId": "ETX9XFEI7N",
"status": 400,
"timestamp": 1437910620120
}
The request is send through the following python code:
import requests,json
auth_token = "some auth token"
url = "https://api.linkedin.com/v1/people/~/shares?format=json&oauth2_access_token="+auth_token
headers = {'content-type': 'application/x-www-form-urlencoded','x-li-format':'json'}
data = {
"comment":"Check out developer.linkedin.com!",
"content":{
"title": "LinkedIn Developers Resources",
"description": "Leverage LinkedIn's APIs to maximize engagement",
"submitted-url": "https://developer.linkedin.com",
"submitted-image-url": "https://example.com/logo.png"
},
"visibility":{
"code": "anyone"
}
}
response = requests.post( url , json= data , headers=headers )
return HttpResponse( response )
I made sure that I followed all the instructions in their documentation and can't find the mistake I am making.
Note: i have tried json=data and data=data both are not working
Remove content-type from the headers dictionary.
requests sets the correct Content-Type when using the json keyword argument.
You have three basic problems:
Please read the documentation on oauth2; because you are not passing in the token correctly.
The share URL does not take a oauth2_token argument.
You have the wrong content-type header.