SendStreak logo

How to send transactional emails with Gmail - with Node.js and Python examples

Using Gmail for transactional emails is a cost-effective way to begin your journey with programmatical email. This method helps you avoid the need to subscribe to a paid provider like Postmark, go though difficult approval processes like with AWS SES or risk using unreliable free services whose emails often end up in spam folders.

Gmail, both the free version and the paid Google Workspace used by companies, supports the standard SMTP protocol to send emails. This guide will focus on using SMTP. While Gmail also offers the more advanced Gmail API for sending emails, building code with this API may limit compatibility with other email providers or vendors, making scaling your solution more challenging.

Preparing your Gmail account

There are only a few steps required to send emails programmatically through Gmail:

  1. Enable 2-Step Verification
  2. Generate an App password

Enable 2-Step Verification

Starting in 2022, Google now requires the use of 2-Step Verification (2FA) to generate App passwords. If you already enabled it for your account, you can freely ignore this section and jump right into generating an App password.

To enable it, follow these steps:

  1. Log in to Gmail and click on your avatar in the top right corner. Google Account Settings
  2. Choose Manage your Google Account  
  3. In the new tab, click on Security in the left menu.
  4. Find and click on the 2-Step Verification button in the middle of the page. 2-Step Verification
  5. Follow the setup wizard. You can opt for the text message method or use an authenticator app like Google’s for Android or Apple devices. 2-Step Verification wizard

Generate an application password

While Google supports sending emails through its SMTP interface, the credentials you need to use are not your actual Gmail credentials. In fact, you should never use your normal Gmail credentials for anything other than logging in to Gmail. To authenticate to the Google SMTP servers, you need to generate a so-called App password. This separate password will serve as a drop-in replacement for your real Gmail password when sending emails programmatically.

  1. Similarly to enabling 2-Step Verification, log in to Gmail (if you haven’t already) and click on your avatar in the top right corner.
  2. Choose Manage your Google Account Google Account Settings
  3. In the new tab, click on Security in the left menu.
  4. Find and click on the 2-Step Verification button in the middle of the page. 2-Step Verification on
  5. Scroll to the bottom of the page and click the right arrow in the App passwords box. Google App passwords
  6. Type a name for the password that you will generate. We used “SMTP access” in our example, but you can also give it any other name that will help you identify the password later (e.g., when you want to revoke or regenerate it). App password name
  7. Click Create and make a note of the generated password immediately because you will not see it again. App password generated
  8. Click Done, and you’re all set!

Sending an email programmatically

We’ll implement some example code in this guide using Node.js and Python, but the basics are very similar with both languages:

  1. Find a suitable SDK that implements the SMTP protocol (you really don’t want to mess with raw SMTP commands over a TCP connection).
  2. Initialize the SDK with some server parameters and your Gmail credentials. These parameters and credentials are:
    • Google’s SMTP server: smtp.gmail.com
    • Server port: 587
    • The SMTP username, which is your full Gmail address
    • The SMTP password, which is the previously generated App password
  3. Send your predefined email content to the desired recipients.

The Node.js example

In Node.js, we’ll use the well-known Nodemailer library. This is a powerful email toolkit that supports more features than we need here, such as email attachments, DKIM, proxies, or OAuth. However, we’ll only be using a small subset of its features.

Let’s install the library:

npm install —save nodemailer

Initialize the library with the parameters and credentials we acquired previously:

const nodemailer = require('nodemailer');

// Create a transporter object to interact with the SMTP server
let transporter = nodemailer.createTransport({
  host: 'smtp.gmail.com',
  port: 587,
  // Don't worry, it will be secure using TLS
  secure: false,
  auth: {
    // Your full Gmail email address
    user: 'example@gmail.com',
    // The 16 character App password you generated, without spaces
    pass: 'abcdefghijklmnop',
  }
});

At this point, we’ve constructed a transporter object that is ready to send emails. Let’s proceed to do so. We need to define an email object that we’ll pass to the sendMail function of the transporter. In our example, this email object will contain the most commonly used parameters. For more information, you can refer to Nodemailer’s documentation on the same function.

const message = {
  // You need to use your email address, as Gmail doesn't allow sending from anything else
  from: 'example@gmail.com',
  to: 'your_recipient@gmail.com',
  subject: 'Nodemailer test',
  text: 'Hello from Nodemailer, this is a test email',
  html: '<h1>Hello from Nodemailer</h1><p>This is a test email</p>'
};

Please note that we’ve defined two different content formats for the email. The text field provides a clear-text representation of our message, which is used by clients that don’t support rich-text format emails or when a simplified preview is needed. The html field contains a rich-text format using HTML, allowing you to give more structure and formatting to your content.

Please also note that we used the same “from” email address for which we generated the App password. This is a must, as you can only send emails through Gmail on your behalf.

Now simply pass it to the sendMail function and log any potential results or errors:

transporter.sendMail(message).then(info => {
  console.log(info);
  // Optionally you may want to focus on info.response to check for success
}, error => {
  console.log(error);
});

Save the file as nodejs_gmail_example.js and execute it:

node nodejs_gmail_example.js

Now observe the response that is printed in the console. If it contains a response field that includes a response code that starts with 2xx, then your operation was successful. These status codes are similar to HTTP response codes and you can learn more about them here.

Nodemailer email arrived to Gmail

The Python example

For our Python example, we’ll use the emails library, which is a high-level SMTP client. Unlike the built-in smtplib, this library doesn’t require you to know the intricate details of SMTP commands and allows you to interact with the server using simple functions, such as send.

Install:

pip install emails

Note: depending on your system, you may need to use pip3 instead of pip.

Unlike with the Nodemailer example, we need to first construct the message. Next, we will invoke the send function with the server parameters and credentials:

import emails

# You need to use your email address, as Gmail doesn't allow sending from anything else
sender_email = 'example@gmail.com'
subject = 'Python test with the emails library'
body = 'Hello from the emails library, this is a test email'

message = emails.html(html=body,
                      subject=subject,
                      mail_from=sender_email)

Then prepare the server connection parameters:

smtp_server = 'smtp.gmail.com'
smtp_port = 587
# Your full Gmail email address
username = 'example@gmail.com'
# The 16 character App password you generated, without spaces
password = 'abcdefghijklmnop'

smtp_options = {
    "host": smtp_server, 
    "port": smtp_port, 
    "ssl": False, 
    "tls": True,
    "user": username,
    "password": password,
}

And finally send the email:

recipient_email = 'your_recipient@gmail.com'

try:
    response = message.send(to=recipient_email, smtp=smtp_options)
    if response.success:
        print('Email sent!')
    else:
        print('Failed to send email:', response.error)
except Exception as e:
    print('An error occurred:', e)

Save your file as python_gmail_example.py and execute it:

python python_gmail_example.py
Email sent!

If you receive the Email sent! message in your console, it worked!

Python email arrived to Gmail

Summary and next steps

Using Gmail to send transactional emails from your application is certainly doable and is a great way to get started. While you can send up to 10,000 emails a day using a paid Google Workspace account (3,000 to external domains), this number decreases to 500 if you use a free Gmail account. This number may seem small, but it can certainly be enough for a private blog or to keep the subscribers of a small business up to date.

Elevate your email sending

While we got started sending our first transactional email in literally 5 minutes, this is surely not a complete solution for a SaaS or mobile application. You need to hardcode email content in your code, implement tracking to know who you sent an email to and who hasn’t received it yet, and handle bounced emails, potential unsubscriptions, etc. This is an enormous amount and certainly not something you should do unless you want to reinvent the wheel.

SendStreak is a SaaS application that provides you with all these features, not more, not less. It’s a bring-your-own-server solution that lets you integrate your Gmail SMTP credentials and provides you with an easy-to-use API to send emails. The user-friendly dashboard allows you to edit your email templates with the help of variables, keep an eye on your audience, and even set up more advanced workflows like email automation or email marketing campaigns.

Try SendStreak for Free now!