Laravel wrapper for the Gmail API

Overview

Laravel Gmail

Build Status Scrutinizer Code Quality GitHub issues Total Downloads Monthly Downloads GitHub license

Gmail

Gmail API for Laravel 8

You need to create an application in the Google Console. Guidance here.

if you need Laravel 5 compatibility please use version 2.0.x. if you need Laravel 6 compatibility please use version 3.0.x. if you need Laravel 7 compatibility please use version 4.0.x.

Requirements

  • PHP ^7.4|^8.0
  • Laravel 8

Installation

Add dacastro4/laravel-gmail to composer.json.

"dacastro4/laravel-gmail": "^5.1"

Run composer update to pull down the latest version.

Or run

composer require dacastro4/laravel-gmail

Now open up config/app.php and add the service provider to your providers array.

'providers' => [
    Dacastro4\LaravelGmail\LaravelGmailServiceProvider::class,
]

Now add the alias.

'aliases' => [
    'LaravelGmail' => Dacastro4\LaravelGmail\Facade\LaravelGmail::class,
]

For laravel >=5.5 that's all. This package supports Laravel new Package Discovery.

For <= PHP 7.4 compatibility use version v5.0

Migration from 4.0 to 5.0

Requires Laravel 8 and you have to change the dependency to "laravel/laravel": "^8.0" Please, follow Upgrading To 8.0 From 6.x Guide

Migration from 3.0 to 4.0

Requires Laravel 7 and you have to change the dependency to "laravel/laravel": "^7.0" Please, follow Upgrading To 7.0 From 6.x Guide

Migration from 2.0 to 3.0

Requires Laravel 6 and you only have to change the dependency to "laravel/laravel": "^6.0"

Migration from 1.0 to 2.0

The only changed made was the multi credentials feature.

  • Change your composer.json from "dacastro4/laravel-gmail": "^1.0" to "dacastro4/laravel-gmail": "^2.0"

I had to change version because of a typo and that might break apps calling those attributes.

All variable with the word "threat" was change to "thread" (yeah, I know.. sorry) Ex:

Mail Class $threatId => $threadId

Replyable Class $mail->setReplyThreat() => $mail->setReplyThread()

and so on.

Migration from 0.6 to 1.0

The only changed made was the multi credentials feature.

  • Change your composer.json from "dacastro4/laravel-gmail": "^0.6" to "dacastro4/laravel-gmail": "^1.0"

If you don't want the multi user credentials, you don't have to do anything else, if you do, you're going to have to login again to create a new credentials file per user.

Configuration

You only have to set the following variables on your .env file and you'll be on your way:

GOOGLE_PROJECT_ID=
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
GOOGLE_REDIRECT_URI=
GOOGLE_ALLOW_MULTIPLE_CREDENTIALS
GOOGLE_ALLOW_JSON_ENCRYPT

To modify the scopes and the credentials file name, just run:

Run php artisan vendor:publish --provider="Dacastro4\LaravelGmail\LaravelGmailServiceProvider" and modify the config file config/gmail.php.

Allow multi user credentials

To allow multi user credentials change allow_multiple_credentials to true in your config file or set the .env variable GOOGLE_ALLOW_MULTIPLE_CREDENTIALS to true if you're not using the config file.

Allow encryption for json files

To allow encryption for json files change allow_json_encrypt to true in your config file or set the .env variable GOOGLE_ALLOW_JSON_ENCRYPT to true if you're not using the config file.

