Add an extension setting

Before associating an extension setting with a customer, campaign, or ad group, you must first create the necessary ExtensionFeedItem objects. The extension feed items contain information about what the extension setting will do. We're going to add sitelinks extensions as an example.

First, create the extension feed items:

Java

private static List<StringValue> createExtensionFeedItems(
    GoogleAdsClient googleAdsClient, long customerId, String campaignResourceName) {
  SitelinkFeedItem sitelinkFeedItem1 =
      createSitelinkFeedItem("Store Hours", "http://www.example.com/storehours");

  // Creates an ExtensionFeedItem from the SitelinkFeedItem.
  ExtensionFeedItem extensionFeedItem1 =
      ExtensionFeedItem.newBuilder()
          .setExtensionType(ExtensionType.SITELINK)
          .setSitelinkFeedItem(sitelinkFeedItem1)
          .setTargetedCampaign(StringValue.of(campaignResourceName))
          .build();

  List<ExtensionFeedItemOperation> operations = new ArrayList<>();
  // Creates an ExtensionFeedItemOperation and adds it to the operations List.
  operations.add(ExtensionFeedItemOperation.newBuilder().setCreate(extensionFeedItem1).build());

  SitelinkFeedItem sitelinkFeedItem2 =
      createSitelinkFeedItem("Thanksgiving Specials", "http://www.example.com/thanksgiving");

  DateTime startTime = new DateTime(DateTime.now().getYear(), 11, 20, 0, 0, 0);
  if (startTime.isBeforeNow()) {
    // Move the startTime to next year if the current date is past November 20th.
    startTime = startTime.plusYears(1);
  }
  // Converts to a string in the required format.
  String startTimeString = startTime.toString("yyyy-MM-dd hh:mm:ss");

  // Use the same year as startTime when creating endTime.
  DateTime endTime = new DateTime(startTime.getYear(), 11, 27, 23, 59, 59);
  String endTimeString = endTime.toString("yyyy-MM-dd hh:mm:ss");

  // Targets this sitelink for United States only.
  // A list of country codes can be referenced here:
  // https://developers.google.com/adwords/api/docs/appendix/geotargeting
  String unitedStates = ResourceNames.geoTargetConstant(2840);

  ExtensionFeedItem extensionFeedItem2 =
      ExtensionFeedItem.newBuilder()
          .setExtensionType(ExtensionType.SITELINK)
          .setSitelinkFeedItem(sitelinkFeedItem2)
          .setTargetedCampaign(StringValue.of(campaignResourceName))
          .setStartDateTime(StringValue.of(startTimeString))
          .setEndDateTime(StringValue.of(endTimeString))
          .setTargetedGeoTargetConstant(StringValue.of(unitedStates))
          .build();

  operations.add(ExtensionFeedItemOperation.newBuilder().setCreate(extensionFeedItem2).build());

  SitelinkFeedItem sitelinkFeedItem3 =
      createSitelinkFeedItem("Wifi available", "http://www.example.com/mobile/wifi");

  ExtensionFeedItem extensionFeedItem3 =
      ExtensionFeedItem.newBuilder()
          .setExtensionType(ExtensionType.SITELINK)
          .setSitelinkFeedItem(sitelinkFeedItem3)
          .setTargetedCampaign(StringValue.of(campaignResourceName))
          .setDevice(FeedItemTargetDevice.MOBILE)
          .setTargetedKeyword(
              KeywordInfo.newBuilder()
                  .setText("free wifi")
                  .setMatchType(KeywordMatchType.BROAD)
                  .build())
          .build();

  operations.add(ExtensionFeedItemOperation.newBuilder().setCreate(extensionFeedItem3).build());

  SitelinkFeedItem sitelinkFeedItem4 =
      createSitelinkFeedItem("Happy hours", "http://www.example.com/happyhours");

  ExtensionFeedItem extensionFeedItem4 =
      ExtensionFeedItem.newBuilder()
          .setExtensionType(ExtensionType.SITELINK)
          .setSitelinkFeedItem(sitelinkFeedItem4)
          .setTargetedCampaign(StringValue.of(campaignResourceName))
          .addAdSchedules(
              createAdScheduleInfo(
                  DayOfWeek.MONDAY, 18, MinuteOfHour.ZERO, 21, MinuteOfHour.ZERO))
          .addAdSchedules(
              createAdScheduleInfo(
                  DayOfWeek.TUESDAY, 18, MinuteOfHour.ZERO, 21, MinuteOfHour.ZERO))
          .addAdSchedules(
              createAdScheduleInfo(
                  DayOfWeek.WEDNESDAY, 18, MinuteOfHour.ZERO, 21, MinuteOfHour.ZERO))
          .addAdSchedules(
              createAdScheduleInfo(
                  DayOfWeek.THURSDAY, 18, MinuteOfHour.ZERO, 21, MinuteOfHour.ZERO))
          .addAdSchedules(
              createAdScheduleInfo(
                  DayOfWeek.FRIDAY, 18, MinuteOfHour.ZERO, 21, MinuteOfHour.ZERO))
          .build();

  operations.add(ExtensionFeedItemOperation.newBuilder().setCreate(extensionFeedItem4).build());

  // Creates the ExtensionFeedItemServiceClient.
  try (ExtensionFeedItemServiceClient extensionFeedItemServiceClient =
      googleAdsClient.getLatestVersion().createExtensionFeedItemServiceClient()) {
    // Adds the ExtensionFeedItem.
    MutateExtensionFeedItemsResponse response =
        extensionFeedItemServiceClient.mutateExtensionFeedItems(
            Long.toString(customerId), operations);
    System.out.printf("Added %d ExtensionFeedItems:%n", response.getResultsCount());
    List<StringValue> resourceNames = new ArrayList<>();
    for (MutateExtensionFeedItemResult result : response.getResultsList()) {
      System.out.printf(
          "Created ExtensionFeedItems with resource name '%s'.%n", result.getResourceName());
      resourceNames.add(StringValue.of(result.getResourceName()));
    }
    return resourceNames;
  }
}

