Remarketing Samples

The code samples below provide examples of common remarketing functions using the AdWords API. Client Library.

Create a remarketing user list (audience)

<?php
/**
 * Copyright 2017 Google Inc. All Rights Reserved.
 *
 * 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.
 */

namespace Google\AdsApi\Examples\AdWords\v201809\Remarketing;

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

use Google\AdsApi\AdWords\AdWordsServices;
use Google\AdsApi\AdWords\AdWordsSession;
use Google\AdsApi\AdWords\AdWordsSessionBuilder;
use Google\AdsApi\AdWords\v201809\cm\ConversionTrackerService;
use Google\AdsApi\AdWords\v201809\cm\Operator;
use Google\AdsApi\AdWords\v201809\cm\Predicate;
use Google\AdsApi\AdWords\v201809\cm\PredicateOperator;
use Google\AdsApi\AdWords\v201809\cm\Selector;
use Google\AdsApi\AdWords\v201809\rm\AdwordsUserListService;
use Google\AdsApi\AdWords\v201809\rm\BasicUserList;
use Google\AdsApi\AdWords\v201809\rm\UserListConversionType;
use Google\AdsApi\AdWords\v201809\rm\UserListMembershipStatus;
use Google\AdsApi\AdWords\v201809\rm\UserListOperation;
use Google\AdsApi\Common\OAuth2TokenBuilder;

/**
 * This example adds a new remarketing list audience to the account and
 * retrieves the associated remarketing tag code.
 */
class AddAudience
{

    public static function runExample(
        AdWordsServices $adWordsServices,
        AdWordsSession $session
    ) {
        $userListService = $adWordsServices->get($session, AdwordsUserListService::class);
        $conversionTrackerService = $adWordsServices->get($session, ConversionTrackerService::class);

        // Create a conversion type (tag).
        $conversionType = new UserListConversionType();
        $conversionType->setName('Mars cruise customers #' . uniqid());

        // Create a basic user list.
        $userList = new BasicUserList();
        $userList->setName('Mars cruise customers #' . uniqid());
        $userList->setConversionTypes([$conversionType]);

        // Set additional settings (optional).
        $userList->setDescription(
            'A list of mars cruise customers in the last year'
        );
        $userList->setStatus(UserListMembershipStatus::OPEN);
        $userList->setMembershipLifeSpan(365);

        // Create a user list operation and add it to the list.
        $operations = [];
        $operation = new UserListOperation();
        $operation->setOperand($userList);
        $operation->setOperator(Operator::ADD);
        $operations[] = $operation;

        // Create the user list on the server.
        $userList = $userListService->mutate($operations)->getValue()[0];

        // Create the selector.
        $selector = new Selector();
        $selector->setFields([
            'Id', 'GoogleGlobalSiteTag', 'GoogleEventSnippet']);
        $selector->setPredicates(
            [
                new Predicate(
                    'Id',
                    PredicateOperator::IN,
                    [$userList->getConversionTypes()[0]->getId()]
                )
            ]
        );

        // Retrieve the conversion tracker and print out its information.
        $conversionTracker = $conversionTrackerService->get($selector)->getEntries()[0];
        printf(
            "Audience with name '%s' and ID %d was added.\n",
            $userList->getName(),
            $userList->getId()
        );
        printf(
            "Google global site tag:\n%s\n\n",
            $conversionTracker->getGoogleGlobalSiteTag()
        );
        printf(
            "Google event snippet:\n%s\n\n",
            $conversionTracker->getGoogleEventSnippet()
        );
    }

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

        // Construct an API session configured from a properties file and the
        // OAuth2 credentials above.
        $session = (new AdWordsSessionBuilder())->fromFile()->withOAuth2Credential($oAuth2Credential)->build();
        self::runExample(new AdWordsServices(), $session);
    }
}

AddAudience::main();

Create an AdWords conversion tracker and add to it upload conversions

<?php
/**
 * Copyright 2017 Google Inc. All Rights Reserved.
 *
 * 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.
 */

namespace Google\AdsApi\Examples\AdWords\v201809\Remarketing;

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

use Google\AdsApi\AdWords\AdWordsServices;
use Google\AdsApi\AdWords\AdWordsSession;
use Google\AdsApi\AdWords\AdWordsSessionBuilder;
use Google\AdsApi\AdWords\v201809\cm\AdWordsConversionTracker;
use Google\AdsApi\AdWords\v201809\cm\ConversionTrackerCategory;
use Google\AdsApi\AdWords\v201809\cm\ConversionTrackerOperation;
use Google\AdsApi\AdWords\v201809\cm\ConversionTrackerService;
use Google\AdsApi\AdWords\v201809\cm\ConversionTrackerStatus;
use Google\AdsApi\AdWords\v201809\cm\Operator;
use Google\AdsApi\AdWords\v201809\cm\UploadConversion;
use Google\AdsApi\Common\OAuth2TokenBuilder;

/**
 * This example adds an AdWords conversion tracker and an upload conversion
 * tracker.
 */
class AddConversionTrackers
{

