mjoyce91
mjoyce91

Reputation: 326

Sending an email with Gmail's API using only a token?

I'm trying to using Google's API to send an email. I have a web application powered by AngularJS where the user signs in with their google account (via passport.js) using oauth2. A new access token is written to their account on my database. Their google user ID is also written to their account. I'd like the user to be able to send an email via an HTTP request using simply their user Id and access token. I'm using Postman to make some test requests, but I keep getting this error:

{
  "error": {
    "errors": [
      {
        "domain": "global",
        "reason": "insufficientPermissions",
        "message": "Insufficient Permission"
      }
    ],
    "code": 403,
    "message": "Insufficient Permission"
  }
}

I'm using the following link to make a POST request:

https://content.googleapis.com/gmail/v1/users/106xxxxxxxxxxx/messages/send

In my header, I have:

Authorization: Bearer yaxx._wxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Content-Type: application/json

My body:

{
 "raw": "test"
}

I've had some of the emails intermittently come in using this method, but I can't seem to recreate a successful request with certainty. I'm a little confused by Google's documentation. Do I need to explicitly grant access as seen in the example at the bottom of this page?

Upvotes: 3

Views: 3806

Answers (1)

Tholle
Tholle

Reputation: 112887

The access token you mentioned needs to be present in the POST-request you send the mail with. The Oauth2-procotol dictates that you need to either pass along a header Authorization: Bearer <ACCESS_TOKEN>, or a parameter access_token=<ACCESS_TOKEN>.

The value of raw also needs to be a valid base64-encoded rfc822 mail. An example in JavaScript could look like the following:

// Base64-encode the mail and make it URL-safe 
// (replace all "+" with "-" and all "/" with "_")
var encodedMail = btoa(
      "Content-Type: text/plain; charset=\"UTF-8\"\n" +
      "MIME-Version: 1.0\n" +
      "Content-Transfer-Encoding: 7bit\n" +
      "Subject: Subject of the mail\n" +
      "From: [email protected]\n" +
      "To: [email protected]\n\n" +

      "This is where the mail text will go"
    ).replace(/\+/g, '-').replace(/\//g, '_');

This will result in a string that you use as the raw in the request body.

A request in Postman would then look like the following:

POST https://www.googleapis.com/gmail/v1/users/me/messages/send?access_token=<ACCESS_TOKEN>

{ // The encoded mail from the example above.
 "raw": "Q29udGVudC1UeXBlOiB0ZXh0L3BsYWluOyBjaGFyc2V0PSJVVEYtOCIKTUlNRS1WZXJzaW9uOiAxLjAKQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZzogN2JpdApTdWJqZWN0OiBTdWJqZWN0IG9mIHRoZSBtYWlsCkZyb206IHNlbmRlckBnbWFpbC5jb20KVG86IHJlY2lldmVyQGdtYWlsLmNvbQoKVGhpcyBpcyB3aGVyZSB0aGUgbWFpbCB0ZXh0IHdpbGwgZ28="
}

You also need to supply the Content-Type-header with the value of application/json. Note that you don't have to use a userId. Supplying me will make Google use the user associated with the supplied access token automatically.

Also make sure you asked for a sufficient permission scope with Passport. https://mail.google.com/ will work.

Upvotes: 4

Related Questions