C#

private static List<string> CreateExtensionFeedItems(GoogleAdsClient client,
    long customerId, string campaignResourceName)
{
    // Get the ExtensionFeedItemServiceClient.
    ExtensionFeedItemServiceClient extensionFeedItemService =
        client.GetService(Services.V5.ExtensionFeedItemService);

    SitelinkFeedItem sitelinkFeedItem1 = CreateSitelinkFeedItem(
        "Store Hours", "http://www.example.com/storehours");

    // Creates an ExtensionFeedItem from the SitelinkFeedItem.
    ExtensionFeedItem extensionFeedItem1 = new ExtensionFeedItem()
    {
        ExtensionType = ExtensionType.Sitelink,
        SitelinkFeedItem = sitelinkFeedItem1,
        TargetedCampaign = campaignResourceName
    };

    List<ExtensionFeedItemOperation> operations = new List<ExtensionFeedItemOperation>();

    // Creates an ExtensionFeedItemOperation and adds it to the operations List.
    operations.Add(new ExtensionFeedItemOperation() { Create = extensionFeedItem1 });

    SitelinkFeedItem sitelinkFeedItem2 = CreateSitelinkFeedItem(
        "Thanksgiving Specials", "http://www.example.com/thanksgiving");

    DateTime startTime = new DateTime(DateTime.Now.Year, 11, 20, 0, 0, 0);
    if (startTime < DateTime.Now)
    {
        // Move the startTime to next year if the current date is past November 20th.
        startTime = startTime.AddYears(1);
    }

    // Converts to a string in the required format.
    string startTimeString = startTime.ToString("yyyy-MM-dd hh:mm:ss");

    // Use the same year as startTime when creating endTime.
    DateTime endTime = new DateTime(startTime.Year, 11, 27, 23, 59, 59);

    string unitedStates = ResourceNames.GeoTargetConstant(2840);

    ExtensionFeedItem extensionFeedItem2 = new ExtensionFeedItem()
    {
        ExtensionType = ExtensionType.Sitelink,
        SitelinkFeedItem = sitelinkFeedItem2,
        TargetedCampaign = campaignResourceName,

        // StartDateTime should be formatted in "yyyy-MM-dd hh:mm:ss" format.
        StartDateTime = startTime.ToString("yyyy-MM-dd hh:mm:ss"),

        // EndDateTime should be formatted in "yyyy-MM-dd hh:mm:ss" format.
        EndDateTime = endTime.ToString("yyyy-MM-dd hh:mm:ss"),

        // Targets this sitelink for United States only.
        // A list of country codes can be referenced here:
        // https://developers.google.com/adwords/api/docs/appendix/geotargeting
        TargetedGeoTargetConstant = ResourceNames.GeoTargetConstant(2840)
    };

    operations.Add(new ExtensionFeedItemOperation() { Create = extensionFeedItem2 });

    SitelinkFeedItem sitelinkFeedItem3 = CreateSitelinkFeedItem(
        "Wifi available", "http://www.example.com/mobile/wifi");

    ExtensionFeedItem extensionFeedItem3 = new ExtensionFeedItem()
    {
        ExtensionType = ExtensionType.Sitelink,
        SitelinkFeedItem = sitelinkFeedItem3,
        TargetedCampaign = campaignResourceName,
        Device = FeedItemTargetDevice.Mobile,
        TargetedKeyword = new KeywordInfo()
        {
            Text = "free wifi",
            MatchType = KeywordMatchType.Broad
        }
    };

    operations.Add(new ExtensionFeedItemOperation() { Create = extensionFeedItem3 });

    SitelinkFeedItem sitelinkFeedItem4 = CreateSitelinkFeedItem(
        "Happy hours", "http://www.example.com/happyhours");

    ExtensionFeedItem extensionFeedItem4 = new ExtensionFeedItem()
    {
        ExtensionType = ExtensionType.Sitelink,
        SitelinkFeedItem = sitelinkFeedItem4,
        TargetedCampaign = campaignResourceName,
        AdSchedules = {
            CreateAdScheduleInfo(DayOfWeekEnum.Types.DayOfWeek.Monday, 18,
                MinuteOfHour.Zero, 21, MinuteOfHour.Zero),
            CreateAdScheduleInfo(DayOfWeekEnum.Types.DayOfWeek.Tuesday, 18,
                MinuteOfHour.Zero, 21, MinuteOfHour.Zero),
            CreateAdScheduleInfo(DayOfWeekEnum.Types.DayOfWeek.Wednesday, 18,
                MinuteOfHour.Zero, 21, MinuteOfHour.Zero),
            CreateAdScheduleInfo(DayOfWeekEnum.Types.DayOfWeek.Thursday, 18,
                MinuteOfHour.Zero, 21, MinuteOfHour.Zero),
            CreateAdScheduleInfo(DayOfWeekEnum.Types.DayOfWeek.Friday, 18,
                MinuteOfHour.Zero, 21, MinuteOfHour.Zero),
        }
    };

    operations.Add(new ExtensionFeedItemOperation() { Create = extensionFeedItem4 });

    // Adds the ExtensionFeedItem.
    MutateExtensionFeedItemsResponse response =
        extensionFeedItemService.MutateExtensionFeedItems(customerId.ToString(),
            operations);
    Console.WriteLine($"Added {response.Results.Count}:");

    List<string> resourceNames = new List<string>();
    foreach (MutateExtensionFeedItemResult result in response.Results)
    {
        Console.WriteLine($"Created ExtensionFeedItems with " +
            $"resource name '{result.ResourceName}'.");
        resourceNames.Add(result.ResourceName);
    }
    return resourceNames;
}

