无法使用OAuth2为AdWords账户生成刷新令牌

3 投票
1 回答
3830 浏览
提问于 2025-04-17 23:52

我在用Python生成AdWords API的刷新令牌时遇到了一些麻烦,需要一些帮助。以下是我的情况:

  • 我有一个AdWords客户,我想通过AdWords API为他们拉取报告(我们现在有开发者令牌了)。假设在AdWords中,客户的账户是521-314-0974(这是我随便编的)。我在这里有点困惑:

下面是我正在尝试让它工作的生成刷新令牌的代码片段:

"""Generates a refresh token for use with AdWords."""

__author__ = 'Nathaniel Payne'

import sys
import urllib2

from oauthlib import oauth2

# Your OAuth 2.0 Client ID and Secret. If you do not have an ID and Secret yet,
# please go to https://console.developers.google.com and create a set.
CLIENT_ID = 'INSERT_CLIENT_ID_HERE'
CLIENT_SECRET = 'INSERT_CLIENT_SECRET_HERE'

# You may optionally provide an HTTPS proxy.
HTTPS_PROXY = None

# The AdWords API OAuth 2.0 scope.
SCOPE = u'https://adwords.google.com/api/adwords'
# This callback URL will allow you to copy the token from the success screen.
CALLBACK_URL = 'urn:ietf:wg:oauth:2.0:oob'
# The HTTP headers needed on OAuth 2.0 refresh requests.
OAUTH2_REFRESH_HEADERS = {'content-type':
                          'application/x-www-form-urlencoded'}
# The web address for generating new OAuth 2.0 credentials at Google.
GOOGLE_OAUTH2_AUTH_ENDPOINT = 'https://accounts.google.com/o/oauth2/auth'
GOOGLE_OAUTH2_GEN_ENDPOINT = 'https://accounts.google.com/o/oauth2/token'


def main():
  oauthlib_client = oauth2.WebApplicationClient(CLIENT_ID)

  authorize_url = oauthlib_client.prepare_request_uri(
      GOOGLE_OAUTH2_AUTH_ENDPOINT, redirect_uri=CALLBACK_URL, scope=SCOPE)
  print ('Log in to your AdWords account and open the following URL: \n%s\n' %
         authorize_url)
  print 'After approving the token enter the verification code (if specified).'
  code = raw_input('Code: ').strip()

  post_body = oauthlib_client.prepare_request_body(
      client_secret=CLIENT_SECRET, code=code, redirect_uri=CALLBACK_URL)
  if sys.version_info[0] == 3:
    post_body = bytes(post_body, 'utf8')
  request = urllib2.Request(GOOGLE_OAUTH2_GEN_ENDPOINT, post_body,
                            OAUTH2_REFRESH_HEADERS)
  if HTTPS_PROXY:
    request.set_proxy(HTTPS_PROXY, 'https')
  raw_response = urllib2.urlopen(request).read().decode()
  oauth2_credentials = oauthlib_client.parse_request_body_response(raw_response)

  print ('Your access token is %s and your refresh token is %s'
         % (oauth2_credentials['access_token'],
            oauth2_credentials['refresh_token']))
  print ('You can cache these credentials into a yaml file with the '
         'following keys:\nadwords:\n  client_id: %s\n  client_secret: %s\n'
         '  refresh_token: %s\n'
         % (CLIENT_ID, CLIENT_SECRET, oauth2_credentials['refresh_token']))


if __name__ == '__main__':
  main()

我有几个问题:

  1. 我是否需要为每个AdWords客户在console.developers.google.com上设置一个特别的项目,以便从AdWords报告API中拉取数据?还是说,我只需要提供一个通用账户的客户端密钥和ID就可以了?
  2. 接着,能不能有人确认一下在下面的Python代码块中,client_ID和Client_Secret应该填什么?我的意思是,我之前使用的是来自https://console.developers.google.com的客户端ID和客户端密钥……这是我们已经设置了账单的分析账户(我之前也用过BigQuery API)。这样做对吗?我不太明白这和这个客户的AdWords账户是怎么关联的。
  3. 在同意屏幕中,我填了我自己的邮箱,因为我是这个项目的拥有者。不过,当我运行代码时,我得到了一个需要运行的URL链接来生成代码。但是,当我运行这个代码片段时:

    print ('Log in to your AdWords account and open the following URL: \n%s\n' %
                 authorize_url)
          print 'After approving the token enter the verification code (if specified).'
          code = raw_input('Code: ').strip()
    

    我收到了一个错误。这是我收到的错误信息:

    Error: redirect_uri_mismatch
    The redirect URI in the request: urn:ietf:wg:oauth:2.0:oob did not match a registered redirect URI
    
    Learn more
        Request Details
        cookie_policy_enforce=false
        scope=https://adwords.google.com/api/adwords
        response_type=code
        access_type=online
        redirect_uri=urn:ietf:wg:oauth:2.0:oob
        display=page
        client_id=XXXXXXXXX.apps.googleusercontent.com
    

    我对此感到困惑。有些人建议我在同意屏幕中更改邮箱地址(我确实这样做了……但没有成功)。总之,我的简单目标是能够通过AdWords API从这个客户那里拉取一份报告(等我搞定了再扩展)。任何帮助都会很感激。谢谢。

1 个回答

8

经过一番努力,我终于解决了这个问题。下面是我成功通过API获取数据的详细步骤。我的情况是,我管理一个包含多个账户的AdWords MCC。因此,我回顾了许多帮助手册,做了以下几步:

  1. 创建一个新的项目,命名为AdWords-API-XXXX。
  2. 在控制台的凭证页面上,我创建了一个新的“本地应用程序的客户端ID”。这样我就能生成我需要的CLIENT_ID和CLIENT_SECRET。最重要的是,它还生成了一个重定向URI,这正是我之前遇到的问题所在。
  3. 我把这两个值添加到主脚本中,并运行了generate_refresh_token.py脚本。这样我就能生成一个有效的刷新令牌。为了确保OAuth2能让我访问我MCC下所有可能的AdWords客户,我必须登录到我的AdWords账户MCC。这个过程生成了一个认证页面的URL,要求我确认是否允许访问AdWords。
  4. 接下来,我创建了一个新的googleads.yaml脚本,并把它放在我的c:\gsutil目录下。这是大多数Python程序查找googleads.yaml文件的地方:

    adwords_client = adwords.AdWordsClient.LoadFromStorage()
    
  5. 完成这些后,我能够成功地从命令行运行脚本,生成最终的输出。这个脚本是:

    python download_criteria_report.py
    

当然,我之前已经修改了我的路径变量,以便从命令行运行Python 2.7。这个脚本是在download_criteria_report.py文件所在的目录中运行的。这个脚本成功运行,使我能够从AdWords API中提取一个测试客户的数据。

接下来的挑战是处理API返回的输出,并将其转换为我可以快速用于分析和存储的格式。

撰写回答