使用ServiceAccount调用Google Ads API报错,请求技术协助
问题描述
尝试通过服务账号(不使用OAuth Scopes)从Google Ads API拉取广告系列数据,已在yaml文件中配置所有服务账号凭证,但收到错误提示:
"生成OAuth访问令牌的Google账户(@gmail.com用户)未关联任何Ads账户。请创建新账户,或将该Google账户添加到现有Ads账户中。"
代码实现
from google.ads.googleads.client import GoogleAdsClient from google.oauth2.service_account import Credentials def get_campaigns_with_service_account(path_to_credential_file): """使用服务账号获取广告系列列表。 参数: client_id: Google Ads API凭证的客户端ID。 client_secret: Google Ads API凭证的客户端密钥(可选)。 refresh_token: Google Ads API凭证的刷新令牌(可选)。 developer_token: Google Ads API项目的开发者令牌。 path_to_credential_file: 服务账号密钥JSON文件的路径。 """ # 配置服务账号凭证 credentials = Credentials.from_service_account_file( path_to_credential_file, scopes=['https://www.googleapis.com/auth/adwords'], # 根据需要调整权限范围 ) # 使用服务账号凭证创建Google Ads客户端 client =GoogleAdsClient.load_from_storage("/content/drive/My Drive/Keys/google-ads.yaml") ga_service = client.get_service("GoogleAdsService", version="v16") # 使用CampaignService # 创建查询语句以获取所有广告系列 query = ("SELECT campaign.id, campaign.name, campaign.status " "FROM campaign") # 获取广告系列信息响应 customer_id = 'XXXXXX' # 替换为实际客户ID def stream_response(client, customer_id, query): return client.get_service("GoogleAdsService", version="v16").search_stream(customer_id=customer_id, query=query)
YAML配置文件
# 开发者令牌 ########################################################################################## # 无论使用OAuth2还是服务账号配置,向Google Ads API发送请求都需要开发者令牌。获取方式请参考相关文档。 ########################################################################################## developer_token: {{token}} # 使用Proto Plus ########################################################################################## # 该参数指定客户端库应返回proto-plus消息还是protobuf消息。值需显式设置为"True"或"False"。 ########################################################################################## use_proto_plus: False # OAuth2配置 ########################################################################################## # 以下配置参数用于推荐的OAuth2流认证。 ########################################################################################## #client_id: INSERT_ID_HERE #client_secret: INSERT_SECRET_HERE #refresh_token: INSERT_REFRESH_TOKEN_HERE # 服务账号配置 ########################################################################################## # 要使用服务账号认证,请在以下配置参数中添加适当的值,并移除上面的三个OAuth2凭证。 # "json_key_file_path"应为本地私钥JSON文件的路径,"impersonated_email"应为用于模拟请求凭证的邮箱地址。 # 如果直接授权访问账户,则"impersonated_email"配置为可选。 ########################################################################################## json_key_file_path: /content/drive/My Drive/Keys/winged-woods-421416-bcf06a74b272.json impersonated_email: api-creds@winged-woods-xxx.iam.gserviceaccount.com # 登录客户ID配置 ########################################################################################## # 仅管理账户需要:指定用于认证API调用的登录客户ID。这将是已认证管理账户的客户ID。 # 应不带短横线设置,例如:1234567890 而非 123-456-7890。 # 如果应用使用多个管理账户+OAuth对,也可以稍后在代码中指定。 ########################################################################################## login_customer_id: XXXXXXXX # 日志配置 ########################################################################################## # 以下可指定日志配置,将作为logging.config.dictConfig的输入。 # 使用根日志配置下的"level"块调整日志级别。注意"format"字段中日志消息默认截断为5000字符。 # 可以通过移除".5000"部分或修改为其他数字来更改长度。 # ######################################################################################## # logging: # version: 1 # disable_existing_loggers: False # formatters: # default_fmt: # format: '[%(asctime)s - %(levelname)s] %(message).5000s' # datefmt: '%Y-%m-%d %H:%M:%S' # handlers: # default_handler: # class: logging.StreamHandler # formatter: default_fmt # loggers: # "": # handlers: [default_handler] # level: INFO # 代理配置 ########################################################################################## # 以下可指定请求使用的可选代理配置。如果没有用户名和密码,只需指定主机和端口。 # ######################################################################################## # http_proxy: http://user:password@localhost:8000
错误信息
FaultMessage: 生成OAuth访问令牌的Google账户(@gmail.com用户)未关联任何Ads账户。请创建新账户,或将该Google账户添加到现有Ads账户中。 message: "生成OAuth访问令牌的Google账户(@gmail.com用户)未关联任何Ads账户。请创建新账户,或将该Google账户添加到现有Ads账户中。" }
解决方案
1. 修正服务账号模拟邮箱配置
你的YAML中impersonated_email填写的是服务账号自身邮箱,这是错误的。服务账号需要模拟一个已关联Google Ads账户的真实用户邮箱(如@gmail.com或企业邮箱),而非服务账号邮箱。
- 替换
impersonated_email为有权访问目标Google Ads账户的用户邮箱。
2. 添加模拟用户到Google Ads账户
登录Google Ads后台,进入「账户设置」→「用户与权限」→「邀请用户」,将模拟邮箱添加为账户用户,并分配足够的权限(如只读或编辑权限)。
3. 移除冗余的凭证初始化代码
代码中手动创建的credentials对象完全多余,GoogleAdsClient.load_from_storage会自动读取YAML中的服务账号配置,删除这部分冗余代码即可:
def get_campaigns_with_service_account(): # 直接从YAML加载客户端 client = GoogleAdsClient.load_from_storage("/content/drive/My Drive/Keys/google-ads.yaml") # 后续逻辑保持不变
4. 验证登录客户ID(针对管理账户)
如果使用的是Google Ads管理账户(MCC),确保login_customer_id填写的是管理账户ID(不带短横线),而非子账户ID;普通账户可直接移除该配置项。
5. 确认服务账号API访问权限
- 检查Google Cloud控制台中,Google Ads API已为你的项目启用;
- 确保服务账号被授予必要的IAM权限(如
roles/adsapi.serviceAgent),通常正确配置YAML和模拟邮箱即可满足需求。
内容的提问来源于stack exchange,提问作者Nikhil Kounjoor
相关产品推荐
相关产品推荐