PHP

private static function createExtensionFeedItems(
    GoogleAdsClient $googleAdsClient,
    int $customerId,
    string $campaignResourceName
) {
    // Creates the first sitelink feed item.
    $sitelinkFeedItem1 =
        self::createSitelinkFeedItem('Store Hours', 'http://www.example.com/storehours');

    // Creates an extension feed item from the sitelink feed item.
    $extensionFeedItem1 = new ExtensionFeedItem([
        'extension_type' => ExtensionType::SITELINK,
        'sitelink_feed_item' => $sitelinkFeedItem1,
        'targeted_campaign' => new StringValue(['value' => $campaignResourceName])
    ]);

    // Creates the second sitelink feed item.
    $sitelinkFeedItem2 = self::createSitelinkFeedItem(
        'Thanksgiving Specials',
        'http://www.example.com/thanksgiving'
    );

    // Start date is set to November 20th. If it's already passed that date for this year,
    // use the same date for the next year instead.
    $targetYearString = date('Y');
    if (strtotime('now') > strtotime('20 November')) {
        $targetYearString = date('Y', strtotime('+1 year'));
    }
    $startTimeString = date('Y-m-d H:i:s', mktime(0, 0, 0, 11, 20, intval($targetYearString)));
    // Use the same year as start time when creating end time.
    $endTimeString = date('Y-m-d H:i:s', mktime(23, 59, 59, 11, 27, intval($targetYearString)));

    // Targets this sitelink for United States only.
    // A list of country codes can be referenced here:
    // https://developers.google.com/adwords/api/docs/appendix/geotargeting
    $unitedStates = ResourceNames::forGeoTargetConstant(2840);

    // Creates an extension feed item from the sitelink feed item.
    $extensionFeedItem2 = new ExtensionFeedItem([
        'extension_type' => ExtensionType::SITELINK,
        'sitelink_feed_item' => $sitelinkFeedItem2,
        'targeted_campaign' => new StringValue(['value' => $campaignResourceName]),
        'start_date_time' => new StringValue(['value' => $startTimeString]),
        'end_date_time' => new StringValue(['value' => $endTimeString]),
        'targeted_geo_target_constant' => new StringValue(['value' => $unitedStates])
    ]);

    // Creates the third sitelink feed item.
    $sitelinkFeedItem3 =
        self::createSitelinkFeedItem('Wifi available', 'http://www.example.com/mobile/wifi');

    // Creates an extension feed item from the sitelink feed item.
    $extensionFeedItem3 = new ExtensionFeedItem([
        'extension_type' => ExtensionType::SITELINK,
        'sitelink_feed_item' => $sitelinkFeedItem3,
        'targeted_campaign' => new StringValue(['value' => $campaignResourceName]),
        'device' => FeedItemTargetDevice::MOBILE,
        'targeted_keyword' => new KeywordInfo([
            'text' => 'free wifi',
            'match_type' => KeywordMatchType::BROAD
        ])
    ]);

    // Creates the fourth sitelink feed item.
    $sitelinkFeedItem4 =
        self::createSitelinkFeedItem('Happy hours', 'http://www.example.com/happyhours');

    // Creates an extension feed item from the sitelink feed item.
    $extensionFeedItem4 = new ExtensionFeedItem([
        'extension_type' => ExtensionType::SITELINK,
        'sitelink_feed_item' => $sitelinkFeedItem4,
        'targeted_campaign' => new StringValue(['value' => $campaignResourceName]),
        'ad_schedules' => [
            self::createAdScheduleInfo(
                DayOfWeek::MONDAY,
                18,
                MinuteOfHour::ZERO,
                21,
                MinuteOfHour::ZERO
            ),
            self::createAdScheduleInfo(
                DayOfWeek::TUESDAY,
                18,
                MinuteOfHour::ZERO,
                21,
                MinuteOfHour::ZERO
            ),
            self::createAdScheduleInfo(
                DayOfWeek::WEDNESDAY,
                18,
                MinuteOfHour::ZERO,
                21,
                MinuteOfHour::ZERO
            ),
            self::createAdScheduleInfo(
                DayOfWeek::THURSDAY,
                18,
                MinuteOfHour::ZERO,
                21,
                MinuteOfHour::ZERO
            ),
            self::createAdScheduleInfo(
                DayOfWeek::FRIDAY,
                18,
                MinuteOfHour::ZERO,
                21,
                MinuteOfHour::ZERO
            )
        ]
    ]);

    // Issues a mutate request to add the extension feed items.
    $extensionFeedItemServiceClient = $googleAdsClient->getExtensionFeedItemServiceClient();
    $response = $extensionFeedItemServiceClient->mutateExtensionFeedItems(
        $customerId,
        [
            new ExtensionFeedItemOperation(['create' => $extensionFeedItem1]),
            new ExtensionFeedItemOperation(['create' => $extensionFeedItem2]),
            new ExtensionFeedItemOperation(['create' => $extensionFeedItem3]),
            new ExtensionFeedItemOperation(['create' => $extensionFeedItem4])
        ]
    );

    // Prints some information about the created extension feed items.
    printf(
        "Created %d extension feed items with the following resource names:%s",
        $response->getResults()->count(),
        PHP_EOL
    );
    $createdExtensionFeedItemsResourceNames = [];
    foreach ($response->getResults() as $addedExtensionFeedItem) {
        /** @var ExtensionFeedItem $addedExtensionFeedItem */
        $addedExtensionFeedItemResourceName = $addedExtensionFeedItem->getResourceName();
        print $addedExtensionFeedItemResourceName . PHP_EOL;
        $createdExtensionFeedItemsResourceNames[] = new StringValue([
            'value' => $addedExtensionFeedItemResourceName
        ]);
    }
    return $createdExtensionFeedItemsResourceNames;
}

