เปลี่ยนแปลงแนวทางปฏิบัติแนะนำ

ชื่อทรัพยากรชั่วคราว

GoogleAdsService.Mutate รองรับชื่อทรัพยากรชั่วคราวที่ใช้อ้างอิงภายหลังในคำขอเดียวกันได้ ซึ่งช่วยให้คุณสร้างแคมเปญ และกลุ่มโฆษณา โฆษณา คีย์เวิร์ด ฯลฯ ที่เกี่ยวข้องไว้ในคำขอเดียวได้ เป็นต้น

ซึ่งทำได้โดยการระบุ resource_name ของทรัพยากรใหม่เพื่อใช้รหัสเชิงลบ เช่น หากสร้างแคมเปญและระบุชื่อทรัพยากรเป็น customers/<YOUR_CUSTOMER_ID>/campaigns/-1 ขณะสร้างกลุ่มโฆษณาเพื่อดำเนินการในภายหลัง คุณจะอ้างอิงได้โดยใช้ชื่อทรัพยากรดังกล่าว และระบบจะแทนที่ -1 ที่คุณระบุด้วยรหัสจริงของแคมเปญที่สร้างขึ้นโดยอัตโนมัติ

โปรดคำนึงถึงสิ่งต่อไปนี้เมื่อใช้ชื่อทรัพยากรชั่วคราว

  • ชื่อทรัพยากรชั่วคราวจะใช้ได้หลังจากที่ได้รับการระบุไว้ในทรัพยากรแล้วเท่านั้น ในตัวอย่างด้านล่าง การทำงานของกลุ่มโฆษณาจะต้องปรากฏหลังจากการทำงานของแคมเปญในรายการการดำเนินการ
  • ระบบจะไม่จำชื่อทรัพยากรชั่วคราวในคำขอเกี่ยวกับงานหรือคำขอเปลี่ยนแปลง หากต้องการอ้างอิงทรัพยากรที่สร้างในงานก่อนหน้าหรือคำขอเปลี่ยนแปลง ให้ใช้ชื่อทรัพยากรจริงของทรัพยากรนั้น
  • สำหรับคำขอเปลี่ยนแปลงงานรายการเดียวหรือคำขอเปลี่ยนแปลง ชื่อทรัพยากรชั่วคราวแต่ละชื่อต้องใช้จำนวนลบที่ไม่ซ้ำกันแม้ว่าจะมาจากทรัพยากรประเภทต่างๆ ก็ตาม หากมีการใช้รหัสชั่วคราวซ้ำในงานเดียวหรือคำขอเปลี่ยนแปลงรายการเดียว ระบบจะแสดงผลข้อผิดพลาด

ตัวอย่าง

เพื่อให้ตัวอย่างที่ชัดเจนยิ่งขึ้นกับสถานการณ์ที่กล่าวไว้ข้างต้น สมมติว่าคุณต้องการเพิ่มแคมเปญ กลุ่มโฆษณา และโฆษณาในคำขอ API คำขอเดียว คุณควรสร้างโครงสร้างสำหรับคำขอที่มีลักษณะคล้ายกันดังต่อไปนี้

mutate_operations: [
  {
    campaign_operation: {
      create: {
        resource_name: "customers/<YOUR_CUSTOMER_ID>/campaigns/-1",
        ...
      }
    }
  },
  {
    ad_group_operation: {
      create: {
        resource_name: "customers/<YOUR_CUSTOMER_ID>/adGroups/-2",
        campaign: "customers/<YOUR_CUSTOMER_ID>/campaigns/-1"
        ...
      }
    }
  },
  {
    ad_group_ad_operation: {
      create: {
        ad_group: "customers/<YOUR_CUSTOMER_ID>/adGroups/-2"
        ...
      }
    }
  },
]

โปรดสังเกตว่าจะมีการใช้รหัสชั่วคราวใหม่สำหรับกลุ่มโฆษณา เนื่องจากเราไม่สามารถนำ -1 ที่เราใช้สำหรับแคมเปญมาใช้ซ้ำ และเรายังอ้างอิงกลุ่มโฆษณานี้เมื่อสร้างโฆษณาของกลุ่มโฆษณาด้วย ตัวกลุ่มโฆษณาอ้างอิงชื่อทรัพยากรที่เราสร้างให้กับแคมเปญในการดำเนินการก่อนหน้าในคำขอ ส่วน resource_name ใน ad_group_ad_operation ไม่จำเป็นเนื่องจากไม่มีการดำเนินการอื่นที่จะอ้างอิง

การดำเนินการประเภทเดียวกันของกลุ่ม

เมื่อใช้ GoogleAdsService.Mutate คุณต้องจัดกลุ่มการดำเนินการเข้าด้วยกันตามทรัพยากรในอาร์เรย์การดำเนินการที่ซ้ำกัน โดยพื้นฐานแล้วเมธอดเปลี่ยนรูปแบบนี้ทำหน้าที่เป็นวิธีเรียกเมธอดการแปลงของทรัพยากรแต่ละรายการตามลำดับโดยอัตโนมัติ ในการดำเนินการนี้ ระบบจะอ่านการดำเนินการจนกว่าจะพบ 1 รายการสำหรับทรัพยากรประเภทต่างๆ จากนั้นจึงรวมการดำเนินการประเภทเดียวกันทั้งหมดไว้ด้วยกันในคำขอเดียว

เช่น หากคุณมีการดำเนินการแคมเปญ 5 รายการ ตามด้วยการดำเนินการกลุ่มโฆษณา 10 รายการในช่อง operations ที่ซ้ำในการเรียก Mutate ระบบจะเรียกใช้ทั้งหมด 2 ครั้งในแบ็กเอนด์ โดยครั้งที่ 1 ไปยัง CampaignService สำหรับการดำเนินการ 5 ครั้ง และครั้งที่ 1 ถัดจาก AdGroupService สำหรับการดำเนินการ 10 รายการ อย่างไรก็ตาม หากคุณต้องการจัดกลุ่มคุณลักษณะที่แตกต่างกัน ประสิทธิภาพอาจแย่ลงมาก หากคุณสร้างแคมเปญ 2 รายการและกลุ่มโฆษณา 2 กลุ่ม แต่รวมเข้าด้วยกันเพื่อให้การดำเนินการเรียงลำดับเป็น [แคมเปญ กลุ่มโฆษณา แคมเปญ กลุ่มโฆษณา] จะทำให้มีการเรียกทั้งหมด 4 ครั้งในแบ็กเอนด์ ซึ่งจะส่งผลให้ประสิทธิภาพของ API ช้าลง และในกรณีร้ายแรงอาจนำไปสู่การหมดเวลาได้

เรียกข้อมูลแอตทริบิวต์ที่เปลี่ยนแปลงได้จากคำตอบ

หากคุณตั้งค่า response_content_type ของคำขอเปลี่ยนแปลงเป็น MUTABLE_RESOURCE การตอบกลับจะมีค่าของช่องที่เปลี่ยนแปลงได้ทั้งหมดสำหรับทุกออบเจ็กต์ที่สร้างหรืออัปเดตโดยคำขอ ใช้ฟีเจอร์นี้เพื่อหลีกเลี่ยงคำขอ search หรือ searchStream เพิ่มเติมหลังคำขอเปลี่ยนแปลงแต่ละรายการ

หากไม่ตั้งค่า response_content_type ค่าเริ่มต้นของ Google Ads API จะเป็น RESOURCE_NAME_ONLY และการตอบกลับจะมีเฉพาะชื่อทรัพยากรของทรัพยากรที่สร้างหรืออัปเดตแต่ละรายการเท่านั้น

ต่อไปนี้คือตัวอย่างการดึงข้อมูลทรัพยากรที่เปลี่ยนแปลงได้จากการเรียก API

Java

