Question

I'm utilizing the Bing Ads API to get campaign stats (clicks, impressions, etc.) from online ads running on bing.

To retrieve these stats, you need to make 2 API requests through the reporting service.

  1. A "SubmitGenerateReport" request that you pass stat fields/date ranges to and returns a ReportRequestId
  2. A "PollGenerateReport" request that you pass the ReportRequestId to and returns a download URL for your requested report

The problem I'm having is that sometimes, the SubmitGenerateReport requests takes an additional second or two to return this ReportRequestId so the page encounters an error "Invalid ReportRequestId" - because it doesn't have one yet. When I reload the page, it solves it most times (if not, an additional reload or two will get it).

I've tried to add a Sleep command after the first request (as you'll see below) but it doesn't seem to solve the issue.

Is there a better option to deal with this? The Bing API team hasn't been much help.

adwordscampaign_controller.rb

#Start Bing Reporting Code - acquire report request ID number
client = Savon.client("https://adcenterapi.microsoft.com/Api/Advertiser/v8/Reporting/ReportingService.svc?wsdl")
@response = client.request :v8, :submit_generate_report, xmlns: "https://adcenter.microsoft.com/v8" do
  soap.namespaces["xmlns:v8"] = "https://adcenter.microsoft.com/v8"
  soap.namespaces["xmlns:i"] = "http://www.w3.org/2001/XMLSchema-instance"
  soap.namespaces["xmlns:a1"] ="http://schemas.microsoft.com/2003/10/Serialization/Arrays"
  soap.header = "<v8:UserName>#{binguser}</v8:UserName><v8:Password>#{bingpass}</v8:Password><v8:DeveloperToken>[removed]</v8:DeveloperToken>"
  soap.body = "<ReportRequest i:nil=\"false\" i:type=\"CampaignPerformanceReportRequest\"><Format i:nil=\"false\">Xml</Format><Language i:nil=\"false\">English</Language>[shortened for the sake of reader sanity]</ReportRequest>"
end

#adding delay to compensate for slow turnaround by report generation
sleep 1.5

@responsehash = @response.to_hash
@responsehashdeep = @responsehash[:submit_generate_report_response][:report_request_id]
@report_req_id = @responsehashdeep.to_s
reportreq = @report_req_id
#report request ID acquired

#acquire Bing report download URL
reportclient = Savon.client("https://adcenterapi.microsoft.com/Api/Advertiser/v8/Reporting/ReportingService.svc?wsdl")
@reportresponse = reportclient.request :v8, :poll_generate_report do
  soap.namespaces["xmlns:v8"] = "https://adcenter.microsoft.com/v8"
  soap.header = "<v8:UserName>[removed]</v8:UserName><v8:Password>[removed]</v8:Password><v8:DeveloperToken>[removed]</v8:DeveloperToken><v8:CustomerId>[removed]</v8:CustomerId><v8:CustomerAccountId>[removed]</v8:CustomerAccountId>"
  soap.body = "<v8:ReportRequestId>#{reportreq}</v8:ReportRequestId>"
end
@reportresponsehash = @reportresponse.to_hash
@reportresponsehashdeep = @reportresponsehash[:poll_generate_report_response][:report_request_status][:report_download_url]
reporturl = @reportresponsehashdeep.to_s
#report download URL acquired
Was it helpful?

Solution

If Bing doesn't have an API to check the status of the report, you could catch the exception and retry. This might be helpful in the later case https://github.com/nfedyashev/retryable

Given where you are putting the sleep call I think you might also be confused as to what is going on. The response is always there when the request returns, but when you make the second API call the report is not ready yet.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top