Difficulties getting user's mail from Gmail inbox in Laravel

Viewed 382

I'm trying to create a Laravel API to interact with Gmail via the Google API client library for PHP. However, I encounter issues with the endpoint to get mails.

So far, I could do authorization and get the access token in my DB. This endpoint return JSON of this format:

{
    "user_id": 1,
    "token": {
        "access_token": "ya29.XXXXXXXXXXXX-K_P9Z0Rd0nU5WzSvU3TMlC0TZQRbMLkDHE1XI3j29mbIRP13dt_NGMb4d9trTECGKiwbjM45Ijk7fbhpLzU2JL7w-6w_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
        "expires_in": 3599,
        "scope": "https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/gmail.readonly",
        "token_type": "Bearer",
        "id_token": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-yK6GHPRATk64GaPcYCuIVyqTYNNvfvr8gCVuTCKr3RMtUz5J97ROZkJRN5w_AQvyJFL369MNTnHQAiqJoPIN2Wes0OAbeq1urpDRMRaAfF6Nuqun-pmewI8g5OCjkUMqekZTKlzCqRl7Xkm4qQRrwk66SxwGdC78Iy5Z_3VG1OIj681zoY18dQu9_ZqGMnwVuHmffmzNInuAmqHcQ7CLM_I_vJbWV3-UKVRF2UtjHvmUydCdo4PrEpL371i8exwPme5IK_xMcywxdfdjxm4duyv6X_ky2MCYwANNBSyBLMYh214FZPowL8choHmMIms-biJlg",
        "created": 1647922921
    },
    "name": "gmail",
    "updated_at": "2022-03-22T04:22:01.000000Z",
    "created_at": "2022-03-22T04:22:01.000000Z",
    "id": 10
}

My second endpoint is to get the mails by using the access token.

My implementation looks like this.

    // Services
    public function getEMails($user_id, $access_token){
        $this->client->setAccessToken($access_token);
        $service = new Gmail($this->client);
        $messages = $service->users_messages->listUsersMessages($user_id);
        return $messages;
    }
   // Controller
    public function getMails(WebService $web_service, GmailServices $gmail_services){
        $access_token = $web_service->token['access_token'];
        $user_id = 'me';
        if (isset($access_token)){
            $mails = $gmail_services->getEMails($user_id, $access_token);
        }
        return $mails;
    }
  // api.php (In route middleware)
  Route::get('/web-service/{mails}', [WebServiceController::class, 'getMails'])->name('web-service.getMails');

Hitting this endpoint, I get the below error.

"message": "Trying to access array offset on value of type null", "exception": "ErrorException"

which corresponds to this line $access_token = $web_service->token['access_token'];

I did some minor research, but I couldn't resolve it. Unfortunately, I'm not advanced in Laravel development, and I'll appreciate any help and feedback.

Furthermore, I equally want to add that my implementation is largely based on Bitfumes test-driven API development on YouTube. Here is the link to the repo https://github.com/bitfumes/laravel-test-driven-api

Thanks!

After trying the above, I was expecting to get the mails and equally work on pagination or querying via LIMIT so that the backend will not over-stress to get all mails at once.

1 Answers

Everything you do should be going though the Google_Client object. Your code is a little confusing to me you have two getEMails methods and neither appear to be using assigning things properly though the client.

When properly initialized it is able to handle everything for you.

$client = new Google_Client();
$client->setApplicationName('Gmail API PHP Quickstart');
$client->setScopes(Google_Service_Gmail::GMAIL_READONLY);
$client->setAuthConfig('credentials.json');
$client->setAccessType('offline');
$client->setPrompt('select_account consent');

You should be testing if the access token has expired. If it is expired then have the Google_Client request a new one.

 if ($client->isAccessTokenExpired()) {
        // Refresh the token if possible, else fetch a new one.
        if ($client->getRefreshToken()) {
            $client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
        } else {
           // request access of the user if it has not been granted.
        }
        // note after refresh remember to store the new refresh token.
    }
Related