googleads / google-ads-php

Google Ads API Client Library for PHP
https://developers.google.com/google-ads/api/docs/client-libs/php
Apache License 2.0
295 stars 262 forks source link

Service Account giving me heart ache. #548

Closed kevmul0929 closed 3 years ago

kevmul0929 commented 3 years ago

I have been working on getting the Google Ads to work with a Service Account. But I just cannot get past the Oauth.

I am using the JSON file that was downloaded when setting up the Service Account. I feel like I have everything set up, but for the life of me, I cannot get going with actually creating any campaigns.

For this project I am using : PHP 8.0 "laravel/framework" : "^7.30", "googleads/google-ads-php": "^7.0", "phpunit/phpunit": "^9.3", "grpc/grpc": "^v1.27.0",

When trying to run the example code from google Create Campaign Example I get hit with the error "User in the cookie is not a valid Ads user."

"grpc-status-details-bin" => array:1 [
    0 => b"""
      \x08\x10\x12×\x01Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.\x1A{\n
      Ctype.googleapis.com/google.ads.googleads.v6.errors.GoogleAdsFailure\x124\n
      2\n
      \x03ˆ\x01\x0E\x12+User in the cookie is not a valid Ads user.
      """

I also have Logging set up with Laravel's Logging system

$this->googleAdsClient = (new GoogleAdsClientBuilder())
    ->withDeveloperToken(config('social.google.client_builder.developer_token'))
    ->withLoginCustomerId((int) config('social.google.client_builder.linked_customer_id'))
    ->withTransport('grpc')
    ->withLogger(Log::getLogger())
    ->withOAuth2Credential((new OAuth2TokenBuilder())
        ->withJsonKeyFilePath(config('social.google.oauth.json_key_file_path'))
        ->withImpersonatedEmail('xxx@xxx.iam.gserviceaccount.com')
        ->withScopes("https://www.googleapis.com/auth/adwords")
        ->build()
    )
    ->build();

The logger puts out this message.

[2021-03-03 15:10:04] testing.WARNING: Request made: Host: "googleads.googleapis.com", Method: "/google.ads.googleads.v6.services.CampaignBudgetService/MutateCampaignBudgets", CustomerId: 5763579756, RequestId: "LD-WXXEBLK2L12---Sir2w", IsFault: 1, FaultMessage: "["User in the cookie is not a valid Ads user."]"  
[2021-03-03 15:10:04] testing.NOTICE: Request
-------
Method Name: /google.ads.googleads.v6.services.CampaignBudgetService/MutateCampaignBudgets
Host: googleads.googleapis.com
Headers: {
    "x-goog-api-client": "gl-php\/8.0.1 gapic\/ gax\/1.7.0 grpc\/1.35.0",
    "x-goog-request-params": "customer_id=5763579756",
    "developer-token": "REDACTED",
    "login-customer-id": "7795580895"
}
Request: 
{"customerId":"5763579756","operations":[{"create":{"name":"Interplanetary Cruise Budget #123","amountMicros":"500000","deliveryMethod":"STANDARD"}}]}

Response
-------
Headers: {
    "request-id": "LD-WXXEBLK2L12---Sir2w",
    "date": "Wed, 03 Mar 2021 23:10:02 GMT",
    "alt-svc": "h3-29=\":443\"; ma=2592000,h3-T051=\":443\"; ma=2592000,h3-Q050=\":443\"; ma=2592000,h3-Q046=\":443\"; ma=2592000,h3-Q043=\":443\"; ma=2592000,quic=\":443\"; ma=2592000; v=\"46,43\""
}

Fault
-------
Status code: 16
Details: Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.
Failure: {"errors":[{"errorCode":{"authenticationError":"NOT_ADS_USER"},"message":"User in the cookie is not a valid Ads user."}]}  

I have been at this for about 3 weeks now and cannot find where I am going wrong. Any and all help is IMMENSELY appreciated!

fiboknacky commented 3 years ago

Does the email that you use to authenticate have an access to Google Ads?

AnashOommen commented 3 years ago

The ->withImpersonatedEmail('xxx@xxx.iam.gserviceaccount.com') line is incorrect. To use service account, the following steps should be done.

1) You should be a GSuite user 2) You should grant your service account domain-wide delegation and impersonation capabilities as explained here: https://developers.google.com/google-ads/api/docs/oauth/service-accounts#granting_impersonation_abilities 3) One or more users of your GSuite domain (e.g. alice@example.com) should be a valid user in the Google Ads account you are making calls to. 4) The user's login email should go into the ->withImpersonatedEmail('xxx') line.

kevmul0929 commented 3 years ago

Thank you both for the help so far!

The email I updated to my email address and now I get a brand new error that does not get logged.

+"error": "unauthorized_client"
+ error_description": "Client is unauthorized to retrieve access tokens using this method, or client not authorized for any of the scopes requested."

This is probably out of the scope of this repo, but any help or direction is very appreciated.

I am guessing I need to update the scope of the user (me). But I guess I suck at google console stuff cuz I can't figure it out.

fiboknacky commented 3 years ago

Could you try following this section and this section again? Thanks.

kevmul0929 commented 3 years ago

Ok, I got this working. There was an issue with how I had the service account set up. For those looking at this later with the same issue, make sure you are using your google email. Not the email sent with the JSON file Google provides. IE: kevin@example.com Not example-app-service@xxx.iam.gserviceaccount.com