Python

def _create_extension_feed_items(client, customer_id, campaign_resource_name):
    """Helper method that creates extension feed items.

    Args:
        client: a GoogleAdsClient instance.
        customer_id: a str Google Ads customer ID, that the extension feed items
            will be created for.
        campaign_resource_name: a str resource name for the campaign that will
            be tracked by the created extension feed items.

    Returns:
        A list containing StringValue resource names for the created extension
        feed items.
    """
    extension_feed_item_service = client.get_service(
        "ExtensionFeedItemService", version="v5"
    )
    geo_target_constant_service = client.get_service(
        "GeoTargetConstantService", version="v5"
    )
    extension_type_enum = client.get_type("ExtensionTypeEnum")
    feed_item_target_device_enum = client.get_type("FeedItemTargetDeviceEnum")
    day_of_week_enum = client.get_type("DayOfWeekEnum")
    minute_of_hour_enum = client.get_type("MinuteOfHourEnum")

    extension_feed_item_operation1 = client.get_type(
        "ExtensionFeedItemOperation", version="v5"
    )
    extension_feed_item1 = extension_feed_item_operation1.create
    extension_feed_item1.extension_type = extension_type_enum.SITELINK
    extension_feed_item1.sitelink_feed_item.link_text.value = "Store Hours"
    extension_feed_item1.targeted_campaign.value = campaign_resource_name
    final_url1 = extension_feed_item1.sitelink_feed_item.final_urls.add()
    final_url1.value = "http://www.example.com/storehours"

    extension_feed_item_operation2 = client.get_type(
        "ExtensionFeedItemOperation", version="v5"
    )
    date_range = _get_thanksgiving_string_date_range()
    extension_feed_item2 = extension_feed_item_operation2.create
    extension_feed_item2.extension_type = extension_type_enum.SITELINK
    extension_feed_item2.sitelink_feed_item.link_text.value = (
        "Thanksgiving Specials"
    )
    extension_feed_item2.targeted_campaign.value = campaign_resource_name
    extension_feed_item2.start_date_time.value = date_range.start_datetime
    extension_feed_item2.end_date_time.value = date_range.end_datetime
    # Targets this sitelink for the United States only.
    # A list of country codes can be referenced here:
    # https://developers.google.com/adwords/api/docs/appendix/geotargeting
    united_states = geo_target_constant_service.geo_target_constant_path(2048)
    extension_feed_item2.targeted_geo_target_constant.value = united_states
    final_url2 = extension_feed_item2.sitelink_feed_item.final_urls.add()
    final_url2.value = "http://www.example.com/thanksgiving"

    extension_feed_item_operation3 = client.get_type(
        "ExtensionFeedItemOperation", version="v5"
    )
    extension_feed_item3 = extension_feed_item_operation3.create
    extension_feed_item3.extension_type = extension_type_enum.SITELINK
    extension_feed_item3.sitelink_feed_item.link_text.value = "Wifi available"
    extension_feed_item3.targeted_campaign.value = campaign_resource_name
    extension_feed_item3.device = feed_item_target_device_enum.MOBILE
    final_url3 = extension_feed_item3.sitelink_feed_item.final_urls.add()
    final_url3.value = "http://www.example.com/mobile/wifi"

    extension_feed_item_operation4 = client.get_type(
        "ExtensionFeedItemOperation", version="v5"
    )
    extension_feed_item4 = extension_feed_item_operation4.create
    extension_feed_item4.extension_type = extension_type_enum.SITELINK
    extension_feed_item4.sitelink_feed_item.link_text.value = "Happy hours"
    extension_feed_item4.targeted_campaign.value = campaign_resource_name
    extension_feed_item4.device = feed_item_target_device_enum.MOBILE
    final_url4 = extension_feed_item4.sitelink_feed_item.final_urls.add()
    final_url4.value = "http://www.example.com/happyhours"
    for day_of_week in [
        day_of_week_enum.MONDAY,
        day_of_week_enum.TUESDAY,
        day_of_week_enum.WEDNESDAY,
        day_of_week_enum.THURSDAY,
        day_of_week_enum.FRIDAY,
    ]:
        _populate_ad_schedule(
            extension_feed_item4.ad_schedules.add(),
            day_of_week,
            18,
            minute_of_hour_enum.ZERO,
            21,
            minute_of_hour_enum.ZERO,
        )

    # Add extension feed items
    try:
        feed_response = extension_feed_item_service.mutate_extension_feed_items(
            customer_id,
            [
                extension_feed_item_operation1,
                extension_feed_item_operation2,
                extension_feed_item_operation3,
                extension_feed_item_operation4,
            ],
        )
    except GoogleAdsException as ex:
        print(
            f'Request with ID "{ex.request_id}" failed with status '
            f'"{ex.error.code().name}" and includes the following errors:'
        )
        for error in ex.failure.errors:
            print(f'\tError with message "{error.message}"')
            if error.location:
                for field_path_element in error.location.field_path_elements:
                    print(f"\t\tOn field: {field_path_element.field_name}")
        sys.exit(1)

    print("Created ExtensionFeedItems:")
    for feed_item in feed_response.results:
        print(f"\tResource name: {feed_item.resource_name}")

    resource_names = [result.resource_name for result in feed_response.results]

    return [
        _to_string_value(client, resource_name)
        for resource_name in resource_names
    ]

