29
votes

I'm currently trying to test the new Gmail REST API.

In the API Explorer it is possible to authorize requests using OAuth 2.0 and to execute a request, i.e. send a message.

First I authorized. enter image description here

I'm using the following test data (and of course I used a valid to email address):

{    
   "raw": "c2VuZGluZyBhIG1haWwgdXNpbmcgR21haWwgUkVTVCBBUEk=",  
   "payload": { 
     "headers": [ 
       { "name": "to",      "value": "[email protected]"   }, 
       { "name": "from",    "value": "[email protected]" }, 
       { "name": "subject", "value": "Test Gmail REST API"  } 
     ],
     "mimeType": "text/plain" 
   }
}

I also get a 200 OK and the following result back, which looks fine.

{
  "id": "146dee391881b35b",
  "threadId": "146dee391881b35b",
}

However, the mail will not be sent successfully and I can find an message from [email protected] in the inbox instead;: "An error occurred, your message has not been sent."

enter image description here

Questions:
1. Did someone test this successfully?
2. Do I have to add some other parameter to get this running?



EDIT: There are 2 different HTTP request methods,

  1. the Upload URI for media upload requests, and
  2. the Metadata URI for metadata-only requests

The API Explorer currently supports metadata requests only, which means plain-text messages without attachment, and this is what I'm trying to do.

3
sure, of course I authorized the request first, else I guess I would not get a 200 OK back...Taifun
@Taifun, How did you created the RFC 2822 string, Is there any libraries or hard coded it, any examples?Sasikanth
@Sasikanth This depends on your favorite programming language. see my answer below how to web-safe base64 encode the complete messageTaifun

3 Answers

57
votes

got it!

after reading the RFC 2822 specification I found out, that the complete message needs to be passed in the raw parameter, see the example:

From: John Doe <[email protected]> 
To: Mary Smith <[email protected]> 
Subject: Saying Hello 
Date: Fri, 21 Nov 1997 09:55:06 -0600 
Message-ID: <[email protected]>

This is a message just to say hello. So, "Hello".

So after base64 encoding the complete message, passing it in the raw parameter without using any other parameter, it works fine.

Edit 1:
As @Amit mentioned, it must be web-safe base64 encoded, see also https://code.google.com/p/stringencoders/wiki/WebSafeBase64

So to convert the base64 alpha into a format that is "web-safe" the following changes are recommended:

+ --> - (char 62, plus to dash)
/ --> _ (char 63, slash to underscore)
= --> * padding

To only convert + to - and /to _ was sufficient for me.

Edit 2:
To answer the question of @Hjulle here an example: you only need the userId and in the request body the raw parameter. Let's assume, your email address is [email protected]

First Base64 encode the complete message (see above) using an online encoder and you get this string:

RnJvbTogSm9obiBEb2UgPGpkb2VAbWFjaGluZS5leGFtcGxlPiAKVG86IE1hcnkgU21pdGggPG1h
cnlAZXhhbXBsZS5uZXQ+IApTdWJqZWN0OiBTYXlpbmcgSGVsbG8gCkRhdGU6IEZyaSwgMjEgTm92
IDE5OTcgMDk6NTU6MDYgLTA2MDAgCk1lc3NhZ2UtSUQ6IDwxMjM0QGxvY2FsLm1hY2hpbmUuZXhh
bXBsZT4KClRoaXMgaXMgYSBtZXNzYWdlIGp1c3QgdG8gc2F5IGhlbGxvLiBTbywgIkhlbGxvIi4=

Now convert + to - and /to _ and you get

RnJvbTogSm9obiBEb2UgPGpkb2VAbWFjaGluZS5leGFtcGxlPiAKVG86IE1hcnkgU21pdGggPG1h
cnlAZXhhbXBsZS5uZXQ-IApTdWJqZWN0OiBTYXlpbmcgSGVsbG8gCkRhdGU6IEZyaSwgMjEgTm92
IDE5OTcgMDk6NTU6MDYgLTA2MDAgCk1lc3NhZ2UtSUQ6IDwxMjM0QGxvY2FsLm1hY2hpbmUuZXhh
bXBsZT4KClRoaXMgaXMgYSBtZXNzYWdlIGp1c3QgdG8gc2F5IGhlbGxvLiBTbywgIkhlbGxvIi4=

Now pass this in the raw parameter of the API Explorer.

2
votes

Note: This is a PHP specific answer, but I'm sure some of you will find it useful.

In case you're struggling with setting up the raw data correctly in PHP as I did, using PHPMailer would make things cleaner and easier for you.

After including the library in your code (if you use composer, just add "phpmailer/phpmailer": "~5.2" in the require section of your composer.json), you set the basic details:

$mail = new PHPMailer();
$mail->From = 'FROM_EMAIL';
$mail->FromName = 'FROM_NAME';
$mail->addAddress('TO_EMAIL','TO_NAME');
$mail->Subject = 'EMAIL_SUBJECT';
$mail->Body = 'EMAIL_BODY';
$mail->preSend(); 
$mime = $mail->getSentMIMEMessage();

Now you can base64 encode the $mime to get the raw string for the Gmail API. Use this instead of simple base64_encode, in order to get a valid web safe encoded string. rtrim(strtr(base64_encode($mime), '+/', '-_'), '=');

1
votes

This worked for me

Url: https://www.googleapis.com/upload/gmail/v1/users/me/messages/send (POST Method)

InHeaders:- "Authorization " : "Bearer ya29.Il-iBylW9AUr6V0QO72ryo17r7hf8i5zh8dU63ZjDNaxAApumh6T7lh20my_DQZomtL_qokZnJEgapYN20LmdlG6lFbqGASL5lqFAKnOoUtZA992JwOlUQxMVW6_Yto7jQ", "Content-Type" : "message/rfc822"

InBody:-

{"raw": "From: <[email protected]> 
To: <[email protected]> 
Subject: Saying Hello
This is a message just to say hello. So, "Hello"."}