Hi Anash,

Our Windows service looks after all of our synching from AW, pushing 
updates to AW and downloading reports from AW. We have sql jobs that kick 
off these requests for all of our accounts multiple times per hour. 
Everything was working fine with Client Login - not to say that it wont 
with OAuth i am sure :)

At the time of the errors, we would have been running up to 15 threads on 
Synch, 15 threads on Updates and 25 threads on Reports. Every request we 
make to the API has a new AdWordsUser object created as follows ....

/* c# code START */
var adWordsUser = new AdWordsUser();

adWordsUser.Config.OAuth2ClientId = myConfig._oAuth2ClientId;
adWordsUser.Config.OAuth2ClientSecret = myConfig._oAuth2ClientSecret;
adWordsUser.Config.OAuth2RefreshToken = myConfig._oAuth2RefreshToken;

return adWordsUser;
/* c# code END */

....
(appreciate that i don't actually have to explicitly set these values as 
they are retrieved from the config at runtime)


within each account synch or update push or report request, we call any or 
all of the following AW services ...

ManagedCustomerService
CampaignService
BudgetService
AdGroupService
AdGroupAdService
AdParamService
CampaignCriterionService
AdGroupCriterionService
CustomerSyncService
ReportUtilitiesService
AdGroupBidModifierService
FeedService
FeedItemService
FeedMappingService
CampaignFeedService

...... 

We were at the AdWords workshop yesterday in London and brought this up 
during the OAuth presentation and Paul (cant remember his surname - too 
many Pauls!) said that it might be because we are creating a new 
AdWordsUser object for each request, and that this may have caused the 
library to have made too many refresh attempts ?

As to how we are retrieving OAuth2 tokens, I have created a refresh token 
using the OAuthTokenGenerator.exe and am simply using this along with my 
ClientId and Secret within the configuration. My understanding from our 
conversation so far was that the actual access token is created and used 
under the hood by the client library and that the refresh token simply 
refreshes this token.

Just as a side note - We also have a wrapper around all our requests to 
catch exceptions and to apply the necessary wait times if we are Rate 
Limited - however we have only been managing ACCOUNT and DEVELOPER scope 
levels of Rate Limit and not the USER level as we were getting with these 
particular Rate Limit exceptions.

I know that the ClientId and Secret and Refresh Token do work because i can 
make requests of our production AW accounts from my local workstation with 
the same OAuth credentials that were failing - it appears to be the 
multiple threads of requests that we are getting stuck on.

Many thanks in advance

Giles






