Google Ads API V3 PHP is not working

1,362 views
Skip to first unread message

Amit Lahiri

unread,
Mar 20, 2020, 8:28:53 AM3/20/20
to AdWords API and Google Ads API Forum
Hello.

I am using PHP to call Google Ads API. 

I am trying to retriev the Google ads campaign id and name. I am using simple curl to do this. Here is my code.

Code
$parameters = [
    "query" => "SELECT campaign.id, campaign.name FROM campaign",
    "token-type" => "Bearar",
    "Authorization" => session()->get('access_token_googleads')['access_token'],
    "developer-token" => "nswf[qf[p[..................",
];
$content_type = 'application/json';
$response = $this->getResponse($url, $parameters, $content_type, $post = true);
echo '<pre>';
print_r($response);

Response
I am getting the below response after execute this code in the browser.

{
  "error": {
    "code": 401,
    "message": "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.",
    "status": "UNAUTHENTICATED"
  }
}

Please let me know what I missed.
I am using this documentation to run the code https://developers.google.com/google-ads/api/docs/reporting/example.
Let me know whether Adwords and Ads are same.
I am using my client's customer id and developer-token supplied by him. I do not not have Ad Manager account. 
I am using Google cloud console > APIs & Services to create OAuth client id. 
Is there anyway I can use REST API to use the Google Ads API V3?

Please help me by resolved this issue, by suggesting, by modifyfying code, etc. I am waiting for the reply.

Google Ads API Forum Advisor Prod

unread,
Mar 20, 2020, 3:22:12 PM3/20/20
to ala...@nuundigital.com, adwor...@googlegroups.com
Hi Amit,

Thank you for reaching out to us. I see that you're encountering an Unauthenticated Error. This means that you've supplied invalid authentication credentials to your API call. Could you please follow these steps to obtain the correct client credentials? For your second query, AdWords API and Google Ads API are very similar with a couple of differences. You can read about the migration changes here. For your third query, Google Ads API V3 is a REST type API. Let me know if you have further questions.

Thank you,
Bryan, Google Ads API Team

ref:_00D1U1174p._5001UXVi3P:ref

Amit Lahiri

unread,
Mar 20, 2020, 4:11:54 PM3/20/20
to AdWords API and Google Ads API Forum
Hello Bryan.

Thanks for the reply. 

Could you please take a look into my below doubts?
1. Is my parameters settings, curl calling and overall coding snippet missed anything? Am I need to add more settings in parameters?
2. I am the developer working for the client. I am using my email address to create OAuth Client Id using GCP. Am I need to create OAuth Client Id using Google Ad Manager's email address?
3. I am using library google-ads-php in the development. I am working with Laravel framework. Is there any better way to implement the same?
4. Where do I get example of REST API?

I am looking forward to your reply. 


Regards & Thanks,
Amit

Google Ads API Forum Advisor Prod

unread,
Mar 23, 2020, 2:37:05 PM3/23/20
to ala...@nuundigital.com, adwor...@googlegroups.com
Hi Amit,

Thank you for the update. I see that you have four concerns. My response is below.
 
1. Is my parameters settings, curl calling and overall coding snippet missed anything? Am I need to add more settings in parameters?
Could you make sure you follow this example in making cUrl API calls? It looks like you need to include the correct authorization parameters to connect to the API.
 
2. I am the developer working for the client. I am using my email address to create OAuth Client Id using GCP. Am I need to create OAuth Client Id using Google Ad Manager's email address?
As long as your email address has been given correct access to the Manager Account and the accounts under it then you should be able to connect to the API and access those accounts. You can check this by logging into the Manager account, then checking "Tools & Settings" > "Setup" > "Account Access". Your email should be listed under "Users". Otherwise, you can also use the Manager Account's email address to make the OAuth Client Credentials.
 
3. I am using library google-ads-php in the development. I am working with Laravel framework. Is there any better way to implement the same?
Could you provide me with the link to the Laravel framework? You should be able to implement this example library for PHP for Google Ads API.
 
4. Where do I get example of REST API?
You can find all the examples of the Google Ads API here.


Let me know if you have further questions.

Thank you,
Bryan, Google Ads API Team


ref:_00D1U1174p._5001UXVi3P:ref

Amit Lahiri

unread,
Mar 24, 2020, 9:54:32 AM3/24/20
to AdWords API and Google Ads API Forum
Hi Bryan. 

Many thanks for the reply. 

1. I am using the same example process as referrred by you https://developers.google.com/google-ads/api/docs/concepts/curl-example
I was confuded with the below code and was not understanding how do I these lines of code in PHP.
curl \
  -d code=AUTHORIZATION CODE \
  -d client_id=CLIENT ID \
  -d client_secret=CLIENT SECRET \
  -d redirect_uri=urn:ietf:wg:oauth:2.0:oob \
  -d grant_type=authorization_code https://accounts.google.com/o/oauth2/token

