I\'ve been reading tutorials and seeing examples for 2 days already, with no success. I want to send an email using Google Apps Gmail account in NodeJS environment, however,
So I was half-step close to the solution, the problem was that while creating const jwtClient = new google.auth.JWT(googleKey.client_email, null, googleKey.private_key, ['https://www.googleapis.com/auth/gmail.send'], null);
i did not mention the account to be impersonated.
The correct initialization should be:
const jwtClient = new google.auth.JWT(googleKey.client_email, null, googleKey.private_key, ['https://www.googleapis.com/auth/gmail.send'], 'user@domain.com');
To summarize, the correct steps are:
Domain Wide Delegation
for the service accountAPI Manager
> Credentials
i have created OAuth 2.0 Client ID
In Google Apps Admin console:
Security
> Advanced Settings
> Manage API client access
i have added the Client ID
from step 4 aboveClient ID
This is the code that sends mails:
const google = require('googleapis');
const googleKey = require('./google-services.json');
const jwtClient = new google.auth.JWT(googleKey.client_email, null, googleKey.private_key, ['https://www.googleapis.com/auth/gmail.send'], '<user to impersonate>');
jwtClient.authorize((err, tokens) => {
if (err) {
console.err(err);
return;
}
console.log('Google auth success')
var gmail = google.gmail({version: 'v1'})
var raw = <build base64 string according to RFC 2822 specification>
var sendMessage = gmail.users.messages.send({
auth: jwtClient,
userId: '<user to impersonate>',
resource: {
raw: raw
}
}, (err, res) => {
if (err) {
console.error(err);
} else {
console.log(res);
}
});
Hope that would be helpful for others
Thanks very much @agoldis. Both the summary steps and the code were very helpful.
It helped me pick up on a few things I needed to fix on both the GoogleWorkspace and the ApplicationCode end of the communication path. Below is my c# implementation for anyone who needs it.
private static void Try4()
{
try {
//file included in project with properties: CopyToOutputDirectory = CopyAlways
var credential = GoogleCredential.FromFile("MyPrj-MyServiceAccount-Credentials.json")
.CreateScoped(new[] { GmailService.Scope.GmailSend })
.CreateWithUser("WhoIAmImpersonating@bla.com")
.UnderlyingCredential as ServiceAccountCredential;
var service = new GmailService(new BaseClientService.Initializer() { HttpClientInitializer = credential });
var nl = Environment.NewLine;
string plainText = "From: WhoIAmImpersonating@bla.com"
+ nl + "To: myfriend@gmail.com,"
+ nl + "Subject: This is the Subject"
+ nl + "Content-Type: text/html; charset=us-ascii"
+ nl
+ nl + "This is the message text.";
var newMsg = new Message() { Raw = Base64UrlEncode(plainText) };
service.Users.Messages.Send(newMsg, "WhoIAmImpersonating@bla.com").Execute();
Console.WriteLine("Message Sent OK");
}
catch (Exception ex) {
Console.WriteLine("Message failed");
}
}
private static string Base64UrlEncode(string input)
{
var inputBytes = System.Text.Encoding.UTF8.GetBytes(input);
return Convert.ToBase64String(inputBytes)
.Replace('+', '-')
.Replace('/', '_')
.Replace("=", "" );
}