Sending emails using PHP with GMail API & OAuth2
If one ever writes an application that faces the end user, then one requirement is common across such apps, i.e. sending emails to verify email, order confirmation, notifications & updates, the list goes on.
If using PHP, then one is presented with the inbuilt mail() function, to send emails. Again there are downsides to using this (outside the scope of this article) so one moves on to PHPMailer which is an excellent library that will help one in a long way, but there’s a catch:
I used my email & password with SMTP authentication to send emails using PHPMailer, and everything was working just fine. But when I deployed the app to server, the script failed. I had turned on Less Secure App Access
from my Google account settings and also clicked on Yes, it was me
button when Google sent a notification to my device asking if it was me who tried to sign in from the server. But still no emails were being sent. The reason behind this is that, I had already logged in to the email from the browser of my development machine & hence I had no issues with authorization. Since I hadn’t logged in from server (why would I? & if I wanted to, how would I?) - thus blocking my sign in attempt.
This was the time when I finally decided to let go of PHPMailer and explore the GMail API. Here’s how I did it:
Prerequisite:
- PHP 5.4 or greater with the command-line interface (CLI) and JSON extension installed
- The Composer dependency management tool
- A Google Cloud Platform project with the API enabled.
Sample Code:
Available here- https://github.com/ajinkyabawaskar/send-email-google-api-oauth2
Concept:
In Layman’s language, this is the OAuth2 concept:
- You ask the user to authorize your application to access their data.
- The user logs into their Google account and ‘Approves’ your application.
- Google then gives you a ‘access_token’ & a ‘refresh_token’
- You have to use the ‘access_token’ as an authorization while calling Google APIs.
- But ‘access_token’ is short-lived and is useless after it expires so you need new ‘access_token’
- So, you can send your ‘refresh_token’ & keep asking for more ‘access_tokens’
- User doesn’t need to authorize again and again until something changes, i.e either you want more data from their account or they change their Google account password, or remove access to your app from their account settings.
Client Library:
To make the above process easy for you to implement, Google provides client libraries that provide an interface for above steps. In case of PHP, the client library is google-api-php-client.
From inside your project directory, run
composer require google/apiclient:^2.0
Doing so will add the library to your composer.json
and install it in vendor
directory.
Credentials:
- Log in to Google Cloud Console > API & Services > Credentials page and create new
OAuth Client ID
. - Download the Client ID as json and put it in your project directory, renaming it as
credentials.json
- Enter http://localhost/project-path/ as redirect URI when creating the credentials.
- DO NOT CREATE
token.json
- it is automatically created by the library.
Finally, code:
Next, create another file in your project directory that will enable you to collect the authorization code sent by Google upon successful user authentication. Google will send this code to the redirect URI you entered while creating the credentials.
// Filename: index.php
<?php>
echo $_GET['code'];
?>
Note that this script runs from the command line & will need modifications to be running as a webpage. Execute this script using:
php send_email.php
When you run the script for the first time, you’ll get an authorization link from CLI. Open this link on the browser of your choice & log in to the account you want to send emails from. Remember, this account needs to be the same as the one you entered in the From:
field of your email earlier. After logging in & clicking “Approve” you’ll be sent to redirect URI & the code will be displayed on http://localhost/project-path/ assuming you followed above steps.
Paste this code on the CLI & two things will happen:
- A
token.json
file will be created at the$tokenPath
location - The emails are sent.
From the next time onwards you execute the script, you won’t have to follow the same login process again. The access_token
and refresh_token
will be used by the client library for authorization.
On ending notes, you can also try out PHPMailer Using Gmail with XOAuth2 to combine mail utilities offered by PHPMailer with OAuth from Google API Client.