Available Scopes

  • all (this one doesn't exists on Gmail Scopes, I added it.)
  • compose
  • insert
  • labels
  • metadata
  • modify
  • readonly
  • send
  • settings_basic
  • settings_sharing

More about Gmail API scopes

Note: To change the scopes, users have to logout and login again.

Additional Scopes

If for some reason you need to add additional scopes.

Add additional scopes in URL Style in config/gmail.php

 'additional_scopes' => [
            'https://www.googleapis.com/auth/drive',
            'https://www.googleapis.com/auth/documents',
            'https://www.googleapis.com/auth/spreadsheets'
    ],

Example

Welcome Blade:

<body>
    <h1>{{ LaravelGmail::user() }}</h1>
    @if(LaravelGmail::check())
        <a href="{{ url('oauth/gmail/logout') }}">logout</a>
    @else
        <a href="{{ url('oauth/gmail') }}">login</a>
    @endif
</body>

Routes:

Route::get('/oauth/gmail', function (){
    return LaravelGmail::redirect();
});

Route::get('/oauth/gmail/callback', function (){
    LaravelGmail::makeToken();
    return redirect()->to('/');
});

Route::get('/oauth/gmail/logout', function (){
    LaravelGmail::logout(); //It returns exception if fails
    return redirect()->to('/');
});

Then if in your controller or wherever you want to do your logic, you do something like:

$messages = LaravelGmail::message()->subject('test')->unread()->preload()->all();
foreach ( $messages as $message ) {
    $body = $message->getHtmlBody();
    $subject = $message->getSubject();
}

Note that if you don't preload the messages you have to do something like: $body = $message->load()->getSubject(); and after that you don't have to call it again.

Documentation

Basic

LaravelGmail::getAuthUrl Gets the URL to auth the user.

LaravelGmail::redirect You can use this as a direct method <a href="{{ LaravelGmail::redirect() }}">Login</a>

LaravelGmail::makeToken() Set and Save AccessToken in json file (useful in the callback)

LaravelGmail::logout Logs out the user

LaravelGmail::check Checks if the user is logged in

LaravelGmail::setUserId($account_id)->makeToken() Set and Save AccessToken for $account_id (added v5.1.2)

Sending

use Dacastro4\LaravelGmail\Services\Message\Mail;

...

$mail = new Mail;

For to, from, cc and bcc, you can set an array of emails and name or a string of email and name.

$mail->using( $token ) If you don't want to use the token file, you can use this function that sets the token to use in the request. It doesn't refresh

$mail->to( $to, $name = null ) sets the recipient email and name as optional

$mail->from( $from, $name = null ) sets sender's email

$mail->cc( $cc, $name = null ) sets carbon copy

$mail->bcc( $bcc, $name = null ) sets a blind carbon copy

$mail->subject( $subject ) sets the subject of the email

$mail->message( $message ) sets the body of the email

$mail->view( 'view.name', $dataArray ) sets the body from a blade file

$mail->attach( ...$path ) add file attachments to the email

$mail->priority( $priority ) sets the priority of the email from 1 to 5

$mail->reply() replies to an existent email

$mail->send() sends a new email

$mail->setHeader( $header, $value ) sets header to the email

Mail

$mail->getId returns the email's ID

$mail->getInternalDate returns date in UNIX format

$mail->getDate returns a Carbon date from the header of the email

$mail->getLabels returns an array of all the labels of the email

$mail->getHeaders returns a collection of the header. Each header is an array with two rows key and value

$mail->getSubject returns an string of the subject

$mail->getFrom Returns an array with name and email of sender

$mail->getFromName Returns string of name

$mail->getFromEmail Returns string of email

$mail->getTo Returns an array with name and email of all recipients

$mail->getDeliveredTo Returns the email of the receiver

$mail->getPlainTextBody Returns the plain text version of the email

$mail->getRawPlainTextBody Returns the raw version of the body base64 encrypted

$mail->hasAttachments Returns a boolean if the email has attachments

$mail->load Load all the information of the email (labels, body, headers). You call this function on a single email. To load from the beginning see preload()

$mail->getHeader( $headerName, $regex = null ) Returns the header by name. Optionally, you can execute a regex on the value

Labels

$mail->markAsRead Removes the 'UNREAD' label from the email.

$mail->markAsUnread Adds the 'UNREAD' label to the email.

$mail->markAsImportant Adds the 'IMPORTANT' label to the email.

$mail->markAsNotImportant Removes the 'IMPORTANT' label from the email.

$mail->addStar Adds the 'STARRED' label to the email.

$mail->removeStar Removes the 'STARRED' label from the email.

$mail->sendToTrash Adds the 'TRASH' label to the email.

$mail->removeFromTrash Removes the 'TRASH' label from the email.

$mail->addLabel($string|$array) Add multiple or single label to the email

$mail->removeLabel($string|$array) Removes multiple or single label from the email

$mail->getAttachments() Get a collection of all the attachments on the email

$mail->getAttachmentsWithData() Get a collection of all the attachments on the email including the data

Attachment

use Dacastro4\LaravelGmail\Services\Message\Attachment
...

$attachment = new Attachment;

$attachment->getId Returns the ID of the attachment

$attachment->getFileName Returns the file name of the attachment

$attachment->getMimeType Returns the mime type Ex: application/pdf

$attachment->getSize Returns the size of the attachment in bytes

$attachment->getData Get the all the information from the attachment. If you call getAttachmentsWithData you won't need this method.

$attachment->saveAttachmentTo($path = null, $filename = null, $disk = 'local') Saves the attachment on the storage folder. You can pass the path, name and disk to use.

Messages

LaravelGmail::message()->all( $pageToken = null ) Returns all the emails from the inbox

LaravelGmail::message()->take(2)->all( $pageToken = null ) The take method limits the emails coming from the query by the number set

LaravelGmail::message()->get( $id ) Returns a single email with all the information

Modifiers

You can modify your query with these methods. For example:

To get all unread emails: LaravelGmail::message()->unread()->all()

message()->unread()

message()->from( $email )

message()->in( $box = 'inbox' )

message()->hasAttachment()

message()->subject($subject)

->after($date) and ->before($date)

message()->raw($query) for customized queries

All the possible filters are in the Filterable Trait

Of course you can use as a fluent api.

    
    LaravelGmail::message()
                ->from('[email protected]')
                ->unread()
                ->in('TRASH')
                ->hasAttachment()
                ->all()

Preload

You can preload the body, header and the rest of every single email just by calling this method.

LaravelGmail::preload()

Example:

    
    LaravelGmail::message()
                ->from('[email protected]')
                ->unread()
                ->in('TRASH')
                ->hasAttachment()
                ->preload()
                ->all()

Watch

https://developers.google.com/gmail/api/reference/rest/v1/users/watch

Example:

    $mailbox = new LaravelGmailClass(config(), $account->id);
    
    // One watch per account + need reinit every 24h+
    $mailbox->stopWatch('[email protected]');

    // Set watch for topic
    $rq = new \Google_Service_Gmail_WatchRequest();
    $rq->setTopicName('projects/YOUR_PROJECT_ID/topics/gmail');
    $mailbox->setWatch('[email protected]', $rq);

History

https://developers.google.com/gmail/api/reference/rest/v1/users.history

Example:

    $historyList = (new LaravelGmailClass(config(), $account->id))
        ->historyList($data['emailAddress'], [
            'startHistoryId' => $startHistoryId,
        ]);
    foreach ($historyList->history as $chunk) {
        foreach ($chunk->messages as $msg) {
            ...
        }
    }

Frequent Issues

Login Required

If you're getting the Login Required error, try creating the gmail-json.json file under /storage/app/gmail/tokens/.

Comments
  • Error getting message

    Error getting message

    I get the following error:

       Symfony\Component\Debug\Exception\FatalThrowableError  : Argument 1 passed to Dacastro4\LaravelGmail\Services\Message\Mail::__construct() must be an instance of Google_Service_Gmail_Message or null, instance of GuzzleHttp\Psr7\Request given, called in /Users/erin/Sites/fitnessmd/vendor/dacastro4/laravel-gmail/src/Services/Message.php on line 126
    
      at /Users/erin/Sites/fitnessmd/vendor/dacastro4/laravel-gmail/src/Services/Message/Mail.php:74
        70| 	 *
        71| 	 * @param \Google_Service_Gmail_Message $message
        72| 	 * @param bool $preload
        73| 	 */
      > 74| 	public function __construct(\Google_Service_Gmail_Message $message = null, $preload = false)
        75| 	{
        76| 
        77| 		$this->service = new Google_Service_Gmail($this);
        78| 
    
      Exception trace:
    
      1   Dacastro4\LaravelGmail\Services\Message\Mail::__construct(Object(GuzzleHttp\Psr7\Request))
          /Users/erin/Sites/fitnessmd/vendor/dacastro4/laravel-gmail/src/Services/Message.php:126
    
      2   Dacastro4\LaravelGmail\Services\Message::get("16dd798f2f62fdb3")
          /Users/erin/Sites/fitnessmd/app/Console/Commands/GetGmailMessages.php:47
    

    When I do this in code:

            $messages = LaravelGmail::message()->unread()->preload()->all();
    
            foreach ($messages as $message) {
                $get_message = LaravelGmail::message()->get($message->getID());
    

    What am I doing wrong?

    opened by edalzell 20
  • Batch Request ?

    Batch Request ?

    Using this package I am able to do What I want but while fetching gmail messages it takes lot of time to get those emails so I found out that we get message id and then using this id we have to get particular message. The reason I understood is we are making multiple call for every email and thats the reason getting emails takes lot of time. Now how do I do it using Batch Request ?

    opened by abhiburk 17
  • getBody on null

    getBody on null

    I found great use of your package however the function getBodyPart() in the file Services/Messages/mail.php line 350 has the option to return null to a function which later calls getBody() on the returned value. And if you call getBody on null it throws a fatal error.

    I found that only messages from icloud causes this problem since gmail's own library sets the body (plaintext) in the payload object rather than in a part.

    As you can see in the images below, one email object does not have parts, it was recieved from an icloud account and the second from a gmail account, however i have tried with yahoo, hotmail and privately hosted mail servers aswell, and those work.

    A suggestion is to do a check first to see if the payload has parts to begin with, and if not extract the data from the payload body itself.

    withparts withoutpart

    opened by buckfuddey 16
  •  InvalidArgumentException in Client.php line 433: Invalid token format

    InvalidArgumentException in Client.php line 433: Invalid token format

    Hello! Help me pls!

    1. Can't understand how to modify the config file config/gmail.php. What to do inside of it? project id,client id,client secret and redirect I set in .env file. Is it necessary to do something with this string ↓ ? 'credentials_file_name' => env( 'GOOGLE_CREDENTIALS_NAME', 'gmail-json' ),

    2. I downloaded .json credentials file from google console, pasted it to: "[my project]/storage/app/gmail/tokens" then I renamed it to: 'gmail-json.json' Is it right?

    opened by Artanty 15
  • Page token missing

    Page token missing

    Page token is missing when using limit data.

    LaravelGmail::message()->limit(10)->in( $box = 'inbox' )->preload()->all();

    How can i access pagetoken.

    opened by shanwazfarooqe 13
  • Can't login with multiple users?

    Can't login with multiple users?

    I have tried setting GOOGLE_ALLOW_MULTITPLE_CREDENTIALS=true in the env file (and refreshing config cache) as well as hardcoding 'allow_multiple_credentials' => true in config/gmail.php.

    But when I login as a User A in one browser, then log in as User B in a different browser, I can only see the data for User A. If I take a look at storage/app/gmail/tokens/ there's only one gmail-json file and when I open it, only the details for User A are in there.

    I'm sure I'm missing something obvious here, but hoping someone can help!

    opened by mcgregorjamie 12
  • Store credentials for multiple users

    Store credentials for multiple users

    I understand that the package is still under development but I just wanted to bring out this issue. At the moment, the credentials file is used to store credentials for only one user. You would have to logout the current user from Gmail so as to get authorization from another user. It would be great to have support for multiple users having their credentials stored in different files (or perhaps same file). This way, when using LaravelGmail::message()->using($token)->all() to specify a different token specific to the current user.

    Here's a similar scenario I experienced. Let's assume we have two users, User A and User B. User A will have their token stored in the credentials file after they authorize our app with Gmail. Now when we try to get the token with LaravelGmail::makeToken() for User B without first logging out User A from Gmail, the LaravelGmail::check() method fails and so the token previously stored for User A will be used for User B. So User B ends up retrieving emails of User A.

    enhancement help wanted 
    opened by jmatembu 11
  • How to send an email?

    How to send an email?

    Thanks again for the awesome package. I'm having troubles sending an email because I don't know what I should be instantiating it with. Current code (that doesn't work):

      $mail = LaravelGmail::message()->to($data['to'])->from('[email protected]')->subject($subject)->message($texteditor)->send();
    

    I don't think this is it.. Haha.

    Would you have any objections to having some helpers to tie it to an existing email in App\User ? I have some updated code that's working for me and I don't mind putting in a PR for it.

    opened by rsmith87 9
  • How to use the multiple credentials?

    How to use the multiple credentials?

    Thanks for the great package, but I'm not sure how to use the multiple credentials for multiple accounts on my backend. Can someone please tell me how to use it?

    opened by alalfakawma 8
  • Gmail returning null Values for email related fields

    Gmail returning null Values for email related fields

    $messages = LaravelGmail::message()->take(1)->all( $pageToken = null ); dd($messages); in requested scopes, it is returning follwing three: #requestedScopes: array:3 [▼ 0 => "https://www.googleapis.com/auth/gmail.readonly" 1 => "https://www.googleapis.com/auth/gmail.modify" 2 => "https://www.googleapis.com/auth/gmail.metadata" ] it is returning null values for email related fields like, to, from, message, to? what might be the reason? #additionalScopes: [] -messageRequest: Google_Service_Gmail_ModifyMessageRequest {#554 ▶} -swiftMessage: Swift_Message {#525 ▶} -parameters: [] -message: null -subject: null -from: null -nameFrom: null -to: null -nameTo: null -cc: null -nameCc: null -bcc: null -nameBcc: null -attachments: [] -priority: 2why dd is showing null for email related parameters? how can I read my emails contents? this is our personal app and we need to access only our personal Gmail emails in our app. Do I need to enable additional scopes to read my emails in Laravel app ? I published gmail.php in config folder using command, added additional scopes also, it's requesting additional scope, but still I am receiving null for email related fields when I dd the $messages = LaravelGmail::message()->take(1)->all( $pageToken = null ); dd($messages); all email related fields like, to, from, message are null in the array returned using dd

    opened by Luqman6666 8
  • Manual input of json file name

    Manual input of json file name

    Great solution, thanks. Is it possible to somehow transfer the name of the json file when calling LaravelGmail :: without recourse to authorization? To be able to work with several confirmed accounts simultaneously, from one laravel account.

    opened by igorhmelevskoy 8
  • refresh_token missing

    refresh_token missing

    Hello guys,

    I'm facing to one issue with the refesh token, btw i check my gmail-json.json and inside i have the access_token but i didn't have the refresh_token which create some issues

    my allow_multiple_credentials is false,

    does anyone met this issue before ?

    Best

    opened by i-polaris 1
  • Set a RefreshToken

    Set a RefreshToken

    Hi. Take into the consideration for future updates to include a custom option to set refreshToken trought env with fetchAccessTokenWithRefreshToken().

    opened by oriceon 0
  • Is it possible to login with just the API Key ?

    Is it possible to login with just the API Key ?

    Hello there,

    I am creating a cron that must fetch the inbox every X minutes to check for new emails and upload attachement somewhere within my app. Question is, I mainly use that in CLI and there is no login/logout consent screen or anything like that since I'm the owner of the gmail account and this feature will be totally invisible for end user.

    Is there a way to skip the OAuth and just use the API key ? Only thing i need is to read email, get attachments and move email.

    Thanks ^^

    opened by DavidSprauel 2
  • How i check multi user login

    How i check multi user login

    i set userid for multiuser login $agence_id = request()->session()->get('userdata')->agence_id; LaravelGmail::setUserId($agence_id)->makeToken(); but how i check user it's login or not in dashboard

    opened by rahulkifwat 0
Releases(v6.0)
Owner
Daniel Castro
Daniel Castro
Mollie API client wrapper for Laravel & Mollie Connect provider for Laravel Socialite

Mollie for Laravel Laravel-Mollie incorporates the Mollie API and Mollie Connect into your Laravel or Lumen project. Accepting iDEAL, Apple Pay, Banco

Mollie 289 Nov 24, 2022
Laravel wrapper package for the Aimon.it API

Laravel Aimon Package A laravel wrapper package for the Aimon.it API. For more information see Aimon Requirements Laravel 6 or later Installation Inst

Ruslan 3 Aug 7, 2022
Laravel API wrapper to interact fluently with your Janus Media Server

Laravel API wrapper to interact fluently with your Janus Media Server. Core server interactions, as well as the video room plugin included.

Richard  Tippin 11 Aug 21, 2022
Open Food Facts API wrapper for Laravel

Laravel Open Food Facts API This package provides a convenient wrapper to the Open Food Facts API for Laravel applications (5.7+). Installation You ca

Open Food Facts 112 Jan 4, 2023
a Google API v3 wrapper for Laravel 4.x

A Google API v3 wrapper for Laravel 4 This package enables a Laravel flavoured way to manage Google services through its API interface (v3) Installati

null 4 Nov 29, 2022
Laravel wrapper for Sentry Official API

Laravel Sentry API Provides a simple laravel wrapper to some of the endpoints listed on (Official Sentry API)[https://docs.sentry.io/api/]. **Note: Th

Pedro Santiago 1 Nov 1, 2021
Simple and ready to use API response wrapper for Laravel.

Laravel API Response Simple Laravel API response wrapper. Installation Install the package through composer: $ composer require obiefy/api-response Re

Obay Hamed 155 Dec 14, 2022
A simple API wrapper to Gigapay's APIs for Laravel Framework

Laravel-Gigapay A simple API wrapper for Gigapay's APIs. It gives you helper methods that will make your work with gigapay's API easy, fast and effici

Asif Patel 3 May 23, 2022
A CommonMark wrapper for Laravel

Laravel Markdown Laravel Markdown was created by, and is maintained by Graham Campbell, and is a CommonMark wrapper for Laravel. It ships with integra

Graham Campbell 1.2k Jan 2, 2023
PayuMoney Gateway wrapper for Laravel.

PayuMoney Integration with Laravel Easy to use integration for PayUMoney into Laravel apps. Video Tutorial Usage composer require infyomlabs/laravel-p

InfyOmLabs (InfyOm Technologies) 10 Nov 29, 2022
A Laravel wrapper for spatie/dns. Allows to query and validate DNS records.

A Laravel wrapper for spatie/dns. Allows to query and validate DNS records.

Astrotomic 22 Nov 17, 2022
A laravel wrapper for BnpParibas Mercanet payment gateway

Laravel Mercanet A laravel wrapper for BnpParibas Mercanet which provide a lightweight public api to process your online payments from your laravel ap

Mouad ZIANI 29 Nov 27, 2022
27Laracurl Laravel wrapper package for PHP cURL class that provides OOP interface to cURL. [10/27/2015] View Details

Laracurl Laravel cURL Wrapper for Andreas Lutro's OOP cURL Class Installation To install the package, simply add the following to your Laravel install

zjango 8 Sep 9, 2018
A wrapper package to run mysqldump from laravel console commands.

A wrapper package to run mysqldump from laravel console commands.

Yada Khov 24 Jun 24, 2022
Laravel wrapper for zendesk/zendesk_api_client_php package.

Laravel Zendesk This package provides integration with the Zendesk API. It supports creating tickets, retrieving and updating tickets, deleting ticket

Huddle Digital 97 Dec 22, 2022
A DOMPDF Wrapper for Laravel

DOMPDF Wrapper for Laravel Laravel wrapper for Dompdf HTML to PDF Converter Require this package in your composer.json and update composer. This will

Barry vd. Heuvel 5.6k Dec 25, 2022
A Laravel wrapper for apex charts

Larapex Charts A Laravel wrapper for apex charts library Check the documentation on: Larapex Chart Docs. Installation Use composer. composer require a

ArielMejiaDev 189 Dec 26, 2022
Laravel SoapClient Wrapper

Laravel SoapClient Wrapper A SoapClient wrapper integration for Laravel. Makes it easy to use Soap in a Laravel application. Please report any bugs or

Michael v/d Rijt 618 Dec 12, 2022
A Laravel wrapper for healthchecks.io

Healthchecks.io is a service that monitors your cron jobs and alerts you when they are down. This package is a wrapper for the Healthchecks.io API.

Robin Martijn 4 Nov 7, 2022