Adwords API - Laravel 5 - Authorization Error

209 views
Skip to first unread message

Thomas in het Veld

unread,
Oct 6, 2017, 5:11:09 AM10/6/17
to AdWords API Forum
Hello,

I am making use of the nikolajlovenhardt/laravel-google-ads library for Laravel 5.

I set up  a product manager account and created an API key, requested the clientId, clientSecret and refreshToken.
I have setup a MCC test account, and notated its clientCustomerId.

But still, I'm getting "Authorized error".

My Adwords config:

<?php

return [
    'ADWORDS' => [
        'developerToken' => 'xxxxxxxxxxxxxxxx',
        'clientCustomerId' => 'xxx-xxx-xxx',

        /*
         * Optional. Set a friendly application name identifier.
         *
         * 'userAgent' => '',
         */

        /*
         * Optional additional AdWords API settings.
         * endpoint = "https://adwords.google.com/"
         *
         * 'isPartialFailure' => false,
         */

        /*
         * Optional setting for utility usage tracking in the user agent in requests.
         * Defaults to true.
         *
         * 'includeUtilitiesInUserAgent' => true,
         */
    ],

    'DFP' => [
        'networkCode' => '',
        'applicationName' => '',
    ],

    'ADWORDS_REPORTING' => [
        /*
         * Optional reporting settings.
         *
         * 'isSkipReportHeader' => false,
         * 'isSkipColumnHeader' => false,
         * 'isSkipReportSummary' => false,
         * 'isUseRawEnumValues' => false,
         */
    ],

    'OAUTH2' => [
        /*
         * Required OAuth2 credentials. Uncomment and fill in the values for the
         * appropriate flow based on your use case. See the README for guidance:
         */

        /*
         * For installed application or web application flow.
        */
         'clientSecret' => 'xxxxxxxxxxxxxxxxxxxxxxx',
         'refreshToken' => 'xxxxxxxxxxxxxxxxxxxxxxxxxxx',

        /*
         * For service account flow.
         * 'jsonKeyFilePath' => 'INSERT_ABSOLUTE_PATH_TO_OAUTH2_JSON_KEY_FILE_HERE'
         * 'scopes' => 'https://www.googleapis.com/auth/adwords',
         */
    ],

    'SOAP' => [
        /*
         * Optional SOAP settings. See SoapSettingsBuilder.php for more information.
         * 'compressionLevel' => <COMPRESSION_LEVEL>,
         * 'wsdlCache' => <WSDL_CACHE>,
         */
    ],

    'PROXY' => [
        /*
         * Optional proxy settings to be used by SOAP requests.
         * 'host' => '<HOST>',
         * 'port' => <PORT>,
         * 'user' => '<USER>',
         * 'password' => '<PASSWORD>',
         */
    ],

    'LOGGING' => [
        /*
         * Optional logging settings.
         * 'soapLogFilePath' => 'path/to/your/soap.log',
         * 'soapLogLevel' => 'INFO',
         * 'reportDownloaderLogFilePath' => 'path/to/your/report-downloader.log',
         * 'reportDownloaderLogLevel' => 'INFO',
         * 'batchJobsUtilLogFilePath' => 'path/to/your/bjutil.log',
         * 'batchJobsUtilLogLevel' => 'INFO',
         */
    ],
];


My Controller:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use LaravelGoogleAds\Services\AdWordsService;
use Google\AdsApi\AdWords\AdWordsServices;
use Google\AdsApi\AdWords\AdWordsSessionBuilder;
use Google\AdsApi\AdWords\v201609\cm\CampaignService;
use Google\AdsApi\AdWords\v201609\cm\OrderBy;
use Google\AdsApi\AdWords\v201609\cm\Paging;
use Google\AdsApi\AdWords\v201609\cm\Selector;

class AdwordsController extends Controller
{
    /** @var AdWordsService */
    protected $adWordsService;
    
    /**
     * @param AdWordsService $adWordsService
     */
    public function __construct(AdWordsService $adWordsService)
    {
        $this->adWordsService = $adWordsService;
    }

    public function index() {
    $test = $this->campaigns();

    //return dd($test);
    }

    public function campaigns()
    {
        $customerClientId = 'xxx-xxx-xxxx';

        $campaignService = $this->adWordsService->getService(CampaignService::class, $customerClientId);

        // Create selector.
        $selector = new Selector();

        $selector->setFields(array('Id', 'Name'));
        $selector->setOrdering(array(new OrderBy('Name', 'ASCENDING')));

        // Create paging controls.
        $selector->setPaging(new Paging(0, 100));

        // Make the get request.
        $page = $campaignService->get($selector);

        dd($page);
    }
}

But still it is giving me the following error:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Header><ResponseHeader xmlns="https://adwords.google.com/api/adwords/cm/v201609"><requestId>00055adb54c6d2180a3781c64d0800fa</requestId><serviceName>CampaignService</serviceName><methodName>get</methodName><operations>1</operations><responseTime>78</responseTime></ResponseHeader></soap:Header><soap:Body><soap:Fault><faultcode>soap:Server</faultcode><faultstring>[AuthorizationError.USER_PERMISSION_DENIED @ ; trigger:'&lt;null&gt;']</faultstring><detail><ApiExceptionFault xmlns="https://adwords.google.com/api/adwords/cm/v201609"><message>[AuthorizationError.USER_PERMISSION_DENIED @ ; trigger:'&lt;null&gt;']</message><ApplicationException.Type>ApiException</ApplicationException.Type><errors xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="AuthorizationError"><fieldPath></fieldPath><trigger>&lt;null&gt;</trigger><errorString>AuthorizationError.USER_PERMISSION_DENIED</errorString><ApiError.Type>AuthorizationError</ApiError.Type><reason>USER_PERMISSION_DENIED</reason></errors></ApiExceptionFault></detail></soap:Fault></soap:Body></soap:Envelope>


I would really appreciate your help. Thank you!

Shwetha Vastrad (AdWords API Team)

unread,
Oct 6, 2017, 10:44:02 AM10/6/17
to AdWords API Forum
Hi, 

This error occurs when there is no link between the manager account authenticated in the request and the client account specified in the headers. You need to use CustomerService.getCustomers() to get the list of AdWords accounts directly access by your OAuth2 credentials and then use ManagedCustomerService to determine which client accounts are linked to your manager account.

If this doesn't work, please provide the SOAP request and response logs and the email address used to generate the refresh token. Please use Reply privately to author when responding. 

Regards,
Shwetha, AdWords API Team.
Reply all
Reply to author
Forward
0 new messages