Send email programmatically for free from your domain

For a website, sending email is usually one of the primary things needed yet many-a-times is not a trivial task. Lets see how to send email programmatically from your domain with ease and moreover for free! Works with both – shared hosting as well as private hosting (VPS).


So what is it that’s needed to send/receive emails from your own domain ? The answer is an SMTP server which is nothing but a server that sends/receives or forwards emails as necessary. Now if you have private hosting (VPS), you sure can setup a mail server, but mind you, this is not as easy as you think, it involves a lot of configuration and resources to be used on your VPS, not to forget the maintenance needed to keep spam at bay. If you have the available hardware and are willing to do this, this extensive guide should help. As far as Shared hosting is concerned, it isn’t possible to install an SMTP server given that no root access is granted. (However, many shared hosting providers provide a free email plan, you could use that if you’d like. If that’s a yes, you can skip to the 2nd step)
send email programmatically with your domain

Requirements

To deploy an easy, hassle-free, maintenance-free email setup for your domain, here’s what we’re gonna need

  • A SMTP Server (we will use a free SMTP server)
  • A domain (you should own it or have permission to modify the DNS records)
  • Code to send email from your server

Send email programmatically for free


1. Setup a SMTP server

As said earlier, we are going to use a free SMTP server. After comparing several services, I settled with SendinBlue which provides excellent service and most importantly has the maximum number of monthly free emails. It allows you to send 9000 emails/month (i.e. 300 daily) which is largely sufficient for small to medium sized organisations. And if not, you could even switch to one of their paid plans.

So lets get started by creating a free account on SendinBlue. They ask you for your company name, and if you don’t have one yet, feel free to provide your future company’s name 😉 Note that you should provide the email address from which you intend to send out emails programmatically. If you didn’t do that, you can do it later as well from the “Senders and IP” setting (see picture below.)

Once you login to your account, navigate to the “SMTP and API” settings from the top right menu.
sendinblue right menu

Then click on the SMTP tab to reveal the settings to the SMTP server that we’re going to use.

These are the settings that you will need to use later in your code to send emails.

Now go to the “Senders and IP” options from the left menu bar (or the top right menu). Here you can add new senders if you’d like. SendinBlue - senders Tab

Click on the “Domains” tab and then click on “Add a new domain“. This should open up a screen as shown below. Add your domain name. Don’t forget to select the option to digitally sign your emails with the domain name. Doing this ensures that your emails don’t end up in the SPAM folder.
SendinBlue - new Domain

As you chose to digitally sign your emails, another screen with several TXT records would be shown to you. You must update your domain accordingly to authenticate your outgoing emails.
SendinBlue - Authenticate domain

2. Update your Domain

Sign in to your domain’s provider and look for “Zone editor” or an area that will allow you to update the domains DNS records. This is crucial for the digital signing of your emails.
Then, add 4 new TXT records as obtained from our previous step. Here’s an example of what that might look like:
domain DNS records
Note: As per my example, I used “@” instead of “xyz.com” and for the subdomains part, I excluded the string “xyz.com” (i.e. I used only mail._domainkey and _dmarc). These settings worked perfectly for me. For the TTL, you could use any value like 1 hour (3600) or more. Save these new records. Know that DNS changes could take up to 48 hours to propagate.


Another important point worth noting is my SPF record (first line in the image above). If you look closely, in addition to what SendinBlue asks us to copy, it also includes “zoho.eu“. That’s because I am using Zoho for receiving my emails. If you’d like to setup Zoho to receive emails, here’s a link that will help.

Once, you are certain that the DNS records were updated, go back to the authenticate screen in the SendinBlue app and click on “Please verify it” A green check should appear once all is good. As soon as your domain is authenticated, you are now ready to send emails ensuring that they bypass the SPAM folder and hit the end user’s inbox.

3. Send email from your Server

There are many popular server-side web languages like Php, Javascript(NodeJS), python, C# and so on. The code to send emails will be different for each language. For this example, we will see how to send emails with the 2 most widely used langauges – PHP and NodeJS.


Send email with PHP

We will be using the popular library PHPMailer to send emails quickly and easily.

Install PHPMailer with composer (or you can even download it as a zip file. See docs.)

# install phpmailer
composer require phpmailer/phpmailer

Here’s a code snippet to send email programmatically with PHP

// email.php
<?php
// Import PHPMailer classes into the global namespace
// These must be at the top of your script, not inside a function
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;

// Load Composer's autoloader
require 'vendor/autoload.php';

// Instantiation and passing `true` enables exceptions
$mail = new PHPMailer(true);

try {
    // Server settings
    $mail->SMTPDebug = true;                                    // Enable verbose debug output
    $mail->isSMTP();                                            // Send using SMTP
    $mail->Host       = 'smtp-relay.sendinblue.com';            // Set the SMTP server to send through
    $mail->SMTPAuth   = true;                                   // Enable SMTP authentication
    $mail->Username   = 'user@example.com';                     // sender email configured in Sendinblue
    $mail->Password   = 'secret';                               // Master password found in Sendinblue
    $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;         // Enable TLS encryption;
    $mail->Port       = 587;                                    // TCP port to connect to

    // Recipients
    $mail->setFrom('user@example.com', 'Mailer');               // sender email with optional name
    $mail->addAddress('joe@example.net', 'Joe User');           // Add a recipient with optional name
    $mail->addReplyTo('info@example.com', 'Information');
    $mail->addCC('cc@example.com');
    $mail->addBCC('bcc@example.com');

    // Content
    $mail->isHTML(true);                                        // Set email format to HTML
    $mail->Subject = 'Here is the subject';
    $mail->Body    = 'This is the HTML message body <b>in bold!</b>';
    $mail->AltBody = 'This is the body in plain text for non-HTML mail clients';

    $mail->send();
    echo 'Message has been sent';
} catch (Exception $e) {
    echo "Message could not be sent. Mailer Error: {$mail->ErrorInfo}";
}

That should be it. Now if you open up email.php in a browser, an email should be sent out successfully.


Send email with Javascript/Node

We will use the library Nodemailer to simplify sending emails.

# install nodemailer with NPM
npm install nodemailer

Then use this simple code snippet to send email programmatically with Javascript

// email.js
"use strict";
const nodemailer = require("nodemailer");

// async..await is not allowed in global scope, must use a wrapper
async function main() {
  // create reusable transporter object using the default SMTP transport
  let transporter = nodemailer.createTransport({
    host: "smtp-relay.sendinblue.com",
    port: 587,
    secure: false, // true for 465, false for other ports
    auth: {
      user: 'foo@example.com', // sender email configured in Sendinblue
      pass: 'password',        // Master password found in Sendinblue
    },
  });

  // send mail with defined transport object
  let info = await transporter.sendMail({
    from: '"Fred Foo 👻" <foo@example.com>',  // sender email address
    to: "bar@example.com, baz@example.com",   // list of receivers
    subject: "Hello ✔",                       // Subject line
    text: "Hello world?",                     // plain text body
    html: "<b>Hello world?</b>",              // html body
  });

  console.log("Message sent: %s", info.messageId);
  // Message sent: <b658f8ca-6296-ccf4-8306-87d57a0b4321@example.com>
}

main().catch(console.error);

Executing the above code (by running node email.js in the terminal), it should send an email to the desired recipient.


Successfully sent Email

When I used the email address which is an authenticated sender in Sendinblue, the email landed successfully in my inbox


Note that, when I used an unauthenticated email address as the sender’s address, (example: tonystark@niketpathak.com), the email ended up in my Spam folder

So to ensure that your email gets to the inbox of the recipient, verify that you have added the desired sender’s email address in Sendinblue (to be specific, under the “Senders & IPs” tab.).


Here are some other reliable SMTP service providers

Feel free to use them instead of Sendinblue. That’s it for now. Hope it helps 🙂


References

Leave a Reply