Hello again Mr. Thanet

"In short, if you would like to get statistics about campaigns, for 
example, the only way for now is to use reporting feature of the API". <- 
That's the line that I needed from you to show to my superiors, thank you! 
hehe

Ok now, let's get into this. I need just one more reply for help.

With the automation of the access token issue already written in your code 
example, basically, finally, you sold it to me. That project seems to work 
flawless... the only thing is that when I download I report, I get nothing 
:(

Let me explain. The interface in the Default.aspx let you do some things. 
One of them is to retrieve a list of campaigns after entering a client id. 
It works, and the query responde with my test campaign. That works well. 
Now, when I try to download a simple report to view a little bit of 
information of that very same campaign, the report downloads blank.

Here is my code:

 ConfigureUserForOAuth();

      ReportDefinition definition = new ReportDefinition();

      definition.reportName = "CAMPAIGN_PERFORMANCE_REPORT";
      definition.reportType = 
ReportDefinitionReportType.CRITERIA_PERFORMANCE_REPORT;
      definition.downloadFormat = DownloadFormat.CSV;
      definition.dateRangeType = ReportDefinitionDateRangeType.ALL_TIME;

      // Create selector.
      Selector selector = new Selector();
      selector.fields = new string[] {"CampaignId", "CampaignStatus", 
"CampaignName"};

      //Predicate predicate = new Predicate();
      //predicate.field = "Status";
      //predicate.@operator = PredicateOperator.IN;
      //predicate.values = new string[] { "ENABLED", "PAUSED" };
      //selector.predicates = new Predicate[] { predicate };

      definition.selector = selector;
      definition.includeZeroImpressions = true;

      string filePath = ExampleUtilities.GetHomeDir() + 
Path.DirectorySeparatorChar + "prueba.csv";

      try
      {
          ReportUtilities utilities = new ReportUtilities(user, "v201502", 
definition);
          using (ReportResponse response = utilities.GetResponse())
          {
              response.Save(filePath);
          }
          //Console.WriteLine("Report was downloaded to '{0}'.", filePath);
          ClientScript.RegisterStartupScript(this.GetType(), "yourMessage", 
"alert('" + "File Downloaded!" + "');", true);
      }
      catch (Exception ex)
      {
          throw new System.ApplicationException("Failed to download 
report.", ex);
      }

I even commented the "predicate" part, and the 
"definition.includeZeroImpressions = true;"  line is there, so I suppose to 
be receiving a .csv file with a least one campaign, but what I get instead 
is a blank .csv, only showing the headers specified in the selector. Same 
thing happens if I download it in xml format. I receive an xml with the 
right column names, but without values.

What I'm doing wrong? Maybe I'm missing one last obvious thing? I'm using 
the wrong report? That should not be an issue anyway, as 
"definition.dateRangeType = ReportDefinitionDateRangeType.ALL_TIME;" 
and "definition.includeZeroImpressions = true;" lines should be enough to 
retrieve everything anyway.

I will be waiting for another reply. I'm just a couple of lines away maybe 
to finish my part of the project. Thank you again for pointing me in the 
right direction.

- Sam

On Friday, March 27, 2015 at 3:12:24 AM UTC-4, Thanet Knack Praneenararat 
(AdWords API Team) wrote:
>
> Hi Samuel,
>
> First, let me update about Selectors that you seem prefer to use to 
> reporting feature.
> According to my colleagues, the reason why Selectors do not expose many 
> statistics (e.g., number of clicks) is because of technical issues of 
> underlying technologies.
> That's why we created a reporting function so that users can get their 
> statistics much faster and the burdens on related machines are reduced.
>
> In short, if you would like to get statistics about campaigns, for 
> example, the only way for now is to use reporting feature of the API.
>
> Regarding your questions about your codes, 
>
>    1. Strange symbols seem to be the result of URL encoding. I don't 
>    think that affects what you would like to do in this program.
>    2. For the access token vs refresh token, they DO differ. Access token 
>    is what should be specified inside request headers 
>    
> <https://developers.google.com/adwords/api/docs/guides/reporting#request-headers>
>  
>    of calls to API. 
>    On the other hand, refresh token is used to get access token when the 
>    access token is expired, on behalf of the user. I recommend you to review 
>    the concept on this page 
>    <https://developers.google.com/adwords/api/docs/guides/authentication>.
>
> By the way, one reason I highly recommend you to try using our code 
> example 
> <https://github.com/googleads/googleads-dotnet-lib/tree/master/examples/AdWords>
>  
> is because it is customized and tested already so you can get your jobs 
> done (or at least get started) quite easily.
> Another good aspect of using the code example in this case is that refresh 
> token is used to get new access tokens (when they are expired) on your 
> behalf *automatically*. 
>
> That's why you don't need to specify access token information in 
> App.config 
> <https://github.com/googleads/googleads-dotnet-lib/blob/master/examples/AdWords/CSharp/App.config>--only
>  
> refresh token is enough.
> However, to call reporting function an access token is still needed. 
> Therefore, when you specify *refresh tokens* instead of *access tokens*, 
> they do not work.
>
> If you still would like to use access tokens, please follow this guide 
> <https://developers.google.com/accounts/docs/OAuth2> about how to 
> retrieve them.
> Please beware that access tokens may get expired and you may need to 
> retrieve a new one every time.
>
> Finally, you can implement to use your refresh token to get new access 
> tokens by yourself as well, 
> but that would re-invent the wheel of our client library. :-)
>
> Best,
> Thanet, AdWords API Team
>
> On Friday, March 27, 2015 at 5:52:48 AM UTC+9, Samuel Otero wrote:
>>
>> Again Mr. Thanet, thank you so much for your fast answer.
>>
>> I'm really trying to get into this. Here is what I have done so far:
>>
>> I decided to keep working on the code example that I showed you. I know 
>> that you recommended me your code example 
>> <https://www.google.com/url?q=https%3A%2F%2Fgithub.com%2Fgoogleads%2Fgoogleads-dotnet-lib%2Fblob%2Fmaster%2Fexamples%2FAdWords%2FCSharp%2Fv201502%2FReporting%2FDownloadCriteriaReport.cs&sa=D&sntz=1&usg=AFQjCNE9f1kpVNUR_8WFP0EA-dvu8cbybQ>,
>>  
>> but mine seems to be a little bit more straightforward. 
>>
>> I downloaded Fiddler to check request and response logs. Here is what I 
>> got:
>>
>> RAW Request:
>>
>> POST https://adwords.google.com/api/adwords/reportdownload/v201409 
>> HTTP/1.1
>> Content-Type: application/x-www-form-urlencoded
>> Authorization: Bearer ****
>> developerToken: ****
>> clientCustomerId: ****
>> Host: adwords.google.com
>> Content-Length: 1180
>> Expect: 100-continue
>> Connection: Keep-Alive
>>
>>
>> __rdxml=%3creportDefinition%3e%0d%0a+++++++++++++++++++++++%3cselector%3e%0d%0a++++++++++++++++++++++++%3cfields%3eCampaignId%3c%2ffields%3e%0d%0a++++++++++++++++++++++++%3cfields%3eId%3c%2ffields%3e%0d%0a++++++++++++++++++++++++%3cfields%3eImpressions%3c%2ffields%3e%0d%0a++++++++++++++++++++++++%3cfields%3eClicks%3c%2ffields%3e%0d%0a++++++++++++++++++++++++%3cfields%3eCost%3c%2ffields%3e%0d%0a++++++++++++++++++++++++%3cpredicates%3e%0d%0a++++++++++++++++++++++++++%3cfield%3eStatus%3c%2ffield%3e%0d%0a++++++++++++++++++++++++++%3coperator%3eIN%3c%2foperator%3e%0d%0a++++++++++++++++++++++++++%3cvalues%3eENABLED%3c%2fvalues%3e%0d%0a++++++++++++++++++++++++++%3cvalues%3ePAUSED%3c%2fvalues%3e%0d%0a++++++++++++++++++++++++%3c%2fpredicates%3e%0d%0a++++++++++++++++++++++%3c%2fselector%3e%0d%0a++++++++++++++++++++++%3creportName%3eCustom+Adgroup+Performance+Report%3c%2freportName%3e%0d%0a++++++++++++++++++++++%3creportType%3eADGROUP_PERFORMANCE_REPORT%3c%2freportType%3e%0d%0a++++++++++++++++++++++%3cdateRangeType%3eLAST_7_DAYS%3c%2fdateRangeType%3e%0d%0a++++++++++++++++++++++%3cdownloadFormat%3eCSV%3c%2fdownloadFormat%3e%0d%0a++++++++++++++++++++%3c%2freportDefinition%3e
>>
>> And here is the response:
>>
>> HTTP/1.1 400 Bad Request
>> Content-Type: text/xml
>> Date: Thu, 26 Mar 2015 20:02:41 GMT
>> Expires: Thu, 26 Mar 2015 20:02:41 GMT
>> Cache-Control: private, max-age=0
>> X-Content-Type-Options: nosniff
>> X-Frame-Options: SAMEORIGIN
>> X-XSS-Protection: 1; mode=block
>> Server: GSE
>> Accept-Ranges: none
>> Vary: Accept-Encoding
>> Transfer-Encoding: chunked
>>
>> e1
>> <?xml version="1.0" encoding="UTF-8" 
>> standalone="yes"?><reportDownloadError><ApiError><type>AuthenticationError.OAUTH_TOKEN_INVALID</type><trigger>&lt;null&gt;</trigger><fieldPath></fieldPath></ApiError></reportDownloadError>
>> 0
>>
>>
>> Now, I have a couple of things that I would like to point out.
>>
>> 1. I don't know why my request shows all of those weirds "%3e%0d%0a++" 
>> characters. I am not very familiar with these kind of request, and I don't 
>> really know if that it's ok or it is not.
>>
>> 2. I can notice that the response clearly 
>> reads: AuthenticationError.OAUTH_TOKEN_INVALID. That gets me and I don't 
>> fully understand why it is invalid. That's the same token that I use to run 
>> this 
>> selector fields 
>> <https://developers.google.com/adwords/api/docs/appendix/selectorfields> and 
>> it works flawless. This topic 
>> <https://groups.google.com/forum/#!topic/adwords-api/3BAagDjiOsE> on 
>> this very forum has a discussion of the situation. One think that I noticed 
>> in the discussion, is that a Refresh Token (what I use in my web.config 
>> file, example: <add key='OAuth2RefreshToken' value='***' />) is not the 
>> same think as the Access Token. There is when I get lost. The OAuth2 Token 
>> Generator gives me a Refresh Token... not an "Access Token" doesn't it? 
>>
>> Maybe the problem here lies in the type of application that I chose to 
>> create my first token. I created a Client Id and a Client Secret for a 
>> "Native Application"... not a web application... but, it really has 
>> something to do with this? Or I'm just missing what should be an obvious 
>> difference between a Refresh and an Access Token?
>>
>> What do you think that should be the next steps for me in order to deal 
>> with the "AuthenticationError.OAUTH_TOKEN_INVALID" error? Again, I used the 
>> same refresh token which I used while testing the Selector Fields... and 
>> those one works. What I am missing? I feel that I'm mixing to entirely 
>> different type of tokens.
>>
>> I will be waiting for your clarification and again, thank you so much for 
>> your willingness to help.
>>
>> - Sam
>>
>>
>> On Thursday, March 26, 2015 at 11:28:21 AM UTC-4, Thanet Knack 
>> Praneenararat (AdWords API Team) wrote:
>>>
>>> Hi Samuel,
>>>
>>> Could you please tell me why you would like to use these selectors 
>>> <https://developers.google.com/adwords/api/docs/appendix/selectorfields#v201409-AdGroupService>
>>>  
>>> as well?
>>> I am still checking with my colleagues about this, but it seems 
>>> reporting feature suits the purpose of getting statistics, such as 
>>> impressions and number of clicks, much more.
>>>
>>> For those selectors you mentioned, I think the main purpose of them is 
>>> to just get the properties of entities themselves, not statistics around 
>>> them.
>>> But please wait until I get more information about the design of these 
>>> selectors.
>>>
>>> Regarding your second question, I'm afraid that it may be difficult for 
>>> us to debug your code according to security and privacy concerns.
>>> Could you please re-check your access token, developer token and client 
>>> customer ID?
>>> If you can provide SOAP request & response logs, that would be much 
>>> easier for us to debug together. (Please be sure to strip your personal 
>>> information off)
>>>
>>> For now, I recommend you to try our code example 
>>> <https://github.com/googleads/googleads-dotnet-lib/blob/master/examples/AdWords/CSharp/v201502/Reporting/DownloadCriteriaReport.cs>first
>>>  
>>> to see if everything is fine before trying external code example.
>>> Though you don't need to use client libraries all the time, they may be 
>>> a good start to see if your settings have no problems. :-)
>>>
>>> Cheers,
>>> Thanet, AdWords API Team
>>>
>>> On Friday, March 27, 2015 at 12:04:09 AM UTC+9, Samuel Otero wrote:
>>>>
>>>> Hello Thanet. I really appreciate your fast answer.
>>>>
>>>> I'm also working with the reporting feature approach, and I get an 
>>>> error saying "bad request". Maybe I'm missing something obvious in the 
>>>> definition. I was thinking to open another topic for it, but now that you 
>>>> mention it, I should take advantage right now :)
>>>>
>>>> Ok let's go by parts. First, I need to find a way anyway to retrieve 
>>>> those clicks using these selectors 
>>>> <https://developers.google.com/adwords/api/docs/appendix/selectorfields#v201409-AdGroupService>,
>>>>  
>>>> because our company want to see both approaches working, so please, if you 
>>>> can help me with that, I will really appreciate it.
>>>>
>>>> Now... about the reporting feature, this is what I am trying to do, 
>>>> following a combination of these instructions 
>>>> <https://developers.google.com/adwords/api/docs/guides/reporting> and this 
>>>> example <https://gist.github.com/ElvisLives/1287940>:
>>>>
>>>>   string URL = "
>>>> https://adwords.google.com/api/adwords/reportdownload/v201409";;
>>>>
>>>>             string authToken = "xxxxxxx";
>>>>             string clientId = "xxxxxx";
>>>>             string fileName = "prueba";
>>>>             string developerToken = "xxxxxx";
>>>>                
>>>>             var request = WebRequest.Create(URL) as HttpWebRequest;
>>>>             request.ContentType = "application/x-www-form-urlencoded";
>>>>             request.Method = "POST";
>>>>             request.Headers.Add("Authorization", "Bearer " + authToken 
>>>> );
>>>>             request.Headers.Add("developerToken", developerToken);
>>>>             request.Headers.Add("clientCustomerId", clientId);
>>>>
>>>>             string xml =
>>>>                 @"<reportDefinition>
>>>>                        <selector>
>>>>                         <fields>CampaignId</fields>
>>>>                         <fields>Id</fields>
>>>>                         <fields>Impressions</fields>
>>>>                         <fields>Clicks</fields>
>>>>                         <fields>Cost</fields>
>>>>                         <predicates>
>>>>                           <field>Status</field>
>>>>                           <operator>IN</operator>
>>>>                           <values>ENABLED</values>
>>>>                           <values>PAUSED</values>
>>>>                         </predicates>
>>>>                       </selector>
>>>>                       <reportName>Custom Adgroup Performance 
>>>> Report</reportName>
>>>>                       
>>>> <reportType>ADGROUP_PERFORMANCE_REPORT</reportType>
>>>>                       <dateRangeType>LAST_7_DAYS</dateRangeType>
>>>>                       <downloadFormat>CSV</downloadFormat>
>>>>                     </reportDefinition>";
>>>>
>>>>             using (var sw = new 
>>>> StreamWriter(request.GetRequestStream()))
>>>>             {
>>>>                 sw.Write("__rdxml=" + HttpUtility.UrlEncode(xml));
>>>>             }
>>>>
>>>>             using (var httpWebResponse = request.GetResponse() as 
>>>> HttpWebResponse)
>>>>             {
>>>>                 if (httpWebResponse.StatusCode == HttpStatusCode.OK)
>>>>                 {
>>>>                     using (Stream stream = 
>>>> httpWebResponse.GetResponseStream())
>>>>                     {
>>>>                         using (FileStream fileStream = 
>>>> File.Create(string.Format("{0}.csv", fileName)))
>>>>                         {
>>>>                             stream.CopyTo(fileStream);
>>>>                         }
>>>>                     }
>>>>                 }
>>>>             }
>>>>
>>>> I replaced the AuthToken, clientId and the Developer Token just for 
>>>> security. When I run this code, I get an exception saying "Bad Request"... 
>>>>
>>>> Example: 
>>>>
>>>>
>>>> <https://lh3.googleusercontent.com/-6W0slKg19PQ/VRQe9N_jXsI/AAAAAAAAAB8/vVmLk6ZRYJM/s1600/Reports%2BException.PNG>
>>>>
>>>>
>>>> If I'm missing something obvious, just bare with me, because this is my 
>>>> first HTTP request, and first time working with Google Api also.
>>>>
>>>> Can you point me into the right direction? Why I receive the exception 
>>>> of bad request??? Also, there is a way to retrieve those clicks using 
>>>> these 
>>>> <https://developers.google.com/adwords/api/docs/appendix/selectorfields#v201409-AdGroupService>
>>>> ?
>>>>
>>>> I will be kinda staring at my monitor waiting for your answer hehe.
>>>>
>>>> Thank you sir.
>>>>
>>>> On Thursday, March 26, 2015 at 10:13:58 AM UTC-4, Thanet Knack 
>>>> Praneenararat (AdWords API Team) wrote:
>>>>>
>>>>> Hi Samuel,
>>>>>
>>>>> Based on what you've described, it seems you may want to use reporting 
>>>>> <https://developers.google.com/adwords/api/docs/guides/reporting> 
>>>>> feature of the API.
>>>>>
>>>>> To get number of clicks and impressions for each campaign, you can use 
>>>>> Campaign 
>>>>> Performance Report 
>>>>> <https://developers.google.com/adwords/api/docs/appendix/reports/campaign-performance-report>
>>>>>  
>>>>> to obtain those relevant fields.
>>>>>
>>>>> Please refer to this C# code example 
>>>>> <https://github.com/googleads/googleads-dotnet-lib/blob/master/examples/AdWords/CSharp/v201502/Reporting/DownloadCriteriaReport.cs>
>>>>>  for 
>>>>> more information. 
>>>>> In the code, Criteria Performance Report 
>>>>> <https://developers.google.com/adwords/api/docs/appendix/reports/criteria-performance-report>
>>>>>  
>>>>> is specified but you can adapt to use Campaign Performance Report quite 
>>>>> easily.
>>>>>
>>>>> Best,
>>>>> Thanet, AdWords API Team
>>>>>
>>>>> On Thursday, March 26, 2015 at 7:18:27 AM UTC+9, Samuel Otero wrote:
>>>>>>
>>>>>> Hi everyone. If someone can help me, I will really appreciate it.
>>>>>>
>>>>>> I am trying to get some basic information from a Campaign under my 
>>>>>> test MCC account. I am using Selector Fields 
>>>>>> <https://developers.google.com/adwords/api/docs/appendix/selectorfields#v201409-AdGroupService>
>>>>>>  to 
>>>>>> do so. 
>>>>>>
>>>>>> I can get the Campaign Id, the Campaign Name, and some other info... 
>>>>>> but I just cannot find a way to retrieve the number of click at the 
>>>>>> Campaign Level, nor the Ad Groups level.
>>>>>>
>>>>>> Basically, I'm just trying to get all the information from this table:
>>>>>>
>>>>>>
>>>>>> <https://lh3.googleusercontent.com/-uaEeGeSnd3M/VRMyx1hqHZI/AAAAAAAAAAM/e1HzQDls9os/s1600/Capture%2BForum.PNG>
>>>>>> I can get my Campaign Name also... I just don't find any selector 
>>>>>> which I could retrieve those clicks. 
>>>>>>
>>>>>> Here is an example of what I'm doing in C#:
>>>>>>
>>>>>> AdWordsUser user = new AdWordsUser();
>>>>>>
>>>>>>             CampaignService campaignService = 
>>>>>> (CampaignService)user.GetService(AdWordsService.v201409.CampaignService);
>>>>>>             DataService dataService = 
>>>>>> (DataService)user.GetService(AdWordsService.v201409.DataService);
>>>>>>             AdGroupService adGroupService = 
>>>>>> (AdGroupService)user.GetService(AdWordsService.v201409.AdGroupService);
>>>>>>
>>>>>>             Selector CampaignServiceSelector = new Selector();
>>>>>>             CampaignServiceSelector.fields = new string[] { "Name", 
>>>>>> "Id", "Status" };
>>>>>>
>>>>>>
>>>>>>             Selector DataServiceSelector = new Selector();
>>>>>>             DataServiceSelector.fields = new string[] {"LocalClicks", 
>>>>>> "LocalImpressions"};
>>>>>>
>>>>>>             Selector adGroupServiceSelector = new Selector();
>>>>>>             adGroupServiceSelector.fields = new string[] { "Status", 
>>>>>> "Name" };
>>>>>>
>>>>>>
>>>>>>             var campaignInfo = 
>>>>>> campaignService.get(CampaignServiceSelector);
>>>>>>             var dataServiceInfo = 
>>>>>> dataService.getCriterionBidLandscape(DataServiceSelector);
>>>>>>             var adGroupServiceInfo = 
>>>>>> adGroupService.get(adGroupServiceSelector);
>>>>>>
>>>>>> I'm just "playing" with the selectors, and I have a pretty good idea 
>>>>>> of how I will create the report that I want. I just don't find a 
>>>>>> selector 
>>>>>> to retrieve those clicks that I marked yellow at that picture. I tried 
>>>>>> to 
>>>>>> use DataService object, which have a method called 
>>>>>> "getAdGroupBidLandscape" 
>>>>>> that seems to have a selector that could work (LocalClicks) but when I 
>>>>>> use 
>>>>>> it, the code returns 0 entries.
>>>>>>
>>>>>> I'm lost! What selector I should use to retrieve those clicks? 
>>>>>>
>>>>>> Please help! Thank you :)
>>>>>>
>>>>>

-- 
-- 
=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~
Also find us on our blog and Google+:
https://googleadsdeveloper.blogspot.com/
https://plus.google.com/+GoogleAdsDevelopers/posts
=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~

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.
Visit this group at http://groups.google.com/group/adwords-api.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/adwords-api/7b29aa91-aed5-4e18-818a-f04f3534eedd%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to