    public static function runExample(
        AdWordsServices $adWordsServices,
        AdWordsSession $session
    ) {
        $conversionTrackerService = $adWordsServices->get($session, ConversionTrackerService::class);
        $conversionTrackers = [];

        // Create an AdWords conversion tracker.
        $adWordsConversionTracker = new AdWordsConversionTracker();
        $adWordsConversionTracker->setName(
            'Interplanetary Cruise Conversion #' . uniqid()
        );

        // Set additional settings (optional).
        $adWordsConversionTracker->setStatus(ConversionTrackerStatus::ENABLED);
        $adWordsConversionTracker->setCategory(
            ConversionTrackerCategory::DEFAULT_VALUE
        );
        $adWordsConversionTracker->setViewthroughLookbackWindow(15);
        $adWordsConversionTracker->setDefaultRevenueValue(23.41);
        $adWordsConversionTracker->setAlwaysUseDefaultRevenueValue(true);
        $conversionTrackers[] = $adWordsConversionTracker;

        // Create an upload conversion for offline conversion imports.
        $uploadConversion = new UploadConversion();
        // Set an appropriate category. This field is optional, and will be set to
        // DEFAULT if not mentioned.
        $uploadConversion->setCategory(ConversionTrackerCategory::LEAD);
        $uploadConversion->setName('Upload Conversion # ' . uniqid());
        $uploadConversion->setViewthroughLookbackWindow(30);
        $uploadConversion->setCtcLookbackWindow(90);

        // Optional: Set the default currency code to use for conversions
        // that do not specify a conversion currency. This must be an ISO 4217
        // 3-character currency code such as "EUR" or "USD".
        // If this field is not set on this UploadConversion, AdWords will use
        // the account's currency.
        $uploadConversion->setDefaultRevenueCurrencyCode('EUR');

        // Optional: Set the default revenue value to use for conversions
        // that do not specify a conversion value. Note that this value
        // should NOT be in micros.
        $uploadConversion->setDefaultRevenueValue(2.50);

        // Optional: To upload fractional conversion credits, mark the upload
        // conversion as externally attributed. See
        // https://developers.google.com/adwords/api/docs/guides/conversion-tracking#importing_externally_attributed_conversions
        // to learn more about importing externally attributed conversions.

        // uploadConversion->setIsExternallyAttributed(true);

        $conversionTrackers[] = $uploadConversion;

        // Create conversion tracker operations and add them to the list.
        $operations = [];
        foreach ($conversionTrackers as $conversionTracker) {
            $operation = new ConversionTrackerOperation();
            $operation->setOperand($conversionTracker);
            $operation->setOperator(Operator::ADD);
            $operations[] = $operation;
        }

        // Create the conversion trackers on the server.
        $result = $conversionTrackerService->mutate($operations);

        // Print out some information about created trackers.
        foreach ($result->getValue() as $conversionTracker) {
            printf(
                "Conversion with ID %d, name '%s', status '%s' and category '%s' was added.\n",
                $conversionTracker->getId(),
                $conversionTracker->getName(),
                $conversionTracker->getStatus(),
                $conversionTracker->getCategory()
            );
            if ($conversionTracker instanceof AdWordsConversionTracker) {
                printf(
                    "Google global site tag:\n%s\n\n",
                    $conversionTracker->getGoogleGlobalSiteTag()
                );
                printf(
                    "Google event snippet:\n%s\n\n",
                    $conversionTracker->getGoogleEventSnippet()
                );
            }
        }
    }

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

        // Construct an API session configured from a properties file and the
        // OAuth2 credentials above.
        $session = (new AdWordsSessionBuilder())->fromFile()->withOAuth2Credential($oAuth2Credential)->build();
        self::runExample(new AdWordsServices(), $session);
    }
}

AddConversionTrackers::main();

Create and populate a user list

<?php
/**
 * Copyright 2017 Google Inc. All Rights Reserved.
 *
 * 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.
 */

namespace Google\AdsApi\Examples\AdWords\v201809\Remarketing;

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

use Google\AdsApi\AdWords\AdWordsServices;
use Google\AdsApi\AdWords\AdWordsSession;
use Google\AdsApi\AdWords\AdWordsSessionBuilder;
use Google\AdsApi\AdWords\v201809\cm\Operator;
use Google\AdsApi\AdWords\v201809\rm\AddressInfo;
use Google\AdsApi\AdWords\v201809\rm\AdwordsUserListService;
use Google\AdsApi\AdWords\v201809\rm\CrmBasedUserList;
use Google\AdsApi\AdWords\v201809\rm\CustomerMatchUploadKeyType;
use Google\AdsApi\AdWords\v201809\rm\Member;
use Google\AdsApi\AdWords\v201809\rm\MutateMembersOperand;
use Google\AdsApi\AdWords\v201809\rm\MutateMembersOperation;
use Google\AdsApi\AdWords\v201809\rm\UserListOperation;
use Google\AdsApi\Common\OAuth2TokenBuilder;

/**
 * This example adds a user list (a.k.a. audience) and uploads members to
 * populate the list.
 *
 * <p><em>Note:</em> It may take up to several hours for the list to be
 * populated with members.
 * Email addresses must be associated with a Google account.
 * For privacy purposes, the user list size will show as zero until the list has
 * at least 1,000 members. After that, the size will be rounded to the two most
 * significant digits.
 */
class AddCrmBasedUserList
{

    private static $EMAILS = [
        'customer1@example.com',
        'customer2@example.com',
        ' Client3@example.com '
    ];

    public static function runExample(
        AdWordsServices $adWordsServices,
        AdWordsSession $session,
        array $emails
    ) {
        $userListService =
            $adWordsServices->get($session, AdwordsUserListService::class);

        // Create a CRM based user list.
        $userList = new CrmBasedUserList();
        $userList->setName(
            'Customer relationship management list #' . uniqid()
        );
        $userList->setDescription(
            'A list of customers that originated from email addresses'
        );

        // CRM-based user lists can use a membershipLifeSpan of 10000 to
        // indicate unlimited; otherwise normal values apply.
        // Sets the membership life span to 30 days.
        $userList->setMembershipLifeSpan(30);
        $userList->setUploadKeyType(CustomerMatchUploadKeyType::CONTACT_INFO);

        // Create a user list operation and add it to the list.
        $operations = [];
        $operation = new UserListOperation();
        $operation->setOperand($userList);
        $operation->setOperator(Operator::ADD);
        $operations[] = $operation;

        // Create the user list on the server and print out some information.
        $userList = $userListService->mutate($operations)->getValue()[0];
        printf(
            "User list with name '%s' and ID %d was added.\n",
            $userList->getName(),
            $userList->getId()
        );

        // Create operation to add members to the user list based on email
        // addresses.
        $mutateMembersOperations = [];
        $mutateMembersOperation = new MutateMembersOperation();
        $operand = new MutateMembersOperand();
        $operand->setUserListId($userList->getId());

        $members = [];
        // Hash normalized email addresses based on SHA-256 hashing algorithm.
        foreach ($emails as $email) {
            $memberByEmail = new Member();
            $memberByEmail->setHashedEmail(self::normalizeAndHash($email));
            $members[] = $memberByEmail;
        }

        $firstName = 'John';
        $lastName = 'Doe';
        $countryCode = 'US';
        $zipCode = '10011';

        $addressInfo = new AddressInfo();
        // First and last name must be normalized and hashed.
        $addressInfo->setHashedFirstName(self::normalizeAndHash($firstName));
        $addressInfo->setHashedLastName(self::normalizeAndHash($lastName));
        // Country code and zip code are sent in plain text.
        $addressInfo->setCountryCode($countryCode);
        $addressInfo->setZipCode($zipCode);

        $memberByAddress = new Member();
        $memberByAddress->setAddressInfo($addressInfo);
        $members[] = $memberByAddress;

        // Add members to the operand and add the operation to the list.
        $operand->setMembersList($members);
        $mutateMembersOperation->setOperand($operand);
        $mutateMembersOperation->setOperator(Operator::ADD);
        $mutateMembersOperations[] = $mutateMembersOperation;

        // Add members to the user list based on email addresses.
        $result = $userListService->mutateMembers($mutateMembersOperations);

        // Print out some information about the added user list.
        // Reminder: it may take several hours for the list to be populated with
        // members.
        foreach ($result->getUserLists() as $userList) {
            printf(
                "%d email addresses were uploaded to user list with name '%s'"
                . " and ID %d and are scheduled for review.\n",
                count($emails),
                $userList->getName(),
                $userList->getId()
            );
        }
    }

