1. Call the following in command line:
composer require google/apiclient
2. In your composer.json file add the following :
{
"autoload":
{
"classmap": [
"vendor/google/apiclient/src/Google"
],
}
}
3. In your http://console.developers.google.com Create a new Client ID in Credentials, Select OAuth 2.0 client ID and click on Create Client ID.
4. In the config folder, add a file name google.php, place and modify the following content
<?php
return [
'client_id' => 'your client id',
'client_secret' => 'yout client secret',
'redirect_uri' => 'rederect uri that you set in developers console', ];
5. In your application folder, I have added a file named GoogleGmail.php in App\Services with the following content :
<?php
namespace App\Services;
use App\GmailEmail;
use Google_Client;
use Google_Service_Gmail;
use Illuminate\Support\Facades\Config;
use PhpSpec\Exception\Exception;
class GoogleGmail
{ protected $client; protected $service; protected $auth_url; protected $defaultUserId; protected $batch; //Get config variables function __construct() { session_start(); $this->defaultUserId = 'me'; $this->client = new Google_Client(); $this->client->setClientId(Config::get('google.client_id')); $this->client->setClientSecret(Config::get('google.client_secret')); $this->client->setRedirectUri(Config::get('google.redirect_uri'));$this->client->addScope([Google_Service_Gmail::MAIL_GOOGLE_COM, Google_Service_Gmail::GMAIL_MODIFY, Google_Service_Gmail::GMAIL_READONLY]);
$this->client->setAccessType("offline"); $this->auth_url = $this->client->createAuthUrl(); $this->service = new Google_Service_Gmail($this->client);if (isset($_REQUEST['logout'])) {
unset($_SESSION['access_token']); }if(isset($_GET['code'])) {
$this->client->authenticate($_GET['code']);$_SESSION['access_token'] = $this->client->getAccessToken(); }
}
// @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
public function redirectToAuth()
{
//redirect to get access code
return redirect($this->auth_url); }
// @param null $optParam
// @return array
public function getEmailsList() //get list of gmail emails id's
{if(isset($_SESSION['access_token'])) {
$this->client->setAccessToken($_SESSION['access_token']); $messages = $this->listMessages($this->service, $this->defaultUserId);return $messages;
}}
//send get request to google for gmail email contents
// @param null $list
// @return array
public function getMailsContents($list = null)
{ $messagesContents = [];if($list) {
foreach($list as $k => $v) {
$content = $this->messagesGetRequest($v->id); array_push($messagesContents, $content); } } return $messagesContents;}
// @param null $id
// @return array|string
public function messagesGetRequest($id = null)
{if($id) {
$data = $this->service->users_messages->get($this->defaultUserId, $id,
['format' => 'full', 'fields' => 'historyId, id, internalDate, labelIds, payload, raw, sizeEstimate, threadId'
]); $payLoad = $data->getPayload(); $headers = $payLoad->getHeaders(); $parts = $payLoad->getParts(); $mimeType = $payLoad->getMimeType(); $body = $payLoad->getBody()->getSize() ? $payLoad->getBody()->getData(): null;$parsedEmail = [ 'mail_id' => $data->id, 'history_id' => $data->historyId, 'thread_id' => $data->threadId, 'internal_date' => $data['modelData']['internalDate']
];foreach ($headers as $header) {
switch ($header['name']) {
case 'To': $parsedEmail['received_to'] = $header['value']; break;case 'From': $parsedEmail['received_from'] = $header['value'];
break; case 'Subject': $parsedEmail['subject'] = $header['value']; break; case 'Date': $parsedEmail['date'] = $header['value']; break; default: break; }}
$parsedEmail['content_body_plain'] = $body && $mimeType === 'text/plain' ? $body : $this->getBodyContentByGmail($parts, true);
$parsedEmail['content_body_html'] = $body && $mimeType === 'text/html' ? $body : $this->getBodyContentByGmail($parts, false);
return $parsedEmail; } else { return ''; }}
//this method we use to get ids of all messages in our getEmailsList() method /**
// @param $service
// @param $userId
// @return array */public function listMessages($service, $userId)
{ $pageToken = NULL; $messages = array(); $opt_param = array(); do { try {if ($pageToken) {
$opt_param['pageToken'] = $pageToken; } $messagesResponse = $service->users_messages->listUsersMessages($userId,$opt_param);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;}
//get new messages id's list /**
// @return array
public function listHistory()
{
$service = $this->service; $userId = $this->defaultUserId; $startHistoryId = null; $opt_param = array('startHistoryId' => $startHistoryId); $pageToken = NULL; $histories = array(); $newestMessage = GmailEmail::orderBy('internal_date','desc')->first(); $opt_param['startHistoryId'] = $newestMessage->history_id; do { try {if($pageToken) {
$opt_param['pageToken'] = $pageToken; } $historyResponse = $service->users_history->listUsersHistory($userId, $opt_param);if ($historyResponse->getHistory()) {
$histories = array_merge($histories, $historyResponse->getHistory());
$pageToken = $historyResponse->getNextPageToken();}
} catch(Exception $e){
print 'An error occurred: ' . $e->getMessage(); } } while ($pageToken); return $histories;}
//extract body content from gmail messages /**
// @param null $parts
// @return mixed
public function getBodyContentByGmail($parts = null, $getPlain = false)
{if($parts) {
foreach($parts as $part) {
if($part->getBody()->getSize()) {
if($part->getMimeType() === 'text/plain' && $getPlain) {
return $part->getBody()->getData(); }if($part->getMimeType() === 'text/html') {
return $part->getBody()->getData(); } } $innerParts = $part->getParts();foreach($innerParts as $innerPart) {
if($innerPart->getMimeType() === 'text/plain' && $getPlain) {
return $innerPart->getBody()->getData(); }if($innerPart->getMimeType() === 'text/html') {
return $innerPart->getBody()->getData(); }}
}
}
}
//save our messages to db
//@param null $mails
public function saveMailsToDb($mails = null)
{if($mails) {
foreach($mails as $mail) {
GmailEmail::firstOrCreate($mail); } }}
//convert history list to messages list
//@param null $historyList
//@return array
public function prepareHistoryList($historyList = null)
{ $messagePartCollection = []; $itemArray = null;if($historyList) {
foreach($historyList as $historyItem) {
$itemArray = $historyItem->getMessages(); $itemArray = array_values($itemArray)[0]; array_push($messagePartCollection, $itemArray); } } return $messagePartCollection; }}
6. And create GmailController to use this service:
<?php
namespace App\Http\Controllers\Api;
use App\GmailEmail;
use App\Http\Controllers\ApiController;
use App\Services\GoogleGmail;
use Illuminate\Support\Facades\Redirect;
class GmailController extends ApiController
{ protected $gmailService; function __construct(GoogleGmail $googleGmail) { $this->gmailService = $googleGmail; }//get code access /**
// @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector public function googleAuth(){ return $this->gmailService->redirectToAuth();
}
// get list of messages , get their contents and save all data to db
public function getEmails(){ $messagesList = null;
$messages = GmailEmail::all();
if(!$messages) {
$messagesList = $this->gmailService->getEmailsList();} else {
$messagesHistoryList = $this->gmailService->listHistory(); $messagesList = $this->gmailService->prepareHistoryList($messagesHistoryList);}
$messagesContents = $this->gmailService->getMailsContents($messagesList);
$this->gmailService->saveMailsToDb($messagesContents);
return redirect(url('/dashboard/messages/gmail/emails')); }}