How to Send Email using Gmail API in PHP

When it comes to a website, we have to send emails to the users for various reasons. PHP provides a mail() function but there are limitations with it. Using this method, your emails most probably end up in spam. You’ll never like it. In the real world, we hardly check spam. Your users will probably miss your important emails.

To resolve this problem, we choose the SMTP server. While integrating SMTP, you need to pass your login details in plain text format or you store them in the database. This can create a security problem. If your server gets compromised, your login credentials can get exposed.

Instead of going for the SMTP server, I’d recommend using the Gmail API which adds extra security. The Gmail API requires you to follow the OAuth 2.0 flow instead of your login credentials. Once you complete the Google OAuth steps, it generates the access token which will be used to send your application emails.

In this article, we study how to integrate Gmail API with the Swift Mailer library. The Swift Mailer is a component-based library for sending emails from PHP applications.

Register an Application and Create Credentials

You first need to grab your OAuth client id and client secret. These credentials are required to build the Google OAuth flow.

Follow the steps below to get your keys.

  • Go to the Google Developer Console.
  • Create a new project. You can also select an existing project.
  • Add a name to your project. Google Console will generate a unique Project ID for it.
  • Your project will appear on top of the left sidebar.
  • Click on Library. You will see a list of Google APIs.
  • Enable Gmail API.
  • Click on the Credentials. Select Oauth Client id under Create credentials. Choose the radio button for Web Application.
  • Give the Name. Under Authorized JavaScript origins enter your domain URL. In the ‘Authorized redirect URIs’ add the link of the redirect URL. In my case, I passed the URL http://localhost/swiftmailer/callback.php
  • Click on the Create button. You will get a client ID and client secret in the pop-up. Copy these details. We will need it in a moment.
Gmail API

Basic Configuration

As I mentioned before, we need to generate an access token. This token should store in the database for later use. Each time our application sends an email, we need to fetch this token and use it.

Let’s create a MySQL table using the following query.

CREATE TABLE `google_oauth` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `provider` varchar(255) NOT NULL,
 `provider_value` text NOT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

Next, create a DB class that will interact with the database and retrieve, store, update token information in the table.

class-db.php

<?php
class DB {
    private $dbHost     = "DB_HOST";
    private $dbUsername = "DB_USERNAME";
    private $dbPassword = "DB_PASSWORD";
    private $dbName     = "DB_NAME";
      
    public function __construct(){
        if(!isset($this->db)){
            // Connect to the database
            $conn = new mysqli($this->dbHost, $this->dbUsername, $this->dbPassword, $this->dbName);
            if($conn->connect_error){
                die("Failed to connect with MySQL: " . $conn->connect_error);
            }else{
                $this->db = $conn;
            }
        }
    }
 
    public function is_token_empty() {
        $result = $this->db->query("SELECT id FROM google_oauth WHERE provider = 'google'");
        if($result->num_rows) {
            return false;
        }
 
        return true;
    }
 
    public function get_access_token() {
        $sql = $this->db->query("SELECT provider_value FROM google_oauth WHERE provider='google'");
        $result = $sql->fetch_assoc();
        return json_decode($result['provider_value']);
    }
 
    public function get_refersh_token() {
        $result = $this->get_access_token();
        return $result->refresh_token;
    }
 
    public function update_access_token($token) {
        if($this->is_token_empty()) {
            $this->db->query("INSERT INTO google_oauth(provider, provider_value) VALUES('google', '$token')");
        } else {
            $this->db->query("UPDATE google_oauth SET provider_value = '$token' WHERE provider = 'google'");
        }
    }
}

We will require few packages to accomplish our task. Those packages are – Swift Mailer and HybridAuth. Install these packages using the below commands.

composer require swiftmailer/swiftmailer
composer require hybridauth/hybridauth

Generate OAuth Access Token for Gmail API

You have installed the HybridAuth library which will generate an access token. For this, you have to follow their configuration setup. Create a config.php file and add the below code to it.

<?php
require_once 'vendor/autoload.php';
require_once 'class-db.php';
 
define('GOOGLE_CLIENT_ID', 'PASTE_CLIENT_ID_HERE');
define('GOOGLE_CLIENT_SECRET', 'PASTE_CLIENT_SECRET_HERE');
 
$config = [
    'callback' => 'YOUR_DOMAIN_URL/callback.php',
    'keys'     => [
                    'id' => GOOGLE_CLIENT_ID,
                    'secret' => GOOGLE_CLIENT_SECRET
                ],
    'scope'    => 'https://mail.google.com',
    'authorize_url_parameters' => [
            'approval_prompt' => 'force', // to pass only when you need to acquire a new refresh token.
            'access_type' => 'offline'
    ]
];
 
$adapter = new Hybridauth\Provider\Google( $config );

You may have noticed I passed the scope https://mail.google.com which is required to get the access token for Gmail API.

The callback.php file will perform the authorization flow and store the access token in the database table.

<?php
require_once 'config.php';

try {
    $adapter->authenticate();
    $token = $adapter->getAccessToken();
    $db = new DB();
    $db->update_access_token(json_encode($token));
    echo "Access token inserted successfully.";
}
catch( Exception $e ){
    echo $e->getMessage() ;
}

Go to the browser, run the YOUR_DOMAIN_URL/callback.php, complete the authentication and you should get your access token in your ‘google_oauth’ table.

Send Email using Gmail API in PHP

Once we get the access token, it becomes easy to use Gmail API to send our emails. All we need to check if the token is expired, if so regenerate it using the refresh token in the background. Store this newly created token in the database and use it.

Your code will be as follows.

<?php
send_email_to_user('ADD_RECIPIENT_EMAIL');

function send_email_to_user($email) {
    require_once 'config.php';

    $db = new DB();
    $arr_token = (array) $db->get_access_token();

    try {
        $transport = (new Swift_SmtpTransport('smtp.googlemail.com', 465, 'ssl'))
            ->setAuthMode('XOAUTH2')
            ->setUsername('YOUR_GOOGLE_EMAIL')
            ->setPassword($arr_token['access_token']);

        // Create the Mailer using your created Transport
        $mailer = new Swift_Mailer($transport);

        // Create a message
        $body = 'Hello, <p>Email sent through <span style="color:red;">Swift Mailer</span>.</p>';

        $message = (new Swift_Message('Email Through Swift Mailer'))
            ->setFrom(['FROM_EMAIL' => 'FROM_NAME'])
            ->setTo([$email])
            ->setBody($body)
            ->setContentType('text/html');

        // Send the message
        $mailer->send($message);

        echo 'Email has been sent.';
    } catch (Exception $e) {
        if( !$e->getCode() ) {
            $refresh_token = $db->get_refersh_token();

            $response = $adapter->refreshAccessToken([
                "grant_type" => "refresh_token",
                "refresh_token" => $refresh_token,
                "client_id" => GOOGLE_CLIENT_ID,
                "client_secret" => GOOGLE_CLIENT_SECRET,
            ]);
            
            $data = (array) json_decode($response);
            $data['refresh_token'] = $refresh_token;

            $db->update_access_token(json_encode($data));

            send_email_to_user($email);
        } else {
            echo $e->getMessage(); //print the error
        }
    }
}

Replace the placeholders with actual values. For simplicity, I used the single parameter of email in the method send_email_to_user. You can change it as per your flow. The basic code would remain the same.

It’s all about sending emails using Gmail API with Swift Mailer in PHP. I would like to hear your thoughts and suggestions in the comment section below.

Related Articles

If you liked this article, then please subscribe to our YouTube Channel for video tutorials.

Leave a Reply

Your email address will not be published. Required fields are marked *