الطلبات غير المتزامنة

أصبحت Search Ads 360 Reporting API الجديدة متاحة الآن توفر واجهة برمجة التطبيقات الجديدة مرونة محسّنة لإنشاء تقارير مخصّصة ودمج البيانات في تطبيقات إعداد التقارير والعمليات. مزيد من المعلومات عن نقل البيانات إلى التجربة الجديدة من "إعلانات شبكة البحث 360" واستخدامها API.

وبما أنّ إنشاء طلبات التقارير الكبيرة قد يستغرق بعض الوقت، لن تتمكّن من استخدام Search Ads 360 API. طريقة غير متزامنة لطلب التقارير وتنزيلها. مع هذا ترسل طلبًا أوليًا يحدد البيانات التي تريدها في التقرير، ثم إرسال طلبات استطلاع إضافية إلى أن تنتهي "إعلانات شبكة البحث 360" من إنشاء التقرير. استنادًا إلى حجم التقرير، تقسّم "إعلانات شبكة البحث 360" البيانات إلى ملفات متعدّدة. بمجرد إنشاء تقرير، يمكنك إرسال طلبات لتنزيل كل ملف تقرير. إذا كنت تطلب كميات أصغر من البيانات، يمكنك إرسال رسالة مزامنة طلبك.

لإجراء طلب غير متزامن

  1. الاتصال بـ "Reports.request()" لتحديد نوع البيانات التي تريد تضمينها في التقرير. راجِع أنواع التقارير للتعرّف على أنواع البيانات التي طلب الموافقة.

    تتحقّق "إعلانات شبكة البحث 360" من صحة الطلب وتعرض رقم تعريف تقرير، وهو معرّف فريد لهذا الطلب. طلبك.

  2. الاتصال بـ "Reports.get()" برقم تعريف التقرير.

    يوضِّح الردّ من "إعلانات شبكة البحث 360" ما يلي:

    • ما إذا كان التقرير جاهزًا للتنزيل
    • إذا كان التقرير جاهزًا، يمكنك استخدام عنوان URL واحد أو أكثر لتنزيله.
  3. الاتصال بـ "Reports.getFile()" لتنزيل ملفات التقارير المُشفَّرة، أو تنزيلها مباشرةً من عناوين URL.

    تعرض "إعلانات شبكة البحث 360" التقرير في ملف بترميز UTF-8.

كم مرة يجب أن أقوم باستطلاع التقارير لمعرفة ما إذا كانت جاهزة؟

يعتمد مقدار الوقت الذي تحتاجه "إعلانات شبكة البحث 360" لإنشاء تقرير بشكل أساسي على مقدار البيانات في التقرير. حاوِل إجراء استطلاع لمعرفة حالة التقرير مرة واحدة في الدقيقة، ثم تعديل التكرار إذا استغرق متوسط طلب التقرير وقتًا أكثر أو أقل بكثير لإنهاء العملية.

تقسيم التقارير غير المتزامنة إلى ملفات متعددة

استجابةً لطلب غير متزامن، تقسّم "إعلانات شبكة البحث 360" تلقائيًا التقارير الكبيرة إلى ملفات متعددة. استخدام Reports.request.maxRowsPerFile لتحديد الحد الأقصى لحجم الملف. نضمن لك أن يحتوي كل ملف تقرير ناتج على maxRowsPerFile صف من التقرير كحد أقصى (لا يتم احتساب العناوين). عنوان URL مختلف لكل ملف ويتم عرضه استجابةً لـ Reports.get(). للحصول على معلومات حول تنزيل ملفات التقارير، راجع تنزيل التقرير.

بالنسبة إلى تقارير ملف CSV، يتم تكرار العنوان في كل ملف.

ملاحظة: لا تتيح واجهة برمجة التطبيقات التقسيم للطلبات غير المتزامنة. وهذا يعني أنه لا يمكنك تحديد الصفوف التي تريد وضع ملفات التقارير فيها. تُعد الطريقة التي يتم بها تقسيم الصفوف بين الملفات وقد يتغير إذا تم عرض التقرير نفسه مجددًا.

مثال غير متزامن

وفي ما يلي نماذج للطلبات والردود باستخدام الأسلوب غير المتزامن.

JSON

POST  https://www.googleapis.com/doubleclicksearch/v2/reports
Authorization: Bearer your OAuth 2.0 access token
Content-type: application/json

{
  "reportScope": {
    "agencyId": "12300000000000456", // Replace with your ID
    "advertiserId": "21700000000011523", // Replace with your ID
  },
  "reportType": "keyword",              // This report covers all keywords in the
                                        // advertiser specified in reportScope.
  "columns": [
    { "columnName": "campaignId" },     // Here are some attribute columns available for keyword
    { "columnName": "keywordText" },    // reports.
    { "columnName": "keywordLandingPage" },

    { "columnName": "date" },           // The date column segments the report by individual days.

    { "columnName": "dfaRevenue" },     // Here are some metric columns available for keyword
    {                                   // reports
      "columnName": "visits",
      "startDate": "2013-01-01",        // Each metric column can optionally specify its own start
      "endDate": "2013-01-31",          // and end date; by default the report timeRange is used.
      "headerText": "visits last month" // Every column can optionally specify a headerText, which
                                        // changes the name of the column in the report.
    }
  ],
  "timeRange" : {
    "startDate" : "2012-05-01",         // Dates are inclusive and specified in YYYY-MM-DD format.
    "endDate" : "2012-05-02"

    // Alternatively, try the "changedMetricsSinceTimestamp" or "changedAttributesSinceTimestamp"
    // options. See Incremental reports.

  },
  "filters": [
    {
      "column" : { "columnName": "keywordLandingPage" },
      "operator" : "startsWith",
      "values" : [                      // With this filter, only keywords with landing pages
        "http://www.foo.com",           // rooted at www.foo.com or www.bar.com are returned.
        "http://www.bar.com"            // See Filtered reports.
      ]
    }
  ],
  "downloadFormat": "csv",
  "maxRowsPerFile": 6000000,            // Required. See Splitting reports into multiple files.
  "statisticsCurrency": "agency",       // Required. See Currency for statistics.
  "verifySingleTimeZone": false,        // Optional. Defaults to false. See Time zone.
  "includeRemovedEntities": false           // Optional. Defaults to false.
}
          

Java

/**
 * Creates a campaign report request, submits the report, and returns the report ID.
 */
private static String createReport(Doubleclicksearch service) throws IOException {
  try {
     return service.reports().request(createSampleRequest()).execute().getId();
  } catch (GoogleJsonResponseException e) {
    System.err.println("Report request was rejected.");
    for (ErrorInfo error : e.getDetails().getErrors()) {
      System.err.println(error.getMessage());
    }
    System.exit(e.getStatusCode());
    return null; // Unreachable code.
  }
}

/**
 * Creates a simple static request that lists the ID and name of all
 * campaigns under agency 12300000000000456 and advertiser 21700000000011523.
 * Substitute your own agency ID and advertiser IDs for the IDs in this sample.
 */
private static ReportRequest createSampleRequest() {
  return new ReportRequest()
      .setReportScope(new ReportScope()
          .setAgencyId(12300000000000456L) // Replace with your ID
          .setAdvertiserId(21700000000011523L)) // Replace with your ID
      .setReportType("campaign")
      .setColumns(Arrays.asList(
          new ReportApiColumnSpec[] {
            new ReportApiColumnSpec().setColumnName("campaignId"),
            new ReportApiColumnSpec().setColumnName("campaign")
          }))
      .setTimeRange(new TimeRange()
          .setStartDate("2012-05-01")
          .setEndDate("2012-05-01"))
      .setDownloadFormat("csv")
      .setStatisticsCurrency("usd")
      .setMaxRowsPerFile(5000000);
}

NET.

تنشئ هذه الدالة تقريرًا يسرد الحملات ضمن أحد المعلِنين ويعيّن الحملات الرمز المميّز الذي تم إرجاعه إلى reportId.
using api = Google.Apis.Doubleclicksearch.v2;

/// <summary>
/// Creates a report with a sample request and returns the report ID.
/// </summary>
/// <param name="service">Search Ads 360 API service.</param>
private static string CreateReport(api.DoubleclicksearchService service)
{

    var req = service.Reports.Request(CreateSampleRequest());
    var report = req.Execute();
    Console.WriteLine("Created report: ID={0}", report.Id);
    return report.Id;
}

/// <summary>
/// Returns a simple static request that lists the ID and name of all
/// campaigns under an advertiser.
/// Substitute your own agency ID and advertiser IDs for the IDs in this sample.
/// </summary>
private static api.Data.ReportRequest CreateSampleRequest()
{
    return new api.Data.ReportRequest
    {
        ReportScope = new api.Data.ReportRequest.ReportScopeData
        {
            AgencyId = 12300000000000456, // Replace with your ID
            AdvertiserId = 21700000000011523 // Replace with your ID
        },
        ReportType = ReportType.CAMPAIGN,
        Columns = new List<api.Data.ReportApiColumnSpec>
        {
            new api.Data.ReportApiColumnSpec
            {
                ColumnName = "campaignId",
            },
            new api.Data.ReportApiColumnSpec
            {
                ColumnName = "campaign",
            },
        },
        TimeRange = new api.Data.ReportRequest.TimeRangeData
        {
            StartDate = "2015-01-01",
            EndDate = "2015-01-07",
        },
        DownloadFormat = "csv",
        StatisticsCurrency = "usd",
        MaxRowsPerFile = 5000000,
    };
}

Python

def request_report(service):
  """Request sample report and print the report ID that DS returns. See Set Up Your Application.

  Args:
    service: An authorized Doubleclicksearch service.
  Returns:
    The report id.
  """
  request = service.reports().request(
      body=
      {
        "reportScope": {
            "agencyId": "12300000000000456", // Replace with your ID
            "advertiserId": "21700000000011523", // Replace with your ID
            "engineAccountId": "700000000073991" // Replace with your ID
            },
        "reportType": "keyword",
        "columns": [
            { "columnName": "campaignId" },
            { "columnName": "keywordText" },
            { "columnName": "keywordLandingPage" },

            { "columnName": "date" },

            { "columnName": "dfaRevenue" },
            {
              "columnName": "visits",
              "startDate": "2013-01-01",
              "endDate": "2013-01-31",
              "headerText": "visits last month"
            }
          ],
          "timeRange" : {
            "startDate" : "2012-05-01",
            "endDate" : "2012-05-02"
          },
          "filters": [
            {
              "column" : { "columnName": "keywordLandingPage" },
              "operator" : "startsWith",
              "values" : [
                "http://www.foo.com",
                "http://www.bar.com"
              ]
            }
          ],
          "downloadFormat": "csv",
          "maxRowsPerFile": 6000000,
          "statisticsCurrency": "agency",
          "verifySingleTimeZone": "false",
          "includeRemovedEntities": "false"
        }
  )

  json_data = request.execute()
  return json_data['id']

في حال نجحت عملية التحقّق من الصحة

إذا اجتاز التقرير عملية التحقّق، تعرِض "إعلانات شبكة البحث 360" رقم تعريف للتقرير. "إعلانات شبكة البحث 360" أيضًا تعرض البيانات الوصفية فيما يتعلق برمز العملة والمنطقة الزمنية.

{
  "kind": "adsdartsearch#report",
  "id": "MTMyNDM1NDYK",                      // This is the report id.
  "isReportReady": false,                    // The report is not finished generating.

  "request": {                               // The request that created this report.
    ...
  },

  "statisticsCurrencyCode": "CAD",           // The currency used for statistics. E.g., if
                                             // advertiser currency was requested, this would be
                                             // currency code of the advertiser in scope.

  "statisticsTimeZone": "America/New_York"   // If all statistics in the report were sourced from
                                             // a single time zone, this would be it. If
                                             // verifySingleTimeZone was set to true in the request,
                                             // then this field will always be populated (or the
                                             // request will fail).
}
      

في حال تعذُّر عملية التحقّق من الصحة

إذا لم يجتَز التقرير عملية التحقّق، تعرض "إعلانات شبكة البحث 360" استجابة HTTP 400. مع كائن الخطأ. على سبيل المثال، لم يحدد مثال الطلب أعلاه عملية الوكالة:

{
 "error": {
   "code": 400,
   "message": "statisticsCurrency: the agency in scope does not have a valid currency. Please make sure the agency is properly initialized in Search Ads 360."
 }
}

استطلاع لمعرفة حالة التقرير

يمكنك الاتصال بـ Report.Get() باستخدام رقم تعريف التقرير.

JSON

GET https://www.googleapis.com/doubleclicksearch/v2/reports/MTMyNDM1NDYK
          

Java

/**
 * Polls the reporting API with the reportId until the report is ready.
 * Returns the report.
 */
private static Report pollUntilReportIsFinished(Doubleclicksearch service, String reportId)
    throws IOException, InterruptedException {
  long delay = 1;
  while (true) {
    Report report = null;
    try {
      report = service.reports().get(reportId).execute();
    } catch (GoogleJsonResponseException e) {
      System.err.println("Report generation has failed.");
      System.exit(e.getStatusCode());
    }
    if (report.getIsReportReady()) {
      return report;
    }
    System.out.format("Report %s is not ready - waiting %s seconds.%n", reportId, delay);
    Thread.sleep(TimeUnit.SECONDS.toMillis(delay));
    delay = delay + delay; // Double the delay for the next iteration.
  }
}

NET.

using api = Google.Apis.Doubleclicksearch.v2;

/// <summary>
/// Polls until the report with the given ID completes.
/// </summary>
/// <param name="service">Search Ads 360 API service.</param>
/// <param name="reportId">Report ID to poll.</param>
/// <exception cref="ApplicationException">
/// Thrown when the report completes, but has failed.
/// </exception>
private static api.Data.Report PollUntilReportIsFinished(
    api.DoubleclicksearchService service,
    string reportId)
{
    TimeSpan delay = TimeSpan.FromSeconds(1);
    while (true)
    {
        api.Data.Report report;
        try
        {
            report = service.Reports.Get(reportId).Execute();
        }
        catch (Google.GoogleApiException ex)
        {
            throw new ApplicationException("Report generation failed", ex);
        }
        if (report.IsReportReady.GetValueOrDefault(false))
        {
            return report;
        }
        Console.WriteLine("Report is not ready - waiting {0}", delay);
        Thread.Sleep(delay);
        delay = delay.Add(delay); // Double the delay for the next iteration.
    }
}

Python

import pprint
import simplejson
from googleapiclient.errors import HttpError

def poll_report(service, report_id):
  """Poll the API with the reportId until the report is ready, up to ten times.

  Args:
    service: An authorized Doubleclicksearch service.
    report_id: The ID DS has assigned to a report.
  """
  for _ in xrange(10):
    try:
      request = service.reports().get(reportId=report_id)
      json_data = request.execute()
      if json_data['isReportReady']:
        pprint.pprint('The report is ready.')

        # For large reports, DS automatically fragments the report into multiple
        # files. The 'files' property in the JSON object that DS returns contains
        # the list of URLs for file fragment. To download a report, DS needs to
        # know the report ID and the index of a file fragment.
        for i in range(len(json_data['files'])):
          pprint.pprint('Downloading fragment ' + str(i) + ' for report ' + report_id)
          download_files(service, report_id, str(i)) # See Download the report.
        return

      else:
        pprint.pprint('Report is not ready. I will try again.')
        time.sleep(10)
    except HttpError as e:
      error = simplejson.loads(e.content)['error']['errors'][0]

      # See Response Codes
      pprint.pprint('HTTP code %d, reason %s' % (e.resp.status, error['reason']))
      break

إذا كان التقرير غير جاهز

وإذا لم يكن التقرير جاهزًا، تعرض "إعلانات شبكة البحث 360" استجابة HTTP 202 وisReportReady. الحقل false.

{
  "kind": "doubleclicksearch#report",
  "id": "MTMyNDM1NDYK",
  "isReportReady": false,
  "request": {
    ...
  },
  ...
}
      

عندما يكون التقرير جاهزًا

عند اكتمال التقرير وكونه جاهزًا للتنزيل، سيتم تشغيل isReportReady true. يتضمّن الردّ أيضًا حقلاً إضافيًا، files، يحتوي على عناوين URL لتنزيل ملفات التقارير.

{
  "kind": "doubleclicksearch#report",
  "id": "MTMyNDM1NDYK",
  "isReportReady": true,
  "request": {
    ...
  },
  ...
  "rowCount": 1329,        // Total rows in the report, not counting headers.
  "files": [
    {
      "url": "https://www.googleapis.com/doubleclicksearch/v2/reports/MTMyNDM1NDYK/files/0"
      "byteCount": "10242323"
    },
    {
      "url": "https://www.googleapis.com/doubleclicksearch/v2/reports/MTMyNDM1NDYK/files/1"
      "byteCount": "10242323"
    }
  ],
}
      

في حال تعذّر إنشاء التقرير

إذا تعذّر على "إعلانات شبكة البحث 360" إنشاء تقرير، سيتم عرض أحد روابط HTTP العديدة. ورموز الخطأ، إلى جانب وصف.

{
  "error" : {
   "code" : 410,            // Or other error codes.
   "message" : "Processing was halted on the backend and will not continue."
  }
}
      

راجِع رموز الاستجابة للحصول على قائمة الأخطاء التي يمكن أن تعرضها "إعلانات شبكة البحث 360".

تنزيل التقرير

