Send Kirby emails with Gmail SMTP and OAuth2

I wanted to use a Gmail address with Kirby’s email utility, but if you use the Gmail SMTP server with standard username/password authentication for Kirby emails, you need set your Gmail account to ‘allow less secure apps’. I didn’t want to do this (there’s a reason this isn’t the default) but the alternative is to authenticate with OAuth2, which isn’t straightforward to setup. I thought I’d post the process I went through here because I couldn’t find it elsewhere.

Thanks to @ahmetbora for pointing me to the beforeSend callback where I could include the required OAuth logic. If someone knows a more elegant solution I’m happy to hear it.

1. Install packages

PHPMailer comes standard with Kirby 3, but it needs the OAuth2 Google Provider package to authenticate. This package is also needed in the get_oauth_token.php script that comes with PHPMailer to get your Gmail refresh token (see step 2 below):

composer require league/oauth2-google

If you want to keep your credentials in a .env file for security reasons, you can use the DotEnv plugin:

composer require bnomei/kirby3-dotenv

2: Get authentication credentials

Before you can start sending emails, you need to authorise your web app first. Create a project in the Google developer console and obtain a client ID and client secret. Then use the get_oauth_token.php script provided by PHPMailer to get a refresh token. This is the most complicated part, but there’s a detailed step by step tutorial here.

3: Configure Kirby

In config.php add the following:

<?php

use League\OAuth2\Client\Provider\Google;
use PHPMailer\PHPMailer\OAuth;

return [
	'email' => [
	  'transport' => [
	    'type' => 'smtp',
	    'host' => 'smtp.gmail.com',
	    'port' => 587,
	    'security' => true,
	    'auth' => true,
	  ],
	  'beforeSend' => function ($mailer) {
	    $mailer->AuthType = 'XOAUTH2';
		// if the kirby3-dotenv plugin is installed, 
		// env() reads your credentials from a .env file
	    $email = env('EMAIL');
	    $clientId = env('GMAIL_CLIENT_ID');
	    $clientSecret = env('GMAIL_CLIENT_SECRET');
	    $refreshToken = env('GMAIL_REFRESH_TOKEN');
	
	    $provider = new Google(
	      [
	        'clientId' => $clientId,
	        'clientSecret' => $clientSecret,
	      ]
	    );
	
	    $mailer->setOAuth(
	      new OAuth(
	        [
	          'provider' => $provider,
	          'clientId' => $clientId,
	          'clientSecret' => $clientSecret,
	          'refreshToken' => $refreshToken,
	          'userName' => $email,
	        ]
	      )
	    );
	
	    return $mailer;
	  },
	],
];
2 Likes

@liliput

The get_oauth_token.php script is in your vendor folder and depending on your setup might not be accessible from your site’s root. The easiest way is to (temporarily) copy the script to your site root and access it in the browser at localhost/get_oauth_token.php

Thanks @phm! I ended up going another route with this particular project but I’m sure I might need your tutorial again in the future, so thanks for reaching out!

Sending mail from different email providers is now easier and more manageable with Kirby 3.6