Add Hotel Ad

Java

This example is not yet available in Java; you can take a look at the other languages.
    

C#

This example is not yet available in C#; you can take a look at the other languages.
    

PHP

<?php

/**
 * Copyright 2018 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

namespace Google\Ads\GoogleAds\Examples\Travel;

require __DIR__ . '/../../vendor/autoload.php';

use GetOpt\GetOpt;
use Google\Ads\GoogleAds\Examples\Utils\ArgumentNames;
use Google\Ads\GoogleAds\Examples\Utils\ArgumentParser;
use Google\Ads\GoogleAds\Examples\Utils\Helper;
use Google\Ads\GoogleAds\Lib\V13\GoogleAdsClient;
use Google\Ads\GoogleAds\Lib\V13\GoogleAdsClientBuilder;
use Google\Ads\GoogleAds\Lib\V13\GoogleAdsException;
use Google\Ads\GoogleAds\Lib\OAuth2TokenBuilder;
use Google\Ads\GoogleAds\V13\Common\HotelAdInfo;
use Google\Ads\GoogleAds\V13\Common\PercentCpc;
use Google\Ads\GoogleAds\V13\Enums\AdGroupAdStatusEnum\AdGroupAdStatus;
use Google\Ads\GoogleAds\V13\Enums\AdGroupStatusEnum\AdGroupStatus;
use Google\Ads\GoogleAds\V13\Enums\AdGroupTypeEnum\AdGroupType;
use Google\Ads\GoogleAds\V13\Enums\AdvertisingChannelTypeEnum\AdvertisingChannelType;
use Google\Ads\GoogleAds\V13\Enums\BudgetDeliveryMethodEnum\BudgetDeliveryMethod;
use Google\Ads\GoogleAds\V13\Enums\CampaignStatusEnum\CampaignStatus;
use Google\Ads\GoogleAds\V13\Errors\GoogleAdsError;
use Google\Ads\GoogleAds\V13\Resources\Ad;
use Google\Ads\GoogleAds\V13\Resources\AdGroup;
use Google\Ads\GoogleAds\V13\Resources\AdGroupAd;
use Google\Ads\GoogleAds\V13\Resources\Campaign;
use Google\Ads\GoogleAds\V13\Resources\Campaign\HotelSettingInfo;
use Google\Ads\GoogleAds\V13\Resources\Campaign\NetworkSettings;
use Google\Ads\GoogleAds\V13\Resources\CampaignBudget;
use Google\Ads\GoogleAds\V13\Services\AdGroupAdOperation;
use Google\Ads\GoogleAds\V13\Services\AdGroupOperation;
use Google\Ads\GoogleAds\V13\Services\CampaignBudgetOperation;
use Google\Ads\GoogleAds\V13\Services\CampaignOperation;
use Google\ApiCore\ApiException;

/**
 * This example creates a hotel campaign, a hotel ad group and hotel ad group ad.
 *
 * <p> Prerequisite: You need to have an access to the Hotel Ads Center, which can be granted during
 * integration with Google Hotels. The integration instructions can be found at:
 * https://support.google.com/hotelprices/answer/6101897.
 */
class AddHotelAd
{
    private const CUSTOMER_ID = 'INSERT_CUSTOMER_ID_HERE';
    // Specify your Hotels account ID below. You can see how to find the account ID in the Hotel
    // Ads Center at: https://support.google.com/hotelprices/answer/6399770.
    // This ID is the same account ID that you use in API requests to the Travel Partner APIs
    // (https://developers.google.com/hotels/hotel-ads/api-reference/).
    private const HOTEL_CENTER_ACCOUNT_ID = 'INSERT_HOTEL_CENTER_ACCOUNT_ID_HERE';
    // Specify maximum bid limit that can be set when creating a campaign using the Percent CPC
    // bidding strategy.
    private const CPC_BID_CEILING_MICRO_AMOUNT = 20000000;