    private static function normalizeAndHash($value)
    {
        return hash('sha256', strtolower(trim($value)));
    }

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

        // Construct an API session configured from a properties file and the
        // OAuth2 credentials above.
        $session = (new AdWordsSessionBuilder())
            ->fromFile()
            ->withOAuth2Credential($oAuth2Credential)
            ->build();
        self::runExample(new AdWordsServices(), $session, self::$EMAILS);
    }
}

AddCrmBasedUserList::main();

Create rule-based user lists

<?php
/**
 * Copyright 2017 Google Inc. All Rights Reserved.
 *
 * 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.
 */

namespace Google\AdsApi\Examples\AdWords\v201809\Remarketing;

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

use DateTime;
use Google\AdsApi\AdWords\AdWordsServices;
use Google\AdsApi\AdWords\AdWordsSession;
use Google\AdsApi\AdWords\AdWordsSessionBuilder;
use Google\AdsApi\AdWords\v201809\cm\Operator;
use Google\AdsApi\AdWords\v201809\rm\AdwordsUserListService;
use Google\AdsApi\AdWords\v201809\rm\CombinedRuleUserList;
use Google\AdsApi\AdWords\v201809\rm\CombinedRuleUserListRuleOperator;
use Google\AdsApi\AdWords\v201809\rm\DateKey;
use Google\AdsApi\AdWords\v201809\rm\DateRuleItem;
use Google\AdsApi\AdWords\v201809\rm\DateRuleItemDateOperator;
use Google\AdsApi\AdWords\v201809\rm\DateSpecificRuleUserList;
use Google\AdsApi\AdWords\v201809\rm\ExpressionRuleUserList;
use Google\AdsApi\AdWords\v201809\rm\NumberKey;
use Google\AdsApi\AdWords\v201809\rm\NumberRuleItem;
use Google\AdsApi\AdWords\v201809\rm\NumberRuleItemNumberOperator;
use Google\AdsApi\AdWords\v201809\rm\Rule;
use Google\AdsApi\AdWords\v201809\rm\RuleBasedUserListPrepopulationStatus;
use Google\AdsApi\AdWords\v201809\rm\RuleItem;
use Google\AdsApi\AdWords\v201809\rm\RuleItemGroup;
use Google\AdsApi\AdWords\v201809\rm\StringKey;
use Google\AdsApi\AdWords\v201809\rm\StringRuleItem;
use Google\AdsApi\AdWords\v201809\rm\StringRuleItemStringOperator;
use Google\AdsApi\AdWords\v201809\rm\UserListOperation;
use Google\AdsApi\AdWords\v201809\rm\UserListRuleTypeEnumsEnum;
use Google\AdsApi\Common\OAuth2TokenBuilder;

/**
 * This example adds two rule-based remarketing user lists: one with no site
 * visit date restrictions, and another that will only include users who visit
 * your site in the next six months.
 */
class AddRuleBasedUserLists
{

    public static function runExample(
        AdWordsServices $adWordsServices,
        AdWordsSession $session
    ) {
        $userListService = $adWordsServices->get($session, AdwordsUserListService::class);

        // Create the user list with no restrictions on site visit date.
        $expressionUserList = new ExpressionRuleUserList();
        $expressionUserList->setName(
            sprintf('Expression based user list created at %s', date('Y-m-d_His'))
        );
        $expressionUserList->setDescription(
            'Users who checked out in three month ' . 'window OR visited the checkout page with more than one item in '
            . 'their cart'
        );
        $expressionUserList->setRule(self::createUserListRule());

        // Optional: Set the prepopulationStatus to REQUESTED to include past users
        // in the user list.
        $expressionUserList->setPrepopulationStatus(
            RuleBasedUserListPrepopulationStatus::REQUESTED
        );

        // Create the user list restricted to users who visit your site within the
        // next six months.
        $startDate = new DateTime();
        $endDate = new DateTime('+6 month');

        $dateUserList = new DateSpecificRuleUserList();
        $dateUserList->setName(
            sprintf('Date rule user list created at %s', date('Y-m-d_His'))
        );
        $dateUserList->setDescription(
            sprintf(
                'Users who visited the site between %s '
                . 'and %s and checked out in three month window OR visited the '
                . 'checkout page with more than one item in their cart',
                $startDate->format('Ymd'),
                $endDate->format('Ymd')
            )
        );
        $dateUserList->setRule(self::createUserListRule());

        // Set the start and end dates of the user list.
        $dateUserList->setStartDate($startDate->format('Ymd'));
        $dateUserList->setEndDate($endDate->format('Ymd'));

        // Create the user list where "Visitors of a page who did visit another
        // page". To create a user list where "Visitors of a page who did not visit
        // another page", change the ruleOperator from AND to AND_NOT.
        $combinedUserList = new CombinedRuleUserList();
        $combinedUserList->setName(
            sprintf('Combined rule user list created at %s', date('Y-m-d_His'))
        );
        $combinedUserList->setDescription('Users who visited two sites.');
        $operands = self::createCombinedUserListRules();
        $combinedUserList->setLeftOperand($operands[0]);
        $combinedUserList->setRightOperand($operands[1]);
        $combinedUserList->setRuleOperator(
            CombinedRuleUserListRuleOperator::AND_VALUE
        );

        // Create operations to add the user lists.
        $operations = [];
        foreach ([$expressionUserList, $dateUserList, $combinedUserList] as $userList) {
            $operation = new UserListOperation();
            $operation->setOperand($userList);
            $operation->setOperator(Operator::ADD);
            $operations[] = $operation;
        }

        // Create the user lists on the server.
        $result = $userListService->mutate($operations);

        // Print out some information about created user lists.
        foreach ($result->getValue() as $userListResult) {
            printf(
                "User list added with ID %d, name '%s', status '%s', list type '%s'"
                . ", account user list status '%s', description '%s'.\n",
                $userListResult->getId(),
                $userListResult->getName(),
                $userListResult->getStatus(),
                $userListResult->getListType(),
                $userListResult->getAccountUserListStatus(),
                $userListResult->getDescription()
            );
        }
    }

