Sending gmail attachment using api failed - api

I'm trying create a draft (or send a message) with attachment to gmail using its API. I've read some answers and tried to built the request according to what I've read here: Mail attachment wrong media type Gmail API
Before coding the function itself, I decided to use a Chrome extension (Simple Rest Client) to simulate the API request. Here's the request body:
Content-Type: multipart_mixed; boundary="foo_bar_baz"
MIME-Version: 1.0
to: receiver#gmail.com
from: sender#gmail.com
subject: Testing Subject
--foo_bar_baz
Content-Type: text/plain; charset="UTF-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
This is the testing text
--foo_bar_baz
Content-Type: image/jpeg
MIME-Version: 1.0
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="test.jpg"
{
"message":
{
"raw" : "_9j_4AAQSkZJRgABAQEAYABgAAD_2wBDAAIBAQIBAQICAgICAgICAwUDAwMDAwYEBAMFBwYHBwcGBwcICQsJCAgKCAcHCg0KCgsMDAwMBwkODw0MDgsMDAz_2wBDAQICAgMDAwYDAwYMCAcIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAz_wAARCAAJAAsDASIAAhEBAxEB_8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL_8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4-Tl5ufo6erx8vP09fb3-Pn6_8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL_8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3-Pn6_9oADAMBAAIRAxEAPwD9Pfiv-wN4q8cftk3Pji30_wCH9z9v8V6H4ksPiFe3cy-MvAunaeuni68N6bCLR92n3_2G8ErLf2yAeIL_AHW021xdfX9FFAH_2Q**"
}
}
--foo_bar_baz--
The request header parameters are as follows:
Authorization: Bearer *given token*
Content-Type: multipart/mixed; boundary="foo_bar_baz"
Content-Length: 1428
As you can see, it's pretty similar to the example in the link above. However, I keep getting the following response:
"message": "Media type 'application/octet-stream' is not supported. Valid media types: [message/rfc822]"
I know the API docs say the only valid media type is message/rfc822 (https://developers.google.com/gmail/api/v1/reference/users/drafts/create). Nonetheless, this sample (https://developers.google.com/gmail/api/guides/uploads#multipart) and others here in Stackoverflow say otherwise. The author of the question in the link above seem to have solved his problem without using message/rfc822 media type.
I gotta be missing something. Can someone help me with this? I'd really appreciate if someone could help me figure it out.

OK, so if you're using the /upload media feature (works for all messages irregardless of size) then for example it should be something like the following (and looks like i was a bit mistaken):
POST https://www.googleapis.com/upload/gmail/v1/users/me/messages/send
Content-Type: multipart/related; boundary=foo_bar_baz
then your POST body should be something like the following (not encoded, etc):
--foo_bar_baz
Content-Type: application/json; charset=UTF-8
{
}
--foo_bar_baz
Content-Type: message/rfc822
MIME-Version: 1.0
to: receiver#gmail.com
from: sender#gmail.com
subject: Testing Subject
--foo_bar_baz
Content-Type: text/plain; charset="UTF-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
This is the testing text
--foo_bar_baz
Content-Type: image/jpeg
MIME-Version: 1.0
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="test.jpg"
--foo_bar_baz--
So things to note are that it's actually "multipart/related" and that has a application/json (for some requests you can add parameters there) part as well as a message/rfc822 part that contains the entire email.
It's not easy for sure--libraries definitely make it less painful if you can use them!

Related

Postman shows "Could not get any response" even though response is OK

I have a WCF service which I make API requests to.
This API call returns a JSON response object and also is able to return it in GZIP compression as well when "gzip" value is used in "Accept-Encoding" header.
The problem is when I try to get the response in GZIP, Postman shows "Could not get any response" although I see response and response's content are OK (200 status code) in Fiddler and can easily decompress the response content in my C# client.
I took a look in Postman Console but all I see is "Error: incorrect header check".
I hardly tried to find any documentation regarding this header check but couldn't find any.
These are the request headers:
POST /correction/v1/document?lang=US HTTP/1.1
Content-Type: text/plain
Accept-Encoding: gzip
User-Agent: PostmanRuntime/7.6.0
Accept: */*
content-length: 630
Connection: close
These are the response headers:
HTTP/1.1 200 OK
Content-Length: 512
Content-Type: application/json; charset=utf-8
Content-Encoding: gzip
Server: Microsoft-HTTPAPI/2.0
Date: Sun, 24 Feb 2019 14:05:50 GMT
Connection: close
The only thing I suspect is wrong is this message from Fiddler:
I integrated this code into mine in order to use GZIP in WCF.
https://github.com/carlosfigueira/WCFSamples/tree/master/MessageEncoder/GZipEncoderAndAutoFormatSelection
Basically, it captures the response before returning to client and use GZipStream for compression.
I got the same issue, I added the following header to fix this issue.
Accept-Encoding : *
I was able to solve a similar issue by using the header Accept-Encoding: */* or if you want to be specific do Accept-Encoding: */* that way the HTTP client will be able to process the response based on the type of encoding received, in the case of a gzip, it will decode the response and show it as normal text.
For me, I removed 'Accept-Encoding' in the request header.
I got this issue when the REST service was returning a zip content (aka. WinZip format). I solved the error by compressing the data using 7zip to produce true gzip format.

Including Content-Transfer-Encoding header in RestSharp multi-part messages?

I am using RestSharp to upload multi-part messages (basically, form data with a file attached at the end). The receiving service seems to require that I specify the Content-Transfer-Encoding header on each part or I get a 400 error on the POST.
I can't find any way in RestSharp to set this, or to specify "headers" that are actually inside the body of the parts. What I need to produce is a payload that looks like this:
POST http://server/object/create HTTP/1.1
User-Agent: RestSharp/105.2.3.0
Content-Type: multipart/form-data; boundary=-----------------------------28947758029299
Host: server:8080
Content-Length: 540
-------------------------------28947758029299
Content-Type: application/xml;charset=US-ASCII
Content-Disposition: form-data; name="form"
Content-Transfer-Encoding: 8bit
<form>this is some form data in XML format</form>
-------------------------------28947758029299
Content-Disposition: form-data; name="1.eml"; filename="1.email"
Content-Type: application/octet-stream; charset=ISO-8859-1
Content-Transfer-Encoding: binary
This is arbitrary file content to attach to the form.
-------------------------------28947758029299--
So far, this is what I've got (I'm prototyping in PowerShell but the results are identical in C#):
$request = New-Object RestSharp.RestRequest("iss", [RestSharp.Method]::POST)
$request.AddParameter("application/xml;charset=UTF-8", $form, [RestSharp.ParameterType]::RequestBody) | Out-Null
$request.AddFile("att.txt", "C:\Development\att.txt", "application/octet-stream; charset=ISO-8859-1") | Out-Null
$response = $rest.Execute($request)
which does everything I need except the Content-Transfer-Encoding part.
Is this possible with RestSharp, or should I drop down to use the HTTP client directly?

Problems attaching a file to a task via API with Active Collab v5

We are using the API of Active Collab v5, which works quite good.
Unfortunately, we are not able to attach a successfully uploaded file to an existing task. We tried several different ways, but never suceeded.
The one way we believe should work, is shown here:
PUT https://<DOMAIN>/api/v1/projects/<PROJECTID>/tasks/<TASKID>
Accept: */*
X-Angie-AuthApiToken: <TOKEN>
Content-Type: text/plain
Accept-Language: en-us
Accept-Encoding: gzip, deflate
{
"attach_uploaded_files": [
"<CODE>"
]
}
Content-Type: application/json; charset=utf-8
X-Angie-ApplicationVersion: 5.11.23
Pragma: no-cache
Server: Apache
Content-Encoding: gzip
Vary: Accept-Encoding
{"single":{"id":<TASKID>,"class":"Task","url_path":"\/projects\/<PROJECTID>\/ tasks\/
<TASKID>","name":"<TASKNAME>","assignee_id":0,"delegated_by_id":0,
" completed_on":null,"completed_by_id":null,"is_completed":false,"comments_count": 0,
"attachments":[],"labels":[],"is_trashed":false,"trashed_on":null," trashed_by_id":0,
"project_id":<PROJECTID>,"is_hidden_from_clients":false,"body":"<BODYTEXT >",
"body_formatted":"<BODYTEXT>","created_on":1481044542,"created_by_id":20,
" updated_on":1481052449,"updated_by_id":20,"task_number":258,"task_list_id":<TLID> ,
"position":17,"is_important":false,"start_on":null,"due_on":null,"estimate":0,
" job_type_id":0,"total_subtasks":0,"completed_subtasks":0,"open_subtasks":0,
" created_from_recurring_task_id":0},"subscribers":[20],"comments":[],"reminders": [],
"subtasks":[],"task_list":{"id":<TLID>,"class":"TaskList",
"url_path":"\/ projects\/<PROJECTID>\/task-lists\/<TLID>","name":"Inbox",
"is_trashed":false,"trashed_on": null,"trashed_by_id":0,"completed_on":null,
"completed_by_id":null,"is_completed" :false,"project_id":8,"created_on":1480605343,
"created_by_id":20,"updated_on": 1481052420,"updated_by_id":20,"start_on":null,
"due_on":null,"position":1," open_tasks":1,"completed_tasks":44},"tracked_time":0,
"tracked_expenses":0}
We always get a 200 OK, but the file remains unattached.
Can someone please tell us what we are doing wrong?
Thank you for your support and best regards.
Lukas.
Everything looks fine except the "Content-Type" header of your request.
Since you are sending a JSON encoded body to the API you need to set the request header to
"Content-type: application/json; charset=utf-8".
cheers
Nick

MTOM+XOP How to get the binary part in WCF and prevent it from being encoded to Base64

I am implementing a client that receives SOAP MTOM+XOP messages. (XDS.b Consumer to retrieve documents)
I know that for small attachments the attached file will be base64 encoded into the body and for big ones the binary data will be attached in a separate MIME part and a as my Client proxy class.
After I get the Message, the binary data already been encoded into the body as base64, so I implemented CustomEncoded and IncommingInspector and I was able to see the buffer and dumping the message before returning it to the client.
My question: I would like to prevent the process of Encoding/Decoding to Base64 if possible. I would like to get the binary part, write it to the file (for example) and if possible to return a file location in the message body instead of the huge base64 encoded string.
Is this possible?
Following is a sample of message I am trying to process (binary part replaced with ...)
HTTP/1.1 200 OK
Date: Tue, 02 Dec 2014 11:07:55 GMT
Server: Apache
Set-Cookie: JSESSIONID=005193579FC6F91CC7BD0B671E616CB6; Path=/um
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: multipart/related; start-info="application/soap+xml"; type="application/xop+xml"; boundary="----=_Part_178_590817.1417518476024"
1ff8
------=_Part_178_590817.1417518476024
Content-Type: application/xop+xml; charset=utf-8; type="application/soap+xml"
Content-Id: <http://corp.com/xds_source>
Content-Transfer-Encoding: 8bit
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope">
<env:Header>
<wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">urn:ihe:iti:2007:RetrieveDocumentSetResponse</wsa:Action>
<wsa:RelatesTo xmlns:wsa="http://www.w3.org/2005/08/addressing">urn:uuid:123503ce-fba9-4bed-a77f-0cf6d9a51744</wsa:RelatesTo>
</env:Header>
<env:Body>
<xdsb:RetrieveDocumentSetResponse xmlns:xdsb="urn:ihe:iti:xds-b:2007">
<RegistryResponse xmlns="urn:oasis:names:tc:ebxml-regrep:xsd:rs:3.0" status="urn:oasis:names:tc:ebxml-regrep:ResponseStatusType:Success"/>
<xdsb:DocumentResponse><xdsb:RepositoryUniqueId>SAMPLE:12345678</xdsb:RepositoryUniqueId>
<xdsb:DocumentUniqueId>1.2.840.113704.7.1.0.14117819932881.1416384260.2</xdsb:DocumentUniqueId>
<xdsb:mimeType>application/vnd.openxmlformats-officedocument.wordprocessingml.document</xdsb:mimeType>
<xdsb:Document><xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include" href="cid:1.urn:uuid:179268344.0#corp.org"/>
</xdsb:Document>
</xdsb:DocumentResponse>
</xdsb:RetrieveDocumentSetResponse>
</env:Body>
</env:Envelope>
------=_Part_178_590817.1417518476024
Content-Type: application/octet-stream
Content-ID: <1.urn:uuid:179268344.0#corp.org>
Content-Transfer-Encoding: binary
...
------=_Part_178_590817.1417518476024--

batch request on google group api with oauth2-playground

I'm trying to understand (and eventually make it work) batch request on the google group API.
With Oauth2 Playground I know how to perform a single request with:
on step 1 authorised API are
https://www.googleapis.com/auth/admin.directory.group.member.readonly
https://www.googleapis.com/auth/admin.directory.group.member
https://www.googleapis.com/auth/admin.directory.group.readonly
https://www.googleapis.com/auth/admin.directory.group
on step 3 I'm making a post request with:
request URI: https://www.googleapis.com/admin/directory/v1/groups/mytestgroup#domain.ext/members
and the body is:
{
"email": "lya#example.com",
"role": "MEMBER"
}
So far so good, but now I'm trying to do the same in a batch request
I tried to follow the explanation here:
https://developers.google.com/admin-sdk/directory/v1/guides/batch#example
but I didn't understood everything so I went there:
https://developers.google.com/storage/docs/json_api/v1/how-tos/batch
So I did the following request with, on step 1 the same API but on step 3:
a post request to:
https://www.googleapis.com/batch
with a custom content-type:
the header is now
multipart/mixed; boundary="batch_foobarbaz"
and in the body request:
--batch_foobarbaz
Content-Type: application/http
POST /admin/directory/v1/groups/mytestgroup#domain.ext/members HTTP/1.1
Content-Type: application/json
content-length: 58
{
"email": "liz#example.com",
"role": "MEMBER"
}
--batch_foobarbaz--
I also tried different variants but I never get to do the correct request, I systematically get 400 error.
Can someone help me with that, I don't know what I can do to correct that.
Thanks in advance, Harold
Okey sorry for the inconvenience, I found my answer. Here is what I've done:
on step 1 authorised API are:
https://www.googleapis.com/auth/admin.directory.group.member.readonly
https://www.googleapis.com/auth/admin.directory.group.member
https://www.googleapis.com/auth/admin.directory.group.readonly
https://www.googleapis.com/auth/admin.directory.group
on step 3 I'm making a post request with:
https://www.googleapis.com/batch
with a custom content-type: multipart/mixed; boundary="batch_foobarbaz"
body request:
--batch_foobarbaz
Content-Type: application/http
Content-Transfer-Encoding: binary
POST /admin/directory/v1/groups/mytestgroup#domain.ext/members HTTP/1.1
Content-type: application/json
{"email": "ldn#example.com", "role": "MEMBER"}
--batch_foobarbaz--
the important part here are the carriage return. They are mandatory after Content-Transfer-Encoding: binary and after Content-type: application/json