You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用PHP调用Google Ads API遭遇NOT_ADS_USER认证错误求助

问题描述

我在使用Google Ads API PHP客户端库结合服务账号JSON文件开发时遇到了问题:

  • 已将服务账号邀请至Google Ads账号,但邀请状态始终显示"Awaiting response",且无法登录服务账号接受邀请。
  • 运行代码调用API时,抛出UNAUTHENTICATED错误,错误码显示NOT_ADS_USER。
  • 尝试在认证请求中添加->withImpersonatedEmail($impersonatedEmail)参数(使用同一项目中拥有Google Ads访问权限的账号),问题仍未解决。

调用代码

<?php
// Include the Google Ads API PHP client library
require_once 'googleads_google-ads-php/vendor/autoload.php';

use Google\Ads\GoogleAds\Lib\V13\GoogleAdsClientBuilder;
use Google\Ads\GoogleAds\Lib\V13\GoogleAdsServerStreamDecorator;
use Google\Ads\GoogleAds\Util\V13\ResourceNames;
use Google\Ads\GoogleAds\V13\Services\GoogleAdsQuery;
use Google\Ads\GoogleAds\Lib\OAuth2TokenBuilder;

$developerToken = "developerToken";
$jsonKeyFilePath = "json_key.json";
$customerId = "CustomerId";

// Set up authentication using a service account JSON file
$googleAdsClient = (new GoogleAdsClientBuilder())
    ->withDeveloperToken($developerToken)
->withOAuth2Credential((new OAuth2TokenBuilder())
    ->withJsonKeyFilePath($jsonKeyFilePath)
    ->withScopes(['https://www.googleapis.com/auth/adwords'])
    ->build())
    ->build();


// Define the query to retrieve data from the age_range_view
$query = "SELECT segments.date, segments.device, metrics.clicks, ad_group_criterion.criterion_id, ad_group_criterion.display_name
          FROM age_range_view
          LIMIT 1000";

try {
    // Execute the query and get the results
    $response = $googleAdsClient->getGoogleAdsServiceClient()->search($customerId, $query);

    // Loop through the rows of data and extract the desired values
    foreach ($response->iterateAllElements() as $googleAdsRow) {
        $date = $googleAdsRow->getSegments()->getDate()->getValue();
        $device = $googleAdsRow->getSegments()->getDevice()->getValue();
        $clicks = $googleAdsRow->getMetrics()->getClicks()->getValue();
        $criterionId = $googleAdsRow->getAdGroupCriterion()->getCriterionId()->getValue();
        $displayName = $googleAdsRow->getAdGroupCriterion()->getDisplayName()->getValue();
        
        // Print the extracted values to the console
        printf("Date: %s | Device: %s | Clicks: %d | Criterion ID: %d | Display Name: %s\n",
            $date,
            $device,
            $clicks,
            $criterionId,
            $displayName
        );
    }
} catch (GoogleAdsException $googleAdsException) {
    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) {
    printf("ApiException was thrown with message '%s'.%s",
        $apiException->getMessage(),
        PHP_EOL
    );
}
?>

错误信息

PHP Fatal error:  Uncaught Google\ApiCore\ApiException: {
    "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.",
    "code": 16,
    "status": "UNAUTHENTICATED",
    "details": [
        {
            "@type": "type.googleapis.com\/google.ads.googleads.v13.errors.GoogleAdsFailure",
            "errors": [
                {
                    "errorCode": {
                        "authenticationError": "NOT_ADS_USER"
                    },
                    "message": "User in the cookie is not a valid Ads user."
                }
            ],
            "requestId": "requestId"
        }
    ]
}

  thrown in /data_import/googleads_google-ads-php/vendor/google/gax/src/ApiException.php on line 267
解决步骤

你遗漏了几个关键步骤,按顺序处理:

  • 手动批准服务账号邀请:服务账号是机器账号,没有登录Google Ads界面的权限,必须用Google Ads账号的管理员(真人账号)登录Google Ads后台,进入「访问权限与用户」页面,找到该服务账号的邀请请求,手动点击批准。这是解决NOT_ADS_USER错误的核心前提。

  • 配置服务账号权限:批准后,给服务账号分配合适的角色(比如「标准」或更高权限),确保它能访问你需要查询的资源(比如age_range_view这类数据视图)。

  • 正确使用模拟用户(Impersonation):如果要使用withImpersonatedEmail,需满足以下条件:

    1. 你的Google Ads账号属于Google Workspace(原G Suite)域。
    2. 在Google Cloud项目中给服务账号启用「域范围委派」。
    3. 在Google Workspace后台配置服务账号的API范围,添加https://www.googleapis.com/auth/adwords。
    4. 被模拟的邮箱必须是已经在Google Ads账号中拥有访问权限的真人用户。
      若你的账号不属于Google Workspace,直接去掉模拟参数,用服务账号本身认证即可(前提是已完成前两步)。
  • 检查代码参数有效性:

    • $customerId必须是不带横杠的纯数字(比如把123-456-7890改成1234567890)。
    • 确认json_key.json路径正确,文件是有效的服务账号密钥,无格式错误。
    • 确保$developerToken是有效的,且与你的Google Ads账号关联。
  • 验证认证流程:可以在代码中添加调试逻辑,打印出获取到的OAuth2令牌,确认令牌有效且未过期。

内容的提问来源于stack exchange,提问作者James

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 20:29:55