    /**
     * Create a user list rule composed of two rule item groups.
     *
     * @return Rule the created rule
     */
    private static function createUserListRule()
    {
        // First rule item group - users who visited the checkout page and had more
        // than one item in their shopping cart.
        $checkoutStringRuleItem = new StringRuleItem();
        $checkoutStringKey = new StringKey();
        $checkoutStringKey->setName('ecomm_pagetype');
        $checkoutStringRuleItem->setKey($checkoutStringKey);
        $checkoutStringRuleItem->setOp(StringRuleItemStringOperator::EQUALS);
        $checkoutStringRuleItem->setValue('checkout');
        $checkoutRuleItem = new RuleItem();
        $checkoutRuleItem->setStringRuleItem($checkoutStringRuleItem);

        $cartSizeNumberRuleItem = new NumberRuleItem();
        $cartSizeNumberKey = new NumberKey();
        $cartSizeNumberKey->setName('cartsize');
        $cartSizeNumberRuleItem->setKey($cartSizeNumberKey);
        $cartSizeNumberRuleItem->setOp(NumberRuleItemNumberOperator::GREATER_THAN);
        $cartSizeNumberRuleItem->setValue(1.0);
        $cartSizeRuleItem = new RuleItem();
        $cartSizeRuleItem->setNumberRuleItem($cartSizeNumberRuleItem);

        // Combine the two rule items into a RuleItemGroup so AdWords will AND their
        // rules together.
        $checkoutMultipleItemGroup = new RuleItemGroup();
        $checkoutMultipleItemGroup->setItems(
            [$checkoutRuleItem, $cartSizeRuleItem]
        );

        // Second rule item group - users who checked out within the next 3 months.
        $today = new DateTime();
        $startDateDateRuleItem = new DateRuleItem();
        $startDateDateKey = new DateKey();
        $startDateDateKey->setName('checkoutdate');
        $startDateDateRuleItem->setKey($startDateDateKey);
        $startDateDateRuleItem->setOp(DateRuleItemDateOperator::AFTER);
        $startDateDateRuleItem->setValue($today->format('Ymd'));
        $startDateRuleItem = new RuleItem();
        $startDateRuleItem->setDateRuleItem($startDateDateRuleItem);

        $threeMonthsLater = new DateTime('+3 month');
        $endDateDateRuleItem = new DateRuleItem();
        $endDateDateKey = new DateKey();
        $endDateDateKey->setName('checkoutdate');
        $endDateDateRuleItem->setKey($endDateDateKey);
        $endDateDateRuleItem->setOp(DateRuleItemDateOperator::BEFORE);
        $endDateDateRuleItem->setValue($threeMonthsLater->format('Ymd'));
        $endDateRuleItem = new RuleItem();
        $endDateRuleItem->setDateRuleItem($endDateDateRuleItem);

        // Combine the date rule items into a RuleItemGroup.
        $checkedOutDateRangeItemGroup = new RuleItemGroup();
        $checkedOutDateRangeItemGroup->setItems(
            [$startDateRuleItem, $endDateRuleItem]
        );

        // Combine the rule item groups into a Rule so AdWords knows how to apply
        // the rules.
        $rule = new Rule();
        $rule->setGroups(
            [$checkoutMultipleItemGroup, $checkedOutDateRangeItemGroup]
        );
        // ExpressionRuleUserLists can use either CNF or DNF for matching. CNF means
        // 'at least one item in each rule item group must match', and DNF means 'at
        // least one entire rule item group must match'. DateSpecificRuleUserList
        // only supports DNF. You can also omit the rule type altogether to default
        // to DNF.
        $rule->setRuleType(UserListRuleTypeEnumsEnum::DNF);

        return $rule;
    }

    /**
     * Create rules to be used as left and right operands of
     * a combined user list.
     *
     * @return Rule[] the array of created rules
     */
    private static function createCombinedUserListRules()
    {
        // Third and fourth rule item groups
        // Visitors of a page who visited another page.
        $site1StringRuleItem = new StringRuleItem();
        $site1StringKey = new StringKey();
        $site1StringKey->setName('url__');
        $site1StringRuleItem->setKey($site1StringKey);
        $site1StringRuleItem->setOp(StringRuleItemStringOperator::EQUALS);
        $site1StringRuleItem->setValue('example.com/example1');
        $site1RuleItem = new RuleItem();
        $site1RuleItem->setStringRuleItem($site1StringRuleItem);

        $site2StringRuleItem = new StringRuleItem();
        $site2StringKey = new StringKey();
        $site2StringKey->setName('url__');
        $site2StringRuleItem->setKey($site2StringKey);
        $site2StringRuleItem->setOp(StringRuleItemStringOperator::EQUALS);
        $site2StringRuleItem->setValue('example.com/example2');
        $site2RuleItem = new RuleItem();
        $site2RuleItem->setStringRuleItem($site2StringRuleItem);

        // Create two RuleItemGroups to show that a visitor browsed two sites.
        $site1ItemGroup = new RuleItemGroup();
        $site1ItemGroup->setItems([$site1RuleItem]);
        $site2ItemGroup = new RuleItemGroup();
        $site2ItemGroup->setItems([$site2RuleItem]);

        // Create two rules to show that a visitor browsed two sites.
        $userVisitedSite1Rule = new Rule();
        $userVisitedSite1Rule->setGroups([$site1ItemGroup]);
        $userVisitedSite2Rule = new Rule();
        $userVisitedSite2Rule->setGroups([$site2ItemGroup]);


        return [$userVisitedSite1Rule, $userVisitedSite2Rule];
    }

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

