Skip to content

Instantly share code, notes, and snippets.

@floriankapaun
Last active September 6, 2021 09:24
Show Gist options
  • Save floriankapaun/1f607727b07d73dae4deb1429a9d5dbe to your computer and use it in GitHub Desktop.
Save floriankapaun/1f607727b07d73dae4deb1429a9d5dbe to your computer and use it in GitHub Desktop.
Create, send and read E-Mails from Gmail API with Symfony (PHP)
<?php
namespace App\Command;
use App\Service\MailboxAdministrationService;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
/**
* Fetches E-Mails with their Details from Gmail Inbox
* Run this Command in your command line via: php bin/console app:fetch-email-details 5
*/
class FetchEmailDetailsCommand extends Command
{
protected static $defaultName = 'app:fetch-email-details';
private $mailboxAdministrationService;
public function __construct(MailboxAdministrationService $mailboxAdministrationService)
{
parent::__construct();
$this->mailboxAdministrationService = $mailboxAdministrationService;
}
protected function configure(): void
{
$this
->setDescription('Fetch E-Mails with their Details from Gmail Inbox')
// configure an argument
->addArgument(
'maxItems',
InputArgument::REQUIRED,
'The maximum amount of items to fetch and process.'
);
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$this->mailboxAdministrationService->fetchEmailDetails(
$input->getArgument('maxItems')
);
return Command::SUCCESS;
}
}
<?php
namespace App\Service;
/**
* Service to create a Gmail client.
*
* Basically copied from the Gmail API PHP Quickstart Tutorial with a few minor adaptations.
* See: https://developers.google.com/gmail/api/quickstart/php#step_2_set_up_the_sample
*/
class GmailService
{
public function getClient()
{
$client = new \Google_Client();
$client->setApplicationName('YOUR_APPLICATION_NAME');
$client->setScopes(array(
\Google_Service_Gmail::MAIL_GOOGLE_COM,
\Google_Service_Gmail::GMAIL_COMPOSE
));
// \Google_Service_Gmail::GMAIL_READONLY
$client->setAuthConfig(dirname(__DIR__, 2) . '/config/credentials/gmail-credentials.json');
$client->setAccessType('offline');
$client->setPrompt('select_account consent');
// Load previously authorized token from a file, if it exists.
// The file token.json stores the user's access and refresh tokens, and is
// created automatically when the authorization flow completes for the first
// time.
$tokenPath = dirname(__DIR__, 2) . '/token.json';
if (file_exists($tokenPath)) {
$accessToken = json_decode(file_get_contents($tokenPath), true);
$client->setAccessToken($accessToken);
}
// If there is no previous token or it's expired.
if ($client->isAccessTokenExpired()) {
// Refresh the token if possible, else fetch a new one.
if ($client->getRefreshToken()) {
$client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
} 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);
$client->setAccessToken($accessToken);
// Check to see if there was an error.
if (array_key_exists('error', $accessToken)) {
throw new Exception(join(', ', $accessToken));
}
}
// Save the token to a file.
if (!file_exists(dirname($tokenPath))) {
mkdir(dirname($tokenPath), 0700, true);
}
file_put_contents($tokenPath, json_encode($client->getAccessToken()));
}
return $client;
}
}
<?php
namespace App\Service;
use App\Service\GmailService;
class MailboxAdministrationService
{
private $gmailService;
private $gmail;
public function __construct(GmailService $gmailService) {
$this->gmailService = $gmailService;
$client = $this->gmailService->getClient();
$this->gmail = new \Google_Service_Gmail($client);
}
/**
* @param $from string sender email address
* @param $to string recipient email address
* @param $subject string email subject
* @param $messageText string email text
* @return Google_Service_Gmail_Message
*/
function createMessage($from, $to, $subject, $messageText)
{
$message = new \Google_Service_Gmail_Message();
$rawMessageString = "From: <{$from}>\r\n";
$rawMessageString .= "To: <{$to}>\r\n";
$rawMessageString .= 'Subject: =?utf-8?B?' . base64_encode($subject) . "?=\r\n";
$rawMessageString .= "MIME-Version: 1.0\r\n";
$rawMessageString .= "Content-Type: text/html; charset=utf-8\r\n";
$rawMessageString .= 'Content-Transfer-Encoding: quoted-printable' . "\r\n\r\n";
$rawMessageString .= "{$messageText}\r\n";
$rawMessage = strtr(base64_encode($rawMessageString), array('+' => '-', '/' => '_'));
$message->setRaw($rawMessage);
return $message;
}
/**
* @param $message Google_Service_Gmail_Message
* @return null|Google_Service_Gmail_Message
*/
function sendMessage($message)
{
try {
$message = $this->gmail->users_messages->send('me', $message);
return $message;
} catch (Exception $e) {
print 'An error occurred: ' . $e->getMessage();
return false;
}
return null;
}
/**
* Fetches E-Mails and their Details from Gmail Inbox, then logs them
*/
public function fetchEmailDetails(int $maxItems = 10)
{
$list = $this->gmail->users_messages->listUsersMessages('me', [
'maxResults' => $maxItems,
]);
// Fetch E-Mail Details
$detailedList = [];
foreach ($list->getMessages() as $mail) {
$detailedList[] = $this->gmail->users_messages->get('me', $mail->id, [
'format' => 'full'
]);
}
// Print them
print_r($detailedList);
return 'done';
}
/**
* Can be used to decode an HTML E-Mails Body to plain Text
*/
public function parseMailBody(string $body): string
{
$body = str_replace(array('-', '_'), array('+', '/'), $body);
$body = base64_decode($body);
// Just some examples on how to replace HTML Tags
$body = str_replace(array('<br>', '</br>', '<strong>', '</strong>'), '', $body);
$body = str_replace('&nbsp;', ' ', $body);
return $body;
}
}
@floriankapaun
Copy link
Author

To authenticate with the Gmail API check out Googles PHP Quickstart Guide.

If you need authentication that lasts longer than seven days, follow the steps described in this Stackoverflow answer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment