Reputation: 1490
I'm using the latest (0.9.8) of the google-api-nodejs-client library for nodeJS.
I'm authenticating just fine with a service account and a JWT scoped to https:\\googleapis.com/auth/gmail.send
(and also to /auth/drive FWIW).
I try to send email (base64urlencoded) like this:
req = mail.users.messages.send(
{
auth: jwtClient, // really works with google drive
userId: [email protected] // actually a legit gmail address
resource: {
raw: message // base64encode(urlencode(RFC822 msg))
}
}, (err, res) => { console.log(err); }
);
and the callback receives this ever so helpful object:
{"code": 400,"errors":[{"domain":"global","reason":"failedPrecondition","message":"Bad Request"}]}
I am aware that google-api-nodejs-client is alpha and that the GMail API itself is evolving (message v. resource, etc.). So some of the info online—including Google's own documentation—is understandably inconsistent. I'm looking for any suggestions, since the error seems very generic.
Upvotes: 4
Views: 1484
Reputation: 1490
Ok. The "problem" was of my own making. And the solution comes in three (or four) easy parts. Just don't try to skip any.
tl;dr, but you'll still need to read! Here's a working gist.
Despite what you may read elsewhere, it is possible to use the Gmail API with a service account -- provided you have a Google Apps account. (Which I do.) This means that you don't have to mess around with OAuth redirects to get your server sending email. This is accomplished through impersonation. [N.B. If you do not have a Google Apps domain, you probably should ask yourself again why you want to use a service account with Gmail; after all, every email is co-owned by a sender and a recipient, even if one or both are robots.]
Here is what you need to do:
var jwtClient = new google.auth.JWT(
serviceaccount_key.client_email
, null
, serviceaccount_key.private_key
, [
'https://www.googleapis.com/auth/gmail.readonly'
, 'https://www.googleapis.com/auth/gmail.send'
]
, 'user@your_google_apps_domain' // a legit user
)
where the scopes you need are determined by which API calls you want to make and have been enabled in your Google Apps domain.
I hope this saves half a day for you.
Upvotes: 6