        // Construct an API session configured from a properties file and the
        // OAuth2 credentials above.
        $session = (new AdWordsSessionBuilder())->fromFile()->withOAuth2Credential($oAuth2Credential)->build();
        self::runExample(new AdWordsServices(), $session);
    }
}

AddRuleBasedUserLists::main();

Import conversion adjustments for existing conversions

<?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
 *
 *     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.
 */

namespace Google\AdsApi\Examples\AdWords\v201809\Remarketing;

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

use Google\AdsApi\AdWords\AdWordsServices;
use Google\AdsApi\AdWords\AdWordsSession;
use Google\AdsApi\AdWords\AdWordsSessionBuilder;
use Google\AdsApi\AdWords\v201809\cm\GclidOfflineConversionAdjustmentFeed;
use Google\AdsApi\AdWords\v201809\cm\OfflineConversionAdjustmentFeedOperation;
use Google\AdsApi\AdWords\v201809\cm\OfflineConversionAdjustmentFeedService;
use Google\AdsApi\AdWords\v201809\cm\Operator;
use Google\AdsApi\Common\OAuth2TokenBuilder;

/**
 * This example demonstrates adjusting one conversion, but you can add more
 * than one operation in a single mutate request.
 */
class UploadOfflineConversionAdjustments
{

    const CONVERSION_NAME = 'INSERT_CONVERSION_NAME_HERE';
    const GCLID = 'INSERT_GOOGLE_CLICK_ID_HERE';
    const CONVERSION_TIME = 'INSERT_CONVERSION_TIME_HERE';
    const ADJUSTMENT_TYPE = 'INSERT_ADJUSTMENT_TYPE_HERE';
    const ADJUSTMENT_TIME = 'INSERT_ADJUSTMENT_TIME_HERE';
    const ADJUSTED_VALUE = 'INSERT_ADJUSTED_VALUE_HERE';

    public static function runExample(
        AdWordsServices $adWordsServices,
        AdWordsSession $session,
        $conversionName,
        $gclid,
        $conversionTime,
        $adjustmentType,
        $adjustmentTime,
        $adjustedValue
    ) {
        $offlineConversionService = $adWordsServices->get(
            $session,
            OfflineConversionAdjustmentFeedService::class
        );

        // Associate conversion adjustments with the existing named conversion
        // tracker. The GCLID should have been uploaded before with a
        // conversion.
        $feed = new GclidOfflineConversionAdjustmentFeed();
        $feed->setConversionName($conversionName);
        $feed->setGoogleClickId($gclid);
        $feed->setConversionTime($conversionTime);
        $feed->setAdjustmentType($adjustmentType);
        $feed->setAdjustmentTime($adjustmentTime);
        $feed->setAdjustedValue($adjustedValue);

        $offlineConversionAdjustmentFeedOperation =
            new OfflineConversionAdjustmentFeedOperation();
        $offlineConversionAdjustmentFeedOperation->setOperator(Operator::ADD);
        $offlineConversionAdjustmentFeedOperation->setOperand($feed);

        // Issues a request to the servers for adjustments of the conversion.
        $result = $offlineConversionService->mutate(
            [$offlineConversionAdjustmentFeedOperation]
        );

        $feed = $result->getValue()[0];
        printf(
            "Uploaded conversion adjustment value of '%s' for Google "
            . "Click ID '%s'.%s",
            $feed->getConversionName(),
            $feed->getGoogleClickId(),
            PHP_EOL
        );
    }

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

        // Construct an API session configured from a properties file and the
        // OAuth2 credentials above.
        $session = (new AdWordsSessionBuilder())->fromFile()
            ->withOAuth2Credential($oAuth2Credential)
            ->build();
        self::runExample(
            new AdWordsServices(),
            $session,
            self::CONVERSION_NAME,
            self::GCLID,
            self::CONVERSION_TIME,
            self::ADJUSTMENT_TYPE,
            self::ADJUSTMENT_TIME,
            floatval(self::ADJUSTED_VALUE)
        );
    }
}

UploadOfflineConversionAdjustments::main();

Import offline call conversions

<?php
/**
 * Copyright 2017 Google Inc. All Rights Reserved.
 *
 * 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.
 */

namespace Google\AdsApi\Examples\AdWords\v201809\Remarketing;

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

use Google\AdsApi\AdWords\AdWordsServices;
use Google\AdsApi\AdWords\AdWordsSession;
use Google\AdsApi\AdWords\AdWordsSessionBuilder;
use Google\AdsApi\AdWords\v201809\cm\OfflineCallConversionFeed;
use Google\AdsApi\AdWords\v201809\cm\OfflineCallConversionFeedOperation;
use Google\AdsApi\AdWords\v201809\cm\OfflineCallConversionFeedService;
use Google\AdsApi\AdWords\v201809\cm\Operator;
use Google\AdsApi\Common\OAuth2TokenBuilder;

/**
 * This code example imports offline call conversion values for calls related
 * to the ads in your account.
 */
class UploadOfflineCallConversions
{