private String createExperimentArms(
    GoogleAdsClient googleAdsClient, long customerId, long campaignId, String experiment) {
  List<ExperimentArmOperation> operations = new ArrayList<>();
  operations.add(
      ExperimentArmOperation.newBuilder()
          .setCreate(
              // The "control" arm references an already-existing campaign.
              ExperimentArm.newBuilder()
                  .setControl(true)
                  .addCampaigns(ResourceNames.campaign(customerId, campaignId))
                  .setExperiment(experiment)
                  .setName("control arm")
                  .setTrafficSplit(40)
                  .build())
          .build());
  operations.add(
      ExperimentArmOperation.newBuilder()
          .setCreate(
              // The non-"control" arm, also called a "treatment" arm, will automatically
              // generate draft campaigns that you can modify before starting the experiment.
              ExperimentArm.newBuilder()
                  .setControl(false)
                  .setExperiment(experiment)
                  .setName("experiment arm")
                  .setTrafficSplit(60)
                  .build())
          .build());

  try (ExperimentArmServiceClient experimentArmServiceClient =
      googleAdsClient.getLatestVersion().createExperimentArmServiceClient()) {
    // Constructs the mutate request.
    MutateExperimentArmsRequest mutateRequest = MutateExperimentArmsRequest.newBuilder()
        .setCustomerId(Long.toString(customerId))
        .addAllOperations(operations)
        // We want to fetch the draft campaign IDs from the treatment arm, so the easiest way to do
        // that is to have the response return the newly created entities.
        .setResponseContentType(ResponseContentType.MUTABLE_RESOURCE)
        .build();

    // Sends the mutate request.
    MutateExperimentArmsResponse response =
        experimentArmServiceClient.mutateExperimentArms(mutateRequest);

    // Results always return in the order that you specify them in the request. Since we created
    // the treatment arm last, it will be the last result.  If you don't remember which arm is the
    // treatment arm, you can always filter the query in the next section with
    // `experiment_arm.control = false`.
    MutateExperimentArmResult controlArmResult = response.getResults(0);
    MutateExperimentArmResult treatmentArmResult = response.getResults(
        response.getResultsCount() - 1);

    System.out.printf("Created control arm with resource name '%s'%n",
        controlArmResult.getResourceName());
    System.out.printf("Created treatment arm with resource name '%s'%n",
        treatmentArmResult.getResourceName());

    return treatmentArmResult.getExperimentArm().getInDesignCampaigns(0);
  }
}
      

C#

/// <summary>
/// Creates the experiment arms.
/// </summary>
/// <param name="client">The Google Ads client.</param>
/// <param name="customerId">The customer ID for which the call is made.</param>
/// <param name="baseCampaignId">ID of the campaign for which the control arm is
/// created.</param>
/// <param name="experimentResourceName">Resource name of the experiment.</param>
/// <returns>The control and treatment arms.</returns>
private static (MutateExperimentArmResult, MutateExperimentArmResult)
    CreateExperimentArms(GoogleAdsClient client, long customerId, long baseCampaignId,
        string experimentResourceName)
{
    // Get the ExperimentArmService.
    ExperimentArmServiceClient experimentService = client.GetService(
        Services.V16.ExperimentArmService);

    // Create the control arm. The control arm references an already-existing campaign.
    ExperimentArmOperation controlArmOperation = new ExperimentArmOperation()
    {
        Create = new ExperimentArm()
        {
            Control = true,
            Campaigns = {
                ResourceNames.Campaign(customerId, baseCampaignId)
            },
            Experiment = experimentResourceName,
            Name = "Control Arm",
            TrafficSplit = 40
        }
    };

    // Create the non-control arm. The non-"control" arm, also called a "treatment" arm,
    // will automatically generate draft campaigns that you can modify before starting the
    // experiment.
    ExperimentArmOperation treatmentArmOperation = new ExperimentArmOperation()
    {
        Create = new ExperimentArm()
        {
            Control = false,
            Experiment = experimentResourceName,
            Name = "Experiment Arm",
            TrafficSplit = 60
        }
    };

    // We want to fetch the draft campaign IDs from the treatment arm, so the
    // easiest way to do that is to have the response return the newly created
    // entities.
    MutateExperimentArmsRequest request = new MutateExperimentArmsRequest
    {
        CustomerId = customerId.ToString(),
        Operations = { controlArmOperation, treatmentArmOperation },
        ResponseContentType = ResponseContentType.MutableResource
    };


    MutateExperimentArmsResponse response = experimentService.MutateExperimentArms(
        request
    );

    // Results always return in the order that you specify them in the request.
    // Since we created the treatment arm last, it will be the last result.
    MutateExperimentArmResult controlArm = response.Results.First();
    MutateExperimentArmResult treatmentArm = response.Results.Last();

    Console.WriteLine($"Created control arm with resource name " +
        $"'{controlArm.ResourceName}.");
    Console.WriteLine($"Created treatment arm with resource name" +
      $" '{treatmentArm.ResourceName}'.");
    return (controlArm, treatmentArm);
}

      

