Re: AdWords API google-api-ads-ruby invalid grant

698 views
Skip to first unread message

Anash P. Oommen (AdWords API Team)

unread,
May 24, 2013, 10:35:43 AM5/24/13
to adwor...@googlegroups.com
HI Christopher,

Could you see if making scope space separated instead of comma separated solves your issue?

Cheers,
Anash P. Oommen,
AdWords API Advisor

On Thursday, May 23, 2013 1:50:12 PM UTC+5:30, Christopher Sell wrote:
Hi all, sorry to repost, but I am experiencing a new error using oauth2 with google-api-ads-ruby gem and I wanted to update my question.

I am using omniauth for oauth2 authentication with Google.
  config.omniauth :google_oauth2, ENV['GOOGLE_CONSUMER_KEY'], ENV['GOOGLE_CONSUMER_SECRET'],
                  {
                    :scope => "userinfo.email,userinfo.profile,analytics.readonly,http://gdata.youtube.com,https://adwords.google.com/api/adwords/",
                    :approval_prompt => "force",
                    :access_type => "offline"
                  }

Great: I am able to authenticate the user, get their access_token, refresh_token, and verification_code and store them in my database.

Bad: Now I am actually trying to make calls to the AdWords API on their behalf and experiencing the following error:
AdsCommon::Errors::AuthError: Authorization error occured: Authorization failed.  Server message:
{
  "error" : "invalid_grant"
}

I know I need to authorize with adwords using the verification code and this is where I am getting the error.
Here is the method I am using to call the AdWords API. My code is failing on adwords.authorize()
    config_filename = File.join(Rails.root, 'config', 'adwords_api.yml')
    adwords = AdwordsApi::Api.new(config_filename)
    api_version = :v201302
    token = adwords.authorize({:oauth2_verification_code => google_authentication.verification_code})
    campaign_srv = adwords.service(:CampaignService, api_version)

Here is my adwords_api.yml file:
---
:authentication:
  # Authentication method, for web applications OAuth is recommended.
  :method: OAuth2

  # Auth parameters for OAuth2.0 method.
  :oauth2_client_id: MY CLIENT_ID
  :oauth2_client_secret: MY CLIENT SECRET
  :oauth2_access_type: 'offline'
  :oauth2_approval_prompt: 'force'
  # Callback is set up by the application at runtime.

  # Other parameters.
  :developer_token: MY_DEVELOPER_TOKEN
  :user_agent: MARKETSTARTER
:service:
  :environment: PRODUCTION
:connection:
  # Enable to request all responses to be compressed.
  :enable_gzip: false
:library:
  :log_level: INFO



Christopher Sell

unread,
May 24, 2013, 12:49:32 PM5/24/13
to adwor...@googlegroups.com
I changed the file adwords_api.yml file  to be space separated and I am still getting invalid grant.

:authentication:
  :method: OAuth2
  :oauth2_client_id: MYCLIENTID
  :oauth2_client_secret: MYCLIENTSECRET
  :oauth2_access_type: 'offline'
  :oauth2_approval_prompt: 'force'
  :oauth2_scope: "userinfo.email userinfo.profile analytics.readonly http://gdata.youtube.com https://adwords.google.com/api/adwords/"

  :developer_token: MYDEVTOKEN
  :user_agent: MARKETSTARTER
:service:
  :environment: PRODUCTION
:connection:
  :enable_gzip: false
:library:
  :log_level: INFO

Omniauth works fine. I am able to get the access token, refresh token, and verification code for the user. 
I get the user to approve all the necessary scopes as well. Screenshot attached.

The problem starts when I call a method trying to access the AdWords API and authorize. That is when I get the invalid grant error.

Here is the method I am using to call the AdWords API and the adwords_api.yml file setup.

def update_adwords
    self.google_refresh_access_token unless self.google_access_token_live? #refresh access token if over an 1 hour old.
    google_authentication = self.authentications.find(:first, :conditions => { :provider => 'google_oauth2'})
    config_filename = File.join(Rails.root, 'config', 'adwords_api.yml')
    adwords = AdwordsApi::Api.new(config_filename)
    api_version = :v201302
    token = adwords.authorize({:oauth2_verification_code => google_authentication.verification_code}) #this is where error is happening
    campaign_srv = adwords.service(:CampaignService, api_version)
end

:authentication:
  :method: OAuth2
  :oauth2_client_id: MYCLIENTID
  :oauth2_client_secret: MYCLIENTSECRET
  :oauth2_access_type: 'offline'
  :oauth2_approval_prompt: 'force'
  :oauth2_scope: "userinfo.email userinfo.profile analytics.readonly http://gdata.youtube.com https://adwords.google.com/api/adwords/"

  :developer_token: MYDEVTOKEN
  :user_agent: MARKETSTARTER
:service:
  :environment: PRODUCTION
:connection:
  :enable_gzip: false
:library:
  :log_level: INFO

Sumit Bisht

unread,
Sep 19, 2013, 6:29:53 AM9/19/13
to adwor...@googlegroups.com
Hi All!
Is there any solution to this problem?
I too have the same problem and while my application worked fine with hardcoded values, it was failing with this approach.

Danial Klimkin

unread,
Sep 20, 2013, 6:30:21 AM9/20/13
to adwor...@googlegroups.com
Hello Christopher, Sumit,


In case you use 3rd party lib to obtain access and refresh token, you don't need to use verification code again (it is already used and no longer valid).

Instead, pass the refresh token directly to the library as:

token = {
  :access_token=>"AbCdEf",
  :refresh_token=>"gHiJkL",
  :issued_at=>(time access token issued),
  :expires_in=>3600
}
adwords.authorize({:oauth2_token => token})

Note, you don't need to provide scope as it is already requested by you with omniauth.


-Danial, AdWords API Team.

Orr Yakobi

unread,
Aug 2, 2017, 1:18:16 AM8/2/17
to AdWords API Forum
How do u I access the time that access token was issued at?

Sreelakshmi Sasidharan (AdWords API Team)

unread,
Aug 9, 2017, 5:56:12 PM8/9/17
to AdWords API Forum
Hi Orr, 

Are you still looking for the issued time of an access token? You might not be able to get the issued time directly, but you can derive that based on the 'expires_in' time. To get the 'expires_in' time please use this link and provide the access token that you want to check for. If you want to do this programatically, you can use the following link: https://www.googleapis.com/oauth2/v2/userinfo?access_token="YOUR_ACCESS_TOKEN". An access token is short lived and it will expire in 3600 seconds.

Thanks,
Sreelakshmi, AdWords API Team
Reply all
Reply to author
Forward
0 new messages