    const CALLER_ID = 'INSERT_CALLER_ID_HERE';
    // For times use the format yyyyMMdd HHmmss tz. For more details on formats,
    // see:
    // https://developers.google.com/adwords/api/docs/appendix/codes-formats#date-and-time-formats
    // For time zones, see:
    // https://developers.google.com/adwords/api/docs/appendix/codes-formats#timezone-ids
    const CALL_START_TIME = 'INSERT_CALL_START_TIME_HERE';
    const CONVERSION_NAME = 'INSERT_CONVERSION_NAME_HERE';
    const CONVERSION_TIME = 'INSERT_CONVERSION_TIME_HERE';
    const CONVERSION_VALUE = 'INSERT_CONVERSION_VALUE_HERE';

    public static function runExample(
        AdWordsServices $adWordsServices,
        AdWordsSession $session,
        $callerId,
        $callStartTime,
        $conversionName,
        $conversionTime,
        $conversionValue
    ) {
        $offlineCallConversionService = $adWordsServices->get(
            $session,
            OfflineCallConversionFeedService::class
        );

        // Associate offline call conversions with the existing named conversion
        // tracker. If this tracker was newly created, it may be a few hours before
        // it can accept conversions.
        $feed = new OfflineCallConversionFeed();
        $feed->setCallerId($callerId);
        $feed->setCallStartTime($callStartTime);
        $feed->setConversionName($conversionName);
        $feed->setConversionTime($conversionTime);
        $feed->setConversionValue($conversionValue);

        $offlineCallConversionOperations = [];
        $offlineCallConversionOperation = new OfflineCallConversionFeedOperation();
        $offlineCallConversionOperation->setOperator(Operator::ADD);
        $offlineCallConversionOperation->setOperand($feed);
        $offlineCallConversionOperations[] = $offlineCallConversionOperation;

        // This example uploads only one call conversion, but you can upload
        // multiple call conversions by passing additional operations.
        $result = $offlineCallConversionService->mutate($offlineCallConversionOperations);

        $feed = $result->getValue()[0];
        printf(
            "Uploaded offline call conversion value of '%s' for caller ID '%s'.\n",
            $feed->getConversionValue(),
            $feed->getCallerId()
        );
    }


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

        // Construct an API session configured from a properties file and the
        // OAuth2 credentials above.
        $session = (new AdWordsSessionBuilder())->fromFile()->withOAuth2Credential($oAuth2Credential)->build();
        self::runExample(
            new AdWordsServices(),
            $session,
            self::CALLER_ID,
            self::CALL_START_TIME,
            self::CONVERSION_NAME,
            self::CONVERSION_TIME,
            floatval(self::CONVERSION_VALUE)
        );
    }
}

UploadOfflineCallConversions::main();

Import offline click conversions

<?php
/**
 * Copyright 2017 Google Inc. All Rights Reserved.
 *
 * 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.
 */

namespace Google\AdsApi\Examples\AdWords\v201809\Remarketing;

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

use Google\AdsApi\AdWords\AdWordsServices;
use Google\AdsApi\AdWords\AdWordsSession;
use Google\AdsApi\AdWords\AdWordsSessionBuilder;
use Google\AdsApi\AdWords\v201809\cm\OfflineConversionFeed;
use Google\AdsApi\AdWords\v201809\cm\OfflineConversionFeedOperation;
use Google\AdsApi\AdWords\v201809\cm\OfflineConversionFeedService;
use Google\AdsApi\AdWords\v201809\cm\Operator;
use Google\AdsApi\Common\OAuth2TokenBuilder;

/**
 * This code example imports offline conversion values for specific clicks to
 * your account. To get Google Click ID for a click, run
 * CLICK_PERFORMANCE_REPORT.
 */
class UploadOfflineConversions
{

    const CONVERSION_NAME = 'INSERT_CONVERSION_NAME_HERE';
    const GCLID = 'INSERT_GOOGLE_CLICK_ID_HERE';
    const CONVERSION_TIME = 'INSERT_CONVERSION_TIME_HERE';
    const CONVERSION_VALUE = 'INSERT_CONVERSION_VALUE_HERE';

    public static function runExample(
        AdWordsServices $adWordsServices,
        AdWordsSession $session,
        $conversionName,
        $gclid,
        $conversionTime,
        $conversionValue
    ) {
        $offlineConversionService = $adWordsServices->get($session, OfflineConversionFeedService::class);

        // Associate offline conversions with the existing named conversion tracker.
        // If this tracker was newly created, it may be a few hours before it can
        // accept conversions.
        $feed = new OfflineConversionFeed();
        $feed->setConversionName($conversionName);
        $feed->setConversionTime($conversionTime);
        $feed->setConversionValue($conversionValue);
        $feed->setGoogleClickId($gclid);

        // Optional: To upload fractional conversion credits, set the external
        // attribution model and credit. To use this feature, your conversion
        // tracker should be marked as externally attributed. See
        // https://developers.google.com/adwords/api/docs/guides/conversion-tracking#importing_externally_attributed_conversions
        // to learn more about importing externally attributed conversions.

        // $feed->setExternalAttributionModel('Linear');
        // $feed->setExternalAttributionCredit(0.3);

        $offlineConversionOperation = new OfflineConversionFeedOperation();
        $offlineConversionOperation->setOperator(Operator::ADD);
        $offlineConversionOperation->setOperand($feed);
        $offlineConversionOperations = [$offlineConversionOperation];

        $result = $offlineConversionService->mutate($offlineConversionOperations);

        $feed = $result->getValue()[0];
        printf(
            "Uploaded offline conversion value of %d for Google Click ID = '%s' to '%s'.\n",
            $feed->getConversionValue(),
            $feed->getGoogleClickId(),
            $feed->getConversionName()
        );
    }

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

        // Construct an API session configured from a properties file and the
        // OAuth2 credentials above.
        $session = (new AdWordsSessionBuilder())->fromFile()->withOAuth2Credential($oAuth2Credential)->build();
        self::runExample(
            new AdWordsServices(),
            $session,
            self::CONVERSION_NAME,
            self::GCLID,
            self::CONVERSION_TIME,
            floatval(self::CONVERSION_VALUE)
        );
    }
}

UploadOfflineConversions::main();

Upload offline data for store sales transactions

<?php
/**
 * Copyright 2017 Google Inc. All Rights Reserved.
 *
 * 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.
 */