Ruby

def create_extension_feed_items(client, customer_id, campaign_resource_name)
  extension_feed_items = [
    client.resource.extension_feed_item do |efi|
      efi.extension_type = :SITELINK
      efi.sitelink_feed_item = create_sitelink_feed_item(
          client, 'Store Hours', 'http://www.example.com/storehours')
      efi.targeted_campaign = campaign_resource_name
    end,
    client.resource.extension_feed_item do |efi|
      efi.extension_type = :SITELINK
      efi.sitelink_feed_item = create_sitelink_feed_item(
          client, 'Thanksgiving Specials', 'http://www.example.com/thanksgiving')
      efi.targeted_campaign = campaign_resource_name
      efi.start_date_time =
          DateTime.new(Date.today.year, 11, 20, 0, 0, 0).strftime("%Y-%m-%d %H:%M:%S")
      efi.end_date_time =
          DateTime.new(Date.today.year, 11, 27, 23, 59, 59).strftime("%Y-%m-%d %H:%M:%S")

      # Targets this sitelink for United States only.
      # A list of country codes can be referenced here:
      # https://developers.google.com/google-ads/api/reference/data/geotargets
      efi.targeted_geo_target_constant = client.path.geo_target_constant(2840)
    end,
    client.resource.extension_feed_item do |efi|
      efi.extension_type = :SITELINK
      efi.sitelink_feed_item = create_sitelink_feed_item(
          client, 'Wifi available', 'http://www.example.com/wifi')
      efi.targeted_campaign = campaign_resource_name
      efi.device = :MOBILE
      efi.targeted_keyword = client.resource.keyword_info do |ki|
        ki.text = 'free wifi'
        ki.match_type = :BROAD
      end
    end,
    client.resource.extension_feed_item do |efi|
      efi.extension_type = :SITELINK
      efi.sitelink_feed_item = create_sitelink_feed_item(
          client, 'Happy hours', 'http://www.example.com/happyhours')
      efi.targeted_campaign = campaign_resource_name
      efi.ad_schedules << create_ad_schedule(client, :MONDAY,    18, :ZERO, 21, :ZERO)
      efi.ad_schedules << create_ad_schedule(client, :TUESDAY,   18, :ZERO, 21, :ZERO)
      efi.ad_schedules << create_ad_schedule(client, :WEDNESDAY, 18, :ZERO, 21, :ZERO)
      efi.ad_schedules << create_ad_schedule(client, :THURSDAY,  18, :ZERO, 21, :ZERO)
      efi.ad_schedules << create_ad_schedule(client, :FRIDAY,    18, :ZERO, 21, :ZERO)
    end
  ]

  operations = extension_feed_items.map do |efi|
    client.operation.create_resource.extension_feed_item(efi)
  end

  response = client.service.extension_feed_item.mutate_extension_feed_items(
    customer_id: customer_id,
    operations: operations,
  )

  puts "Created #{response.results.size} extension feed items with the following resource names:"
  response.results.map do |result|
    puts "\t#{result.resource_name}"
    result.resource_name
  end