    public static function main()
    {
        // Either pass the required parameters for this example on the command line, or insert them
        // into the constants above.
        $options = (new ArgumentParser())->parseCommandArguments([
            ArgumentNames::CUSTOMER_ID => GetOpt::REQUIRED_ARGUMENT,
            ArgumentNames::HOTEL_CENTER_ACCOUNT_ID => GetOpt::REQUIRED_ARGUMENT,
            ArgumentNames::CPC_BID_CEILING_MICRO_AMOUNT => GetOpt::OPTIONAL_ARGUMENT
        ]);

        // Generate a refreshable OAuth2 credential for authentication.
        $oAuth2Credential = (new OAuth2TokenBuilder())->fromFile()->build();

        // Construct a Google Ads client configured from a properties file and the
        // OAuth2 credentials above.
        $googleAdsClient = (new GoogleAdsClientBuilder())->fromFile()
            ->withOAuth2Credential($oAuth2Credential)
            ->build();

        try {
            self::runExample(
                $googleAdsClient,
                $options[ArgumentNames::CUSTOMER_ID] ?: self::CUSTOMER_ID,
                $options[ArgumentNames::HOTEL_CENTER_ACCOUNT_ID] ?: self::HOTEL_CENTER_ACCOUNT_ID,
                $options[ArgumentNames::CPC_BID_CEILING_MICRO_AMOUNT]
                    ?: self::CPC_BID_CEILING_MICRO_AMOUNT
            );
        } catch (GoogleAdsException $googleAdsException) {
            printf(
                "Request with ID '%s' has failed.%sGoogle Ads failure details:%s",
                $googleAdsException->getRequestId(),
                PHP_EOL,
                PHP_EOL
            );
            foreach ($googleAdsException->getGoogleAdsFailure()->getErrors() as $error) {
                /** @var GoogleAdsError $error */
                printf(
                    "\t%s: %s%s",
                    $error->getErrorCode()->getErrorCode(),
                    $error->getMessage(),
                    PHP_EOL
                );
            }
            exit(1);
        } catch (ApiException $apiException) {
            printf(
                "ApiException was thrown with message '%s'.%s",
                $apiException->getMessage(),
                PHP_EOL
            );
            exit(1);
        }
    }

    /**
     * Runs the example.
     *
     * @param GoogleAdsClient $googleAdsClient the Google Ads API client
     * @param int $customerId the customer ID
     * @param int $hotelCenterAccountId the Hotel Center account ID
     * @param int $cpcBidCeilingMicroAmount the CPC bid ceiling micro amount
     */
    public static function runExample(
        GoogleAdsClient $googleAdsClient,
        int $customerId,
        int $hotelCenterAccountId,
        int $cpcBidCeilingMicroAmount
    ) {
        // Creates a budget to be used by the campaign that will be created below.
        $budgetResourceName = self::addCampaignBudget($googleAdsClient, $customerId);
        // Creates a hotel campaign.
        $campaignResourceName = self::addHotelCampaign(
            $googleAdsClient,
            $customerId,
            $budgetResourceName,
            $hotelCenterAccountId,
            $cpcBidCeilingMicroAmount
        );
        // Creates a hotel ad group.
        $adGroupResourceName =
            self::addHotelAdGroup($googleAdsClient, $customerId, $campaignResourceName);
        // Creates a hotel ad group ad.
        self::addHotelAdGroupAd($googleAdsClient, $customerId, $adGroupResourceName);
    }

    /**
     * Creates a new campaign budget in the specified client account.
     *
     * @param GoogleAdsClient $googleAdsClient the Google Ads API client
     * @param int $customerId the customer ID
     * @return string the resource name of the newly created budget
     */
    private static function addCampaignBudget(GoogleAdsClient $googleAdsClient, int $customerId)
    {
        // Creates a campaign budget.
        $budget = new CampaignBudget([
            'name' => 'Interplanetary Cruise Budget #' . Helper::getPrintableDatetime(),
            'delivery_method' => BudgetDeliveryMethod::STANDARD,
            // Sets the amount of budget.
            'amount_micros' => 50000000,
            // Makes the budget explicitly shared.
            'explicitly_shared' => true
        ]);

        // Creates a campaign budget operation.
        $campaignBudgetOperation = new CampaignBudgetOperation();
        $campaignBudgetOperation->setCreate($budget);

        // Issues a mutate request.
        $campaignBudgetServiceClient = $googleAdsClient->getCampaignBudgetServiceClient();
        $response = $campaignBudgetServiceClient->mutateCampaignBudgets(
            $customerId,
            [$campaignBudgetOperation]
        );

        /** @var CampaignBudget $addedBudget */
        $addedBudget = $response->getResults()[0];
        printf(
            "Added a budget with resource name '%s'.%s",
            $addedBudget->getResourceName(),
            PHP_EOL
        );

        return $addedBudget->getResourceName();
    }

