Reputation: 63
I have a PHP website from which I send notification emails to our customers. The email is sent from a html form in which we generate the body, the recepient etc from our database.
At the moment the email are sent through the PHP mail function using this code:
function SEND_MAIL($RECIPIENT,$EMAILSUBJECT,$EMAILBODY){
$emailfrom = '[email protected]';
$fromname = 'From name';
$headers =
'Return-Path: ' . $emailfrom . "\r\n" .
'From: ' . $fromname . ' <' . $emailfrom . '>' . "\r\n" .
'X-Priority: 3' . "\r\n" .
'X-Mailer: PHP ' . phpversion() . "\r\n" .
'Reply-To: ' . $fromname . ' <' . $emailfrom . '>' . "\r\n" .
'MIME-Version: 1.0' . "\r\n" .
'Content-Transfer-Encoding: 8bit' . "\r\n" .
'Content-Type: text/html; charset=ISO-8859-1' . "\r\n";
$params = '-f ' . $emailfrom;
$sendit = mail($RECIPIENT, $EMAILSUBJECT, $EMAILBODY, $headers, $params);
}
SEND_MAIL($CONTACTS_EMAIL,$EMAILSUBJECT_PERSON_A,$EMAILBODY_PERSON_A);
We would like to replace this function using the GMAIL API as we want to keep track of the sent mails in our GMAIL account. We are using Bluehost as provider, so SMTP to the GMAIL server cannot be used. We are using this function in many places so we prefer just to modify that piece of code if possible. I have spent days trying to get this to work and finally I'm having some result.
So far I have configured everything in the google developers console, I was able to run the quickstart.php (as described in this tutorial). Using this tutorial we uploaded the JSON file and where able to access the GMAIL account's folders(labels) after the token that we copy/pasted from gmail was set.
Then I was able to send an email using a code sample I found online
session_start();
require __DIR__ . '/vendor/autoload.php';
// Replace this with your Google Client ID
$client_id = 'blabla.apps.googleusercontent.com';
$client_secret = 'secret';
$redirect_uri = 'https://www.redirecturl';
$client = new Google_Client();
$client->setClientId($client_id);
$client->setClientSecret($client_secret);
$client->setRedirectUri($redirect_uri);
// We only need permissions to compose and send emails
$client->addScope("https://www.googleapis.com/auth/gmail.compose");
$service = new Google_Service_Gmail($client);
// Redirect the URL after OAuth
if (isset($_GET['code'])) {
$client->authenticate($_GET['code']);
$_SESSION['access_token'] = $client->getAccessToken();
$redirect = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
header('Location: ' . filter_var($redirect, FILTER_SANITIZE_URL));
}
// If Access Toket is not set, show the OAuth URL
if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
$client->setAccessToken($_SESSION['access_token']);
} else {
$authUrl = $client->createAuthUrl();
}
if ($client->getAccessToken() && isset($_POST['message'])) {
$_SESSION['access_token'] = $client->getAccessToken();
// Prepare the message in message/rfc822
try {
// The message needs to be encoded in Base64URL
$emailad=$_POST['emailad'];
$username=$_POST['username'];
$emailbody=$_POST['emailbody'];
$strSubject = $_POST['subject'];
$strRawMessage = "From: fromname <fromemail>\r\n";
$strRawMessage .= "To: $username <$emailad>\r\n";
$strRawMessage .= 'Subject: =?utf-8?B?' . base64_encode($strSubject) . "?=\r\n";
$strRawMessage .= "MIME-Version: 1.0\r\n";
$strRawMessage .= "Content-Type: text/html; charset=utf-8\r\n";
$strRawMessage .= 'Content-Transfer-Encoding: quoted-printable' . "\r\n\r\n";
$strRawMessage .= "$emailbody\r\n";
$mime = rtrim(strtr(base64_encode($strRawMessage), '+/', '-_'), '=');
$msg = new Google_Service_Gmail_Message();
$msg->setRaw($mime);
$service->users_messages->send("me", $msg);
} catch (Exception $e) {
print($e->getMessage());
unset($_SESSION['access_token']);
}
} ?>
<? if ( isset ( $authUrl ) ) { ?>
<a href="<?= $authUrl; ?>"><img src="google.png" title="Sign-in with Google" /></a>
<? } else { ?>
<form method="POST" action="">
<textarea name="emailbody" required></textarea>
<input type="email" required name="emailad">
<input type="text" required name="subject">
<input type="text" required name="username">
<input type="submit" value="submit">
</form>
<? } ?>
This last method requires also a token from google and account access is requested.
So we would like to use one of these two methods to replace our SEND_MAIL function. I would also like to know if it is possible to NEVER expire the access token so that if we allow access once we never have to go through the Gmail acceptance procedure.
Thanks for your help!
Upvotes: 0
Views: 6693
Reputation: 126
There is no way of getting an access token that does NOT expire, but there is a way to get what is called a refresh token. The refresh token never expires and is useable until you unauthorize your application.
I used the code you provided and with some minor tweaks and changes I was able to send an email using the Google Gmail API. The only down side the refresh token and original access token need to be stored in a database or file so the Google PHP API can review the tokens, but this limits the need to have to log back and reauthorize your app.
Authentication File -- This file should only be used once. It is to set the tokens in the database. After you set the tokens you can delete this file from your server.
<?php
require '/var/www/html/vendor/autoload.php'; // For Google Client Composer
// Replace this with your Google Client ID
$client_id = 'blabla.apps.googleusercontent.com';
$client_secret = 'secret';
$redirect_uri = 'https://www.redirecturl';
$client = new Google_Client();
$client->setClientId($client_id);
$client->setClientSecret($client_secret);
$client->setRedirectUri($redirect_uri);
$client->setAccessType('offline'); //Added for Refresh Token
$client->setApprovalPrompt('force'); //Added for Refresh Token
// We only need permissions to compose and send emails
$client->addScope("https://www.googleapis.com/auth/gmail.compose");
// Redirect the URL after OAuth
if (isset($_GET['code'])) {
$client->authenticate($_GET['code']);
$_SESSION['access_token'] = $client->getAccessToken();
}
// If Access Token is not set, show the OAuth URL
if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
$display = "display: none";
$client->setAccessToken($_SESSION['access_token']);
} else {
$authUrl = $client->createAuthUrl();
}
$access_token = $client->getAccessToken();
echo '<a href="'.$authUrl.'" style="'.$display.'">Authorize ME PLZ</a>';
if ($access_token != null) {
echo "You're In!";
}
// Saves Access Token Into Database to be Used In SEND_MAIL function
$mysqli = new mysqli('servername', 'username', 'password', 'database');
$stmt = $mysqli->prepare("INSERT INTO refresh_token (refresh, original) VALUES (?, ?)");
$stmt->bind_param("ss", json_encode($access_token), json_encode($access_token)); // Updated to remove warning
$stmt->execute();
$stmt->close();
?>
SEND_MAIL FUNCTION -- Gets values from database to authenticate Gmail API:
<?php
require '/var/www/html/vendor/autoload.php';
function SEND_MAIL($RECIPIENT,$EMAILSUBJECT,$EMAILBODY){
//Get Refresh Token From Database set when running Authentication File
$conn = new mysqli("servername", "username", "password", 'database');
$sql = "SELECT * FROM refresh_token";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
$token = $row['original'];
$refresh_token = $row['refresh'];
}
}
$conn->close();
// Replace this with your Google Client ID
$client_id = 'blabla.apps.googleusercontent.com';
$client_secret = 'secret';
$redirect_uri = 'https://www.redirecturl';
$client = new Google_Client();
$client->setClientId($client_id);
$client->setClientSecret($client_secret);
$client->setRedirectUri($redirect_uri);
$client->addScope("https://www.googleapis.com/auth/gmail.compose");
$client->setAccessType('offline');
$client->setApprovalPrompt('force');
$client->setAccessToken($token);
if ($client->isAccessTokenExpired()) {
$client->refreshToken($refresh_token);
$newtoken = $client->getAccessToken();
$client->setAccessToken($newtoken);
}
$service = new Google_Service_Gmail($client);
$fromemail = "<the-email-you-want-to-send-from>@gmail.com";
$strRawMessage = "From: Email <$fromemail> \r\n";
$strRawMessage .= "To: <$RECIPIENT>\r\n";
$strRawMessage .= 'Subject: =?utf-8?B?' . base64_encode($EMAILSUBJECT) . "?=\r\n";
$strRawMessage .= "MIME-Version: 1.0\r\n";
$strRawMessage .= "Content-Type: text/html; charset=utf-8\r\n";
$strRawMessage .= 'Content-Transfer-Encoding: quoted-printable' . "\r\n\r\n";
$strRawMessage .= "$EMAILBODY\r\n";
$mime = rtrim(strtr(base64_encode($strRawMessage), '+/', '-_'), '=');
$msg = new Google_Service_Gmail_Message();
$msg->setRaw($mime);
$service->users_messages->send("me", $msg);
}
SEND_MAIL('[email protected]', 'Test', 'Hey!');
?>
Upvotes: 3