يمكنك تنزيل التقرير من خلال النقر مباشرةً على عنوان URL لكل ملف تقرير، أو من خلال طلب الرقم Reports.getFile() باستخدام رقم تعريف التقرير ورقم الملف (تمت فهرسة 0). تعرض "إعلانات شبكة البحث 360" التقرير في ملف بترميز UTF-8.

في ما يلي أمثلة على طلبات "Reports.getFile()":

JSON

GET https://www.googleapis.com/doubleclicksearch/v2/reports/MTMyNDM1NDYK/files/0?alt=media
أو
GET https://www.googleapis.com/doubleclicksearch/v2/reports/MTMyNDM1NDYK/files/1?alt=media
          

Java

/**
 * Downloads the shards of a completed report to the given local directory.
 * Files are named CampaignReport0.csv, CampaignReport1.csv, and so on.
 */
private static void downloadFiles(
    Doubleclicksearch service,
    Report report,
    String localPath) throws IOException {
  for (int i = 0; i < report.getFiles().size(); i++) {
    FileOutputStream outputStream =
        new FileOutputStream(new File(localPath, "CampaignReport" + i));
    service.reports().getFile(report.getId(), i).executeAndDownloadTo(outputStream);
    outputStream.close();
  }
}

NET.

using api = Google.Apis.Doubleclicksearch.v2;

/// <summary>
/// Downloads the shards of a completed report to the given local directory.
/// Files are named CampaignReport0.csv, CampaignReport1.csv, and so on.
/// </summary>
/// <param name="service">Search Ads 360 API service.</param>
/// <param name="report">Report ID to download.</param>
/// <param name="localPath">Path of the directory to place downloaded files.</param>
private static void DownloadFiles(
    api.DoubleclicksearchService service,
    api.Data.Report report,
    string localPath)
{
    Directory.CreateDirectory(localPath);
    for (int i = 0; i < report.Files.Count; ++i)
    {
        string fileName = Path.Combine(
            localPath,
            string.Format("CampaignReport{0}.csv", i));
        Console.WriteLine("Downloading shard {0} to {1}", i, fileName);
        using (Stream dst = File.OpenWrite(fileName))
        {
            service.Reports.GetFile(report.Id, i).Download(dst);
        }
    }
}

Python

def download_files(service, report_id, report_fragment):
  """Generate and print sample report.

  Args:
    service: An authorized Doubleclicksearch service.
    report_id: The ID DS has assigned to a report.
    report_fragment: The 0-based index of the file fragment from the files array.
  """
  f = file('report-' + report_fragment + '.csv', 'w')
  request = service.reports().getFile_media(reportId=report_id, reportFragment=report_fragment)
  f.write(request.execute().decode('utf-8'))
  f.close()

مثال للتقرير

في ما يلي مثال على تقرير CSV. يتضمّن كل جزء في ملف التقرير عنوانًا خاصًا به الصف. للحصول على تفاصيل حول هذا التنسيق، راجِع RFC. 4180.

keywordText,campaignId,landingPageUrl,day,revenue,visits last month,my revenue
google,71700000002104742,http://www.google.com,2012-05-01,10.2,5,20
google,71700000002104742,http://www.google.com,2012-05-02,11,10,60.23
      

تنزيل ملف تحديد أرقام التعريف

يمكنك تنزيل الملف الذي يحتوي على عمليات ربط أرقام التعريف بين التجربتَين السابقة والأخرى من "إعلانات شبكة البحث 360". التجربة الجديدة من "إعلانات شبكة البحث 360". بالنسبة إلى المعلِن المعنيّ، يتضمّن الملف جميع الكيانات الفرعية (مثل حسابات محرّكات البحث والحملات والمجموعات الإعلانية وغيرها) المتوفّرة في كلّ من التجربة السابقة من "إعلانات شبكة البحث 360" والتجربة الجديدة من "إعلانات شبكة البحث 360"

Python

def download_mapping_file(service, file_name, agency_id, advertiser_id):
    """Generate and save mapping file to a csv.

    Args:
      service: An authorized Doubleclicksearch service.
      file_name: Filename to write the ID mapping file.
      agency_id: DS ID of the agency.
      advertiser_id: DS ID of the advertiser.
    """
    request = service.reports().getIdMappingFile_media(agencyId=agency_id,
        advertiserId=advertiser_id)

    response = request.execute()
    response = response.decode('utf-8')

    f = open(file_name + '.csv', 'w')
    f.write(response)
    f.close()