Last active
August 10, 2019 20:13
-
-
Save cmundi/6c7d3578ff36d13cff84438b8c39bffc to your computer and use it in GitHub Desktop.
Google API Service Account Demo for Gmail and Drive
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Using Google Drive and Google Mail with a Service Account. | |
// | |
// Amswer to http://stackoverflow.com/questions/37902022/gmail-api-with-nodejs-send-gives-400-bad-request?answertab=active#tab-top | |
// | |
// A service account is pretty much like a normal Google account, except that yo can't get get a "shell" like | |
// the Gmail webapp or Drive webapp into it. To manage email with a Service Account, the administrator for the | |
// domain which owns the email addresses must enable API access for the Service Account. That's described in my | |
// SO post and the links therein. Assuming you've set all that up, it's time to have some fun! | |
// | |
// This gist was significantly inspired by examples distributed by Google under the Apache License 2 and is returned to | |
// the community also under the Apache License 2. | |
var fs = require('fs'); | |
var base64 = require('base64-url'); // for encoding our email | |
// service account key - keep it safe | |
var key = require('./serviceaccount_key.json'); | |
// google apis | |
var google = require('googleapis'); | |
var drive = google.drive('v3'); | |
var mail = google.gmail('v1'); | |
// new up a client - include whatever scopes you need | |
var jwtClient = new google.auth.JWT( | |
key.client_email, | |
null, | |
key.private_key, | |
['https://www.googleapis.com/auth/drive', // drive scope | |
'https://www.googleapis.com/auth/gmail.readonly', // for labels | |
'https://www.googleapis.com/auth/gmail.send'], // mail scope | |
"maria@our_google_apps_domain.com"); // the user which wil be impersonated by our service account | |
// grab some tokens; we won't have to get our hands dirty because its's all nicely encapsulated in the jwtClient | |
jwtClient.authorize(function(err, tokens) { | |
if (err) { | |
console.log('JWT Auth Error: ' + err); | |
return; | |
} | |
// Let's have a look just for funsies! | |
console.log('Got tokens:' + JSON.stringify(tokens)); | |
// Find out what our friend Maria has in her Google Drive | |
listFiles(); | |
// Leave a present for her! | |
console.log('pushing file...'); | |
var request = putFile('test.png'); // not much of a present... | |
console.log(JSON.stringify(request)); // hey check out that HTTPS request! | |
// What labels is Maria using in Gmail? | |
request = mail.users.labels.list({auth: jwtClient, userId: 'me'}, | |
(err,res) => { | |
if (err) console.log('Labels Error:\n' + JSON.stringify(err)); | |
if (res) console.log('Labels:\n' + JSON.stringify(res)); | |
} | |
); | |
// now we're going to send an email from Maria to Manny. | |
var msg = [ | |
'Content-Type: text/plain; charset=utf-8\n', | |
'MIME-Version: 1.0\n', | |
'Content-Transfer-Encoding: 7bit\n', | |
'To: [email protected]\n', // who's this Danny guy, and why is Maria sending him email? | |
'From: maria@our_google_apps_domain.com\n', // better match the impersonated account | |
'Subject: Happy Hour\n\n', | |
'See you at happy hour!' | |
].join(''); | |
console.log(msg); | |
safe = base64.escape(base64.encode(msg)); | |
console.log(safe); | |
request = mail.users.messages.send( | |
{ | |
auth: jwtClient, | |
userId: 'me', // this refers to the service avvount | |
resource: | |
{ | |
raw: safe | |
} | |
}, | |
(err,resp)=>{ | |
console.log('error:\n' + JSON.stringify(err)); | |
console.log('response:\n' + JSON.stringify(resp)); | |
} | |
); | |
console.log(JSON.stringify(request)); | |
}); | |
// Make an authorized request to list Drive files. | |
function listFiles() { | |
drive.files.list({ auth: jwtClient, pageSize: 10, fields: "nextPageToken, files(id, name)" }, | |
function(err, resp) { | |
// handle err and response | |
if (err) { | |
console.log('FAIL: ', err); | |
} else { | |
var files = resp.files; | |
if (files.length == 0) | |
console.log('no files found'); | |
else { | |
console.log('Files:'); | |
for (var i=0; i<files.length;i++) { | |
var file = files[i]; | |
console.log('%s (%s)', file.name, file.id); | |
} | |
} | |
} | |
}); | |
}; | |
function putFile(filename) { | |
var req = drive.files.create({ | |
auth: jwtClient, | |
resource: { | |
name: 'testimage.png', | |
mimeType: 'image/png' | |
}, | |
media: { | |
mimeType: 'image/png', | |
body: fs.createReadStream(filename) | |
} | |
}, ()=> { | |
console.log('drive.files.create callback here!'); | |
listFiles(); | |
} ); | |
return req; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This answers how to get a Service Account to work with Gmail plus some fun with Google Drive.