    /**
     * Creates a new hotel campaign in the specified client account.
     *
     * @param GoogleAdsClient $googleAdsClient the Google Ads API client
     * @param int $customerId the customer ID
     * @param string $budgetResourceName the resource name of budget for a new campaign
     * @param int $hotelCenterAccountId the Hotel Center account ID
     * @param int $cpcBidCeilingMicroAmount the CPC bid ceiling micro amount
     * @return string the resource name of the newly created campaign
     */
    private static function addHotelCampaign(
        GoogleAdsClient $googleAdsClient,
        int $customerId,
        string $budgetResourceName,
        int $hotelCenterAccountId,
        int $cpcBidCeilingMicroAmount
    ) {
        // Creates a campaign.
        $campaign = new Campaign([
            'name' => 'Interplanetary Cruise Campaign #' . Helper::getPrintableDatetime(),
            // Configures settings related to hotel campaigns including advertising channel type
            // and hotel setting info.
            'advertising_channel_type' => AdvertisingChannelType::HOTEL,
            'hotel_setting' => new HotelSettingInfo(['hotel_center_id' => $hotelCenterAccountId]),
            // Recommendation: Set the campaign to PAUSED when creating it to prevent
            // the ads from immediately serving. Set to ENABLED once you've added
            // targeting and the ads are ready to serve.
            'status' => CampaignStatus::PAUSED,
            // Sets the bidding strategy to PercentCpc. Only Manual CPC and Percent CPC can be used
            // for hotel campaigns.
            'percent_cpc' => new PercentCpc([
                'cpc_bid_ceiling_micros' => $cpcBidCeilingMicroAmount
            ]),
            // Sets the budget.
            'campaign_budget' => $budgetResourceName,
            // Configures the campaign network options. Only Google Search is allowed for
            // hotel campaigns.
            'network_settings' => new NetworkSettings([
                'target_google_search' => true,
            ]),
        ]);

        // Creates a campaign operation.
        $campaignOperation = new CampaignOperation();
        $campaignOperation->setCreate($campaign);

        // Issues a mutate request to add campaigns.
        $campaignServiceClient = $googleAdsClient->getCampaignServiceClient();
        $response = $campaignServiceClient->mutateCampaigns($customerId, [$campaignOperation]);

        /** @var Campaign $addedCampaign */
        $addedCampaign = $response->getResults()[0];
        printf(
            "Added a hotel campaign with resource name '%s'.%s",
            $addedCampaign->getResourceName(),
            PHP_EOL
        );

        return $addedCampaign->getResourceName();
    }

    /**
     * Creates a new hotel ad group in the specified campaign.
     *
     * @param GoogleAdsClient $googleAdsClient the Google Ads API client
     * @param int $customerId the customer ID
     * @param string $campaignResourceName the resource name of campaign that a new ad group will
     *     belong to
     * @return string the resource name of the newly created ad group
     */
    private static function addHotelAdGroup(
        GoogleAdsClient $googleAdsClient,
        int $customerId,
        string $campaignResourceName
    ) {
        // Creates an ad group.
        $adGroup = new AdGroup([
            'name' => 'Earth to Mars Cruise #' . Helper::getPrintableDatetime(),
            // Sets the campaign.
            'campaign' => $campaignResourceName,
            // Sets the ad group type to HOTEL_ADS.
            // This cannot be set to other types.
            'type' => AdGroupType::HOTEL_ADS,
            'cpc_bid_micros' => 10000000,
            'status' => AdGroupStatus::ENABLED,
        ]);

        // Creates an ad group operation.
        $adGroupOperation = new AdGroupOperation();
        $adGroupOperation->setCreate($adGroup);

        // Issues a mutate request to add an ad group.
        $adGroupServiceClient = $googleAdsClient->getAdGroupServiceClient();
        $response = $adGroupServiceClient->mutateAdGroups($customerId, [$adGroupOperation]);

        /** @var AdGroup $addedAdGroup */
        $addedAdGroup = $response->getResults()[0];
        printf(
            "Added a hotel ad group with resource name '%s'.%s",
            $addedAdGroup->getResourceName(),
            PHP_EOL
        );

        return $addedAdGroup->getResourceName();
    }

    /**
     * Creates a new hotel ad group ad in the specified ad group.
     *
     * @param GoogleAdsClient $googleAdsClient the Google Ads API client
     * @param int $customerId the customer ID
     * @param string $adGroupResourceName the resource name of ad group that a new ad group ad will
     *     belong to
     */
    private static function addHotelAdGroupAd(
        GoogleAdsClient $googleAdsClient,
        int $customerId,
        string $adGroupResourceName
    ) {
        // Creates a new hotel ad.
        $ad = new Ad([
            'hotel_ad' => new HotelAdInfo(),
        ]);

        // Creates a new ad group ad and sets the hotel ad to it.
        $adGroupAd = new AdGroupAd([
            'ad' => $ad,
            // Set the ad group ad to enabled.  Setting this to paused will cause an error
            // for hotel campaigns.  For hotels pausing should happen at either the ad group or
            // campaign level.
            'status' => AdGroupAdStatus::ENABLED,
            // Sets the ad group.
            'ad_group' => $adGroupResourceName
        ]);

        // Creates an ad group ad operation.
        $adGroupAdOperation = new AdGroupAdOperation();
        $adGroupAdOperation->setCreate($adGroupAd);

        // Issues a mutate request to add an ad group ad.
        $adGroupAdServiceClient = $googleAdsClient->getAdGroupAdServiceClient();
        $response = $adGroupAdServiceClient->mutateAdGroupAds($customerId, [$adGroupAdOperation]);

        /** @var AdGroupAd $addedAdGroupAd */
        $addedAdGroupAd = $response->getResults()[0];
        printf(
            "Added a hotel ad group ad with resource name '%s'.%s",
            $addedAdGroupAd->getResourceName(),
            PHP_EOL
        );
    }
}

AddHotelAd::main();

      

Python

#!/usr/bin/env python
# Copyright 2018 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""This example adds a hotel campaign, ad group, and ad group ad.