2. I am using the same library with examples as referred by you. 


In the meantime I have resolved the issue of OAuth2 login issue. I am facing new issue at the moment. I am explaiing my issues and doubts. 

1. I have opened a new Test account and use it's customer id in my code. After running getting the below error.

ApiException was thrown with message '{
    "message": "Request contains an invalid argument.",
    "code": 3,
    "status": "INVALID_ARGUMENT",
    "details": [
        {
            "@type": 0,
            "data": "type.googleapis.com\/google.ads.googleads.v3.errors.GoogleAdsFailure"
        },
        {
            "@type": 0,
            "data": [
                {
                    "errorCode": {
                        "queryError": "REQUESTED_METRICS_FOR_MANAGER"
                    },
                    "message": "Metrics cannot be requested for a manager account. To retrieve metrics, issue separate requests against each client account under the manager account."
                }
            ]
        }
    ]
}'.

What it is saying in "message": "Metrics cannot be requested for a manager account. To retrieve metrics, issue separate requests against each client account under the manager account."? What am I supposed to do? I still do not have the access to Manager account. I can access the Test account only. 

2. How do I get customer id when log in? 
3. Is it possible to access the 10 different customer campaign details with 10 different customer ids, but with the same client id, client secret, refresh token and developer token? I wish to write a dynamic where I will make the customer id dynamic as log in with other resources constant. Is it possible?

I am waiting for the reply.


Best Regards,
Amit 

Google Ads API Forum Advisor Prod

unread,
Mar 24, 2020, 3:24:01 PM3/24/20
to ala...@nuundigital.com, adwor...@googlegroups.com
Hi Amit,

I see that you have several inquiries. You can find my answers below.

For parts 1 and 2, I see that you're trying to use a curl request and using our PHP client libraries together. Could you confirm if you're using this example to obtain the campaigns?

For part 3, I see that you're having an issue that is with an invalid argument. It looks like you're trying to query the campaign information from the manager account. You aren't able to perform this action on manager accounts as they only manage accounts, not campaigns. For you to obtain this information, you will need to query the campaign information from each account under the manager account.

4. You are able to see the customer ID of the current account you're logged into by clicking the "?" button on the top right hand corner of the UI. It should list your Customer ID.

5. It is possible to have the same client id, client secret, refresh token, and developer token used in the same API call type for all 10 different accounts. You just need to make sure that the user is given correct access in the manager account that holds these 10 accounts. You can check this by going into "Tools & Settings" > "Setup" > "Account Access". Under the "Users" tab, you should be able to find a list of users that are given access to the manager account and the accounts underneath it.

Amit Lahiri

unread,
Mar 25, 2020, 10:24:40 AM3/25/20
to AdWords API and Google Ads API Forum
Hi Bryan.

Once again many thanks for the reply. 

Current Issue
Previous issue was resolved. Currently, I am getting a different error. This is the error,
                      Streaming calls are not supported while using the REST transport.

More comments
1. Yes I am using the example you are referring. 
2. Here is my code, 
    public static function runExample(GoogleAdsClient $googleAdsClient, int $customerId)
    {
        $googleAdsServiceClient = $googleAdsClient->getGoogleAdsServiceClient();
        // Creates a query that retrieves all campaigns.
        $query = 'SELECT campaign.id, campaign.name FROM campaign ORDER BY campaign.id';
        // Issues a search stream request.
        /** @var GoogleAdsServerStreamDecorator $stream */
        $stream = $googleAdsServiceClient->searchStream($customerId, $query);

        // Iterates over all rows in all messages and prints the requested field values for
        // the campaign in each row.
        foreach ($stream->readAll() as $response) {
            /** @var SearchGoogleAdsStreamResponse $response */
            foreach ($response->getResults() as $googleAdsRow) {
                /** @var GoogleAdsRow $googleAdsRow */
                printf(
                    "Campaign with ID %d and name '%s' was found.%s",
                    $googleAdsRow->getCampaign()->getId()->getValue(),
                    $googleAdsRow->getCampaign()->getName()->getValue(),
                    PHP_EOL
                );
            }
        }
    }

It looks like getting the error, in this line,
$stream = $googleAdsServiceClient->searchStream($customerId, $query);

And it occurs because the function searchStream(.....).

3. Is there anyway I can get the CUSTOMER_ID dynamically, after log in? Currently, I am using CUSTOMER_ID as a constant.

Please help me to resolve the issue.


Thanks,
Amit 

