I am struggling for days with the set up in trying to access GMail Google API from a node.js script using googleapis lib. I succeeded once but I cannot remember how I did it , I tried to reset a project, service-account and G-Suite Domain wide delegation following the Google doc ..
Here is what I did :
In my GCP Console console, 1. Existing organisation : lechorodescharentes.org 2. In this organisation , I created a project : choro-dev 3. In this project I created a service account : choro-dev-postoffice with choro-dev-postoffice with role TokenGenerator and enabled the Google Apps Domain-wid Delegation downloaded the new private key ( JSON file ) 4. I enabled the GMail API ( from Libray menu)
In my G-Suite domain's admin console, 5. I added the following copes for this service account's ClientID "https://www.googleapis.com/auth/admin.directory.user", "https://www.googleapis.com/auth/admin.directory.group"
Node.js client I am trying to access the GMail API with the following Firebase function code using the node.js googleapis library with server -server authentication using service account see node.js client code In this code, I have 2 authentication functions connect() : to a JSON Web Token authorize() : to request an access token from the Google OAuth 2.0 Authorization Server
Deployed the Firebase function
- Run the function
- Got the JWT client displayed
- Function ended with error : {"infos":"unauthorized_client: Client is unauthorized to retrieve access tokens using this method."}
node.js client code
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
const {google} = require('googleapis');
const nodemailer = require('nodemailer')
const _ = require('lodash');
const KEY = require('./service-key.json');
function connect () {
return new Promise((resolve, reject) => {
const jwtClient = new google.auth.JWT(
KEY.client_email,
null,
KEY.private_key,
_.values(KEY.scopes), // scopes as authorized in G-Suite admin
KEY.admin_email . // impersonated user
);
jwtClient.authorize((err) => {
if(err) {
reject(err);
} else {
resolve(jwtClient); // returns client
}
});
});
}
// Send a message to the contact user
function sendMessage (client, sender, msg) {
return new Promise((resolve, reject) => {
var transporter = nodemailer.createTransport({
host: 'smtp.gmail.com',
port: 465,
secure: true,
auth: {
type: 'OAuth2',
user: KEY.admin_email,
serviceClient: KEY.client_id,
privateKey: KEY.private_key,
accessToken: client.access_token,
refreshToken: client.refresh_token,
expires: client.expiry_date
}
});
const mailOptions = {
from: 'SITE CONTACT<' + sender + '>',
to: KEY.contact_email,
subject: 'Message',
text: 'From: ' + sender + '\n\n' + msg,
html: '<h1>Message</h1><p>From: ' + sender + '</p><p>' + msg + '</p>'
};
transporter.sendMail(mailOptions, (err, response) => {
if (err) {
reject(err);
return;
}
resolve(response);
});
});
}
function newContactMessage (from, msg) {
return connect()
.then(client => {
return sendMessage(client, from, msg);
});
}
exports.sendContactMessage = functions.https.onRequest((req, res) => {
const sender_email = 'dufourisabelle@orange.fr';
const sender_msg = 'just a test message to contact the site owner.'
newContactMessage(sender_email, sender_msg).then(() => {
return {status: 200};
}, error => {
return {status: error.status, infos: error.message};
}).then(response => {
return res.send(response);
}).catch(console.error);
});
What could I add to it ? I'll try to re-initiate the all process and pray ... ??