In this tutorial, I covered how to send email with Gmail API using Service Account in Node.js.
Sending emails programmatically is a common requirement for web applications. The Gmail API provides a powerful way to send emails through your Gmail account using a service account. In this tutorial, I’ll show you how to use the Gmail API to send email with Service account in Node.js, leveraging the popular Nodemailer library to prepare MIME messages.
Table of Contents
Introduction
Prerequisites
Before we begin, make sure you have the following:
- Node.js installed on your system.
- A Gmail account with access to the Google Developers Console.
- Basic understanding of JavaScript and Node.js.
Setting Up a Service Account
First, you need to create a service account in the Google Developers Console:
- Go to the Google Developers Console and create a new project.
- Enable the Gmail API for your project.
- Go to ‘Credentials’ and create a new service account.
- Download the JSON key file for your service account and keep it secure; you’ll need it in your Node.js application.
Configuring Nodemailer
Nodemailer is a Node.js library for sending emails. It supports many mail transport systems, but here we’ll use it to generate MIME messages that can be sent via the Gmail API.
First, install Nodemailer using npm:
npm install nodemailer
We’ll configure Nodemailer to create a stream transport that we can use to generate raw MIME messages:
const nodemailer = require('nodemailer'); const mailTransport = nodemailer.createTransport({ streamTransport: true, newline: "unix", buffer: true });
Sending Email
To send an email using the Gmail API, you must first create a raw MIME message. You can use Nodemailer to do this, then send it using the Gmail API’s users.messages.send
method.
Here’s a basic example of using Nodemailer to create a MIME message:
const message = { to: '[email protected]', subject: 'Hello!', text: 'Hello world!', html: '<p><b>Hello</b> world!</p>' }; mailTransport.sendMail(message, (err, info) => { if (err) { console.error('Error generating email MIME', err); } else { // Send the MIME message via Gmail API sendMimeMessage(info.message.toString('base64')); } });
Now, you need to implement the sendMimeMessage
function to send the MIME message using the Gmail API and your service account.
Here’s an example of how you would use the Gmail API with a service account to send an email:
const { google } = require('googleapis'); async function sendMimeMessage(mimeMessage) { const gmail = google.gmail('v1'); const auth = new google.auth.JWT( credentials.client_email, // From your JSON key file null, credentials.private_key, // From your JSON key file ['https://www.googleapis.com/auth/gmail.send'] ); await auth.authorize(); const response = await gmail.users.messages.send({ auth: auth, userId: 'me', resource: { raw: mimeMessage } }); console.log(response); }
Output: Your console will display the response from the Gmail API which contains the ID of the sent message and other details.
Complete Example
Here is a complete example that includes the creation of the MIME message and sending it using the Gmail API. Remember to populate the credentials
object with your service account details from the JSON key file.
const { google } = require('googleapis'); const nodemailer = require('nodemailer'); // Credentials obtained from your service account JSON key file const credentials = { client_email: 'YOUR_SERVICE_ACCOUNT_EMAIL', private_key: 'YOUR_SERVICE_ACCOUNT_PRIVATE_KEY' }; // Configure Nodemailer to generate an SMTP configuration const mailTransport = nodemailer.createTransport({ streamTransport: true, newline: 'unix', buffer: true }); // Email contents const mailOptions = { from: '[email protected]', to: '[email protected]', subject: 'Test Email via Gmail API', text: 'Hello! This is a test email sent via Gmail API with a service account.', html: '<p> Hello. This is using <strong>Gmail API</strong></p>' }; // Function to send the email using Gmail API async function sendMimeMessage(mimeMessage) { const gmail = google.gmail({ version: 'v1' }); const jwtClient = new google.auth.JWT( credentials.client_email, null, credentials.private_key, ['https://www.googleapis.com/auth/gmail.send'], // Specify the email address of the user the service account is impersonating. // Ensure the service account has domain-wide authority to impersonate this user. '[email protected]' ); // Authorize the JWT client and get a token to make API calls await jwtClient.authorize(); // Send the email using the Gmail API const response = await gmail.users.messages.send({ auth: jwtClient, userId: 'me', resource: { raw: mimeMessage } }); console.log('Email sent:', response.data); } // Generate MIME message and send email mailTransport.sendMail(mailOptions, (err, info) => { if (err) { return console.error('Failed to send mail:', err); } const mimeMessage = info.message.toString('base64'); sendMimeMessage(mimeMessage) .then(() => console.log('Email sent successfully.')) .catch(error => console.error('Error sending email:', error)); });
Summary
In this tutorial, we’ve explored how to send email with the Gmail API using a service account in Node.js. We configured Nodemailer to create the necessary MIME message and used the Gmail API’s users.messages.send
method to send the email. This allows for secure and efficient email delivery directly from your Node.js application.