0
votes

I've been able to get this far without knowing about XML since the Savon gem translates Ruby code into XML, but now I'm stuck. I'm requesting a CampaignPerformanceReport from the API and I'm able to successfully retrieve the data I need, but now I need to add a filter to only get 'Paused' campaigns.

Following this documentation I sent this message to the API:

<env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tns="https://bingads.microsoft.com/Reporting/v13" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns="https://bingads.microsoft.com/Reporting/v13">
  <env:Header>
    <AuthenticationToken>foo</AuthenticationToken>
    <CustomerAccountId>foo</CustomerAccountId>
    <CustomerId>foo</CustomerId>
    <DeveloperToken>foo</DeveloperToken>
  </env:Header>
  <env:Body>
    <tns:SubmitGenerateReportRequest>
      <ReportRequest xsi:nil="false" xsi:type="CampaignPerformanceReportRequest">
        <ExcludeColumnHeaders>true</ExcludeColumnHeaders>
        <ExcludeReportFooter>true</ExcludeReportFooter>
        <ExcludeReportHeader>true</ExcludeReportHeader>
        <Format>Csv</Format>
        <Language>English</Language>
        <ReportName>CampaignPerformanceReportRequest</ReportName>
        <ReturnOnlyCompleteData>false</ReturnOnlyCompleteData>
        <Aggregation>Summary</Aggregation>
        <Columns>
          <CampaignPerformanceReportColumn>CampaignName</CampaignPerformanceReportColumn>
          <CampaignPerformanceReportColumn>CampaignStatus</CampaignPerformanceReportColumn>
          <CampaignPerformanceReportColumn>Spend</CampaignPerformanceReportColumn>
          <CampaignPerformanceReportColumn>Impressions</CampaignPerformanceReportColumn>
          <CampaignPerformanceReportColumn>Clicks</CampaignPerformanceReportColumn>
          <CampaignPerformanceReportColumn>Conversions</CampaignPerformanceReportColumn>
          <CampaignPerformanceReportColumn>Revenue</CampaignPerformanceReportColumn>
          <CampaignPerformanceReportColumn>PhoneCalls</CampaignPerformanceReportColumn>
        </Columns>
        <Filter>
          <CampaignStatusReportFilter>Paused</CampaignStatusReportFilter>
        </Filter>
        <Scope>
          <AccountIds xmlns:a1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
            <a1:long>foo</a1:long>
          </AccountIds>
        </Scope>
        <Time>
          <CustomDateRangeEnd>
            <Day>31</Day>
            <Month>01</Month>
            <Year>2019</Year>
          </CustomDateRangeEnd>
          <CustomDateRangeStart>
            <Day>01</Day>
            <Month>01</Month>
            <Year>2019</Year>
          </CustomDateRangeStart>
          <PredefinedTime xsi:nil="true"/>
          <ReportTimeZone>EasternTimeUSCanada</ReportTimeZone>
        </Time>
      </ReportRequest>
    </tns:SubmitGenerateReportRequest>
  </env:Body>
</env:Envelope>

The request is accepted and processed, but the data that is returned shows only 'Active' campaigns. I'm sure there is an issue with the way I'm filtering. Here is the Ruby code I'm using to generate the request.

report_request = {
      '@xsi:nil' => false,
      '@xsi:type' => 'CampaignPerformanceReportRequest',
      'ExcludeColumnHeaders' => true,
      'ExcludeReportFooter' => true,
      'ExcludeReportHeader' => true,
      'Format' => 'Csv',
      'Language' => 'English',
      'ReportName' => 'CampaignPerformanceReportRequest',
      'ReturnOnlyCompleteData' => false,
      'Aggregation' => 'Summary',
      'Columns' => {
         'CampaignPerformanceReportColumn' => [
           'CampaignName',
           'CampaignStatus',
           'Spend',
           'Impressions',
           'Clicks',
           'Conversions',
           'Revenue',
           'PhoneCalls'
         ]
      },
      'Filter' => { 'CampaignStatusReportFilter' => 'Paused' },
      'Scope' => {
        'AccountIds' => {
          '@xmlns:a1' => 'http://schemas.microsoft.com/2003/10/Serialization/Arrays',
          'a1:long' => account_id,
        }
      },
   etc...
}

I've tried matching the syntax in the documentation linked to above exactly, but it still returns only 'Active' campaigns, which leads me to believe that that is the default setting and the API just ignores my improper filtering.

If anyone could help me figure out what I'm doing wrong here it would be greatly appreciated.

1
the usual first question: Have you tried to model your request in SoapUI? If it works there as expected we can analyze your Ruby code.Steffen Roller
I'm not sure what SoapUI is. What are you asking me to test? I know exactly what the problem is, I'm just not sure how to read the syntax listed in the Bing Ads API documentation. If I knew what format they wanted the request in then I could do it by myself.Jordan Lagan
soapui.com. But it seems your question is mislabelled? It has nothing to do with Savon, XML or Ruby but everything with Bing?Steffen Roller
I didn't label my question as relating to Ruby, only xml, savon and bing-ads-api. I labelled it as such because I think someone who understands xml will be able to tell me how to understand the syntax in the documentation that I linked to. I've already spent a few hours on it, and am still researching as we speak, but I can't figure it out. I'm not being lazy or simply trying to get others to do my work for me, I've just reached the limit of my understanding and am actively trying to find the problems in my code. Your comment isn't very helpful as it doesn't point me in any useful direction.Jordan Lagan
No worries, that wasn't meant as a criticism. I've been there :-). It seems you need somebody with a good insight of the Bing API. Unfortunately that isn't me, sorry.Steffen Roller

1 Answers

1
votes

Please note that multiple sub filter types are available e.g., AccountStatus, AdDistribution, DeviceOS, DeviceType, and Status.

You can use the following syntax (I tested and confirmed it today) to only include report data where the device type is Tablet and campaign status is Paused. You can remove the device tablet filter, as I only added it to show how to add multiple filters.

<Filter>
    <AccountStatus i:nil="true"/>
    <AdDistribution i:nil="true"/>
    <DeviceOS i:nil="true"/>
    <DeviceType>Tablet</DeviceType>
    <Status>Paused</Status>
</Filter>

Sorry that I don't have a Ruby sample on hand, but here is a C# snippet that helps generate the above XML within the SOAP request:

Filter = new CampaignPerformanceReportFilter {
    DeviceType = DeviceTypeReportFilter.Tablet,
    Status = CampaignStatusReportFilter.Active
},

TIP: Each Bing Ads API service operation includes a syntax template e.g., SubmitGenerateReport. You'll just need to carve out the portions applicable to your request e.g., only one report request type at a time.

Please also feel free to reach our team via the Bing Ads API Development forum and contact support links.

I hope this helps!