Google Ads API Forum Advisor Prod

unread,
Mar 25, 2020, 3:44:25 PM3/25/20
to ala...@nuundigital.com, adwor...@googlegroups.com
Hi Amit,

I see you have two queries. You will find my answers below.

1. Issue with REST Transport.
Could you provide the REST request and response logs where this error occurs so that I may further investigate this issue?

2. How to obtain Customer_ID dynamically.
Could you clarify what you're using the customer_ID for? Are you trying to query for a list of customer_IDs? If so, you can use the Customer Report to pull customer.id under the manager account. 

Amit Lahiri

unread,
Mar 25, 2020, 4:06:21 PM3/25/20
to AdWords API and Google Ads API Forum
Hi Bryan. 

Thanks a lot for the reply one again. 


1. REST transport: here is the code. 

    public function profile()
    {
        // Either pass the required parameters for this example on the command line, or insert them into the constants above. 
        $options = (new ArgumentParser())->parseCommandArguments([
            ArgumentNames::CUSTOMER_ID => GetOpt::REQUIRED_ARGUMENT
        ]);
        
        // Generate a refreshable OAuth2 credential for authentication. 
        $oAuth2Credential = (new OAuth2TokenBuilder())
            ->withClientId('XXXXXX......')
            ->withClientSecret('XXXXXX......')
            ->withRefreshToken('XXXXXX......')
            ->build();

        // Construct a Google Ads client configured from a properties file and the OAuth2 credentials above. 
        $googleAdsClient = (new GoogleAdsClientBuilder())
            ->withOAuth2Credential($oAuth2Credential)
            ->withDeveloperToken('XXXXXX......')
            ->withLoginCustomerId('1234567890')
            ->build();
        
        try {            
            self::runExample(                
                $googleAdsClient,
                $options[ArgumentNames::CUSTOMER_ID] ?: self::CUSTOMER_ID
            );
        } catch (GoogleAdsException $googleAdsException) {
            echo '<pre>';
            printf(
                "Request with ID '%s' has failed.%sGoogle Ads failure details:%s",
                $googleAdsException->getRequestId(),
                PHP_EOL,
                PHP_EOL
            );
            foreach ($googleAdsException->getGoogleAdsFailure()->getErrors() as $error) {
                /** @var GoogleAdsError $error */
                printf(
                    "\t%s: %s%s",
                    $error->getErrorCode()->getErrorCode(),
                    $error->getMessage(),
                    PHP_EOL
                );
            }
        } catch (ApiException $apiException) {
            echo '<pre>';
            printf(
                "ApiException was thrown with message '%s'.%s",
                $apiException->getMessage(),
                PHP_EOL
            );
        }
    }

    public static function runExample(GoogleAdsClient $googleAdsClient, int $customerId)
    {
        $googleAdsServiceClient = $googleAdsClient->getGoogleAdsServiceClient();
        
        // Creates a query that retrieves all campaigns.
        $query = 'SELECT campaign.id, campaign.name FROM campaign ORDER BY campaign.id';
        
        // Issues a search stream request.
        /** @var GoogleAdsServerStreamDecorator $stream */
        $stream = $googleAdsServiceClient->searchStream($customerId, $query);

        // Iterates over all rows in all messages and prints the requested field values for
        // the campaign in each row.
        foreach ($stream->readAll() as $response) {
            /** @var SearchGoogleAdsStreamResponse $response */
            foreach ($response->getResults() as $googleAdsRow) {
                /** @var GoogleAdsRow $googleAdsRow */
                printf(
                    "Campaign with ID %d and name '%s' was found.%s",
                    $googleAdsRow->getCampaign()->getId()->getValue(),
                    $googleAdsRow->getCampaign()->getName()->getValue(),
                    PHP_EOL
                );
            }
        }
    }


2. Customer Id issue: 
I am using CUSTOMER_ID to retrieve the data from table campaign. Where do I find the table lists and their corresponding use? 
In the code above, there is a constant CUSTOMER_ID. I wish to make this constant value dynamic after successful log in, means user will get the customer id / ids to choose from once log in successfully. 

Common question:
Is there anyway I can call Google Ads API using REST, such as,
$response = file_get_contents("https://ads.google.com/api/v3/?param1=val1.........");
print_r($response);

Awaiting your reply. 


Thanks,
Amit 

Amit Lahiri

unread,
Mar 26, 2020, 3:14:47 PM3/26/20
to AdWords API and Google Ads API Forum
Hi Bryan. 

I am adding to the last post. 

Error is generating from the below line of code, following the error given. 
$stream = $googleAdsServiceClient->searchStream($customerId, $query);

BadMethodCallException
Streaming calls are not supported while using the REST transport.