On Tuesday, November 5, 2013 11:54:29 AM UTC, Anash P. Oommen (AdWords API 
Team) wrote:
>
> Hi Giles,
>
> The error suggests that you are refreshing the access token very 
> frequently (or rather, the library is doing this very frequently for some 
> reason). Could you provide more details on how your code works? Is it multi 
> threaded? Are you creating mutliple AdWordsUsers? How are you retrieving 
> OAuth2 tokens? Feel free to reply to author and ping this thread in case 
> you don't want to discuss some of these details in the public forum.
>
> Cheers,
> Anash P. Oommen,
> AdWords API Advisor.
>
> On Sunday, November 3, 2013 2:42:32 PM UTC-5, giles bodger wrote:
>>
>> Hi Anash,
>>
>> So we put our OAuth2 enabled application into our production environment, 
>> which caters for synching data, updating data and processing reports. We 
>> immediately ran into hundreds of the following errors .....
>>
>> ........
>>
>> <ExceptionType>Google.Api.Ads.Common.Lib.AdsOAuthException</ExceptionType>
>>     <StackTrace>An unhandled exception occurred.
>> [Google.Api.Ads.Common.Lib.AdsOAuthException]: Failed to refresh access 
>> token.
>> &lt;HTML&gt;
>> &lt;HEAD&gt;
>> &lt;TITLE&gt;User Rate Limit Exceeded&lt;/TITLE&gt;
>> &lt;/HEAD&gt;
>> &lt;BODY BGCOLOR="#FFFFFF" TEXT="#000000"&gt;
>> &lt;H1&gt;User Rate Limit Exceeded&lt;/H1&gt;
>> &lt;H2&gt;Error 403&lt;/H2&gt;
>> &lt;/BODY&gt;
>> &lt;/HTML&gt;
>>
>>
>> Stack Trace: 
>>    at 
>> Google.Api.Ads.Common.Lib.OAuth2ProviderForApplications.RefreshAccessTokenInOfflineMode()
>>    at Google.Api.Ads.Common.Lib.OAuth2ProviderBase.GetAuthHeader()
>>    at Google.Api.Ads.AdWords.Lib.AdWordsSoapClient.InitForCall(String 
>> methodName, Object[] parameters)
>>
>>       .........
>>
>>
>> I thought from your explanation, that the access token is refreshed 
>> automatically - under the hood by the client library framework - when we 
>> supply the refresh token at run time - which is what i am doing.
>>
>> We have hit rate limit exceeded errors previously and have built in 
>> support to back off to not keep incurring them (appreciate that we don't 
>> incur a penalty for requests made when developer / account level usage is 
>> in breach) and making unnecessary requests.
>>
>> If you could shed any light on this I would be most appreciative
>>
>> many thanks in advance
>>
>> Giles
>>
>>
>>
>> On Tuesday, October 15, 2013 3:08:15 PM UTC+1, Anash P. Oommen (AdWords 
>> API Team) wrote:
>>>
>>> Hi Giles,
>>>
>>> That's a lot of questions, I'll try to get all your questions answered. 
>>> Feel free to follow up if you have more questions.
>>>
>>> At a low level, OAuth flow involves 
>>>     (a) generating an authorization url
>>>     (b) Navigating the user to the url and asking user to authorize it.
>>>     (c) Obtaining an authorization code from server once the user 
>>> authorizes the access (This is the authorization code you see on the url)
>>>     (d) Exchanging the authorization code for an access token (for 
>>> authorizing your API calls, short lived, typically expires in 1 hour) and 
>>> optionally a refresh token (for obtaining a new access token once the old 
>>> one expires, won't expire until the user explicitly revokes this token)
>>>     (e) Making calls with access token in OAuth2 Authorization header.
>>>     (f) Detecting when the access token expires (either track remaining 
>>> lifetime of the token, or examine the errorcode thrown by the server)
>>>     (g) Use refresh token to get a new access token, repeat (e) and (f)
>>>
>>> If you have just one customer, you can use OAuthTokenGenerator.exe to 
>>> do steps (a) to (d). If you have an application where users login 
>>> interactively, you need to implement (a) to (d) as shown in the OAuth 
>>> ASP.NET code example. The client library takes care of (e) to (g) 
>>> provided you mention the configuration in app.config or you load them into 
>>> AdWordsUser at runtime.
>>>
>>> To answer your specific questions,
>>>
>>> 1. Yes, you are right in thinking that you can generate the 
>>> configuration one-time using OAuthTokenGenerator.exe and use that with your 
>>> Windows service.
>>> 2. No, it is used only for obtaining the access and refresh tokens.
>>> 3. Yes, it is used to refresh the access token automatically once it 
>>> expires. Since your service is a Windows service, you will definitely need 
>>> this token.
>>> 4. ClientId and ClientSecret won't expire. Only access token will expire.
>>> 5. Yes, you can.
>>> 6. Yes, you need to keep the project on the Google API Console in tact, 
>>> since the access and refresh tokens are issued against the Google API 
>>> Console.
>>>
>>> Hope this helps. Let me know if you have more questions,
>>>
>>> Cheers,
>>> Anash P. Oommen,
>>> AdWords API Advisor
>>>
>>> On Tuesday, October 15, 2013 6:14:13 PM UTC+5:30, giles bodger wrote:
>>>>
>>>> Hi all,
>>>>
>>>> So we have a Windows Service which we use to manage our AdWords 
>>>> accounts and am now trying to convert to using OAuth2 from ClientLogin as 
>>>> the Authorization Method.
>>>> The situation is such that I don't have a need to send a user to a 
>>>> redirect page to verify access to their data, I simply need MY Windows 
>>>> service to be able to access MY Adwords account data.
>>>>
>>>> reading up on the following page ......
>>>>
>>>> https://code.google.com/p/google-api-adwords-dotnet/wiki/UsingOAuth#Adding_OAuth2_support_for_your_application_(multiple_logins)
>>>>
>>>> Because we have a hierarchy of Advertiser accounts all linked under a 
>>>> single master MCC, I think I am right in saying that I can create the 
>>>> necessary ClientID and the Client Secret by using the 
>>>> "OAuth2TokenGenerator.exe" application, and indeed I went through the 
>>>> following the steps......
>>>>
>>>>    1. Navigated to the page https://code.google.com/apis/console/ 
>>>>    2. Log in to the adwords account
>>>>    3. Create a new Project (although I don't really know what a 
>>>>    project is or what it is for ?)
>>>>    4. Then, not in the new "cloud console" dashboard but the old one, 
>>>>    i was able to click on "API Access" and then "Create an OAuth2 client 
>>>> Id"
>>>>    5. I then entered this data along with the already entered OAuth2 
>>>>    Scope in the OAuth2TokenGenerator
>>>>    6. A browser window then opened to a localhost domain with the 
>>>>    following url , 
>>>> http://localhost:8080/?code=[<http://localhost:8080/?code=4/SdZV4PkI8lbav1fOPSTdyHRzOZhr.Eg9_Y1PlO9seOl05ti8ZT3YR3M5ugwI>REMOVED
>>>>  
>>>>    FOR SECURITY PURPOSES] , I am presuming that this browser window opened 
>>>> in 
>>>>    order for me to verify that i, as the adwords account user, will allow 
>>>> my 
>>>>    windows service (that i am creating the OAuth2 configuration for) to 
>>>> have 
>>>>    access to. As I was logged into adwords we had some sort of redirection 
>>>> and 
>>>>    an Authentication Code "code" was given as you can see in the 
>>>> querystring.
>>>>    7. The OAuth2TokenGenerator then presented me with the OAuth2 
>>>>    configuration that I will need
>>>>    
>>>>
>>>> <add key='AuthorizationMethod' value='OAuth2' />
>>>> <add key='OAuth2ClientId' value='[VALUE]' />
>>>> <add key='OAuth2ClientSecret' value='[VALUE]' />
>>>> <add key='OAuth2RefreshToken' value='[VALUE]' />
>>>>
>>>> So I add these to my app.config, and then whenever I make a request via 
>>>> the Adwords API to access my account, I am creating the following 
>>>> AdWordsUser ....
>>>>
>>>>
>>>> /* c# code START */
>>>> var adWordsUser = new AdWordsUser();
>>>>
>>>> adWordsUser.Config.OAuth2ClientId = myConfig._oAuth2ClientId;
>>>> adWordsUser.Config.OAuth2ClientSecret = myConfig._oAuth2ClientSecret;
>>>> adWordsUser.Config.OAuth2RefreshToken = myConfig._oAuth2RefreshToken; 
>>>> // what is this used for ?
>>>>
>>>> return adWordsUser;
>>>> /* c# code END */
>>>>
>>>>
>>>> So this then seems to work and I appear to be able to access the data 
>>>> in my Adwords account, which is great, but can I ask the following
>>>>
>>>>
>>>>    1. Is this the correct method for setting up OAuth2 access to an 
>>>>    Adwords account for use within a Windows Service? - I have no user 
>>>> other 
>>>>    than myself that would need to verify that my Windows Service is 
>>>> allowed 
>>>>    access to my Adwords account data.
>>>>    2. Do I have any need for the Authorisation Code as given in the 
>>>>    browser window as described in point 6 above as I explained the 
>>>>    OAuth2TokenGenerator process ?
>>>>    3. When I create my AdWordsUser object, do I need to utilise the 
>>>>    OAuth2RefreshToken? Is this RefreshToken relevent to my set up?
>>>>    4. Is my ClientId and ClientSecret about to expire at any point in 
>>>>    the future, like an Access Token might expire with a mobile application 
>>>>    style user access scenario?
>>>>    5. We currently deploy more than one Windows Service to access the 
>>>>    same Adwords account. Can more than 1 Windows service use these same 
>>>>    credentials at the same time?
>>>>    6. When logged into my account at 
>>>>    https://code.google.com/apis/console/b/0/, I can see my "ClientId 
>>>>    For Installed Applications" within which I see my Client ID and Client 
>>>>    Secret - I also see RedirectURI's. Do I have any need for these?
>>>>    
>>>>
>>>>
>>>> A lot of questions i know, so many thanks in advance
>>>>
>>>> Giles Bodger
>>>>
>>>>
>>>>  
>>>>
>>>>
>>>>
>>>>  
>>>>
>>>

-- 
-- 
=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~
Also find us on our blog and discussion group:
http://googleadsdeveloper.blogspot.com
http://groups.google.com/group/adwords-api
=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~

You received this message because you are subscribed to the Google
Groups "AdWords API Forum" group.
To post to this group, send email to adwords-api@googlegroups.com
To unsubscribe from this group, send email to
adwords-api+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/adwords-api?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"AdWords API Forum" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to adwords-api+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to