PHP

private static function createExperimentArms(
    GoogleAdsClient $googleAdsClient,
    int $customerId,
    int $campaignId,
    string $experimentResourceName
): string {
    $operations = [];
    $experimentArm1 = new ExperimentArm([
        // The "control" arm references an already-existing campaign.
        'control' => true,
        'campaigns' => [ResourceNames::forCampaign($customerId, $campaignId)],
        'experiment' => $experimentResourceName,
        'name' => 'control arm',
        'traffic_split' => 40
    ]);
    $operations[] = new ExperimentArmOperation(['create' => $experimentArm1]);
    $experimentArm2 = new ExperimentArm([
        // The non-"control" arm, also called a "treatment" arm, will automatically
        // generate draft campaigns that you can modify before starting the
        // experiment.
        'control' => false,
        'experiment' => $experimentResourceName,
        'name' => 'experiment arm',
        'traffic_split' => 60
    ]);
    $operations[] = new ExperimentArmOperation(['create' => $experimentArm2]);

    // Issues a request to create the experiment arms.
    $experimentArmServiceClient = $googleAdsClient->getExperimentArmServiceClient();
    $response = $experimentArmServiceClient->mutateExperimentArms(
        MutateExperimentArmsRequest::build($customerId, $operations)
            // We want to fetch the draft campaign IDs from the treatment arm, so the easiest
            // way to do that is to have the response return the newly created entities.
            ->setResponseContentType(ResponseContentType::MUTABLE_RESOURCE)
    );
    // Results always return in the order that you specify them in the request.
    // Since we created the treatment arm last, it will be the last result.
    $controlArmResourceName = $response->getResults()[0]->getResourceName();
    $treatmentArm = $response->getResults()[count($operations) - 1];
    print "Created control arm with resource name '$controlArmResourceName'" . PHP_EOL;
    print "Created treatment arm with resource name '{$treatmentArm->getResourceName()}'"
        . PHP_EOL;

    return $treatmentArm->getExperimentArm()->getInDesignCampaigns()[0];
}
      

Python

def create_experiment_arms(client, customer_id, base_campaign_id, experiment):
    """Creates a control and treatment experiment arms.

    Args:
        client: an initialized GoogleAdsClient instance.
        customer_id: a client customer ID.
        base_campaign_id: the campaign ID to associate with the control arm of
          the experiment.
        experiment: the resource name for an experiment.

    Returns:
        the resource name for the new treatment experiment arm.
    """
    operations = []

    campaign_service = client.get_service("CampaignService")

    # The "control" arm references an already-existing campaign.
    operation_1 = client.get_type("ExperimentArmOperation")
    exa_1 = operation_1.create
    exa_1.control = True
    exa_1.campaigns.append(
        campaign_service.campaign_path(customer_id, base_campaign_id)
    )
    exa_1.experiment = experiment
    exa_1.name = "control arm"
    exa_1.traffic_split = 40
    operations.append(operation_1)

    # The non-"control" arm, also called a "treatment" arm, will automatically
    # generate draft campaigns that you can modify before starting the
    # experiment.
    operation_2 = client.get_type("ExperimentArmOperation")
    exa_2 = operation_2.create
    exa_2.control = False
    exa_2.experiment = experiment
    exa_2.name = "experiment arm"
    exa_2.traffic_split = 60
    operations.append(operation_2)

    experiment_arm_service = client.get_service("ExperimentArmService")
    request = client.get_type("MutateExperimentArmsRequest")
    request.customer_id = customer_id
    request.operations = operations
    # We want to fetch the draft campaign IDs from the treatment arm, so the
    # easiest way to do that is to have the response return the newly created
    # entities.
    request.response_content_type = (
        client.enums.ResponseContentTypeEnum.MUTABLE_RESOURCE
    )
    response = experiment_arm_service.mutate_experiment_arms(request=request)

    # Results always return in the order that you specify them in the request.
    # Since we created the treatment arm second, it will be the second result.
    control_arm_result = response.results[0]
    treatment_arm_result = response.results[1]

    print(
        f"Created control arm with resource name {control_arm_result.resource_name}"
    )
    print(
        f"Created treatment arm with resource name {treatment_arm_result.resource_name}"
    )

    return treatment_arm_result.experiment_arm.in_design_campaigns[0]
      

