Search code examples
phpgoogle-apigmailgoogle-api-php-clientgmail-api

failedPrecondition error when authenticating with service account to Google API


I'm trying to fetch a given email from my own inbox (as project owner) using the Google API 2.0.0 RC4 for PHP.

I have a project setup, a downloaded authentication file in JSON format and I have enabled the gmail API in the Google Developers Console.

But when I run the following code I get a "Bad Request" error with reason "failedPrecondition". Now this leads me to believe that there is something wrong with the access rights, but I can't figure out what I need to do here.

Code:

<?php
    require_once("google-api-php-client-2.0.0-RC4/vendor/autoload.php");

    $client = new Google_Client();

    // set the scope(s) that will be used
    $client->setScopes(["https://www.googleapis.com/auth/gmail.readonly"]);

    $client->setApplicationName("MyProject");
    // set the authorization configuration using the 2.0 style
    $client->setAuthConfigFile("myAuthFile.json");

    $gmailHandle = new Google_Service_Gmail($client);

    $messages = $gmailHandle->users_messages->get("[email protected]", "12343445asd56");

    echo json_encode($messages);

?>

And the complete error looks like this:

Fatal error: Uncaught exception 'Google_Service_Exception' with message '{ "error": { "errors": [ { "domain": "global", "reason": "failedPrecondition", "message": "Bad Request" } ], "code": 400, "message": "Bad Request" } } '


Solution

  • I just ran into this and finally found the solution. You are getting that error because you are using a service account without specifying a "subject" as part of the configuration. That is required for the API to know which email address you are acting as when using the service account. You can see it attempting to use this subject in Google_Client::createApplicationDefaultCredentials

    The solution is to add the following line in the code after you have called setAuthConfig()

    $client->setConfig('subject', '[email protected]');
    

    Be sure to then use the keyword 'me' when fetching the messages from the inbox as you are now acting as the email address which you have configured as 'subject'.