Reputation: 432
I have donwloaded new Gmail API source code from Google PHP client library.
I inititalized the service using:
set_include_path("./google-api-php-client-master/src/".PATH_SEPARATOR.get_include_path());
require_once 'Google/Client.php';
require_once 'Google/Service/Gmail.php';
$client = new Google_Client();
$client->setClientId($this->config->item('gmailapi_clientid'));
$client->setClientSecret($this->config->item('gmailapi_clientsecret'));
$client->setRedirectUri(base_url('auth'));
$client->addScope('email');
//$client->addScope('profile');
$client->addScope('https://mail.google.com');
$client->setAccessType('offline');
$gmailService = new Google_Service_Gmail($client);
What should I do next? How to read Gmail messages using Gmail API PHP library?
Upvotes: 24
Views: 49084
Reputation: 5266
Building on the excellent answers from @Samphors and @Muffy, here is how you would do this in the MVC world of Symfony
My controller...
class GMailController extends AbstractController
{
/**
* @Route("/g/mail", name="app_g_mail")
*/
public function index(Request $request): Response
{
$code = $request->query->get('code');
return $this->render('g_mail/index.html.twig', [
'controller_name' => 'GMailController',
'code' => $code
]);
}
/**
* @Route("/g/mail/test", name="app_g_mail_test", methods={"POST"})
*/
public function test(Request $request) : Response
{
$filepath = '../client_secret.json';
$contents = file_get_contents($filepath);
$client = new Client();
$client->setApplicationName('Gmail_test');
$client->setAuthConfigFile($filepath);
$client->addScope('email');
$client->addScope('https://mail.google.com');
$client->setRedirectUri('https://localhost:8005/g/mail');
$client->setAccessType('offline');
// Redirect the URL after OAuth
$code = $request->request->get('code');
if ($code) {
error_log('code is set = '.$code);
$client->authenticate($code);
$_SESSION['access_token'] = $client->getAccessToken();
}
// If Access Toket is not set, show the OAuth URL
if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
error_log('setting access token');
$client->setAccessToken($_SESSION['access_token']);
} else {
error_log('creating authorization url');
$authUrl = $client->createAuthUrl();
error_log($authUrl);
return new JsonResponse(['success' => true, 'authUrl' => $authUrl]);
}
if ($client->getAccessToken()) {
$_SESSION['access_token'] = $client->getAccessToken();
// Prepare the message in message/rfc822
try {
$service = new Gmail($client);
$optParams = [];
$optParams['maxResults'] = 5; // Return Only 5 Messages
$optParams['labelIds'] = 'INBOX'; // Only show messages in Inbox
$messages = $service->users_messages->listUsersMessages('me',$optParams);
$list = $messages->getMessages();
$messageId = $list[0]->getId(); // Grab first Message
$optParamsGet = [];
$optParamsGet['format'] = 'full'; // Display message in payload
$message = $service->users_messages->get('me',$messageId,$optParamsGet);
$messagePayload = $message->getPayload();
$headers = $message->getPayload()->getHeaders();
$parts = $message->getPayload()->getParts();
$body = $parts[0]['body'];
$rawData = $body->data;
$sanitizedData = strtr($rawData,'-_', '+/');
$decodedMessage = base64_decode($sanitizedData);
return new JsonResponse(['success' => true, 'message' => $decodedMessage]);
} catch(Exception $e) {
error_log('in exception handler');
error_log($e);
return new JsonResponse(['success' => false, 'error' => $e->__toString()]);
}
}
return new JsonResponse(['success' => false]);
}
}
My twig template...
{% extends 'base.html.twig' %}
{% block title %}GMail API Bench{% endblock %}
{% block body %}
<div class="container m-5">
<div class="row my-2">
<div class="col-12">
<button type="button" class="btn btn-primary btn-lg" id="test-gmail-button">Test GMail API</button>
</div>
</div>
<div class="row my-2">
<h4><b>Authorization:</b></h4>
<div id="test-authorization">
<a id="authorization-link" href="#"></a>
</div>
<input type="hidden" id="gmail-authorization-code" value="{{ code }}">
{% if code is not null %}
<span class="text-success"><h4>Authorized</h4></span>
{% endif %}
</div>
<div class="row my-2">
<h4><b>Results:</b></h4>
<div id="test-results">
</div>
</div>
</div>
{% endblock %}
{% block javascripts %}
<script src="/static/site/js/gmail_bench.js?v=1.20230126"></script>
{% endblock %}
My client-side JavaScript...
$(document).ready(() => {
console.log('gmail_bench.js: in document ready')
})
$('#test-gmail-button').on('click', function(ev) {
console.log('test gmail');
let code = $('#gmail-authorization-code').val();
$.ajax({
url: '/g/mail/test',
type: 'POST',
data: {
code: code
},
success: function(data, textStatus) {
if(data.success) {
if(data.authUrl) {
$('#authorization-link').attr('href',data.authUrl);
$('#authorization-link').html('Authorize');
}
if(data.message) {
$('#test-results').empty().append(data.message);
}
} else {
$('#test-results').empty().append(data.error);
}
},
error: function(xhr, textStatus) {
console.log('in test gmail error');
console.log(xhr);
console.log(textStatus);
}
})
})
So the way this works is the first post to the test endpoint returns the authorization url. This is added as a link on the page...
Then after authorization, the OAuth2 code is added to the page...
Finally the second click on test butter sends the code and the email contents come back...
Upvotes: 0
Reputation: 1614
This is the sample code I used to develop an email ticketing system. It shows how to retrieve labels, messages, and headers.
<?php
require_once __DIR__ . '/vendor/autoload.php';
define('APPLICATION_NAME', 'Gmail API PHP Quickstart');
define('CREDENTIALS_PATH', '~/.credentials/gmail-php-quickstart.json');
define('CLIENT_SECRET_PATH', __DIR__ . '/client_secret.json');
// If modifying these scopes, delete your previously saved credentials
// at ~/.credentials/gmail-php-quickstart.json
define('SCOPES', implode(' ', array(
Google_Service_Gmail::GMAIL_READONLY)
));
if (php_sapi_name() != 'cli') {
throw new Exception('This application must be run on the command line.');
}
/**
* Returns an authorized API client.
* @return Google_Client the authorized client object
*/
function getClient() {
$client = new Google_Client();
$client->setApplicationName(APPLICATION_NAME);
$client->setScopes(SCOPES);
$client->setAuthConfig(CLIENT_SECRET_PATH);
$client->setAccessType('offline');
// Load previously authorized credentials from a file.
$credentialsPath = expandHomeDirectory(CREDENTIALS_PATH);
if (file_exists($credentialsPath)) {
$accessToken = json_decode(file_get_contents($credentialsPath), true);
} else {
// Request authorization from the user.
$authUrl = $client->createAuthUrl();
printf("Open the following link in your browser:\n%s\n", $authUrl);
print 'Enter verification code: ';
$authCode = trim(fgets(STDIN));
// Exchange authorization code for an access token.
$accessToken = $client->fetchAccessTokenWithAuthCode($authCode);
// Store the credentials to disk.
if(!file_exists(dirname($credentialsPath))) {
mkdir(dirname($credentialsPath), 0700, true);
}
file_put_contents($credentialsPath, json_encode($accessToken));
printf("Credentials saved to %s\n", $credentialsPath);
}
$client->setAccessToken($accessToken);
// Refresh the token if it's expired.
if ($client->isAccessTokenExpired()) {
$client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
file_put_contents($credentialsPath, json_encode($client->getAccessToken()));
}
return $client;
}
/**
* Expands the home directory alias '~' to the full path.
* @param string $path the path to expand.
* @return string the expanded path.
*/
function expandHomeDirectory($path) {
$homeDirectory = getenv('HOME');
if (empty($homeDirectory)) {
$homeDirectory = getenv('HOMEDRIVE') . getenv('HOMEPATH');
}
return str_replace('~', realpath($homeDirectory), $path);
}
/**
* Get list of Messages in user's mailbox.
*
* @param Google_Service_Gmail $service Authorized Gmail API instance.
* @param string $userId User's email address. The special value 'me'
* can be used to indicate the authenticated user.
* @return array Array of Messages.
*/
function listMessages($service, $userId, $optArr = []) {
$pageToken = NULL;
$messages = array();
do {
try {
if ($pageToken) {
$optArr['pageToken'] = $pageToken;
}
$messagesResponse = $service->users_messages->listUsersMessages($userId, $optArr);
if ($messagesResponse->getMessages()) {
$messages = array_merge($messages, $messagesResponse->getMessages());
$pageToken = $messagesResponse->getNextPageToken();
}
} catch (Exception $e) {
print 'An error occurred: ' . $e->getMessage();
}
} while ($pageToken);
return $messages;
}
function getHeaderArr($dataArr) {
$outArr = [];
foreach ($dataArr as $key => $val) {
$outArr[$val->name] = $val->value;
}
return $outArr;
}
function getBody($dataArr) {
$outArr = [];
foreach ($dataArr as $key => $val) {
$outArr[] = base64url_decode($val->getBody()->getData());
break; // we are only interested in $dataArr[0]. Because $dataArr[1] is in HTML.
}
return $outArr;
}
function base64url_decode($data) {
return base64_decode(str_pad(strtr($data, '-_', '+/'), strlen($data) % 4, '=', STR_PAD_RIGHT));
}
function getMessage($service, $userId, $messageId) {
try {
$message = $service->users_messages->get($userId, $messageId);
print 'Message with ID: ' . $message->getId() . ' retrieved.' . "\n";
return $message;
} catch (Exception $e) {
print 'An error occurred: ' . $e->getMessage();
}
}
function listLabels($service, $userId, $optArr = []) {
$results = $service->users_labels->listUsersLabels($userId);
if (count($results->getLabels()) == 0) {
print "No labels found.\n";
} else {
print "Labels:\n";
foreach ($results->getLabels() as $label) {
printf("- %s\n", $label->getName());
}
}
}
// Get the API client and construct the service object.
$client = getClient();
$service = new Google_Service_Gmail($client);
$user = 'me';
// Print the labels in the user's account.
listLabels($service, $user);
// Get the messages in the user's account.
$messages = listMessages($service, $user, [
#'maxResults' => 20, // Return 20 messages.
'labelIds' => 'INBOX', // Return messages in inbox.
]);
foreach ($messages as $message) {
print 'Message with ID: ' . $message->getId() . "\n";
$msgObj = getMessage($service, $user, $message->getId());
$headerArr = getHeaderArr($msgObj->getPayload()->getHeaders());
echo 'Message-ID: ' . $headerArr['Message-ID'];
echo "\n";
echo 'In-Reply-To: ' . (empty($headerArr['In-Reply-To']) ? '' : $headerArr['In-Reply-To']);
echo "\n";
echo 'References: ' . (empty($headerArr['References']) ? '': $headerArr['References']);
echo "\n";
#print_r($headerArr);
$bodyArr = getBody($msgObj->getPayload()->getParts());
echo 'Body: ' . (empty($bodyArr[0]) ? '' : $bodyArr[0]);
}
Reference:
https://developers.google.com/gmail/api/quickstart/php https://developers.google.com/gmail/api/v1/reference/users/messages/modify#php
Upvotes: 3
Reputation: 421
For the sake of demonstration, you can do something like this:
$optParams = [];
$optParams['maxResults'] = 5; // Return Only 5 Messages
$optParams['labelIds'] = 'INBOX'; // Only show messages in Inbox
$messages = $service->users_messages->listUsersMessages('me',$optParams);
$list = $messages->getMessages();
$messageId = $list[0]->getId(); // Grab first Message
$optParamsGet = [];
$optParamsGet['format'] = 'full'; // Display message in payload
$message = $service->users_messages->get('me',$messageId,$optParamsGet);
$messagePayload = $message->getPayload();
$headers = $message->getPayload()->getHeaders();
$parts = $message->getPayload()->getParts();
$body = $parts[0]['body'];
$rawData = $body->data;
$sanitizedData = strtr($rawData,'-_', '+/');
$decodedMessage = base64_decode($sanitizedData);
var_dump($decodedMessage);
Upvotes: 26
Reputation: 530
This is the full function, You can use it because It worked fine.
session_start();
$this->load->library('google');
$client = new Google_Client();
$client->setApplicationName('API Project');
$client->setScopes(implode(' ', array(Google_Service_Gmail::GMAIL_READONLY)));
//Web Applicaion (json)
$client->setAuthConfigFile('key/client_secret_105219sfdf2456244-bi3lasgl0qbgu5hgedg9adsdfvqmds5c0rkll.apps.googleusercontent.com.json');
$client->setAccessType('offline');
// 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()) {
$_SESSION['access_token'] = $client->getAccessToken();
// Prepare the message in message/rfc822
try {
// The message needs to be encoded in Base64URL
$service = new Google_Service_Gmail($client);
$optParams = [];
$optParams['maxResults'] = 5; // Return Only 5 Messages
$optParams['labelIds'] = 'INBOX'; // Only show messages in Inbox
$messages = $service->users_messages->listUsersMessages('me',$optParams);
$list = $messages->getMessages();
$messageId = $list[0]->getId(); // Grab first Message
$optParamsGet = [];
$optParamsGet['format'] = 'full'; // Display message in payload
$message = $service->users_messages->get('me',$messageId,$optParamsGet);
$messagePayload = $message->getPayload();
$headers = $message->getPayload()->getHeaders();
$parts = $message->getPayload()->getParts();
$body = $parts[0]['body'];
$rawData = $body->data;
$sanitizedData = strtr($rawData,'-_', '+/');
$decodedMessage = base64_decode($sanitizedData);
var_dump($decodedMessage);
} catch (Exception $e) {
print($e->getMessage());
unset($_SESSION['access_token']);
}
}
// If there is no access token, there will show url
if ( isset ( $authUrl ) ) {
echo $authUrl;
}
Upvotes: 12
Reputation: 9225
I'd start here: https://developers.google.com/gmail/api/v1/reference/users/messages/list and https://developers.google.com/gmail/api/v1/reference/users/messages/get
note that when you get a list of messages only the IDs of those messages are returned then you use the ID with the get method to actually get the message content:
Upvotes: 2