Ruby

def create_experiment_arms(client, customer_id, base_campaign_id, experiment)
  operations = []
  operations << client.operation.create_resource.experiment_arm do |ea|
    # The "control" arm references an already-existing campaign.
    ea.control = true
    ea.campaigns << client.path.campaign(customer_id, base_campaign_id)
    ea.experiment = experiment
    ea.name = 'control arm'
    ea.traffic_split = 40
  end
  operations << client.operation.create_resource.experiment_arm do |ea|
    # The non-"control" arm, also called a "treatment" arm, will automatically
    # generate draft campaigns that you can modify before starting the
    # experiment.
    ea.control = false
    ea.experiment = experiment
    ea.name = 'experiment arm'
    ea.traffic_split = 60
  end

  response = client.service.experiment_arm.mutate_experiment_arms(
    customer_id: customer_id,
    operations: operations,
    # We want to fetch the draft campaign IDs from the treatment arm, so the
    # easiest way to do that is to have the response return the newly created
    # entities.
    response_content_type: :MUTABLE_RESOURCE,
  )

  # Results always return in the order that you specify them in the request.
  # Since we created the treatment arm last, it will be the last result.
  control_arm_result = response.results.first
  treatment_arm_result = response.results.last

  puts "Created control arm with resource name #{control_arm_result.resource_name}."
  puts "Created treatment arm with resource name #{treatment_arm_result.resource_name}."

  treatment_arm_result.experiment_arm.in_design_campaigns.first
end
      

Perl

sub create_experiment_arms {
  my ($api_client, $customer_id, $base_campaign_id, $experiment) = @_;

  my $operations = [];
  push @$operations,
    Google::Ads::GoogleAds::V16::Services::ExperimentArmService::ExperimentArmOperation
    ->new({
      create => Google::Ads::GoogleAds::V16::Resources::ExperimentArm->new({
          # The "control" arm references an already-existing campaign.
          control   => "true",
          campaigns => [
            Google::Ads::GoogleAds::V16::Utils::ResourceNames::campaign(
              $customer_id, $base_campaign_id
            )
          ],
          experiment   => $experiment,
          name         => "control arm",
          trafficSplit => 40
        })});

  push @$operations,
    Google::Ads::GoogleAds::V16::Services::ExperimentArmService::ExperimentArmOperation
    ->new({
      create => Google::Ads::GoogleAds::V16::Resources::ExperimentArm->new({
          # The non-"control" arm, also called a "treatment" arm, will automatically
          # generate draft campaigns that you can modify before starting the
          # experiment.
          control      => "false",
          experiment   => $experiment,
          name         => "experiment arm",
          trafficSplit => 60
        })});

  my $response = $api_client->ExperimentArmService()->mutate({
    customerId => $customer_id,
    operations => $operations,
    # We want to fetch the draft campaign IDs from the treatment arm, so the
    # easiest way to do that is to have the response return the newly created
    # entities.
    responseContentType => MUTABLE_RESOURCE
  });

  # Results always return in the order that you specify them in the request.
  # Since we created the treatment arm last, it will be the last result.
  my $control_arm_result   = $response->{results}[0];
  my $treatment_arm_result = $response->{results}[1];

  printf "Created control arm with resource name '%s'.\n",
    $control_arm_result->{resourceName};
  printf "Created treatment arm with resource name '%s'.\n",
    $treatment_arm_result->{resourceName};
  return $treatment_arm_result->{experimentArm}{inDesignCampaigns}[0];
}