32

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": "info@something.com"   }, 
       { "name": "from",    "value": "taifunbaer@gmail.com" }, 
       { "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 nobody@gmail.com 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.

Taifun
  • 6,165
  • 17
  • 60
  • 188
  • sure, of course I authorized the request first, else I guess I would not get a `200 OK` back... – Taifun Jun 27 '14 at 20:41
  • @Taifun, How did you created the RFC 2822 string, Is there any libraries or hard coded it, any examples? – Sasikanth Mar 25 '15 at 05:22
  • @Sasikanth This depends on your favorite programming language. [see my answer below](http://stackoverflow.com/a/24461102/1545993) how to web-safe base64 encode the complete message – Taifun Mar 25 '15 at 13:42

4 Answers4

63

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 <jdoe@machine.example> 
To: Mary Smith <mary@example.net> 
Subject: Saying Hello 
Date: Fri, 21 Nov 1997 09:55:06 -0600 
Message-ID: <1234@local.machine.example>

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 jdoe@machine.example

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.

Community
  • 1
  • 1
Taifun
  • 6,165
  • 17
  • 60
  • 188
  • 2
    url encoding required. http://stackoverflow.com/questions/22128789/converting-string-to-web-safe-base64-format – Amit G Jul 31 '14 at 09:42
  • https://gist.github.com/AkashkumarDev/20ab002e7f5785ae778e any idea where is problem ? – Martin Aug 17 '14 at 03:31
  • @akdev for questions please start a new question instead of commenting here. thank you. – Taifun Aug 18 '14 at 22:32
  • http://stackoverflow.com/questions/25396463/how-to-send-message-using-gmail-api-with-ruby-google-api-client – Martin Aug 20 '14 at 03:56
  • Doesn't work for me http://stackoverflow.com/questions/28122074/gmail-api-emails-bouncing – Allen King Jan 24 '15 at 06:03
  • @taifun, my message sending successfully. but, how to add threadId and labelId while sending the message? – m2j Jan 23 '16 at 08:00
  • @users4393829 please [ask a new question](https://stackoverflow.com/questions/ask) – Taifun Jan 23 '16 at 14:44
  • already did. https://stackoverflow.com/questions/34960683/gmail-api-adding-label-id-and-thread-id-while-sending-as-reply-send-mail-with-s – m2j Jan 24 '16 at 00:01
3

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: <from@gmail.com> 
To: <to@gmail.com> 
Subject: Saying Hello
This is a message just to say hello. So, "Hello"."}
2

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), '+/', '-_'), '=');

Community
  • 1
  • 1
trajchevska
  • 942
  • 7
  • 13
  • 7
    the question is : "using the new Gmail REST API?"... so why talk about PHPMailer... – mcfly Jul 21 '18 at 14:48
  • @mcfly because I spent two days researching how to implement this in PHP and I figured why not share my findings on this lovely knowledge sharing platform, with people who, like me, ran onto this answer because they couldn't find what they're looking for. Note the disclaimer at the top. Happy Monday! – trajchevska Jul 23 '18 at 09:54
  • 3
    still not in the right subject... i can post how to send and email with python then java too and people looking for the real subject answer will be so happy to find this here. – mcfly Jul 24 '18 at 12:21
  • This does answer the question in a sense that you get a fully prepared message built by PHPMailer and then use Gmail API to send it. The idea is to get some 3rd party library and not deal with the raw settings of the message. – Vladan Sep 21 '18 at 14:28
0

you don't need to send that message as a raw json payload, you could just send it as a messsage. e.g.

POST https://www.googleapis.com/upload/gmail/v1/users/me/messages/send


Headers:-
"Authorization":"Bearer <Your-Token>", 
"Content-Type" : "message/rfc822"

Body:
"From: <from@gmail.com> 
To: <to@gmail.com> 
Subject: Saying Hello
This is a message just to say hello. So, 'Hello'"
  • In fact, this is correct answer. The answer by Taifun that is currently of the highest score is verbose, not to the point, and is inferior to this answer. This shows the problem of the legacy scoring system of SO. – user15483624 Apr 04 '23 at 15:28