end

Perl

sub create_extension_feed_items {
  my ($api_client, $customer_id, $campaign_resource_name) = @_;

  my $operations = [];

  my $sitelink_feed_item_1 = create_sitelink_feed_item("Store Hours",
    "http://www.example.com/storehours");

  # Create an extension feed item from the sitelink feed item.
  my $extension_feed_item_1 =
    Google::Ads::GoogleAds::V5::Resources::ExtensionFeedItem->new({
      extensionType    => SITELINK,
      sitelinkFeedItem => $sitelink_feed_item_1,
      targetedCampaign => $campaign_resource_name
    });

  # Create an extension feed item operation and add it to the operations list.
  push @$operations,
    Google::Ads::GoogleAds::V5::Services::ExtensionFeedItemService::ExtensionFeedItemOperation
    ->new({
      create => $extension_feed_item_1
    });

  my $sitelink_feed_item_2 = create_sitelink_feed_item("Thanksgiving Specials",
    "http://www.example.com/thanksgiving");

  # Set the start_time and end_time to show the Thanksgiving specials link only
  # from 20 - 27 Nov.
  my ($sec, $min, $hour, $mday, $mon, $year) = localtime(time);
  my $start_time = mktime(0, 0, 0, 20, 10, $year);
  if ($start_time < time) {
    # Move the start_time to next year if the current date is past November 20th.
    $year += 1;
    $start_time = mktime(0, 0, 0, 20, 10, $year);
  }
  # Convert to a string in the required format.
  my $start_time_string = strftime("%Y-%m-%d %H:%M:%S", localtime($start_time));

  # Use the same year as start_time when creating end_time.
  my $end_time        = mktime(59, 59, 23, 27, 10, $year);
  my $end_time_string = strftime("%Y-%m-%d %H:%M:%S", localtime($end_time));

  # Target this sitelink for United States only.
  # A list of country codes can be referenced here:
  # https://developers.google.com/adwords/api/docs/appendix/geotargeting
  my $united_states =
    Google::Ads::GoogleAds::V5::Utils::ResourceNames::geo_target_constant(2840);

  my $extension_feed_item_2 =
    Google::Ads::GoogleAds::V5::Resources::ExtensionFeedItem->new({
      extensionType             => SITELINK,
      sitelinkFeedItem          => $sitelink_feed_item_2,
      targetedCampaign          => $campaign_resource_name,
      startDateTime             => $start_time_string,
      endDateTime               => $end_time_string,
      targetedGeoTargetConstant => $united_states
    });

  push @$operations,
    Google::Ads::GoogleAds::V5::Services::ExtensionFeedItemService::ExtensionFeedItemOperation
    ->new({
      create => $extension_feed_item_2
    });

  my $sitelink_feed_item_3 = create_sitelink_feed_item("Wifi available",
    "http://www.example.com/mobile/wifi");

  # Set the targeted device to show the wifi details primarily for high end
  # mobile users.
  # Target this sitelink for the keyword "free wifi".
  my $extension_feed_item_3 =
    Google::Ads::GoogleAds::V5::Resources::ExtensionFeedItem->new({
      extensionType    => SITELINK,
      sitelinkFeedItem => $sitelink_feed_item_3,
      targetedCampaign => $campaign_resource_name,
      device           => MOBILE,
      targetedKeyword  => Google::Ads::GoogleAds::V5::Common::KeywordInfo->new({
          text      => "free wifi",
          matchType => BROAD
        })});

  push @$operations,
    Google::Ads::GoogleAds::V5::Services::ExtensionFeedItemService::ExtensionFeedItemOperation
    ->new({
      create => $extension_feed_item_3
    });

  my $sitelink_feed_item_4 = create_sitelink_feed_item("Happy hours",
    "http://www.example.com/happyhours");

  # Set the feed item schedules to show the happy hours link only during Mon - Fri
  # 6PM to 9PM.
  my $extension_feed_item_4 =
    Google::Ads::GoogleAds::V5::Resources::ExtensionFeedItem->new({
      extensionType    => SITELINK,
      sitelinkFeedItem => $sitelink_feed_item_4,
      targetedCampaign => $campaign_resource_name,
      adSchedules      => [
        create_ad_schedule_info(MONDAY,    18, ZERO, 21, ZERO),
        create_ad_schedule_info(TUESDAY,   18, ZERO, 21, ZERO),
        create_ad_schedule_info(WEDNESDAY, 18, ZERO, 21, ZERO),
        create_ad_schedule_info(THURSDAY,  18, ZERO, 21, ZERO),
        create_ad_schedule_info(FRIDAY,    18, ZERO, 21, ZERO)]});

  push @$operations,
    Google::Ads::GoogleAds::V5::Services::ExtensionFeedItemService::ExtensionFeedItemOperation
    ->new({
      create => $extension_feed_item_4
    });

  # Add the extension feed item.
  my $extension_feed_item_response =
    $api_client->ExtensionFeedItemService()->mutate({
      customerId => $customer_id,
      operations => $operations
    });

  my $extension_feed_item_results = $extension_feed_item_response->{results};
  printf "Added %d extension feed items:\n",
    scalar @$extension_feed_item_results;

  my $resource_names = [];
  foreach my $extension_feed_item_result (@$extension_feed_item_results) {
    printf "\tCreated extension feed item with resource name '%s'.\n",
      $extension_feed_item_result->{resourceName};
    push @$resource_names, $extension_feed_item_result->{resourceName};
  }

  return $resource_names;
}

Then, associate the extension feed items with an existing campaign:

Java

private void runExample(GoogleAdsClient googleAdsClient, long customerId, long campaignId) {
  String campaignResourceName = ResourceNames.campaign(customerId, campaignId);

  List<StringValue> extensionFeedItems =
      createExtensionFeedItems(googleAdsClient, customerId, campaignResourceName);

  // Creates a CampaignExtensionSetting.
  CampaignExtensionSetting campaignExtensionSetting =
      CampaignExtensionSetting.newBuilder()
          .setCampaign(StringValue.of(campaignResourceName))
          .setExtensionType(ExtensionType.SITELINK)
          .addAllExtensionFeedItems(extensionFeedItems)
          .build();

  // Creates the operation.
  CampaignExtensionSettingOperation operation =
      CampaignExtensionSettingOperation.newBuilder().setCreate(campaignExtensionSetting).build();

  // Creates the CampaignExtensionSettingServiceClient.
  try (CampaignExtensionSettingServiceClient campaignExtensionSettingServiceClient =
      googleAdsClient.getLatestVersion().createCampaignExtensionSettingServiceClient()) {
    // Adds the CampaignExtensionSettingServiceClient.
    MutateCampaignExtensionSettingsResponse response =
        campaignExtensionSettingServiceClient.mutateCampaignExtensionSettings(
            Long.toString(customerId), ImmutableList.of(operation));
    for (MutateCampaignExtensionSettingResult result : response.getResultsList()) {
      System.out.printf(
          "Created CampaignExtensionSetting with resource name '%s'.%n",
          result.getResourceName());
    }
  }
}

C#

public void Run(GoogleAdsClient client, long customerId, long campaignId)
{
    // Get the CampaignExtensionSettingServiceClient.
    CampaignExtensionSettingServiceClient campaignExtensionSettingService =
        client.GetService(Services.V5.CampaignExtensionSettingService);

    string campaignResourceName = ResourceNames.Campaign(customerId, campaignId);

    List<string> extensionFeedItems =
        CreateExtensionFeedItems(client, customerId, campaignResourceName);

    // Creates a CampaignExtensionSetting.
    CampaignExtensionSetting campaignExtensionSetting = new CampaignExtensionSetting()
    {
        Campaign = campaignResourceName,
        ExtensionType = ExtensionType.Sitelink,
        ExtensionFeedItems = { extensionFeedItems }
    };

    // Creates the operation.
    CampaignExtensionSettingOperation operation = new CampaignExtensionSettingOperation()
    {
        Create = campaignExtensionSetting
    };

    try
    {
        MutateCampaignExtensionSettingsResponse response =
            campaignExtensionSettingService.MutateCampaignExtensionSettings(
                customerId.ToString(), new[] { operation });
        foreach (MutateCampaignExtensionSettingResult result in response.Results)
        {
            Console.WriteLine($"Created CampaignExtensionSetting with resource" +
                $" name '{result.ResourceName}'.");
        }
    }
    catch (GoogleAdsException e)
    {
        Console.WriteLine("Failure:");
        Console.WriteLine($"Message: {e.Message}");
        Console.WriteLine($"Failure: {e.Failure}");
        Console.WriteLine($"Request ID: {e.RequestId}");
        throw;
    }
}

PHP

