Службы настройки расширений

Использование служб настройки расширений

Предположим, вы рекламируете в AdWords ресторан. Вы уже создали кампанию, но хотите добавить в объявления следующую информацию:

  • Часы работы. Ссылка, которая будет направлять пользователей по адресу http://www.example.com/storehours.
  • Данные о пищевой ценности блюд. Ссылка на страницу http://www.example.com/menu/nutritiondata.
  • Часы скидок. Ссылка на страницу http://www.example.com/happyhours, которая должна показываться только с 18:00 до 21:00 по будням и с 17:00 до 20:00 по субботам.
  • Специальное меню в День благодарения. Вы планируете предложить посетителям особые угощения в День благодарения. Ссылка для заказа блюд (http://www.example.com/thanksgiving) должна отображаться только с 20 по 27 ноября.

Все это – расширения объявлений AdWords. Ими можно управлять с помощью служб настройки расширений в AdWords API.

Добавление расширений

Расширения объявлений можно добавлять на уровне аккаунта, кампании или группы объявлений (на некоторых уровнях доступны не все типы расширений). Для новых расширений следует применять оператор ADD или SET. Если SET используется для расширения, которое не существует, добавляется новое расширение. Есть насколько видов расширений.

Помимо ссылки на главную целевую страницу, вы можете создать дополнительные ссылки на другие страницы сайта. Это упростит навигацию по нему для пользователей.

Следующий фрагмент кода будет добавлять новые расширения в кампании посредством службы CampaignExtensionSettingService:

// Get the CampaignExtensionSettingService.
CampaignExtensionSettingService campaignExtensionSettingService =
    (CampaignExtensionSettingService) user.GetService(
         AdWordsService.v201705.CampaignExtensionSettingService);

CampaignExtensionSetting campaignExtensionSetting =
    new CampaignExtensionSetting();
campaignExtensionSetting.campaignId = campaignId;
campaignExtensionSetting.extensionType = FeedType.SITELINK;

SitelinkFeedItem link1 = new SitelinkFeedItem() {
    sitelinkText = "Store Hours",
    sitelinkUrl = "http://www.example.com/storehours"
};

SitelinkFeedItem link2 = new SitelinkFeedItem() {
    sitelinkText = "Thanksgiving Specials",
    sitelinkUrl = "http://www.example.com/thanksgiving",
    startTime = "20141120 000000 EST",
    endTime = "20141127 235959 EST",

    // Target this sitelink for United States only. See
    // https://developers.google.com/adwords/api/docs/appendix/geotargeting
    // for valid geolocation codes.
    geoTargeting = new Location () {
      id = 2840
    };
};

SitelinkFeedItem link3 = new SitelinkFeedItem() {
    sitelinkText = "Nutrition Data",
    sitelinkUrl = "http://www.example.com/menu/nutritiondata"
};

SitelinkFeedItem link4 = new SitelinkFeedItem() {
    sitelinkText = "Happy hours",
    sitelinkUrl = "http://www.example.com/happyhours",
    scheduling = new FeedItemSchedule[] {
        new FeedItemSchedule() {
            dayOfWeek = AdWords.v201705.DayOfWeek.MONDAY,
            startHour = 18,
            startMinute = MinuteOfHour.ZERO,
            endHour = 21,
            endMinute = MinuteOfHour.ZERO
        },
        new FeedItemSchedule() {
            dayOfWeek = AdWords.v201705.DayOfWeek.TUESDAY,
            startHour = 18,
            startMinute = MinuteOfHour.ZERO,
            endHour = 21,
            endMinute = MinuteOfHour.ZERO
        },
        new FeedItemSchedule() {
            dayOfWeek = AdWords.v201705.DayOfWeek.WEDNESDAY,
            startHour = 18,
            startMinute = MinuteOfHour.ZERO,
            endHour = 21,
            endMinute = MinuteOfHour.ZERO
        },
        new FeedItemSchedule() {
            dayOfWeek = AdWords.v201705.DayOfWeek.THURSDAY,
            startHour = 18,
            startMinute = MinuteOfHour.ZERO,
            endHour = 21,
            endMinute = MinuteOfHour.ZERO
        },
        new FeedItemSchedule() {
            dayOfWeek = AdWords.v201705.DayOfWeek.FRIDAY,
            startHour = 18,
            startMinute = MinuteOfHour.ZERO,
            endHour = 21,
            endMinute = MinuteOfHour.ZERO
        },
        new FeedItemSchedule() {
            dayOfWeek = AdWords.v201705.DayOfWeek.SATURDAY,
            startHour = 17,
            startMinute = MinuteOfHour.ZERO,
            endHour = 21,
            endMinute = MinuteOfHour.ZERO
        }
    }
};

campaignExtensionSetting.extensionSetting = new ExtensionSetting() {
    extensions = new ExtensionFeedItem[] {
        link1, link2, link3, link4
    },
};

CampaignExtensionSettingOperation operation = new CampaignExtensionSettingOperation() {
    operand = campaignExtensionSetting,
    @operator = Operator.ADD,
};

CampaignExtensionSettingReturnValue retVal = campaignExtensionSettingService.mutate(
    new CampaignExtensionSettingOperation[] {operation});

Номера телефонов

Расширение CallFeedItem позволит вам показывать в объявлениях номер телефона своей компании. Нажав на него, пользователь сможет сразу вам позвонить. Следующий фрагмент кода показывает, как это настроить:

CallFeedItem callFeedItem = new CallFeedItem() {
    callCountryCode = "US",
    callPhoneNumber = "212-565-0000",
};

CampaignExtensionSetting campaignExtensionSetting =
    new CampaignExtensionSetting();
campaignExtensionSetting.campaignId = campaignId;

campaignExtensionSetting.extensionSetting = new ExtensionSetting() {
    extensions = new ExtensionFeedItem[] { callFeedItem },
};

Отзывы

В объявлениях также можно показывать отзывы клиентов. Для этого потребуется следующий фрагмент кода:

ReviewFeedItem reviewFeeditem = new ReviewFeedItem() {
    reviewSourceName = "Example Food review magazine",
    reviewSourceUrl =
        "http://www.example.com/reviews/2014/03/the-amazing-example-hotel",
    reviewText = "The best food in New York city!",
    reviewTextExactlyQuoted = true
};

CampaignExtensionSetting campaignExtensionSetting =
    new CampaignExtensionSetting();
campaignExtensionSetting.campaignId = campaignId;

campaignExtensionSetting.extensionSetting = new ExtensionSetting() {
    extensions = new ExtensionFeedItem[] { reviewFeeditem },
};

Уточнения

Уточнения – это дополнительная информация о ваших продуктах или услугах, которая добавляется под текстовое объявление. Чтобы настроить такое расширение, потребуется фрагмент кода следующего вида:

CalloutFeedItem freeDeliveryCallout = new CalloutFeedItem() {
   calloutText = "Free delivery",
};
CalloutFeedItem kidsCallout = new CalloutFeedItem() {
   calloutText = "Kids eat free",
};

CampaignExtensionSetting campaignExtensionSetting = new CampaignExtensionSetting();
campaignExtensionSetting.campaignId = campaignId;
campaignExtensionSetting.extensionType = FeedType.CALLOUT;
campaignExtensionSetting.extensionSetting = new ExtensionSetting() {
    extensions = new ExtensionFeedItem[] {
        freeDeliveryCallout, kidsCallout
    }
};

Ссылки на приложения

Если у вас есть приложение для Android или iOS, вы можете предлагать его владельцам мобильных устройств, показывая в объявлениях ссылки для скачивания. Их увидят только авторизованные пользователи Google, которые ещё не установили это приложение. При нажатии на ссылку они будут переходить на страницу в Google Play или App Store. Расширение с переадресацией в Google Play настраивается с помощью следующего фрагмента кода:

AppFeedItem appFeedItem = new AppFeedItem() {
    appId = "com.example.mobileapp",
    appStore = AppFeedItemAppStore.GOOGLE_PLAY,
    appLinkText = "Install our mobile app!",
    appUrl = "https://play.google.com/store/apps/details?id=com.example.mobileapp"
};

CampaignExtensionSetting campaignExtensionSetting =
    new CampaignExtensionSetting();
campaignExtensionSetting.campaignId = campaignId;

campaignExtensionSetting.extensionSetting = new ExtensionSetting() {
    extensions = new ExtensionFeedItem[] { appFeedItem },
};

Сообщения

Расширения для сообщений позволяют пользователям одним нажатием на значок в объявлении отправлять вам SMS – например, чтобы получить дополнительную информацию, сделать заказ, записаться на прием и т. п. Следующий фрагмент кода будет добавлять новые расширения посредством службы MessageFeedItem:

MessageFeedItem messageFeedItem = new MessageFeedItem() {
    messageBusinessName = "Travel Here",
    messageCountryCode = "US",
    messagePhoneNumber = "212-565-0000",
    messageText = "I want to know more.",
    messageExtensionText = "Ask us about travel.",
};

CampaignExtensionSetting campaignExtensionSetting =
    new CampaignExtensionSetting();
campaignExtensionSetting.campaignId = campaignId;

campaignExtensionSetting.extensionSetting = new ExtensionSetting() {
    extensions = new ExtensionFeedItem[] { messageFeedItem },
};

Цены

Цена – это расширение объявлений, которое позволяет показывать пользователям данные о стоимости ваших продуктов. Настраивая его, вы вводите список товаров, услуг, мероприятий и т п., указывая их цены.

Вы можете добавить в объявление заголовки, описания и цены 3–8 продуктов, а также использовать гибкие возможности настройки и таргетинга.

Расширение "Цена" доступно на уровне аккаунта, кампании и группы объявлений.

Чтобы настроить его, потребуется следующий фрагмент кода:

// Create the price extension feed item.
PriceFeedItem priceFeedItem = new PriceFeedItem();
priceFeedItem.setPriceExtensionType(PriceExtensionType.SERVICES);

// Price qualifier is optional.
priceFeedItem.setPriceQualifier(PriceExtensionPriceQualifier.FROM);
priceFeedItem.setTrackingUrlTemplate("http://tracker.example.com/?u={lpurl}");
priceFeedItem.setLanguage("en");
FeedItemCampaignTargeting campaignTargeting = new FeedItemCampaignTargeting();
campaignTargeting.setTargetingCampaignId(campaignId);
priceFeedItem.setCampaignTargeting(campaignTargeting);
priceFeedItem.setScheduling(
    new FeedItemScheduling(
        new FeedItemSchedule[] {
          new FeedItemSchedule(DayOfWeek.SUNDAY, 10, MinuteOfHour.ZERO, 18, MinuteOfHour.ZERO),
          new FeedItemSchedule(DayOfWeek.SATURDAY, 10, MinuteOfHour.ZERO, 22, MinuteOfHour.ZERO)
        }));

// To create a price extension, at least three table rows are needed.
List<PriceTableRow> priceTableRows = new ArrayList<>();
String currencyCode = "USD";
priceTableRows.add(
    createPriceTableRow(
        "Scrubs",
        "Body Scrub, Salt Scrub",
        "http://www.example.com/scrubs",
        "http://m.example.com/scrubs",
        60000000,
        currencyCode,
        PriceExtensionPriceUnit.PER_HOUR));
priceTableRows.add(
    createPriceTableRow(
        "Hair Cuts",
        "Once a month",
        "http://www.example.com/haircuts",
        "http://m.example.com/haircuts",
        75000000,
        currencyCode,
        PriceExtensionPriceUnit.PER_MONTH));
priceTableRows.add(
    createPriceTableRow(
        "Skin Care Package",
        "Four times a month",
        "http://www.example.com/skincarepackage",
        null,
        250000000,
        currencyCode,
        PriceExtensionPriceUnit.PER_MONTH));
priceFeedItem.setTableRows(priceTableRows.toArray(new PriceTableRow[priceTableRows.size()]));

// Create your campaign extension settings. This associates the sitelinks
// to your campaign.
CustomerExtensionSetting customerExtensionSetting = new CustomerExtensionSetting();
customerExtensionSetting.setExtensionType(FeedType.PRICE);
ExtensionSetting extensionSetting = new ExtensionSetting();
extensionSetting.setExtensions(new ExtensionFeedItem[] {priceFeedItem});
customerExtensionSetting.setExtensionSetting(extensionSetting);

Ссылка на createPriceTableRow определяется, как показано ниже.

/**
 * Creates a new {@link PriceTableRow} with the specified attributes.
 *
 * @param header the header for the row
 * @param description the description for the row
 * @param finalUrl the final URL for the row
 * @param finalMobileUrl the final mobile URL for the row, or null if this field should not be set
 * @param priceInMicros the price for the row, in micros
 * @param currencyCode the currency for the row
 * @param priceUnit the price unit for the row
 * @return a new {@link PriceTableRow}
 */
private static PriceTableRow createPriceTableRow(
    String header,
    String description,
    String finalUrl,
    String finalMobileUrl,
    long priceInMicros,
    String currencyCode,
    PriceExtensionPriceUnit priceUnit) {
  PriceTableRow priceTableRow = new PriceTableRow();
  priceTableRow.setHeader(header);
  priceTableRow.setDescription(description);

  UrlList finalUrls = new UrlList();
  finalUrls.setUrls(new String[] {finalUrl});
  priceTableRow.setFinalUrls(finalUrls);

  if (finalMobileUrl != null) {
    UrlList finalMobileUrls = new UrlList();
    finalMobileUrls.setUrls(new String[] {finalMobileUrl});
    priceTableRow.setFinalMobileUrls(finalMobileUrls);
  }

  MoneyWithCurrency price = new MoneyWithCurrency();
  Money priceMoney = new Money();
  price.setCurrencyCode(currencyCode);
  priceMoney.setMicroAmount(priceInMicros);
  price.setMoney(priceMoney);
  priceTableRow.setPrice(price);
  priceTableRow.setPriceUnit(priceUnit);

  return priceTableRow;
}

Промоакции

В расширениях для промоакций можно рассказывать пользователям о распродажах и скидках. У таких расширений есть много полей для настройки. Вот какие из них заполнять обязательно:

  • promotionTarget – поле с текстом, который появляется в объявлении при показе расширения.
  • percentOff или moneyAmountOff – в этих полях указывается размер скидки.

    • Значение в поле percentOff указывается в микроединицах. Например, если размер скидки составляет 1%, нужно указать 1 000 000. Если вы укажете значение 10000000, скидка будет составлять 10%.
    • В поле moneyAmountOff указывается значение в микроединицах и валюта.
  • finalUrls – поле с адресом целевой страницы, на которую пользователь перейдет, если нажмет на расширение.

Необязательные поля:

  • occasion. Примеры значений: NEW_YEARS или HALLOWEEN.

    • Если вы заполняете поле occasion, не используя службы настройки расширений, проследите за тем, чтобы значения совпадали со значениями перечислений для объекта PromotionFeedItem.
  • discountModifier – позволяет добавить слово "до". Оно требуется, если цены в рамках промоакции меняются.

    • Если вы заполняете поле discountModifier, не используя службы настройки расширений, проследите за тем, чтобы значения совпадали со значениями перечислений для объекта PromotionFeedItem.
  • promotionCode – это поле потребуется заполнить, если для получения скидки нужно ввести код.

  • ordersOverAmount – это поле потребуется заполнить, если для участия в промоакции нужно потратить определенную сумму.

    • Примечание. У объекта PromotionFeedItem может быть только один объект promotionCode или ordersOverAmount.
  • promotionStart и promotionEnd – эти поля потребуется заполнить, если вы хотите, чтобы расширение показывалось только в течение периода промоакции. Значение нужно указывать в формате "дата и время". Единственное допустимое значение для времени – 000000. Пример: если промоакция действует только в июне, в поле promotionStart нужно указать "20170601 000000", а в поле promotionEnd – "20170701 000000".

    • Чтобы очистить эти поля, укажите значение "00000101 000000".

Подробнее об остальных полях можно узнать в документации по объекту PromotionFeedItem.

Вот пример фрагмента кода, который нужен, чтобы создать расширение для промоакции:

PromotionFeedItem promotionFeedItem = new PromotionFeedItem() {
    promotionTarget = "Wool Socks",
    percentOff = 10000000,
    promotionCode = "WinterSocksDeal",
    finalUrls = new string[] { "http://www.example.com/socks" },
};

CampaignExtensionSetting campaignExtensionSetting =
    new CampaignExtensionSetting();
campaignExtensionSetting.campaignId = campaignId;

campaignExtensionSetting.extensionSetting = new ExtensionSetting() {
    extensions = new ExtensionFeedItem[] { promotionFeedItem },
};

Обновление расширений объявлений

Предположим, вы решили назначить новое время скидок в вашем ресторане в субботу: с 17 до 22 часов.

Первый этап – получить список существующих параметров:

// Get the CampaignExtensionSettingService.
CampaignExtensionSettingService campaignExtensionSettingService =
    (CampaignExtensionSettingService) user.GetService(
         AdWordsService.v201705.CampaignExtensionSettingService);

Selector selector = new Selector() {
    fields = new string[] { "CampaignId", "ExtensionType", "Extensions" },
    predicates = new Predicate[] {
        new Predicate() {
            field = "CampaignId",
            @operator = PredicateOperator.EQUALS,
            values = new string[] {campaignId.ToString()}
        },
        new Predicate() {
            field = "ExtensionType",
            @operator = PredicateOperator.EQUALS,
            values = new string[] {"SITELINK"}
        },
    }
};

CampaignExtensionSettingPage page = campaignExtensionSettingService.get(selector);

Затем мы обновляем нужную дополнительную ссылку:

CampaignExtensionSetting campaignExtensionSetting = page.entries[0];
foreach (SitelinkFeedItem siteLink in
     campaignExtensionSetting.extensionSetting.extensions) {
  if (siteLink.sitelinkText == "Happy hours") {
    foreach (FeedItemSchedule schedule in siteLink.scheduling) {
      if (schedule.dayOfWeek == AdWords.v201705.DayOfWeek.SATURDAY) {
         schedule.startHour = 17;
         schedule.startMinute = MinuteOfHour.ZERO;
         schedule.endHour = 22;
         schedule.endMinute = MinuteOfHour.ZERO;
      }
    }
  }
}

Наконец, отправляем на сервер измененный параметр campaignExtensionSetting:

CampaignExtensionSettingOperation operation = new CampaignExtensionSettingOperation() {
  operand = campaignExtensionSetting,
  @operator = Operator.SET,
};

Чтобы новые параметры не переопределяли старые, не забудьте отправить обратно все элементы фида, даже если вы изменяете только один из них.

Удаление расширений объявлений

Чтобы управлять расширениями объявлений, службы настройки расширений используют фиды. Когда вы создаете новую настройку расширения, служба создает элементы в нужном фиде и связывает их с кампанией, группой объявлений или аккаунтом.

Если вы удалите объект ExtensionFeedItem из настройки расширения или настройку целиком, службы удалят связь между элементами фида и объектом. Однако сами элементы фида удалены не будут, поскольку они могут быть связаны с другим объектом.

Есть два способа удалить связь между элементом фида и объектом:

  1. Вы можете удалить всю настройку расширения с помощью оператора REMOVE. В результате будет удалена связь между объектом и всеми элементами фида в настройке.
  2. Вы можете удалить отдельные объекты ExtensionFeedItem настройки расширения. Для этого нужно создать новый набор объектов ExtensionFeedItem и не включать в него те, которые вы хотите удалить.

В обоих случаях элементы фида удалены не будут. Если они не связаны с другими объектами, их следует удалить отдельно. Это освободит место для новых расширений. Элементы фида также можно оставить для повторного использования в других настройках расширений.

Если вы не удалите элементы фида, созданные службами настройки расширений, или не найдете им применение, по мере удаления расширений эти элементы будут накапливаться. В итоге может случиться так, что вы достигнете ограничения на количество элементов фида в аккаунте.

Удаление элементов фида

Чтобы удалить элементы фида, оставшиеся после разрыва связи с объектом, скопируйте элементы feedId и feedItemId из удаляемого расширения и удалите соответствующий им объект FeedItem.

CampaignExtensionSettingOperation operation = new CampaignExtensionSettingOperation() {
  operand = campaignExtensionSetting,
  @operator = Operator.REMOVE,
};

campaignExtensionSettingService.mutate(new CampaignExtensionSettingOperation[] {operation});

List<FeedItemOperation> operations = new List<FeedItemOperation>();
foreach(ExtensionFeedItem extensionFeedItem in
    campaignExtensionSetting.extensionSetting.extensions) {
  FeedItemOperation operation = new FeedItemOperation() {
    @operator = Operator.REMOVE,
    operand = new FeedItem() {
      feedItemId = extensionFeedItem.feedItemId,
      feedId = extensionFeedItem.feedId
    }
  };
  operations.Add(operation);
}

feedItemService.mutate(operations.ToArray());

Команда REMOVE в отношении службы CampaignExtensionSettingService удаляет связь между расширением и кампанией. Команда REMOVE в отношении FeedItemService удаляет элементы фида, освобождая место для новых расширений.

Повторное использование элементов фида

Один элемент фида можно связать с несколькими объектами. Например, если вы хотите, чтобы одни и те же ссылки появлялись в нескольких кампаниях, вы можете связать каждую кампанию с одним и тем же набором элементов фида.

Удалив расширение объявления из объекта, вы можете связать элемент фида с другим объектом. Для этого вам понадобится объект feedItemId из ответа.

Пример: если у вас есть объект feedItemId из удаленной настройки расширения, сохраненный в переменной storedFeedItemId, вы можете повторно использовать его, добавив feedItemId в SitelinkFeedItem:

SitelinkFeedItem link = new SitelinkFeedItem() {
  feedItemId = storedFeedItemId
};

CampaignExtensionSetting campaignExtensionSetting = new CampaignExtensionSetting();
campaignExtensionSetting.extensionSetting = new ExtensionSetting() {
  extensions = new ExtensionFeedItem[] {
    link
  }
};

CampaignExtensionSettingOperation operation = new CampaignExtensionSettingOperation() {
  operand = campaignExtensionSetting,
  @operator = Operator.ADD,
};

CampaignExtensionSettingReturnValue retVal = campaignExtensionSettingService.mutate(
    new CampaignExtensionSettingOperation[] {operation});

Варианты таргетинга для расширений

Помимо таргетинга расширений на уровне клиента, кампании или группы объявлений посредством параметра ExtensionSetting, вы также можете настраивать его для отдельных элементов ExtensionFeedItem с помощью атрибутов campaignTargeting, adGroupTargeting, keywordTargeting или geoTargeting.

При выборе любого из этих вариантов элементы фида расширений будут выбираться для каждого конкретного показа с помощью свойств ExtensionSetting.

Например, вы создаете элемент фида SitelinkFeedItem со следующими параметрами таргетинга:

adGroupTargeting.TargetingAdGroupId = 12345
keywordTargeting.id = 7890

Кроме того, вы задаете для AdGroupExtensionSetting ограничение платформы – MOBILE.

AdWords будет добавлять в объявления этой группы дополнительные ссылки из SitelinkFeedItem, только если атрибуты показа удовлетворяют критериям таргетинга как для объекта AdGroupExtensionSetting, так и для SitelinkFeedItem.

Случай Атрибуты показа Результат
1
  • Идентификатор группы объявлений 12345.
  • Ключевое слово 7890.
  • Обычный компьютер.
SitelinkFeedItem не будет использоваться, поскольку платформа "обычный компьютер" не соответствует таргетингу AdGroupExtensionSetting.
2
  • Идентификатор группы объявлений 12345.
  • Ключевое слово 8910.
  • Мобильное устройство.
SitelinkFeedItem не будет использоваться, поскольку ключевое слово 7890 не соответствует таргетингу SitelinkFeedItem.
3
  • Идентификатор группы объявлений 12345.
  • Ключевое слово 7890.
  • Мобильное устройство.
SitelinkFeedItem будет использоваться, поскольку атрибуты удовлетворяют критериям таргетинга AdGroupExtensionSetting и SitelinkFeedItem.

Отслеживание эффективности расширений

Чтобы отслеживать эффективность расширений, используйте отчеты по меткам-заполнителям и по элементам фида метки-заполнителя. Найти нужное расширение можно с помощью столбца FeedItemId.

Переход на службы настройки расширений

Далее мы расскажем о преимуществах и недостатках служб настройки расширений. Эта информация поможет вам определить, подходят ли они для ваших нужд или вам лучше по-прежнему работать со службами фида. Вы также узнаете, как выполнить переход на новое решение.

Службы настройки расширений предоставляют упрощенный интерфейс для работы с существующими расширениями, основанными на фиде. В частности, они:

  • поддерживают все существующие расширения;
  • предоставляют упрощенный API, который позволяет управлять расширениями в кампаниях и группах объявлений.

Нужно ли мне перейти на службы настройки расширений?

Службы настройки расширений поддерживают все функции расширений, доступные в настоящее время в интерфейсе AdWords. Мы рекомендуем большинству рекламодателей выполнить переход. Это не отнимет у вас много времени, но принесет пользу. Подробнее читайте ниже.

В каких случаях удобнее использовать службы настройки расширений

Если вам просто нужно добавить расширение в кампанию или группу объявлений, указав, на каких устройствах или по какому графику оно должно показываться, рекомендуем воспользоваться службами настройки расширений. Их дополнительное преимущество в том, что, в отличие от служб фидов, они поддерживают схему и данные вашего фида. Таким образом, вам не придется адаптировать его структуру.

В каких случаях лучше продолжить работу со службами фидов

Устаревшие службы фидов подходят рекламодателям, которым требуется использовать одну или несколько из перечисленных ниже возможностей. Эти возможности не поддерживаются службами настройки расширений.

  • Указание адресов.
  • Специальные поля и функции сопоставления.
  • Добавление сразу нескольких фидов. Службы настройки расширений позволяют настраивать только по одному фиду для расширений каждого типа.

Осуществление перехода

Если все ваши фиды созданы в пользовательском интерфейсе AdWords, вы можете сразу же перейти на службы настройки расширений.

Если же у вас есть специальные фиды, созданные в API, вам необходимо выполнить следующие действия:

  1. Получите элементы в специальных фидах.
  2. Решите, какие из них вы хотите оставить.
  3. Удалите фиды CustomerFeed, CampaignFeed и AdGroupFeed, которые используют элементы из специальных фидов.
  4. Создайте параметры CustomerExtensionSetting, CampaignExtensionSetting и AdGroupExtensionSetting, использующие новые элементы фида ExtensionFeedItem.
  5. Удалите элементы фида, которые больше не применяются (необязательно).

Ниже мы расскажем о том, как выполнить обновление расширений на уровне кампании. Процедура для групп объявлений аналогична.

Получение элементов в специальных фидах

Чтобы получить элементы в специальных фидах, сначала нужно определить все такие фиды, созданные в AdWords API, с помощью следующего кода:

private Feed[] GetFeeds(AdWordsUser user) {
  FeedService feedService = (FeedService)user.GetService(
      AdWordsService.v201705.FeedService);
  FeedPage page = feedService.query("SELECT Id, Name, Attributes where " +
      "Origin='USER' and FeedStatus='ENABLED'");
  return page.entries;
}

Далее необходимо получить элементы в этих фидах. В нашем примере рассматривается код для дополнительных ссылок. Для других расширений процедура аналогичная.

private FeedItem[] GetFeedItems(AdWordsUser user, long feedId) {
  FeedItemService feedItemService = (FeedItemService) user.GetService(
      AdWordsService.v201705.FeedItemService);
  FeedItemPage page = feedItemService.query(string.Format("Select FeedItemId, " +
      "AttributeValues, Scheduling where Status = 'ENABLED' and FeedId = '{0}'", feedId));
  return page.entries;
}

Для удобства обработки загрузите значения в локально определенный класс под названием SitelinkFromFeed:

class SiteLinkFromFeed {
  public long FeedId {get;set;}
  public long FeedItemId { get; set; }
  public string Text { get; set; }
  public string Url { get; set; }
  public string[] FinalUrls { get; set; }
  public string[] FinalMobileUrls { get; set; }
  public string TrackingUrlTemplate { get; set; }
  public string Line2 { get; set; }
  public string Line3 { get; set; }
  public FeedItemSchedule[] Scheduling { get; set; }
}

Кроме того, нужно определить несколько констант, которые помогут в синтаксическом анализе FeedMapping. Значения этих тегов приведены здесь.

const int PLACEHOLDER_TYPE_SITELINKS = 1;

class SiteLinkFields {
  public const long TEXT = 1;
  public const long URL = 2;
  public const long LINE2 = 3;
  public const long LINE3 = 4;
  public const long FINAL_URLS = 5;
  public const long FINAL_MOBILE_URLS = 6;
  public const long TRACKING_URL_TEMPLATE = 7;
};

Чтобы преобразовать FeedItem в объект SitelinksFromFeed, вы должны извлечь FeedMapping из фида, а затем соотнести каждый атрибут со свойствами объекта:

private Dictionary<long, SiteLinkFromFeed> GetSiteLinksFromFeed(AdWordsUser user,
    long feedId) {
  Dictionary<long, SiteLinkFromFeed> siteLinks =
      new Dictionary<long, SiteLinkFromFeed>();

  Dictionary<long, long> feedMappings = GetFeedMapping(user, feedId,
      PLACEHOLDER_TYPE_SITELINKS);
  FeedItem[] feedItems = GetFeedItems(user, feedId);

  if (feedItems != null) {
    foreach (FeedItem feedItem in feedItems) {
      SiteLinkFromFeed sitelinkFromFeed = new SiteLinkFromFeed() {
        FeedId = feedItem.feedId,
        FeedItemId = feedItem.feedItemId
      };
      foreach (FeedItemAttributeValue attributeValue in feedItem.attributeValues) {
        switch (attributeValue.feedAttributeId) {
          case SiteLinkFields.TEXT:
            sitelinkFromFeed.Text = attributeValue.stringValue;
            break;

          case SiteLinkFields.URL:
            sitelinkFromFeed.Url = attributeValue.stringValue;
            break;

          case SiteLinkFields.FINAL_URLS:
            sitelinkFromFeed.FinalUrls = attributeValue.stringValues;
            break;

          case SiteLinkFields.FINAL_MOBILE_URLS:
            sitelinkFromFeed.FinalMobileUrls = attributeValue.stringValues;
            break;

          case SiteLinkFields.TRACKING_URL_TEMPLATE:
            sitelinkFromFeed.TrackingUrlTemplate = attributeValue.stringValue;
            break;

          case SiteLinkFields.LINE2:
            sitelinkFromFeed.Line2 = attributeValue.stringValue;
            break;

          case SiteLinkFields.LINE3:
            sitelinkFromFeed.Text = attributeValue.stringValue;
            break;
        }
      }
      sitelinkFromFeed.Scheduling = feedItem.scheduling;
      siteLinks.Add(feedItem.feedItemId, sitelinkFromFeed);
    }
  }
  return siteLinks;
}

private Dictionary<long, long> GetFeedMapping(AdWordsUser user, long feedId,
    long placeHolderType) {
  FeedMappingService feedMappingService = (FeedMappingService) user.GetService(
      AdWordsService.v201705.FeedMappingService);
  FeedMappingPage page = feedMappingService.query(string.Format(
      "SELECT FeedMappingId,AttributeFieldMappings where FeedId='{0}' " +
      "and PlaceholderType={1} and Status='ENABLED'",
      feedId, placeHolderType));

  Dictionary<long, long> attributeMappings = new Dictionary<long, long>();

  if (page.entries != null) {
    foreach (FeedMapping feedMapping in page.entries) {
      foreach (AttributeFieldMapping attributeMapping in
          feedMapping.attributeFieldMappings) {
        attributeMappings.Add(attributeMapping.feedAttributeId,
            attributeMapping.fieldId);
      }
    }
  }
  return attributeMappings;
}

Выбор элементов фида, которые нужно сохранить

Определите список элементов фида, связанных с кампанией. Для этого следует извлечь ее CampaignFeed и выполнить синтаксический анализ функции сопоставления matchingFunction. Поскольку такие функции позволяют написать дерево выражения общего назначения, создать синтаксический анализатор – сложная задача, которую мы не будем рассматривать в этом руководстве. Вместо этого мы выберем самый простой случай, когда несколько элементов одного фида были связаны с кампанией. Функция сопоставления будет иметь следующий вид:

FEEDITEM_ID IN (FEEDITEM_ID_1, FEEDITEM_ID_2…)

private CampaignFeed[] GetCampaignFeeds(AdWordsUser user, Feed feed, int placeholderType) {
  CampaignFeedService campaignFeedService = (CampaignFeedService) user.GetService(
      AdWordsService.v201705.CampaignFeedService);

  CampaignFeedPage page = campaignFeedService.query(string.Format(
      "SELECT CampaignId, MatchingFunction, PlaceholderTypes where Status='ENABLED' " +
      "and FeedId = '{0}' and PlaceholderTypes CONTAINS_ANY[{1}]", feed.id, placeholderType));
  return page.entries;
}

private List<long> GetFeedItemsForCampaign(CampaignFeed campaignFeed) {
  List<long> feedItems = new List<long>();
  if (campaignFeed.matchingFunction.lhsOperand.Length == 1 &&
      campaignFeed.matchingFunction.lhsOperand[0] is RequestContextOperand &&
      (campaignFeed.matchingFunction.lhsOperand[0] as
           RequestContextOperand).contextType ==
           RequestContextOperandContextType.FEED_ITEM_ID &&
      campaignFeed.matchingFunction.@operator == FunctionOperator.IN) {
    foreach (ConstantOperand argument in campaignFeed.matchingFunction.rhsOperand) {
      feedItems.Add(argument.longValue);
    }
  }
  return feedItems;
}

Удаление существующего CampaignFeed

Перед тем как задать в кампании параметры расширения объявлений, необходимо удалить в ней существующий CampaignFeed, созданный вручную. Это связано с тем, что AdWords поддерживает только один CampaignFeed для каждого типа расширения на кампанию. Когда вы удалите CampaignFeed, созданный вручную, и определите настройки расширений, служба CampaignExtensionSettingService сможет создать новый, управляемый системой CampaignFeed.

private CampaignFeed DeleteCampaignFeed(AdWordsUser user, CampaignFeed campaignFeed) {
  CampaignFeedService campaignFeedService = (CampaignFeedService) user.GetService(
      AdWordsService.v201705.CampaignFeedService);

  CampaignFeedOperation operation = new CampaignFeedOperation() {
    operand = campaignFeed,
    @operator = Operator.REMOVE,
  };

  return campaignFeedService.mutate(
       new CampaignFeedOperation[] { operation }).value[0];
}

Определение настроек расширений

Теперь можно задать параметры расширения, соответствующие прежним элементам фида:

private static void CreateExtensionSetting(AdWordsUser user,
    Dictionary<long, SiteLinkFromFeed> feedItems, CampaignFeed campaignFeed,
    List<long> feedItemIds) {
  CampaignExtensionSetting extensionSetting = new CampaignExtensionSetting() {
    campaignId = campaignFeed.campaignId,
    extensionType = FeedType.SITELINK,
    extensionSetting = new ExtensionSetting() {
    }
  };

  List<ExtensionFeedItem> extensionFeedItems = new List<ExtensionFeedItem>();

  foreach (long feedItemId in feedItemIds) {
    SiteLinkFromFeed feedItem = feedItems[feedItemId];
    SitelinkFeedItem newFeedItem = new SitelinkFeedItem() {
      sitelinkText = feedItem.Text,
      sitelinkUrl = feedItem.Url,
      sitelinkFinalUrls = feedItem.FinalUrls,
      sitelinkFinalMobileUrls = feedItem.FinalMobileUrls,
      sitelinkTrackingUrlTemplate = feedItem.TrackingUrlTemplate,
      sitelinkLine2 = feedItem.Line2,
      sitelinkLine3 = feedItem.Line3,
      scheduling = feedItem.Scheduling
    };
    extensionFeedItems.Add(newFeedItem);
  }
  extensionSetting.extensionSetting.extensions = extensionFeedItems.ToArray();

  CampaignExtensionSettingService campaignExtensionSettingService =
      (CampaignExtensionSettingService) user.GetService(
          AdWordsService.v201705.CampaignExtensionSettingService);
  CampaignExtensionSettingOperation operation =
      new CampaignExtensionSettingOperation() {
        operand = extensionSetting,
        @operator = Operator.ADD
      };

  campaignExtensionSettingService.mutate(
      new CampaignExtensionSettingOperation[] {operation});
  return;
}

Имейте в виду, что этот метод не предполагает дедупликацию настроек расширений. Вы можете улучшить этот код, чтобы исключить повторяющиеся элементы.

Удаление старых FeedItem

Осталось удалить старые FeedItem:

private void DeleteOldFeedItems(AdWordsUser user, List<long> feedItemIds,
    long feedId) {
  if (feedItemIds.Count == 0) {
    return;
  }
  List<FeedItemOperation> operations = new List<FeedItemOperation>();
  foreach (long feedItemId in feedItemIds) {
    FeedItemOperation operation = new FeedItemOperation() {
      @operator = Operator.REMOVE,
      operand = new FeedItem() {
        feedItemId = feedItemId,
        feedId = feedId
      }
    };
    operations.Add(operation);
  }
  FeedItemService feedItemService = (FeedItemService) user.GetService(
      AdWordsService.v201705.FeedItemService);
  feedItemService.mutate(operations.ToArray());
  return;
}

Это необязательный этап, но мы рекомендуем удалить неиспользуемые элементы фидов, поскольку допустимое количество активных элементов ограничено.

Сборка

Полный цикл этой программы соответствует последовательности этапов, рассмотренных выше:

Feed[] feeds = GetFeeds(user);
foreach (Feed feed in feeds) {
  Dictionary<long, SiteLinkFromFeed> feedItems = GetSiteLinksFromFeed(user, feed.id);
  CampaignFeed[] campaignFeeds = GetCampaignFeeds(user, feed,
      PLACEHOLDER_TYPE_SITELINKS);

  if (campaignFeeds != null) {
    HashSet<long> allFeedItemsToDelete = new HashSet<long>();
    foreach (CampaignFeed campaignFeed in campaignFeeds) {
      // Optional: Replace with custom logic that upgrades only selected
      // feed items.
      List<long> feedItemIds = GetFeedItemsForCampaign(campaignFeed);
      DeleteCampaignFeed(user, campaignFeed);
      CreateExtensionSetting(user, feedItems, campaignFeed, feedItemIds);
      allFeedItemsToDelete.UnionWith(feedItemIds);
    }
    DeleteOldFeedItems(user, new List<long>(allFeedItemsToDelete), feed.id);
  }
}

Примеры кода

Ознакомьтесь с примерами кода в наших клиентских библиотеках, чтобы узнать подробнее о службах настройки расширений.

Оставить отзыв о...

Текущей странице
Нужна помощь? Обратитесь в службу поддержки.