namespace Google\AdsApi\Examples\AdWords\v201809\Remarketing;

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

use Google\AdsApi\AdWords\AdWordsServices;
use Google\AdsApi\AdWords\AdWordsSession;
use Google\AdsApi\AdWords\AdWordsSessionBuilder;
use Google\AdsApi\AdWords\v201809\cm\ApiError;
use Google\AdsApi\AdWords\v201809\cm\Money;
use Google\AdsApi\AdWords\v201809\cm\Operator;
use Google\AdsApi\AdWords\v201809\rm\FirstPartyUploadMetadata;
use Google\AdsApi\AdWords\v201809\rm\MoneyWithCurrency;
use Google\AdsApi\AdWords\v201809\rm\OfflineData;
use Google\AdsApi\AdWords\v201809\rm\OfflineDataUpload;
use Google\AdsApi\AdWords\v201809\rm\OfflineDataUploadOperation;
use Google\AdsApi\AdWords\v201809\rm\OfflineDataUploadService;
use Google\AdsApi\AdWords\v201809\rm\OfflineDataUploadType;
use Google\AdsApi\AdWords\v201809\rm\OfflineDataUploadUserIdentifierType;
use Google\AdsApi\AdWords\v201809\rm\StoreSalesTransaction;
use Google\AdsApi\AdWords\v201809\rm\ThirdPartyUploadMetadata;
use Google\AdsApi\AdWords\v201809\rm\UploadMetadata;
use Google\AdsApi\AdWords\v201809\rm\UserIdentifier;
use Google\AdsApi\Common\OAuth2TokenBuilder;

/**
 * This code example shows how to upload offline data for store sales
 * transactions.
 */
class UploadOfflineData
{

    // The external upload ID can be any number that you use to keep track of
    // your uploads.
    const EXTERNAL_UPLOAD_ID = 'INSERT_EXTERNAL_UPLOAD_ID';

    // Insert the conversion type name that you'd like to attribute this upload
    // to.
    const CONVERSION_NAME = 'INSERT_CONVERSION_NAME';

    // Change the below constant to ThirdPartyUploadMetadata::class if uploading
    // third party data.
    const STORE_SALES_UPLOAD_COMMON_METADATA_TYPE =
        FirstPartyUploadMetadata::class;

    // The three constants below are needed when uploading third party data.
    // You can safely ignore them if you are uploading first party data.
    // For times, use the format yyyyMMdd HHmmss tz. For more details on formats,
    // see:
    // https://developers.google.com/adwords/api/docs/appendix/codes-formats#date-and-time-formats
    // For time zones, see:
    // https://developers.google.com/adwords/api/docs/appendix/codes-formats#timezone-ids
    const ADVERTISER_UPLOAD_TIME = 'INSERT_ADVERTISER_UPLOAD_TIME';
    const BRIDGE_MAP_VERSION_ID = 'INSERT_BRIDGE_MAP_VERSION_ID';
    const PARTNER_ID = 'INSERT_PARTNER_ID';

    // Insert email addresses below for creating user identifiers.
    private static $EMAIL_ADDRESSES = ['EMAIL_ADDRESS_1', 'EMAIL_ADDRESS_2'];

    public static function runExample(
        AdWordsServices $adWordsServices,
        AdWordsSession $session,
        $conversionName,
        $externalUploadId,
        $storeSalesUploadCommonMetadataType,
        array $emailAddresses,
        $advertiserUploadTime,
        $bridgeMapVersionId,
        $partnerId
    ) {
        $session->setPartialFailure(true);
        $offlineDataUploadService =
            $adWordsServices->get($session, OfflineDataUploadService::class);

        // Create the first offline data for upload.
        // This transaction occurred 7 days ago with amount of 200 USD.
        $transactionTime1 = new \DateTime('-7d');
        $transactionAmount1 = 200000000;
        $transactionCurrencyCode1 = 'USD';
        $userIdentifierList1 = [
            self::createUserIdentifier(
                OfflineDataUploadUserIdentifierType::HASHED_EMAIL,
                $emailAddresses[0]
            ),
            self::createUserIdentifier(
                OfflineDataUploadUserIdentifierType::STATE,
                'New York'
            )
        ];
        $offlineData1 = self::createOfflineData(
            $transactionTime1,
            $transactionAmount1,
            $transactionCurrencyCode1,
            $conversionName,
            $userIdentifierList1
        );

        // Create the second offline data for upload.
        // This transaction occurred 14 days ago with amount of 450 EUR.
        $transactionTime2 = new \DateTime('-14d');
        $transactionAmount2 = 450000000;
        $transactionCurrencyCode2 = 'EUR';
        $userIdentifierList2 = [
            self::createUserIdentifier(
                OfflineDataUploadUserIdentifierType::HASHED_EMAIL,
                $emailAddresses[1]
            ),
            self::createUserIdentifier(
                OfflineDataUploadUserIdentifierType::STATE,
                'California'
            )
        ];
        $offlineData2 = self::createOfflineData(
            $transactionTime2,
            $transactionAmount2,
            $transactionCurrencyCode2,
            $conversionName,
            $userIdentifierList2
        );

        // Create offline data upload object.
        $offlineDataUpload = new OfflineDataUpload();
        $offlineDataUpload->setExternalUploadId($externalUploadId);
        $offlineDataUpload->setOfflineDataList([$offlineData1, $offlineData2]);

        // Set the type and metadata of this upload.
        $reflectionClass =
            new \ReflectionClass($storeSalesUploadCommonMetadataType);
        $storeSalesUploadCommonMetadata = $reflectionClass->newInstance();
        $storeSalesUploadCommonMetadata->setLoyaltyRate(1.0);
        $storeSalesUploadCommonMetadata->setTransactionUploadRate(1.0);

        if ($storeSalesUploadCommonMetadataType
            === FirstPartyUploadMetadata::class) {
            $offlineDataUpload->setUploadType(
                OfflineDataUploadType::STORE_SALES_UPLOAD_FIRST_PARTY
            );
        } elseif ($storeSalesUploadCommonMetadataType
            === ThirdPartyUploadMetadata::class) {
            $offlineDataUpload->setUploadType(
                OfflineDataUploadType::STORE_SALES_UPLOAD_THIRD_PARTY
            );
            $storeSalesUploadCommonMetadata->setAdvertiserUploadTime(
                $advertiserUploadTime
            );
            $storeSalesUploadCommonMetadata->setValidTransactionRate(1.0);
            $storeSalesUploadCommonMetadata->setPartnerMatchRate(1.0);
            $storeSalesUploadCommonMetadata->setPartnerUploadRate(1.0);
            $storeSalesUploadCommonMetadata->setBridgeMapVersionId(
                $bridgeMapVersionId
            );
            $storeSalesUploadCommonMetadata->setPartnerId($partnerId);
        }

        $uploadMetadata = new UploadMetadata();
        $uploadMetadata->setStoreSalesUploadCommonMetadata(
            $storeSalesUploadCommonMetadata
        );
        $offlineDataUpload->setUploadMetadata($uploadMetadata);

        // Create an offline data upload operation.
        $offlineDataUploadOperation = new OfflineDataUploadOperation();
        $offlineDataUploadOperation->setOperator(Operator::ADD);
        $offlineDataUploadOperation->setOperand($offlineDataUpload);

        $operations = [];
        $operations[] = $offlineDataUploadOperation;
        // Upload offline data on the server and print some information.
        $result =
            $offlineDataUploadService->mutate($operations);
        $offlineDataUpload = $result->getValue()[0];
        printf(
            "Uploaded offline data with external upload ID %d and upload"
            . " status %s\n",
            $offlineDataUpload->getExternalUploadId(),
            $offlineDataUpload->getUploadStatus()
        );

        // Print any partial failure errors from the response.
        if (empty($result->getPartialFailureErrors())) {
            return;
        }
        foreach ($result->getPartialFailureErrors() as $apiError) {
            // Gets the index of the failed operation from the error's field
            // path elements.
            $operationIndex =
                self::getFieldPathElementIndex($apiError, 'operations');

            if (!is_null($operationIndex)) {
                $failedOfflineDataUpload =
                    $operations[$operationIndex]->getOperand();
                // Gets the index of the entry in the offline data list from the
                // error's field path elements.
                $offlineDataListIndex = self::getFieldPathElementIndex(
                    $apiError,
                    'offlineDataList'
                );

                printf(
                    "Offline data list entry %d in operation %d with "
                    . "external upload ID %d and type '%s' has triggered a "
                    . "failure for the following reason: '%s'.\n",
                    $offlineDataListIndex,
                    $operationIndex,
                    $failedOfflineDataUpload->getExternalUploadId(),
                    $failedOfflineDataUpload->getUploadType(),
                    $apiError->getErrorString()
                );
            } else {
                printf(
                    "A failure for the following reason: '%s' has "
                    . "occurred.\n",
                    $apiError->getErrorString()
                );
            }
        }
    }

