简体   繁体   中英

Google adwords api how to authorize with service account impersonation

I'm trying to develop a ruby script to query the Google Adwords API using service account credentials. I know that the json credentials file works in another script which isn't ruby but I can't get past authorization in this ruby script. I can't find any examples using this pattern. I don't want to use OAuth2 . I know this script is not well developed but I'm just trying to get the basics. What am I doing wrong here?

My company has a G Suite account and I have full administrator permissions.

Here is my code:

    #!/usr/bin/ruby

    require 'googleauth'
    require 'fileutils'
    require 'adwords_api'

    API_VERSION = :v201809

    scopes = ["https://www.googleapis.com/auth/adwords"]
    credential_file = File.open('credentials/adwords-production.json')
    prn = "adwords@mycompany.com"

    authorizer = Google::Auth::ServiceAccountCredentials.make_creds(json_key_io: credential_file, scope: scopes, prn: prn)

    def get_report_fields(report_type)

      adwords = AdwordsApi::Api.new

      report_def_srv = adwords.service(:ReportDefinitionService, API_VERSION)

      # Get report fields.
      fields = report_def_srv.get_report_fields(report_type)
      if fields
        puts "Report type '%s' contains the following fields:" % report_type
        fields.each do |field|
          puts ' - %s (%s)' % [field[:field_name], field[:field_type]]
          puts '  := [%s]' % field[:enum_values].join(', ') if field[:enum_values]
        end
      end
    end

    begin
        report_type = 'ACCOUNT_PERFORMANCE_REPORT'
        get_report_fields(report_type)
    end

From Google's docs here :

All AdWords API calls must be authorized through OAuth2. OAuth2 enables your AdWords API client app to access a user's Google Ads account without having to handle or store the user's login info.

It appears you have to use OAuth2 Authentication.

Further reading here confirms this:

Your app will need to access user data and contact other Google services on your behalf. Authentication via OAuth2 allows your app to operate on behalf of your account.

To enable your app to access the API, you need an OAuth2 client ID and client secret.

You say you have done this somewhere else where you were able to use a JSON file, so I looked into the source a little.

The source for the Ruby API is here and here . It appears there really is no other way to manage credentials, at least in the Ruby API. Looking here:

    # Retrieve correct soap_header_handler.
    #
    # Args:
    # - auth_handler: instance of an AdsCommon::Auth::BaseHandler subclass to
    #   handle authentication
    # - version: intended API version
    # - header_ns: header namespace
    # - default_ns: default namespace
    #
    # Returns:
    # - SOAP header handler
    #
    def soap_header_handler(auth_handler, version, header_ns, default_ns)
      auth_method = @config.read('authentication.method', :OAUTH2)
      handler_class = case auth_method
        when :OAUTH2, :OAUTH2_SERVICE_ACCOUNT
          AdsCommon::SavonHeaders::OAuthHeaderHandler
        else
          raise AdsCommon::Errors::AuthError,
              "Unknown auth method: %s" % auth_method
        end
      return handler_class.new(@credential_handler, auth_handler, header_ns,
                                  default_ns, version)
    end

Notice that unless OAuth is used, it throws an error. There really is no other way to authenticate. Even if you managed to authenticate another way and try passing it to the credential manager, it will reject it.

Short answer: This is not possible in the Ruby API without hacking it some way.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM