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
294 stars 262 forks source link

Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. #893

Closed TomSenter closed 1 year ago

TomSenter commented 1 year ago

I've integrated your library into a Laravel app, and retrieved the refresh token along with the clientID and clientSecret. I've ran the GetCampaign flow, and it keeps coming up with this error - Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential.

I thought the library was supposed to automatically generate the access token from the refresh token, and then make the request to the ads API?

I'll put my code for the Get campaigns object below.

Could you help me out please.

TomSenter commented 1 year ago
<?php

namespace App\Helpers\GoogleAds;

use GetOpt\GetOpt;
use Google\Ads\GoogleAds\Lib\V13\GoogleAdsClient;
use Google\Ads\GoogleAds\Lib\V13\GoogleAdsClientBuilder;
use Google\Ads\GoogleAds\Lib\V13\GoogleAdsException;
use Google\Ads\GoogleAds\Lib\OAuth2TokenBuilder;
use Google\Ads\GoogleAds\Lib\V13\GoogleAdsServerStreamDecorator;
use Google\Ads\GoogleAds\V13\Errors\GoogleAdsError;
use Google\Ads\GoogleAds\V13\Services\GoogleAdsRow;
use Google\ApiCore\ApiException;

class GetCampaigns implements GoogleAdsInterface {

    public function __construct(
        private $CUSTOMER_ID
    ){

    }

    /**
     * Run the get campaign code
     *
     * @return string
     */
    public function handle() : string{

        $oAuth2Credential = (new OAuth2TokenBuilder())
        ->withClientId(env('GOOGLE_ADS_CLIENT_ID'))
        ->withClientSecret(env('GOOGLE_ADS_CLIENT_SECRET'))
        ->withRefreshToken(env('GOOGLE_ADS_REFRESH_TOKEN'))
        ->build();

        $googleAdsClient = (new GoogleAdsClientBuilder())
            ->withOAuth2Credential($oAuth2Credential)
            ->withDeveloperToken(env('GOOGLE_ADS_DEV_TOKEN'))
            ->build();

        try {
            return $this->run(
                $googleAdsClient,
            );
        } catch (GoogleAdsException $googleAdsException) {
            $combined_string = sprintf(
                "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 */
                $combined_string .= sprintf(
                    "\t%s: %s%s",
                    $error->getErrorCode()->getErrorCode(),
                    $error->getMessage(),
                    PHP_EOL
                );
            }

            return $combined_string;
        } catch (ApiException $apiException) {
            return sprintf(
                "ApiException was thrown with message '%s'.%s",
                $apiException->getMessage(),
                PHP_EOL
            );
        }

    }

    /**
     * Run the request to google
     * @param GoogleAdsClient $googleAdsClient the Google Ads API client
     *
     * @return string
     */
    public function run(
        GoogleAdsClient $googleAdsClient
    ) : string {

        $googleAdsServiceClient = $googleAdsClient->getGoogleAdsServiceClient();
        $query = 'SELECT campaign.id, campaign.name FROM campaign ORDER BY campaign.id';
        /** @var GoogleAdsServerStreamDecorator $stream */
        $stream =
            $googleAdsServiceClient->searchStream($this->CUSTOMER_ID, $query);

        $combined_string = '';
        foreach ($stream->iterateAllElements() as $googleAdsRow) {
            /** @var GoogleAdsRow $googleAdsRow */
           $combined_string .= sprintf(
                "Campaign with ID %d and name '%s' was found.%s",
                $googleAdsRow->getCampaign()->getId(),
                $googleAdsRow->getCampaign()->getName(),
                PHP_EOL
            );
        }

        return $combined_string;

    }

}
fiboknacky commented 1 year ago

The client library should take care of fetching new access tokens when needed. Can you double check if env('GOOGLE_ADS_CLIENT_ID') works as expected? And what happens when you run the code example from the command line, e.g., from your local machine?

TomSenter commented 1 year ago

I've tried running it in the command line. I've also swapped out the env('GOOGLE_ADS_CLIENT_ID') for a string with the client id in it. I've also tried your Laravel Example app and that has shown the same error. Have you seen this error before?

fiboknacky commented 1 year ago

I've not seen that before. Can you try it outside Laravel first? The ones in BasicOperations, e.g., GetCampaigns.php, are the easiest one to try.

TomSenter commented 1 year ago

I've done that too, and get the exact same error.

I've also linked my account to the google ads account as a manager, and recreated the credentials so I'm not sure what the issue is.

fiboknacky commented 1 year ago

Could you contact the team on the Google Ads API forum please? We need to take a look at your credentials more closely but we cannot do that safely on GitHub. On the forum, you'll be able to Reply privately to author and share more of your information there.

Don't forget to mention this issue page, so the team there can send your case to me. Thank you.

clin407 commented 1 year ago

@TomSenter did you figure this out? running into the same issue and have similar concerns (access token can be generated but i don't see it being passed through the headers).