3

I am trying to send email from NodeJS running on a Linux server to Google Gmail RESR HTTP API. Not using libraries, just sending https. I have figured out the OAuth part, have an access token and get responses from google. But I cannot get past various error messages. I have posted the code below. It is not obvious but EmailSend() is called after I get the access token from google, so yeah it is being called.

var emailStr = new Buffer(
      "Content-Type: text/plain; charset=\"UTF-8\"\n" +
      "MIME-Version: 1.0\n" +
      "Content-Transfer-Encoding: 7bit\n" +
      "to: SOMEONE@gmail.com\n" +
      "from: SOMEONEELSE@MYDOMAIN.com\n" +
      "subject: Subject Text\n\n" +

      "The actual message text goes here"
).toString("base64").replace(/\+/g, '-').replace(/\//g, '_');
//var emailBase64UrlSafe = Rtrim( emailStr, '=' );
//var emailBase64UrlSafe = JsStrToUrlSafe ( emailStr );
var emailBase64UrlSafe = emailStr;

var http = require('https');
function EmailSend() {
  
  var post_data = emailBase64UrlSafe;
  var post_options = {
      hostname: 'www.googleapis.com',
      port: '443',
      path: '/gmail/v1/users/me/messages/send',
      method: 'POST',
      headers: {
        "Authorization": 'Bearer '+googleAccessKey['access_token'],
        "Content-Type" : "application/json; charset=UTF-8"
      },
  };
  console.log( post_options );

  var post_req = http.request(post_options, function(res) {
      res.setEncoding('utf8');
      res.on('data', function (chunk) {
          console.log('Response: ' + chunk);
      });
  });
  post_req.write(JSON.stringify({ "raw": emailBase64UrlSafe }));
  post_req.end();
}; /* end EmailSend() */
Response: {
"error": {
 "errors": [
  {
   "domain": "global",
   "reason": "failedPrecondition",
   "message": "Bad Request"
  }
 ],
 "code": 400,
 "message": "Bad Request"
}

Resources used:

  1. https://www.rfc-editor.org/rfc/rfc2822#appendix-A

  2. https://developers.google.com/identity/protocols/OAuth2ServiceAccount

  3. https://nodejs.org/api/https.html#https_https_request_options_callback

  4. Send email using Google API with only access token

Community
  • 1
  • 1
user3356715
  • 181
  • 2
  • 12
  • I could not get these resources into the post without messing up the formatting. So here they are. 1. https://tools.ietf.org/html/rfc2822#appendix-A 2. https://developers.google.com/identity/protocols/OAuth2ServiceAccount 3. https://nodejs.org/api/https.html#https_https_request_options_callback 4. http://stackoverflow.com/questions/29504289/send-email-using-google-api-with-only-access-token?rq=1 – user3356715 Jun 13 '15 at 22:26
  • Are you doing domain wide delegation and impersonating the user for your service account? check this link https://developers.google.com/drive/web/delegation otherwise it will throw this error. – SGC Jun 16 '15 at 16:39
  • Look at the documentation, you need to post an object, of which the message is just a part: https://developers.google.com/gmail/api/v1/reference/users/messages/send – gcbirzan Jun 17 '15 at 16:08

1 Answers1

4

Tried it for myself, and it worked!

var http = require('https');

var mail = new Buffer(
    "From: example@gmail.com\n" +
    "To: example@gmail.com\n" +
    "Subject: Subject Text\n\n" +

    "Message text"
).toString("base64").replace(/\+/g, '-').replace(/\//g, '_');


var post_options = {
  hostname: 'www.googleapis.com',
  port: '443',
  path: '/gmail/v1/users/me/messages/send',
  method: 'POST',
  headers: {
    "Authorization": 'Bearer <ACCESS_TOKEN>',
    "Content-Type" : "application/json"
  }
};

var post_req = http.request(post_options, function(res) {
  res.setEncoding('utf8');
  res.on('data', function (chunk) {
      console.log('Response: ' + chunk);
  });
});

post_req.write(JSON.stringify({ "raw": mail }));
post_req.end();
Tholle
  • 108,070
  • 19
  • 198
  • 189