Prerequisite: You need to have access to the Hotel Ads Center, which can be
granted during integration with Google Hotels. The integration instructions can
be found at:
https://support.google.com/hotelprices/answer/6101897.
"""


import argparse
import sys
import uuid

from google.ads.googleads.client import GoogleAdsClient
from google.ads.googleads.errors import GoogleAdsException


def main(
    client, customer_id, hotel_center_account_id, cpc_bid_ceiling_micro_amount
):
    budget_resource_name = add_budget(client, customer_id)

    campaign_resource_name = add_hotel_campaign(
        client,
        customer_id,
        budget_resource_name,
        hotel_center_account_id,
        cpc_bid_ceiling_micro_amount,
    )

    ad_group_resource_name = add_hotel_ad_group(
        client, customer_id, campaign_resource_name
    )

    add_hotel_ad(client, customer_id, ad_group_resource_name)


def add_budget(client, customer_id):
    campaign_budget_service = client.get_service("CampaignBudgetService")

    # Create a budget, which can be shared by multiple campaigns.
    campaign_budget_operation = client.get_type("CampaignBudgetOperation")
    campaign_budget = campaign_budget_operation.create
    campaign_budget.name = f"Interplanetary Budget {uuid.uuid4()}"
    campaign_budget.delivery_method = (
        client.enums.BudgetDeliveryMethodEnum.STANDARD
    )
    campaign_budget.amount_micros = 500000

    # Add budget.
    campaign_budget_response = campaign_budget_service.mutate_campaign_budgets(
        customer_id=customer_id, operations=[campaign_budget_operation]
    )

    budget_resource_name = campaign_budget_response.results[0].resource_name

    print(f"Created budget with resource name '{budget_resource_name}'.")

    return budget_resource_name


def add_hotel_ad(client, customer_id, ad_group_resource_name):
    ad_group_ad_service = client.get_service("AdGroupAdService")

    # Creates a new ad group ad and sets the hotel ad to it.
    ad_group_ad_operation = client.get_type("AdGroupAdOperation")
    ad_group_ad = ad_group_ad_operation.create
    ad_group_ad.ad_group = ad_group_resource_name
    # Set the ad group ad to enabled.  Setting this to paused will cause an error
    # for hotel campaigns.  For hotels pausing should happen at either the ad group or
    # campaign level.
    ad_group_ad.status = client.enums.AdGroupAdStatusEnum.ENABLED
    client.copy_from(ad_group_ad.ad.hotel_ad, client.get_type("HotelAdInfo"))

    # Add the ad group ad.
    ad_group_ad_response = ad_group_ad_service.mutate_ad_group_ads(
        customer_id=customer_id, operations=[ad_group_ad_operation]
    )

    ad_group_ad_resource_name = ad_group_ad_response.results[0].resource_name

    print(f"Created hotel ad with resource name '{ad_group_ad_resource_name}'.")

    return ad_group_resource_name


def add_hotel_ad_group(client, customer_id, campaign_resource_name):
    ad_group_service = client.get_service("AdGroupService")

    # Create ad group.
    ad_group_operation = client.get_type("AdGroupOperation")
    ad_group = ad_group_operation.create
    ad_group.name = f"Earth to Mars cruise {uuid.uuid4()}"
    ad_group.status = client.enums.AdGroupStatusEnum.ENABLED
    ad_group.campaign = campaign_resource_name
    # Sets the ad group type to HOTEL_ADS. This cannot be set to other types.
    ad_group.type_ = client.enums.AdGroupTypeEnum.HOTEL_ADS
    ad_group.cpc_bid_micros = 10000000

    # Add the ad group.
    ad_group_response = ad_group_service.mutate_ad_groups(
        customer_id=customer_id, operations=[ad_group_operation]
    )

    ad_group_resource_name = ad_group_response.results[0].resource_name

    print(
        "Added a hotel ad group with resource name '{ad_group_resource_name}'."
    )

    return ad_group_resource_name


def add_hotel_campaign(
    client,
    customer_id,
    budget_resource_name,
    hotel_center_account_id,
    cpc_bid_ceiling_micro_amount,
):
    campaign_service = client.get_service("CampaignService")

    # Create campaign.
    campaign_operation = client.get_type("CampaignOperation")
    campaign = campaign_operation.create
    campaign.name = f"Interplanetary Cruise Campaign {uuid.uuid4()}"

    # Configures settings related to hotel campaigns including advertising
    # channel type and hotel setting info.
    campaign.advertising_channel_type = (
        client.enums.AdvertisingChannelTypeEnum.HOTEL
    )
    campaign.hotel_setting.hotel_center_id = hotel_center_account_id

    # Recommendation: Set the campaign to PAUSED when creating it to prevent the
    # ads from immediately serving. Set to ENABLED once you've added targeting
    # and the ads are ready to serve.
    campaign.status = client.enums.CampaignStatusEnum.PAUSED

    # Set the bidding strategy to PercentCpc. Only Manual CPC and Percent CPC
    # can be used for hotel campaigns.
    campaign.percent_cpc.cpc_bid_ceiling_micros = cpc_bid_ceiling_micro_amount

    # Sets the budget.
    campaign.campaign_budget = budget_resource_name

    # Set the campaign network options. Only Google Search is allowed for hotel
    # campaigns.
    campaign.network_settings.target_google_search = True

    # Add the campaign.
    campaign_response = campaign_service.mutate_campaigns(
        customer_id=customer_id, operations=[campaign_operation]
    )

    campaign_resource_name = campaign_response.results[0].resource_name

    print(
        "Added a hotel campaign with resource name '{campaign_resource_name}'."
    )

    return campaign_resource_name


if __name__ == "__main__":
    # GoogleAdsClient will read the google-ads.yaml configuration file in the
    # home directory if none is specified.
    googleads_client = GoogleAdsClient.load_from_storage(version="v13")

    parser = argparse.ArgumentParser(
        description=(
            "Adds an expanded text ad to the specified ad group ID, "
            "for the given customer ID."
        )
    )
    # The following argument(s) should be provided to run the example.
    parser.add_argument(
        "-c",
        "--customer_id",
        type=str,
        required=True,
        help="The Google Ads customer ID.",
    )
    parser.add_argument(
        "-b",
        "--cpc_bid_ceiling_micro_amount",
        type=int,
        required=True,
        help=("The cpc bid ceiling micro amount for the hotel campaign."),
    )
    parser.add_argument(
        "-a",
        "--hotel_center_account_id",
        type=int,
        required=True,
        help="The hotel center account ID.",
    )
    args = parser.parse_args()

    try:
        main(
            googleads_client,
            args.customer_id,
            args.hotel_center_account_id,
            args.cpc_bid_ceiling_micro_amount,
        )
    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)

      

Ruby

This example is not yet available in Ruby; you can take a look at the other languages.
    

Perl

#!/usr/bin/perl -w
#
# Copyright 2019, Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# This example creates a hotel campaign, a hotel ad group and hotel ad
# group ad.
#
# Prerequisite: You need to have access to the Hotel Ads Center, which can be
# granted during integration with Google Hotels. The integration instructions
# can be found at:
# https://support.google.com/hotelprices/answer/6101897

use strict;
use warnings;
use utf8;

use FindBin qw($Bin);
use lib "$Bin/../../lib";
use Google::Ads::GoogleAds::Client;
use Google::Ads::GoogleAds::Utils::GoogleAdsHelper;
use Google::Ads::GoogleAds::V13::Resources::CampaignBudget;
use Google::Ads::GoogleAds::V13::Resources::Campaign;
use Google::Ads::GoogleAds::V13::Resources::HotelSettingInfo;
use Google::Ads::GoogleAds::V13::Resources::NetworkSettings;
use Google::Ads::GoogleAds::V13::Resources::AdGroup;
use Google::Ads::GoogleAds::V13::Resources::AdGroupAd;
use Google::Ads::GoogleAds::V13::Resources::Ad;
use Google::Ads::GoogleAds::V13::Common::PercentCpc;
use Google::Ads::GoogleAds::V13::Common::HotelAdInfo;
use Google::Ads::GoogleAds::V13::Enums::BudgetDeliveryMethodEnum   qw(STANDARD);
use Google::Ads::GoogleAds::V13::Enums::AdvertisingChannelTypeEnum qw(HOTEL);
use Google::Ads::GoogleAds::V13::Enums::AdGroupTypeEnum qw(HOTEL_ADS);
use Google::Ads::GoogleAds::V13::Enums::CampaignStatusEnum;
use Google::Ads::GoogleAds::V13::Enums::AdGroupStatusEnum;
use Google::Ads::GoogleAds::V13::Enums::AdGroupAdStatusEnum;
use
  Google::Ads::GoogleAds::V13::Services::CampaignBudgetService::CampaignBudgetOperation;
use Google::Ads::GoogleAds::V13::Services::CampaignService::CampaignOperation;
use Google::Ads::GoogleAds::V13::Services::AdGroupService::AdGroupOperation;
use Google::Ads::GoogleAds::V13::Services::AdGroupAdService::AdGroupAdOperation;

use Getopt::Long qw(:config auto_help);
use Pod::Usage;
use Cwd          qw(abs_path);
use Data::Uniqid qw(uniqid);

# The following parameter(s) should be provided to run the example. You can
# either specify these by changing the INSERT_XXX_ID_HERE values below, or on
# the command line.
#
# Parameters passed on the command line will override any parameters set in
# code.
#
# Running the example with -h will print the command line usage.
my $customer_id = "INSERT_CUSTOMER_ID_HERE";
# Specify your Hotels Ads Center account ID below. You can see how to find the
# account ID in the Hotel Ads Center at:
# https://support.google.com/hotelprices/answer/6399770.
# This ID is the same account ID that you use in API requests to the Travel
# Partner APIs at:
# https://developers.google.com/hotels/hotel-ads/api-reference/.
my $hotel_center_account_id = "INSERT_HOTEL_CENTER_ACCOUNT_ID_HERE";
# Specify maximum bid limit that can be set when creating a campaign using the
# Percent CPC bidding strategy.
my $cpc_bid_ceiling_micro_amount = 20000000;

sub add_hotel_ad {
  my ($api_client, $customer_id, $hotel_center_account_id,
    $cpc_bid_ceiling_micro_amount)
    = @_;

  # Create a budget to be used by the campaign that will be created below.
  my $budget_resource_name = add_campaign_budget($api_client, $customer_id);

  # Create a hotel campaign.
  my $campaign_resource_name =
    add_hotel_campaign($api_client, $customer_id,
    $budget_resource_name, $hotel_center_account_id,
    $cpc_bid_ceiling_micro_amount);

  # Create a hotel ad group.
  my $ad_group_resource_name =
    add_hotel_ad_group($api_client, $customer_id, $campaign_resource_name);

  # Create a hotel ad group ad.
  add_hotel_ad_group_ad($api_client, $customer_id, $ad_group_resource_name);

  return 1;
}

# Creates a new campaign budget in the specified client account.
sub add_campaign_budget {
  my ($api_client, $customer_id) = @_;

  # Create a campaign budget.
  my $campaign_budget =
    Google::Ads::GoogleAds::V13::Resources::CampaignBudget->new({
      name           => "Interplanetary Cruise Budget #" . uniqid(),
      deliveryMethod => STANDARD,
      # Set the amount of budget.
      amountMicros => 5000000,
      # Make the budget explicitly shared.
      explicitlyShared => "true"
    });

  # Create a campaign budget operation.
  my $campaign_budget_operation =
    Google::Ads::GoogleAds::V13::Services::CampaignBudgetService::CampaignBudgetOperation
    ->new({create => $campaign_budget});

  # Add the campaign budget.
  my $campaign_budget_resource_name =
    $api_client->CampaignBudgetService()->mutate({
      customerId => $customer_id,
      operations => [$campaign_budget_operation]})->{results}[0]{resourceName};

  printf "Added a budget with resource name: '%s'.\n",
    $campaign_budget_resource_name;

  return $campaign_budget_resource_name;
}

# Creates a new hotel campaign in the specified client account.
sub add_hotel_campaign {
  my ($api_client, $customer_id, $budget_resource_name,
    $hotel_center_account_id, $cpc_bid_ceiling_micro_amount)
    = @_;

  # Create a hotel campaign.
  my $campaign = Google::Ads::GoogleAds::V13::Resources::Campaign->new({
      name => "Interplanetary Cruise Campaign #" . uniqid(),
      # Configure settings related to hotel campaigns including advertising
      # channel type and hotel setting info.
      advertisingChannelType => HOTEL,
      hotelSetting           =>
        Google::Ads::GoogleAds::V13::Resources::HotelSettingInfo->new({
          hotelCenterId => $hotel_center_account_id
        }
        ),
      # Recommendation: Set the campaign to PAUSED when creating it to prevent
      # the ads from immediately serving. Set to ENABLED once you've added
      # targeting and the ads are ready to serve.
      status => Google::Ads::GoogleAds::V13::Enums::CampaignStatusEnum::PAUSED,
      # Set the bidding strategy to PercentCpc. Only Manual CPC and Percent CPC
      # can be used for hotel campaigns.
      percentCpc => Google::Ads::GoogleAds::V13::Common::PercentCpc->new(
        {cpcBidCeilingMicros => $cpc_bid_ceiling_micro_amount}
      ),
      # Set the budget.
      campaignBudget => $budget_resource_name,
      # Configure the campaign network options. Only Google Search is allowed for
      # hotel campaigns.
      networkSettings =>
        Google::Ads::GoogleAds::V13::Resources::NetworkSettings->new({
          targetGoogleSearch => "true"
        })});

  # Create a campaign operation.
  my $campaign_operation =
    Google::Ads::GoogleAds::V13::Services::CampaignService::CampaignOperation->
    new({create => $campaign});

  # Add the campaign.
  my $campaign_resource_name = $api_client->CampaignService()->mutate({
      customerId => $customer_id,
      operations => [$campaign_operation]})->{results}[0]{resourceName};

  printf "Added a hotel campaign with resource name: '%s'.\n",
    $campaign_resource_name;

  return $campaign_resource_name;
}

# Creates a new hotel ad group in the specified campaign.
sub add_hotel_ad_group {
  my ($api_client, $customer_id, $campaign_resource_name) = @_;

  # Create an ad group.
  my $ad_group = Google::Ads::GoogleAds::V13::Resources::AdGroup->new({
    name => "Earth to Mars Cruise #" . uniqid(),
    # Set the campaign.
    campaign => $campaign_resource_name,
    # Set the ad group type to HOTEL_ADS.
    # This cannot be set to other types.
    type         => HOTEL_ADS,
    cpcBidMicros => 1000000,
    status => Google::Ads::GoogleAds::V13::Enums::AdGroupStatusEnum::ENABLED
  });

  # Create an ad group operation.
  my $ad_group_operation =
    Google::Ads::GoogleAds::V13::Services::AdGroupService::AdGroupOperation->
    new({create => $ad_group});

  # Add the ad group.
  my $ad_group_resource_name = $api_client->AdGroupService()->mutate({
      customerId => $customer_id,
      operations => [$ad_group_operation]})->{results}[0]{resourceName};

  printf "Added a hotel ad group with resource name: '%s'.\n",
    $ad_group_resource_name;

  return $ad_group_resource_name;
}

# Creates a new hotel ad group ad in the specified ad group.
sub add_hotel_ad_group_ad {
  my ($api_client, $customer_id, $ad_group_resource_name) = @_;

  # Create an ad group ad and set a hotel ad to it.
  my $ad_group_ad = Google::Ads::GoogleAds::V13::Resources::AdGroupAd->new({
      # Set the ad group.
      adGroup => $ad_group_resource_name,
      # Set the ad to a new shopping product ad.
      ad => Google::Ads::GoogleAds::V13::Resources::Ad->new({
          hotelAd => Google::Ads::GoogleAds::V13::Common::HotelAdInfo->new()}
      ),
      status => Google::Ads::GoogleAds::V13::Enums::AdGroupAdStatusEnum::ENABLED
    });

  # Create an ad group ad operation.
  my $ad_group_ad_operation =
    Google::Ads::GoogleAds::V13::Services::AdGroupAdService::AdGroupAdOperation
    ->new({create => $ad_group_ad});

  # Add the ad group ad.
  my $ad_group_ad_resource_name = $api_client->AdGroupAdService()->mutate({
      customerId => $customer_id,
      operations => [$ad_group_ad_operation]})->{results}[0]{resourceName};

  printf "Added a hotel ad group ad with resource name: '%s'.\n",
    $ad_group_ad_resource_name;

  return $ad_group_ad_resource_name;
}

# Don't run the example if the file is being included.
if (abs_path($0) ne abs_path(__FILE__)) {
  return 1;
}

# Get Google Ads Client, credentials will be read from ~/googleads.properties.
my $api_client = Google::Ads::GoogleAds::Client->new();

# By default examples are set to die on any server returned fault.
$api_client->set_die_on_faults(1);

# Parameters passed on the command line will override any parameters set in code.
GetOptions(
  "customer_id=s"                  => \$customer_id,
  "hotel_center_account_id=i"      => \$hotel_center_account_id,
  "cpc_bid_ceiling_micro_amount=i" => \$cpc_bid_ceiling_micro_amount
);

# Print the help message if the parameters are not initialized in the code nor
# in the command line.
pod2usage(2)
  if not check_params($customer_id, $hotel_center_account_id,
  $cpc_bid_ceiling_micro_amount);

# Call the example.
add_hotel_ad($api_client, $customer_id =~ s/-//gr,
  $hotel_center_account_id, $cpc_bid_ceiling_micro_amount);

=pod

=head1 NAME

add_hotel_ad

=head1 DESCRIPTION

This example creates a hotel campaign, a hotel ad group and hotel ad group ad.

Prerequisite: You need to have access to the Hotel Ads Center, which can be granted
during integration with Google Hotels. The integration instructions can be found at:
https://support.google.com/hotelprices/answer/6101897

=head1 SYNOPSIS

add_hotel_ad.pl [options]

    -help                           Show the help message.
    -customer_id                    The Google Ads customer ID.
    -hotel_center_account_id        The Hotel Ads Center account ID.
    -cpc_bid_ceiling_micro_amount   [optional] The CPC bid ceiling micro amount.

=cut