Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Cope99's avatar

Google API - Service account connection - Laravel 5

For anyone who would like to use Google API with a service account connection, here is what I have to done in order to make it work :

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 Service account and click on Create Client ID

4- Next, take the *.p12 file and place it somewhere in your laravel directory (in my case in assets).

5- Next, create a new Gooogle calendar (http://calendar.google.com) with any Google account and share it with your Service Account's Email Address created in step 3 and save it.

6- In the config folder, add a file name google.php, place and modify the following content :

<?php

return [

    /*
    |--------------------------------------------------------------------------
    | Client ID
    |--------------------------------------------------------------------------
    |
    | The Client ID can be found in the OAuth Credentials under Service Account
    |
    */
    'client_id' => 'something.apps.googleusercontent.com',

    /*
    |--------------------------------------------------------------------------
    | Service account name
    |--------------------------------------------------------------------------
    |
    | The Service account name is the Email Address that can be found in the
    | OAuth Credentials under Service Account
    |
    */
    'service_account_name' => 'something@developer.gserviceaccount.com',

    /*
    |--------------------------------------------------------------------------
    | Key file location
    |--------------------------------------------------------------------------
    |
    | This is the location of the .p12 file from the Laravel root directory
    |
    */
    'key_file_location' => '/resources/assets/filename.p12',
];

7- In your application folder, I have added a file named GoogleCalendar.php in App\Services with the following content :

<?php namespace App\Services;

use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Config;

class GoogleCalendar {

    protected $client;

    protected $service;

    function __construct() {
        /* Get config variables */
        $client_id = Config::get('google.client_id');
        $service_account_name = Config::get('google.service_account_name');
        $key_file_location = base_path() . Config::get('google.key_file_location');

        $this->client = new \Google_Client();
        $this->client->setApplicationName("Your Application Name");
        $this->service = new \Google_Service_Calendar($this->client);

        /* If we have an access token */
        if (Cache::has('service_token')) {
          $this->client->setAccessToken(Cache::get('service_token'));
        }

        $key = file_get_contents($key_file_location);
        /* Add the scopes you need */
        $scopes = array('https://www.googleapis.com/auth/calendar');
        $cred = new \Google_Auth_AssertionCredentials(
            $service_account_name,
            $scopes,
            $key
        );

        $this->client->setAssertionCredentials($cred);
        if ($this->client->getAuth()->isAccessTokenExpired()) {
          $this->client->getAuth()->refreshTokenWithAssertion($cred);
        }
        Cache::forever('service_token', $this->client->getAccessToken());
    }

    public function get($calendarId)
    {
        $results = $this->service->calendars->get($calendarId);
        dd($results);
    }
}

8- Next add the following where you need to use Google Calendar

use App\Services\GoogleCalendar;
[...]
    public function functionName(GoogleCalendar $calendar)
    {
        $calendarId = "YourCalendarID";
        $result = $calendar->get($calendarId);
    }
0 likes
32 replies
Brano's avatar

Hi, I`m little confused, I did exactly all of this, bud I got :

syntax error, unexpected 'public' (T_PUBLIC)

where can by a mistake?

Cope99's avatar

You are probably missing a closing braces ( } ) somewhere. Send your code and I'll check it out.

Brano's avatar

I get rid of previous error and got another : Argument 1 passed to controller::functionName() must be an instance of app\services\GoogleCalendar, none given , I have this in controller: public function functionName(GoogleCalendar $calendar) { $calendarId = "YourCalendarID"; $result = $calendar->get($calendarId); }

kfirba's avatar

@Cope99 Thanks for that.

/* Add the scopes you need */
$scopes = array('https://www.googleapis.com/auth/calendar');

I was wondering what the scopes are?

I do intend to use the YouTube service in order to upload videos and get the video link returned after upload. Any tips on how to implement that (I need to upload all of the videos to my channel only and set the privacy status to unlisted so I can then just use the video link in my website)?

Cope99's avatar

Instead of

use App\Services\GoogleCalendar;
[...]
    public function functionName(GoogleCalendar $calendar)
    {
        $calendarId = "YourCalendarID";
        $result = $calendar->get($calendarId);
    }

use

use App\Services\GoogleCalendar;
[...]
    public function functionName()
    {
        $calendar = new GoogleCalendar;
        $calendarId = "YourCalendarID";
        $result = $calendar->get($calendarId);
    }

The scope for YouTube is https://www.googleapis.com/auth/youtube

If you need more information about YouTube API you can find the reference at https://developers.google.com/youtube/v3/docs/

Brano's avatar

thx for advice, i change it in this way:

<?php

 use App\Services\GoogleCalendar;

class domovController extends BaseController {

    public function domov()
    {
          $calendar = new GoogleCalendar();
        $calendarId = "xxxx@gmail.com";
        $result = $calendar->get($calendarId);
    }
    
}

bud i got : Symfony \ Component \ Debug \ Exception \ FatalErrorException (E_ERROR) Class 'App\Services\GoogleCalendar' not found

but on this adress : app\ ..... is the GoogleCalendar.php from your tutorial

Brano's avatar

thanks , it helps but now I got : Undefined variable: service

public function get($calendarId)
    {
        $results = $service->calendars->get($calendarId);
        dd($results);
    }
Cope99's avatar

@Brano

    $service = new \Google_Service_Calendar($this->client);

should have been

    $this->service = new \Google_Service_Calendar($this->client);

and

    $results = $service->calendars->get($calendarId);

should have been

    $results = $this->service->calendars->get($calendarId);
1 like
Brano's avatar

I know how to read events from calendar, @Cope99 can you please help me how to insert events into calendar?

edit: I think I got it, but your previous advices help me a lot

mottihoresh's avatar

Thank you for the great post, really informative. I was looking for a way to integrate url shorting into my app, and this pattern fit perfectly.

A quick question tho... What if i wanted to implement several client services? how would you take care of the scopes?

Ozan's avatar

There is no need to add this to composer.json... It automatically autoloads the vendor directory anyway.

{
    "autoload": {
        "classmap": [
            "vendor/google/apiclient/src/Google"
        ],
    }
}
akilsree1's avatar

Thanks for this tutorial. I am able to get Calendar API details for my given credentials,

But I want Reporting API details using Google API client package,

Can you give the same steps for Google Analytics Web Application. I am struggling hard for that with errors. Is there any link to follow steps like this, please comment here or email me akilsree1@gmail.com. Any help is greatly appreciated..

sakarya's avatar

Hello.

I'm taking 404 Calendar not found error.

How can resolve it?

Thanks..

1 like
Naim's avatar

Two words : ['Thank', 'You'] ;-)

tigre's avatar

Guys, how can i display this calendar. I followed those steps and get dd(result), with bunch of information. How can i get real calendar that i can edit?

LFVN's avatar

Hi,

I am getting this error:

Google_Auth_Exception in OAuth2.php line 364: Error refreshing the OAuth2 token, message: '{ "error" : "invalid_grant" }'

And I did some changes because Laravel 5.2 does not deal with "services" the way it´s stated here. So, I used GoogleCalendar function as a controller. If this is not the right way, please, can someone here inform the right manner to work with Laravel 5.2?

Regards,

ValsiS's avatar

can someone help me with this ?

i don't know how to create that Client ID,

step by step explication it will be perfect

ikbentomas's avatar

I've changed the setup a little to fit into Lumen, as a ServiceProvider. While doing so I removed all OAuth2 code because the tutorial nicely explained how to setup a service account Therefore there is no need for an application name nor the ClientID.

.env

GOOGLE_SERVICE_ACCOUNT_NAME=service_name@project_name.iam.gserviceaccount.com
GOOGLE_KEY_FILE_LOCATION=/resources/assets/service_key.p12

If you forget to write down your service_account_name you can find it back in the IAM console

/App/Providers/GoogleClientServiceProvider.php

<?php namespace App\Providers;

use Laravel\Lumen\Providers\EventServiceProvider as ServiceProvider;

class GoogleClientServiceProvider  extends ServiceProvider{

    function register(){
        /* Get config variables */
        $service_account_name = getenv('GOOGLE_SERVICE_ACCOUNT_NAME');
        $key_file_location = base_path() . getenv('GOOGLE_KEY_FILE_LOCATION');

        $key = file_get_contents($key_file_location);
        /* Add the scopes you need */
        $scopes = ['https://www.googleapis.com/auth/calendar'];

        $cred = new \Google_Auth_AssertionCredentials(
            $service_account_name,
            $scopes,
            $key
        );

        $client = new \Google_Client();
        $client->setAssertionCredentials($cred);

        // repeat this block for as many Google_Services_* as you like
        // don't forget to add scopes for other services.
        $this->app->singleton(\Google_Service_Calendar::class, function ($app) use ($client) {
            return new \Google_Service_Calendar($client);
        });
    }

}

Enable the ServiceProvider

/bootstrap/app.php

$app->register(App\Providers\GoogleClientServiceProvider::class);

I use automatic resolution to retrieve the calendar client. To find out what your calendar ID's are you should first list your calendars.

/App/Http/Controllers/CalendarController.php

<?php

namespace App\Http\Controllers;

use Google_Service_Calendar;

class CalendarController extends Controller
{

    public function show(Google_Service_Calendar $client){
        $calendarList = $client->calendarList->listCalendarList();
        dd($calendarList->getItems());
    }
    
}
sogeniusio's avatar

After hours I'm finally getting a response. But not what I expected. I'm getting "Login required" anyone know why.

** GoogleClientServiceProvider.php (excuse the comments) **

<?php 

namespace App\Providers;

use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;

use Illuminate\Support\Facades\Cache as Cache;
use Illuminate\Support\Facades\Config as Config;

class GoogleClientServiceProvider extends ServiceProvider
{

    function register() {
        /* Get config variables */
        $service_account_name = getenv('GOOGLE_SERVICE_ACCOUNT_NAME');
        $key_file_location = base_path() . getenv('GOOGLE_KEY_FILE_LOCATION');

        // /* If we have an access token */
        // if (Cache::has('service_token')) {
        //   $this->client->setAccessToken(Cache::get('service_token'));
        // }

        $key = file_get_contents($key_file_location);

        /* Add the scopes you need */
        $scopes = [
            'https://www.googleapis.com/auth/admin.directory.user',
            'https://www.googleapis.com/auth/admin.directory.user.readonly'
        ];
        // $cred = new \Google_Auth_AssertionCredentials(
        //     $service_account_name,
        //     $scopes,
        //     $key
        // );

        // $this->client = new \Google_Client();

        // $this->client->setAssertionCredentials($cred);

        // if ($this->client->getAuth()->isAccessTokenExpired()) {
        //   $this->client->getAuth()->refreshTokenWithAssertion($cred);
        // }
        // Cache::forever('service_token', $this->client->getAccessToken());

        // // repeat this block for as many Google_Services_* as you like
        // // don't forget to add scopes for other services.

        $client = new Google_Client();
        $cred = $client->loadServiceAccountJson($key_file_location, ['https://www.googleapis.com/auth/content']);
        $oauthClient = new Google_Auth_OAuth2($client);
        $oauthClient->refreshTokenWithAssertion($cred);
        $client->setAccessToken($oauthClient->getAccessToken());
        $this->app->singleton(\Google_Service_Directory::class, function ($app) use ($client) {
            return new \Google_Service_Directory($client);
        });

    }

    public function getAll()
    {
        $results = $this->service->userinfo->get();
        dd($results);
    }
}

** routes.php **

[...]

Route::get('google-users', 'GoogleApiController@getAllUsers');

[...]

###**otstrap/app.php **

$app->singleton( // had to change this to singleton; kept getting errors
                     // Fatal error: Uncaught Error: Class 'App\Providers\Google_Client' not found 
    App\Providers\GoogleClientServiceProvider::class
);

** GoogleApiController.php **

<?php

namespace App\Http\Controllers;

use Google_Service_Directory;

use Illuminate\Http\Request;

class GoogleApiController extends Controller
{
    public function getAllUsers(Google_Service_Directory $client)
    {
        $userList = $client->users->listUsers();;
        dd($userList->getItems());
    }
}

I'm not quite sure what I'm missing here. Hopefully someone can point me in the right direction. I have verified my credentials:

Image of Credentials

Anastasia's avatar

Sorry, can anyone explane me what is p12 file?

okhalid's avatar

hello thank you first for the tutorial I even do what you do on the tutorial but it displays an error Class 'Google_Auth_AssertionCredentials' not found I work on laravel 5 help me please

Next

Please or to participate in this conversation.