I cannot locate the function searchStream() in the library I am using for gRPC. I have tried with the libraries grpc and grpc-gcp, from packagist.org
What am I supposed to do now?

Google Ads API Forum Advisor Prod

unread,
Mar 26, 2020, 3:24:38 PM3/26/20
to ala...@nuundigital.com, adwor...@googlegroups.com
Hi Amit,

Thank you for the update. I see that you have three concerns. You will find my answers below.

1. Rest Transport issue.
Thank you for providing your code. However, I will need to see your Request and Response logs that are provided after you run the request. You can check how to enable logging for PHP here.

2. Customer ID issue.
Unfortunately there is no field to make the customer ID dynamic, however, you can change this field in between each API call.

3. Common question.
Could you please confirm which service are you trying to call via REST?

Amit Lahiri

unread,
Mar 26, 2020, 3:37:22 PM3/26/20
to AdWords API and Google Ads API Forum
Hi Bryan. 

Thank you for the reply once again. 

1. REST Transport issue:
I am not using ini file, but add the crednetials into the functions, as found in the code. Also, I am using this with Laravel. Please suggest, if there anything to do.

2. Common Question:
By service, I understand the parameter used in scope, and I am using this https://www.googleapis.com/auth/adwords. Am I correct?

Awaiting your reply. 


Thanks,
Amit 


sreenu malae

unread,
Mar 26, 2020, 3:44:00 PM3/26/20
to AdWords API and Google Ads API Forum
Hello Amiti Lahiri,
I faced the same issue  BadMethodCallException.
But I solved it by following a few steps
  1. In terminal execute this "php -i" and check whether your version supports NTS(Non Thread Safe) or TS(thread-safe)
  2. Then download compatible grpc dll from pecl site. Place the dll file in php/ext and C:\Windows\System32.
  3. In C:\Windows\System32 place php7.dll(In my case im using php7) and in php.ini place extension=grpc
  4. Now restart
Note: step one is mandatory. you need to verify it supports NTS or TS 
Hope it will work.

Amit Lahiri

unread,
Mar 26, 2020, 4:15:15 PM3/26/20
to AdWords API and Google Ads API Forum
Hello Sreenu.

Thank you for the reply. 

Application Type
I am using Google Ads REST API in the Laravel application which is a web app using PHP. 
In this type of application I cannot asked client to do all these configuration to run the application. What am I supposed to do here?


NTS / TS
What am I supposed to do after knowing whether my version supports NTS and vice-versa? 
I am using Laravel artisan server to run my code. What am I supposed to do here?

Hoping you understand my issues.

Awaiting your reply. 


Thanks,
Amit 




sreenu malae

unread,
Mar 26, 2020, 4:24:58 PM3/26/20
to AdWords API and Google Ads API Forum
Hey Amit,
I got your point. But i have no idea about laravel 
I'm sorry.
Hope bryan will help you out.

Google Ads API Forum Advisor Prod

unread,
Mar 27, 2020, 3:10:59 PM3/27/20
to ala...@nuundigital.com, adwor...@googlegroups.com
Hi Amit,

Thank you for the update and clarification. I see you're using this client library that includes the Laravel Sample Application implementation. Could you confirm with me if you're following these steps? It looks like you'll need to use the ini.php file as specified in the instructions. 

For obtaining campaign info, you can use AdWords Campaign Performance Report and can change the customer ID used in each call to get each customer's list of campaigns. Let me know if you have further questions.

Amit Lahiri

unread,
Mar 30, 2020, 10:29:52 AM3/30/20
to AdWords API and Google Ads API Forum
Hi Bryan.

I am following this library and followd each steps. Its working fine but stuck at the below line, as I have mentioned earlier, with the below mentioned error message. 

Error is generating from the below line of code, following the error given. 
$stream = $googleAdsServiceClient->searchStream($customerId, $query);

BadMethodCallException
Streaming calls are not supported while using the REST transport.

Let me know if you further information. Awaiting your reply. 


Thanks,
Amit 

Google Ads API Forum Advisor Prod

unread,
Mar 30, 2020, 3:30:17 PM3/30/20
to ala...@nuundigital.com, adwor...@googlegroups.com
Hi Amit,

Thank you for the clarification. Upon further inspection, this looks like an issue pertaining to the client library. Could you post the error you're encountering here, and our php client library support team will take a look at your concern? Let me know if you have further questions.

Amit Lahiri

unread,
Mar 30, 2020, 4:27:25 PM3/30/20
to AdWords API and Google Ads API Forum
Hi Bryan. 

Thanks for the reply once again. 
Done, as you have said, here


Thanks,
Amit
Reply all
Reply to author
Forward
0 new messages