    /**
     * Creates the offline data from the specified transaction time, transaction
     * micro amount, transaction currency, conversion name and user identifier
     * list.
     */
    private static function createOfflineData(
        \DateTime $transactionTime,
        $transactionMicroAmount,
        $transactionCurrency,
        $conversionName,
        array $userIdentifierList
    ) {
        $storeSalesTransaction = new StoreSalesTransaction();

        // For times use the format yyyyMMdd HHmmss [tz].
        // For details, see
        // https://developers.google.com/adwords/api/docs/appendix/codes-formats#date-and-time-formats
        $storeSalesTransaction->setTransactionTime(
            $transactionTime->format('Ymd His')
        );
        $storeSalesTransaction->setConversionName($conversionName);
        $storeSalesTransaction->setUserIdentifiers($userIdentifierList);

        $money = new Money();
        $money->setMicroAmount($transactionMicroAmount);
        $moneyWithCurrency = new MoneyWithCurrency();
        $moneyWithCurrency->setMoney($money);
        $moneyWithCurrency->setCurrencyCode($transactionCurrency);
        $storeSalesTransaction->setTransactionAmount($moneyWithCurrency);

        $offlineData = new OfflineData();
        $offlineData->setStoreSalesTransaction($storeSalesTransaction);

        return $offlineData;
    }

    /**
     * Creates a user identifier from the specified type and value.
     */
    private static function createUserIdentifier($type, $value)
    {
        // If the user identifier type is a hashed type, normalize and hash the
        // value.
        if (0 === strpos($type, 'HASHED_')) {
            $value = hash('sha256', strtolower(trim($value)));
        }
        $userIdentifier = new UserIdentifier();
        $userIdentifier->setUserIdentifierType($type);
        $userIdentifier->setValue($value);

        return $userIdentifier;
    }

    /**
     * Returns the FieldPathElement#getIndex() for the specified field name, if
     * present in the error's field path elements. If not, returns null.
     */
    private static function getFieldPathElementIndex(ApiError $apiError, $field)
    {
        $fieldPathElements = $apiError->getFieldPathElements();
        if (is_null($fieldPathElements) || count($fieldPathElements) === 0) {
            return null;
        }
        for ($i = 0; $i < count($fieldPathElements); $i++) {
            $fieldPathElement = $fieldPathElements[$i];
            if ($field === $fieldPathElement->getField()) {
                return $fieldPathElement->getIndex();
            }
        }
        return null;
    }

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

        // Construct an API session configured from a properties file and the
        // OAuth2 credentials above.
        $session = (new AdWordsSessionBuilder())->fromFile()->withOAuth2Credential($oAuth2Credential)->build();
        self::runExample(
            new AdWordsServices(),
            $session,
            self::CONVERSION_NAME,
            intval(self::EXTERNAL_UPLOAD_ID),
            self::STORE_SALES_UPLOAD_COMMON_METADATA_TYPE,
            self::$EMAIL_ADDRESSES,
            self::ADVERTISER_UPLOAD_TIME,
            self::BRIDGE_MAP_VERSION_ID,
            intval(self::PARTNER_ID)
        );
    }
}

UploadOfflineData::main();

Send feedback about...

AdWords API
AdWords API
Need help? Visit our support page.