public static function runExample(
    GoogleAdsClient $googleAdsClient,
    int $customerId,
    int $campaignId
) {
    $campaignResourceName = ResourceNames::forCampaign($customerId, $campaignId);

    // Creates extension feed items as sitelinks.
    $extensionFeedItems =
        self::createExtensionFeedItems($googleAdsClient, $customerId, $campaignResourceName);

    // Creates a campaign extension setting using the previously created extension feed items.
    $campaignExtensionSetting = new CampaignExtensionSetting([
        'campaign' => new StringValue(['value' => $campaignResourceName]),
        'extension_type' => ExtensionType::SITELINK,
        'extension_feed_items' => $extensionFeedItems
    ]);

    // Creates the campaign extension setting operation.
    $campaignExtensionSettingOperation = new CampaignExtensionSettingOperation();
    $campaignExtensionSettingOperation->setCreate($campaignExtensionSetting);

    // Issues a mutate request to add the campaign extension setting.
    $campaignExtensionSettingServiceClient =
        $googleAdsClient->getCampaignExtensionSettingServiceClient();
    $response = $campaignExtensionSettingServiceClient->mutateCampaignExtensionSettings(
        $customerId,
        [$campaignExtensionSettingOperation]
    );

    // Prints the resource name of the created campaign extension setting.
    /** @var CampaignExtensionSetting $addedCampaignExtensionSetting */
    $addedCampaignExtensionSetting = $response->getResults()[0];
    printf(
        "Created a campaign extension setting with resource name: '%s'%s",
        $addedCampaignExtensionSetting->getResourceName(),
        PHP_EOL
    );
}

Python

def main(client, customer_id, campaign_id):
    """The main method that creates all necessary entities for the example."""
    # Create an extension setting.
    campaign_service = client.get_service("CampaignService", version="v5")
    campaign_ext_setting_service = client.get_service(
        "CampaignExtensionSettingService", version="v5"
    )

    campaign_resource_name = campaign_service.campaign_path(
        customer_id, campaign_id
    )

    feed_item_resource_names = _create_extension_feed_items(
        client, customer_id, campaign_resource_name
    )

    campaign_ext_setting_operation = client.get_type(
        "CampaignExtensionSettingOperation", version="v5"
    )
    extension_type_enum = client.get_type("ExtensionTypeEnum", version="v5")

    campaign_ext_setting = campaign_ext_setting_operation.create
    campaign_ext_setting.campaign.value = campaign_resource_name
    campaign_ext_setting.extension_type = extension_type_enum.SITELINK

    campaign_ext_setting.extension_feed_items.extend(feed_item_resource_names)

    # Add campaign extension setting with site link feed items.
    try:
        response = campaign_ext_setting_service.mutate_campaign_extension_settings(
            customer_id, [campaign_ext_setting_operation]
        )
    except GoogleAdsException as ex:
        print(
            f'Request with ID "{ex.request_id}" failed with status '
            f'"{ex.error.code().name}" and includes the following errors:'
        )
        for error in ex.failure.errors:
            print(f'\tError with message "{error.message}".')
            if error.location:
                for field_path_element in error.location.field_path_elements:
                    print("\t\tOn field: {field_path_element.field_name}")
        sys.exit(1)

    print(
        "Created CampaignExtensionSetting: "
        f'"{response.results[0].resource_name}".'
    )

Ruby

def add_sitelinks(customer_id, campaign_id)
  # GoogleAdsClient will read a config file from
  # ENV['HOME']/google_ads_config.rb when called without parameters
  client = Google::Ads::GoogleAds::GoogleAdsClient.new

  campaign_resource_name = client.path.campaign(customer_id, campaign_id)

  extension_feed_items =
      create_extension_feed_items(client, customer_id, campaign_resource_name)

  operation = client.operation.create_resource.campaign_extension_setting do |ces|
    ces.campaign = campaign_resource_name
    ces.extension_type = :SITELINK
    extension_feed_items.each do |efi|
      ces.extension_feed_items << efi
    end
  end

  response = client.service.campaign_extension_setting.mutate_campaign_extension_settings(
    customer_id: customer_id,
    operations: [operation],
  )

  puts "Created a campaign extension setting with resource name '#{response.results.first.resource_name}'"
end

Perl

sub add_sitelinks {
  my ($api_client, $customer_id, $campaign_id) = @_;

  my $campaign_resource_name =
    Google::Ads::GoogleAds::V5::Utils::ResourceNames::campaign($customer_id,
    $campaign_id);

  # Create extension feed items as sitelinks.
  my $extension_feed_items =
    create_extension_feed_items($api_client, $customer_id,
    $campaign_resource_name);

  # Create a campaign extension setting.
  my $campaign_extension_setting =
    Google::Ads::GoogleAds::V5::Resources::CampaignExtensionSetting->new({
      campaign           => $campaign_resource_name,
      extensionType      => SITELINK,
      extensionFeedItems => $extension_feed_items
    });

  # Create a campaign extension setting operation.
  my $campaign_extension_setting_operation =
    Google::Ads::GoogleAds::V5::Services::CampaignExtensionSettingService::CampaignExtensionSettingOperation
    ->new({
      create => $campaign_extension_setting
    });

  # Add the campaign extension setting.
  my $campaign_extension_setting_response =
    $api_client->CampaignExtensionSettingService()->mutate({
      customerId => $customer_id,
      operations => [$campaign_extension_setting_operation]});

  printf "Created campaign extension setting with resource name '%s'.\n",
    $campaign_extension_setting_response->{results}[0]{resourceName};

  return 1;
}