カスタマー マッチ オーディエンスを作成する

CreateUserListRequest を送信して、カスタマー マッチ オーディエンスを作成します。

リクエスト本文を作成する

UserList リソースを作成します。設定する一般的なフィールドは次のとおりです。

displayName
必須。リストの表示名。この名前は、アカウントが所有するすべてのリストで一意である必要があります。
description
リストの簡単な説明。
integrationCode
システムからの ID。
membershipDuration

オーディエンス メンバーがリストに追加されてからリストに残る期間。値は 1 日単位で指定する必要があります。設定しない場合、デフォルトは最大値になります。

JSON を使用する場合は、期間の日数に 86400(1 日あたりの秒数)を掛けて秒数を計算します。次に、値を乗算結果に設定し、その後に s を続けます。たとえば、有効期間を 90 日にする場合は、90 * 86400 = 7776000 であるため、値 7776000s を使用します。

プロトコル バッファ形式を使用する場合は、日数に基づいて Duration オブジェクトを構築する便利なメソッドを使用します(そのような便利なメソッドが存在する場合)。たとえば、Java 用の protobuf-java-util ライブラリには、fromDays() という便利なメソッドがあります。それ以外の場合は、期間の日数に 86400(1 日あたりの秒数)を掛けて秒数を計算し、その結果を使用して Duration オブジェクトの seconds フィールドを設定します。

カスタマー マッチの必須フィールド

カスタマー マッチ オーディエンスでは、ingestedUserListInfo フィールドは必須です。

オーディエンス メンバーをリストに追加するために使用するデータの種類に基づいて、IngestedUserListInfo で設定するフィールドは次のとおりです。

連絡先情報リスト

連絡先情報(ハッシュ化されたメールアドレス、電話番号、住所)を使用してオーディエンス メンバーを定義する場合は、次のフィールドを設定します。

uploadKeyTypes

CONTACT_ID アップロード キータイプを含むリストに設定します。

uploadKeyTypes リストには 1 つのエントリのみを含める必要があります。

contactIdInfo

ContactIdInfo メッセージに設定します。dataSourceType は、DataSourceType 列挙型の適切な値に設定します。

モバイル ID リスト

モバイル ID を使用してオーディエンス メンバーを定義する場合は、次のフィールドを設定します。

uploadKeyTypes

MOBILE_ID アップロード キータイプを含むリストに設定します。

uploadKeyTypes リストには 1 つのエントリのみを含める必要があります。

mobileIdInfo

MobileIdInfo メッセージに設定します。

  • dataSourceType を DataSourceType 列挙型の適切な値に設定します。

  • keySpace を IOS または ANDROID に設定します。

  • appId を、データが収集されたモバイルアプリを一意に識別する文字列に設定します。

ユーザー ID リスト

ユーザー ID を使用してオーディエンス メンバーを定義する場合は、次のフィールドを設定します。

uploadKeyTypes

USER_ID アップロード キータイプを含むリストに設定します。

uploadKeyTypes リストには 1 つのエントリのみを含める必要があります。

リクエストを作成する

カスタマー マッチ オーディエンスを作成するには、UserList リソースの create リクエストを作成します。

  1. parent フィールドをアカウントのリソース名に設定します。リソース名は accountTypes/{accountType}/accounts/{account} の形式にする必要があります。

  2. リクエストの本文に、作成した UserList を使用します。

  3. 認証情報が parent のユーザーである Google アカウントのものではない場合は、宛先とヘッダーを構成するの説明に従ってヘッダーを設定します。

membershipDuration が 30 日(2592000s)のカスタマー マッチ オーディエンスを作成するリクエストのサンプルを以下に示します。[REST] タブを選択し、[API Explorer で開く] をクリックして、ブラウザからリクエストを試します。クライアント ライブラリをインストールしている場合は、選択したプログラミング言語のタブを選択します。

REST

連絡先情報

{
    "description": "Customer Match for contact info",
    "displayName": "Contact info audience",
    "ingestedUserListInfo": {
        "contactIdInfo": {
            "dataSourceType": "DATA_SOURCE_TYPE_FIRST_PARTY"
        },
        "uploadKeyTypes": [
            "CONTACT_ID"
        ]
    },
    "membershipDuration": "2592000s"
}

Mobile ID

{
    "description": "Customer Match for mobile IDs",
    "displayName": "Mobile ID audience",
    "ingestedUserListInfo": {
        "mobileIdInfo": {
            "dataSourceType": "DATA_SOURCE_TYPE_FIRST_PARTY",
            "keySpace": "ANDROID",
            "appId": "com.labpixies.flood"
        },
        "uploadKeyTypes": [
            "MOBILE_ID"
        ]
    },
    "membershipDuration": "2592000s"
}

ユーザー ID

{
    "description": "Customer Match for user IDs",
    "displayName": "User ID audience",
    "ingestedUserListInfo": {
        "userIdInfo": {
            "dataSourceType": "DATA_SOURCE_TYPE_FIRST_PARTY"
        },
        "uploadKeyTypes": [
            "USER_ID"
        ]
    },
    "membershipDuration": "2592000s"
}

.NET

// Runs the example.
private void RunExample(
    AccountType operatingAccountType,
    string operatingAccountId,
    bool validateOnly,
    UploadKeyType uploadKeyType = UploadKeyType.ContactId,
    AccountType? loginAccountType = null,
    string? loginAccountId = null,
    AccountType? linkedAccountType = null,
    string? linkedAccountId = null,
    KeySpace? keySpace = null,
    string? appId = null
)
{
    if (loginAccountId == null ^ loginAccountType == null)
    {
        throw new ArgumentException(
            "Must specify either both or neither of login account ID and login account "
                + "type"
        );
    }
    if (linkedAccountId == null ^ linkedAccountType == null)
    {
        throw new ArgumentException(
            "Must specify either both or neither of linked account ID and linked account "
                + "type"
        );
    }
    if (uploadKeyType == UploadKeyType.MobileId)
    {
        if (!keySpace.HasValue || string.IsNullOrEmpty(appId))
        {
            throw new ArgumentException(
                "Must specify both keySpace and appId when uploadKeyType is MobileId"
            );
        }
    }
    else if (keySpace.HasValue || !string.IsNullOrEmpty(appId))
    {
        throw new ArgumentException(
            "keySpace and appId are only supported when uploadKeyType is MobileId"
        );
    }

    // Optional: Sets headers to specify the login-account and linked-account if your
    // credentials aren't for a user in the operating account (for example, when
    // authenticating through a Google Ads manager account or Data Partner account).
    CallSettings? callSettings = null;
    if (loginAccountType.HasValue && loginAccountId != null)
    {
        callSettings = callSettings.WithHeader(
            "login-account",
            // Uses the AccountName utility to construct the login-account resource name.
            AccountName.Format(GetEnumOriginalName(loginAccountType.Value), loginAccountId)
        );
    }
    if (linkedAccountType.HasValue && linkedAccountId != null)
    {
        callSettings = callSettings.WithHeader(
            "linked-account",
            // Uses the AccountName utility to construct the linked-account resource name.
            AccountName.Format(
                GetEnumOriginalName(linkedAccountType.Value),
                linkedAccountId
            )
        );
    }

    // Configures the Customer Match user list.
    // For more details on constructing a UserList, see:
    // https://developers.google.com/data-manager/api/devguides/audiences/google-ads/customer-match/create-audience
    var ingestedUserListInfo = new IngestedUserListInfo
    {
        // Sets to a list containing a single UploadKeyType.
        UploadKeyTypes = { uploadKeyType },
    };

    switch (uploadKeyType)
    {
        case UploadKeyType.ContactId:
            // Use CONTACT_ID for hashed email addresses, phone numbers, or physical
            // addresses.
            ingestedUserListInfo.ContactIdInfo = new ContactIdInfo
            {
                DataSourceType = DataSourceType.FirstParty,
            };
            break;
        case UploadKeyType.UserId:
            // Use USER_ID for first-party user IDs assigned to logged-in users.
            // Note: Display & Video 360 does not support USER_ID lists.
            ingestedUserListInfo.UserIdInfo = new UserIdInfo
            {
                DataSourceType = DataSourceType.FirstParty,
            };
            break;
        case UploadKeyType.MobileId:
            // Use MOBILE_ID for mobile advertising IDs.
            ingestedUserListInfo.MobileIdInfo = new MobileIdInfo
            {
                DataSourceType = DataSourceType.FirstParty,
                KeySpace = keySpace!.Value,
                AppId = appId,
            };
            break;
        default:
            throw new ArgumentException($"Unsupported upload key type: {uploadKeyType}");
    }

    string uploadKeyTypeName = GetEnumOriginalName(uploadKeyType);
    var userList = new UserList
    {
        // Required. The display name must be unique among all lists owned by the account.
        DisplayName =
            $"Customer Match ({uploadKeyTypeName}) - {DateTime.Now:yyyy-MM-dd HH:mm:ss}",
        Description = $"Customer Match audience for {uploadKeyTypeName}",
        // Optional. The duration an audience member remains in the list after being added.
        // Must correspond to whole days (defaults to maximum if not set).
        MembershipDuration = Duration.FromTimeSpan(TimeSpan.FromDays(30)),
        // Required for a Customer Match audience.
        IngestedUserListInfo = ingestedUserListInfo,
    };

    // Creates a client for UserListService.
    UserListServiceClient userListServiceClient = UserListServiceClient.Create();

    // Builds the request targeting the parent operating account.
    var request = new CreateUserListRequest
    {
        Parent = AccountName.Format(
            GetEnumOriginalName(operatingAccountType),
            operatingAccountId
        ),
        UserList = userList,
        // Sets validate_only. If true, then the Data Manager API only validates the
        // request but doesn't apply changes.
        ValidateOnly = validateOnly,
    };

    // Sends the request with any configured header settings.
    UserList response = userListServiceClient.CreateUserList(request, callSettings);

    // Logs the created user list. When validate_only is false, response.Id contains the
    // created user list ID, which you pass as the ProductDestinationId in subsequent
    // ingest or remove requests.
    Console.WriteLine($"Response:\n{response}");
}

// Returns the original proto enum name (for example, "GOOGLE_ADS" for
// AccountType.GoogleAds).
private static string GetEnumOriginalName<T>(T enumValue)
    where T : struct, System.Enum =>
    typeof(T)
        .GetField(enumValue.ToString())
        ?.GetCustomAttribute<OriginalNameAttribute>()
        ?.Name
    ?? enumValue.ToString();

Java

/**
 * Runs the example.
 *
 * @param params the parameters for the example
 * @throws IOException if the API request fails
 */
private void runExample(ParamsConfig params) throws IOException {
  // Optional: Sets headers to specify the login-account and linked-account if your credentials
  // aren't for a user in the operating account (for example, when authenticating through a Google
  // Ads manager account or Data Partner account).
  Map<String, String> headers = new HashMap<>();
  if (params.loginAccountId != null) {
    headers.put(
        "login-account",
        // Uses the AccountName utility to construct the login-account resource name.
        AccountName.format(params.loginAccountType.name(), params.loginAccountId));
  }
  if (params.linkedAccountId != null) {
    headers.put(
        "linked-account",
        // Uses the AccountName utility to construct the linked-account resource name.
        AccountName.format(params.linkedAccountType.name(), params.linkedAccountId));
  }

  // Configures the Customer Match user list.
  // For more details on constructing a UserList, see:
  // https://developers.google.com/data-manager/api/devguides/audiences/google-ads/customer-match/create-audience
  IngestedUserListInfo.Builder ingestedUserListInfoBuilder =
      IngestedUserListInfo.newBuilder()
          // Sets to a single UploadKeyType.
          .addUploadKeyTypes(params.uploadKeyType);

  switch (params.uploadKeyType) {
    case CONTACT_ID:
      // Use CONTACT_ID for hashed email addresses, phone numbers, or physical addresses.
      ingestedUserListInfoBuilder.setContactIdInfo(
          ContactIdInfo.newBuilder()
              .setDataSourceType(DataSourceType.DATA_SOURCE_TYPE_FIRST_PARTY));
      break;
    case USER_ID:
      // Use USER_ID for first-party user IDs assigned to logged-in users.
      // Note: Display & Video 360 does not support USER_ID lists.
      ingestedUserListInfoBuilder.setUserIdInfo(
          UserIdInfo.newBuilder()
              .setDataSourceType(DataSourceType.DATA_SOURCE_TYPE_FIRST_PARTY));
      break;
    case MOBILE_ID:
      // Use MOBILE_ID for mobile advertising IDs.
      ingestedUserListInfoBuilder.setMobileIdInfo(
          MobileIdInfo.newBuilder()
              .setDataSourceType(DataSourceType.DATA_SOURCE_TYPE_FIRST_PARTY)
              .setKeySpace(params.keySpace)
              .setAppId(params.appId));
      break;
    default:
      throw new IllegalArgumentException(
          "Unsupported upload key type: " + params.uploadKeyType);
  }

  UserList userList =
      UserList.newBuilder()
          // Required. The display name must be unique among all lists owned by the account.
          .setDisplayName(
              String.format(
                  "Customer Match (%s) - %s",
                  params.uploadKeyType.name(),
                  LocalDateTime.now(ZoneId.systemDefault())
                      .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))))
          .setDescription(
              String.format("Customer Match audience for %s", params.uploadKeyType.name()))
          // Optional. The duration an audience member remains in the list after being added. Must
          // correspond to whole days (defaults to maximum if not set).
          .setMembershipDuration(Durations.fromDays(30))
          // Required for a Customer Match audience.
          .setIngestedUserListInfo(ingestedUserListInfoBuilder)
          .build();

  // Configures the settings for UserListService to include headers.
  UserListServiceSettings userListServiceSettings =
      UserListServiceSettings.newBuilder()
          .setHeaderProvider(FixedHeaderProvider.create(headers))
          .build();

  // Creates a client for UserListService using the settings to include headers if provided.
  // Uses a try-with-resources block so the client shuts down properly.
  try (UserListServiceClient userListServiceClient =
      UserListServiceClient.create(userListServiceSettings)) {
    // Builds the request targeting the parent operating account.
    CreateUserListRequest request =
        CreateUserListRequest.newBuilder()
            .setParent(
                AccountName.format(params.operatingAccountType.name(), params.operatingAccountId))
            .setUserList(userList)
            // Sets validate_only. If true, then the Data Manager API only validates the request
            // but doesn't apply changes.
            .setValidateOnly(params.validateOnly)
            .build();

    // Sends the request.
    UserList response = userListServiceClient.createUserList(request);

    // Logs the created user list. When validate_only is false, response.getId() contains the
    // created user list ID, which you pass as the product_destination_id in subsequent ingest or
    // remove requests.
    LOGGER.info(() -> String.format("Response:%n%s", response));
  }
}

ノード

/**
 * Runs the CreateUserList sample.
 * @param {string} operatingAccountType The account type of the operating account.
 * @param {string} operatingAccountId The ID of the operating account.
 * @param {boolean} validateOnly Whether to enable validate_only on the request.
 * @param {protos.google.ads.datamanager.v1.IngestedUserListInfo.UploadKeyType} uploadKeyType The upload key type of the user list.
 * @param {string} [loginAccountType] The account type of the login account.
 * @param {string} [loginAccountId] The ID of the login account.
 * @param {string} [linkedAccountType] The account type of the linked account.
 * @param {string} [linkedAccountId] The ID of the linked account.
 * @param {protos.google.ads.datamanager.v1.MobileIdInfo.KeySpace} [keySpace] The key space of mobile IDs. Required when uploadKeyType is MOBILE_ID.
 * @param {string} [appId] The mobile application ID. Required when uploadKeyType is MOBILE_ID.
 */
async function runSample(
  operatingAccountType: string,
  operatingAccountId: string,
  validateOnly: boolean,
  uploadKeyType: protos.google.ads.datamanager.v1.IngestedUserListInfo.UploadKeyType = CONTACT_ID,
  loginAccountType?: string,
  loginAccountId?: string,
  linkedAccountType?: string,
  linkedAccountId?: string,
  keySpace?: protos.google.ads.datamanager.v1.MobileIdInfo.KeySpace,
  appId?: string,
) {
  // Creates a client for UserListService.
  const userListClient = new UserListServiceClient();

  // Optional: Sets headers to specify the login-account and linked-account if
  // your credentials aren't for a user in the operating account (for example,
  // when authenticating through a Google Ads manager account or Data Partner
  // account).
  const headers: {[key: string]: string} = {};

  if (loginAccountType && loginAccountId) {
    headers['login-account'] = userListClient.accountPath(
      loginAccountType,
      loginAccountId,
    );
  }

  if (linkedAccountType && linkedAccountId) {
    headers['linked-account'] = userListClient.accountPath(
      linkedAccountType,
      linkedAccountId,
    );
  }

  // Configures the Customer Match user list.
  // For more details on constructing a UserList, see:
  // https://developers.google.com/data-manager/api/devguides/audiences/google-ads/customer-match/create-audience
  const ingestedUserListInfo = IngestedUserListInfo.create({
    // Sets to a list containing a single UploadKeyType.
    uploadKeyTypes: [uploadKeyType],
  });

  switch (uploadKeyType) {
    case CONTACT_ID:
      // Use CONTACT_ID for hashed email addresses, phone numbers, or physical
      // addresses.
      ingestedUserListInfo.contactIdInfo = ContactIdInfo.create({
        dataSourceType: DataSourceType.DATA_SOURCE_TYPE_FIRST_PARTY,
      });
      break;
    case USER_ID:
      // Use USER_ID for first-party user IDs assigned to logged-in users.
      // Note: Display & Video 360 does not support USER_ID lists.
      ingestedUserListInfo.userIdInfo = UserIdInfo.create({
        dataSourceType: DataSourceType.DATA_SOURCE_TYPE_FIRST_PARTY,
      });
      break;
    case MOBILE_ID:
      // Use MOBILE_ID for mobile advertising IDs.
      ingestedUserListInfo.mobileIdInfo = MobileIdInfo.create({
        dataSourceType: DataSourceType.DATA_SOURCE_TYPE_FIRST_PARTY,
        keySpace,
        appId,
      });
      break;
    default:
      throw new Error(`Unsupported upload key type: ${uploadKeyType}`);
  }

  const uploadKeyTypeName = Object.keys(
    IngestedUserListInfo.UploadKeyType,
  ).find(
    key =>
      IngestedUserListInfo.UploadKeyType[
        key as keyof typeof IngestedUserListInfo.UploadKeyType
      ] === uploadKeyType,
  );
  const timestamp = new Date().toISOString().replace('T', ' ').slice(0, 19);

  const userList = UserList.create({
    // Required. The display name must be unique among all lists owned by the
    // account.
    displayName: `Customer Match (${uploadKeyTypeName}) - ${timestamp}`,
    description: `Customer Match audience for ${uploadKeyTypeName}`,
    // Optional. The duration an audience member remains in the list after
    // being added. Must correspond to whole days (defaults to maximum if
    // not set).
    membershipDuration: Duration.create({
      seconds: 30 * 24 * 60 * 60,
    }),
    // Required for a Customer Match audience.
    ingestedUserListInfo,
  });

  // Builds the request targeting the parent operating account.
  const request = CreateUserListRequest.create({
    parent: userListClient.accountPath(
      operatingAccountType,
      operatingAccountId,
    ),
    userList,
    // Sets validate_only. If true, then the Data Manager API only
    // validates the request but doesn't apply changes.
    validateOnly,
  });

  // Sends the request with any configured header metadata.
  const [response] = await userListClient.createUserList(request, {
    otherArgs: {headers},
  });

  // Logs the created user list. When validate_only is false, response.id
  // contains the created user list ID, which you pass as the
  // product_destination_id in subsequent ingest or remove requests.
  console.log('Response:\n', response);
}

PHP

/**
 * Runs the sample.
 *
 * @param int $operatingAccountType The account type of the operating account.
 * @param string $operatingAccountId The ID of the operating account.
 * @param bool $validateOnly Whether to enable validateOnly on the request.
 * @param int $uploadKeyType The upload key type of the user list.
 * @param int|null $loginAccountType The account type of the login account.
 * @param string|null $loginAccountId The ID of the login account.
 * @param int|null $linkedAccountType The account type of the linked account.
 * @param string|null $linkedAccountId The ID of the linked account.
 * @param int|null $keySpace The key space of mobile IDs. Required when uploadKeyType is MOBILE_ID.
 * @param string|null $appId The mobile application ID. Required when uploadKeyType is MOBILE_ID.
 */
function main(
    int $operatingAccountType,
    string $operatingAccountId,
    bool $validateOnly,
    int $uploadKeyType = UploadKeyType::CONTACT_ID,
    ?int $loginAccountType = null,
    ?string $loginAccountId = null,
    ?int $linkedAccountType = null,
    ?string $linkedAccountId = null,
    ?int $keySpace = null,
    ?string $appId = null
): void {
    // Validates parameters.
    if (($loginAccountType !== null) !== ($loginAccountId !== null)) {
        throw new \InvalidArgumentException(
            'Must specify either both or neither of login account type and login account ID'
        );
    }
    if (($linkedAccountType !== null) !== ($linkedAccountId !== null)) {
        throw new \InvalidArgumentException(
            'Must specify either both or neither of linked account type and linked account ID'
        );
    }
    if ($uploadKeyType === UploadKeyType::MOBILE_ID) {
        if ($keySpace === null || empty($appId)) {
            throw new \InvalidArgumentException(
                'Must specify both key_space and app_id when upload_key_type is MOBILE_ID'
            );
        }
    } elseif ($keySpace !== null || !empty($appId)) {
        throw new \InvalidArgumentException(
            'key_space and app_id are only supported when upload_key_type is MOBILE_ID'
        );
    }

    // Optional: Sets headers to specify the login-account and linked-account if
    // your credentials aren't for a user in the operating account (for example,
    // when authenticating through a Google Ads manager account or Data Partner
    // account).
    $headers = [];

    if ($loginAccountType !== null && $loginAccountId !== null) {
        $headers['login-account'] = [
            UserListServiceClient::accountName(
                AccountType::name($loginAccountType),
                $loginAccountId
            ),
        ];
    }

    if ($linkedAccountType !== null && $linkedAccountId !== null) {
        $headers['linked-account'] = [
            UserListServiceClient::accountName(
                AccountType::name($linkedAccountType),
                $linkedAccountId
            ),
        ];
    }

    // Configures the Customer Match user list.
    // For more details on constructing a UserList, see:
    // https://developers.google.com/data-manager/api/devguides/audiences/google-ads/customer-match/create-audience
    $ingestedUserListInfo = (new IngestedUserListInfo())
        // Sets to a list containing a single UploadKeyType.
        ->setUploadKeyTypes([$uploadKeyType]);

    switch ($uploadKeyType) {
        case UploadKeyType::CONTACT_ID:
            // Use CONTACT_ID for hashed email addresses, phone numbers, or physical addresses.
            $ingestedUserListInfo->setContactIdInfo(
                (new ContactIdInfo())
                    ->setDataSourceType(DataSourceType::DATA_SOURCE_TYPE_FIRST_PARTY)
            );
            break;
        case UploadKeyType::USER_ID:
            // Use USER_ID for first-party user IDs assigned to logged-in users.
            // Note: Display & Video 360 does not support USER_ID lists.
            $ingestedUserListInfo->setUserIdInfo(
                (new UserIdInfo())
                    ->setDataSourceType(DataSourceType::DATA_SOURCE_TYPE_FIRST_PARTY)
            );
            break;
        case UploadKeyType::MOBILE_ID:
            // Use MOBILE_ID for mobile advertising IDs.
            $ingestedUserListInfo->setMobileIdInfo(
                (new MobileIdInfo())
                    ->setDataSourceType(DataSourceType::DATA_SOURCE_TYPE_FIRST_PARTY)
                    ->setKeySpace($keySpace)
                    ->setAppId($appId)
            );
            break;
        default:
            throw new \InvalidArgumentException(
                sprintf('Unsupported upload key type: %s', UploadKeyType::name($uploadKeyType))
            );
    }

    $uploadKeyTypeName = UploadKeyType::name($uploadKeyType);
    $userList = (new UserList())
        // Required. The display name must be unique among all lists owned by the account.
        ->setDisplayName(sprintf(
            'Customer Match (%s) - %s',
            $uploadKeyTypeName,
            (new \DateTime())->format('Y-m-d H:i:s')
        ))
        ->setDescription(sprintf('Customer Match audience for %s', $uploadKeyTypeName))
        // Optional. The duration an audience member remains in the list after being added. Must
        // correspond to whole days (defaults to maximum if not set).
        ->setMembershipDuration((new Duration())->setSeconds(30 * 24 * 60 * 60))
        // Required for a Customer Match audience.
        ->setIngestedUserListInfo($ingestedUserListInfo);

    // Creates a client for UserListService.
    $userListClient = new UserListServiceClient();

    // Builds the request targeting the parent operating account.
    $request = (new CreateUserListRequest())
        ->setParent(
            UserListServiceClient::accountName(
                AccountType::name($operatingAccountType),
                $operatingAccountId
            )
        )
        ->setUserList($userList)
        // Sets validate_only. If true, then the Data Manager API only validates the request
        // but doesn't apply changes.
        ->setValidateOnly($validateOnly);

    try {
        // Sends the request with any configured header metadata.
        $response = $userListClient->createUserList($request, ['headers' => $headers]);

        // Logs the created user list. When validate_only is false, $response->getId() contains the
        // created user list ID, which you pass as the product_destination_id in subsequent ingest or
        // remove requests.
        echo "Response:\n" . json_encode(json_decode($response->serializeToJsonString()), JSON_PRETTY_PRINT) . "\n";
    } catch (ApiException $e) {
        echo 'Error sending request: ' . $e->getMessage() . "\n";
    } finally {
        $userListClient->close();
    }
}

Python

def main(
    operating_account_type: datamanager_v1.ProductAccount.AccountType,
    operating_account_id: str,
    validate_only: bool,
    upload_key_type: datamanager_v1.IngestedUserListInfo.UploadKeyType = (
        datamanager_v1.IngestedUserListInfo.UploadKeyType.CONTACT_ID
    ),
    login_account_type: Optional[
        datamanager_v1.ProductAccount.AccountType
    ] = None,
    login_account_id: Optional[str] = None,
    linked_account_type: Optional[
        datamanager_v1.ProductAccount.AccountType
    ] = None,
    linked_account_id: Optional[str] = None,
    key_space: Optional[datamanager_v1.MobileIdInfo.KeySpace] = None,
    app_id: Optional[str] = None,
) -> None:
    """Runs the sample.

    Args:
     operating_account_type: the account type of the operating account.
     operating_account_id: the ID of the operating account.
     validate_only: whether to enable validate_only on the request.
     upload_key_type: the upload key type of the user list.
     login_account_type: the account type of the login account.
     login_account_id: the ID of the login account.
     linked_account_type: the account type of the linked account.
     linked_account_id: the ID of the linked account.
     key_space: the key space of mobile IDs. Required when upload_key_type is
       MOBILE_ID.
     app_id: the mobile application ID. Required when upload_key_type is
       MOBILE_ID.
    """

    # Validates parameters.
    if bool(login_account_type) != bool(login_account_id):
        raise ValueError(
            "Must specify either both or neither of login account type and "
            "login account ID"
        )
    if bool(linked_account_type) != bool(linked_account_id):
        raise ValueError(
            "Must specify either both or neither of linked account type and "
            "linked account ID"
        )
    if (
        upload_key_type
        == datamanager_v1.IngestedUserListInfo.UploadKeyType.MOBILE_ID
    ):
        if not key_space or not app_id:
            raise ValueError(
                "Must specify both key_space and app_id when upload_key_type "
                "is MOBILE_ID"
            )
    elif key_space or app_id:
        raise ValueError(
            "key_space and app_id are only supported when upload_key_type is "
            "MOBILE_ID"
        )

    # Optional: Sets headers to specify the login-account and linked-account if
    # your credentials aren't for a user in the operating account (for example,
    # when authenticating through a Google Ads manager account or Data Partner
    # account).
    headers = []

    if login_account_id:
        headers.append(
            (
                "login-account",
                f"accountTypes/{login_account_type.name}/accounts/{login_account_id}",
            )
        )

    if linked_account_id:
        headers.append(
            (
                "linked-account",
                f"accountTypes/{linked_account_type.name}/accounts/{linked_account_id}",
            )
        )

    # Configures the Customer Match user list.
    # For more details on constructing a UserList, see:
    # https://developers.google.com/data-manager/api/devguides/audiences/google-ads/customer-match/create-audience
    ingested_user_list_info = datamanager_v1.IngestedUserListInfo(
        # Sets to a list containing a single UploadKeyType.
        upload_key_types=[upload_key_type],
    )

    if (
        upload_key_type
        == datamanager_v1.IngestedUserListInfo.UploadKeyType.CONTACT_ID
    ):
        # Use CONTACT_ID for hashed email addresses, phone numbers, or physical
        # addresses.
        ingested_user_list_info.contact_id_info = datamanager_v1.ContactIdInfo(
            data_source_type=(
                datamanager_v1.DataSourceType.DATA_SOURCE_TYPE_FIRST_PARTY
            )
        )
    elif (
        upload_key_type
        == datamanager_v1.IngestedUserListInfo.UploadKeyType.USER_ID
    ):
        # Use USER_ID for first-party user IDs assigned to logged-in users.
        ingested_user_list_info.user_id_info = datamanager_v1.UserIdInfo(
            data_source_type=(
                datamanager_v1.DataSourceType.DATA_SOURCE_TYPE_FIRST_PARTY
            )
        )
    elif (
        upload_key_type
        == datamanager_v1.IngestedUserListInfo.UploadKeyType.MOBILE_ID
    ):
        # Use MOBILE_ID for mobile advertising IDs.
        ingested_user_list_info.mobile_id_info = datamanager_v1.MobileIdInfo(
            data_source_type=(
                datamanager_v1.DataSourceType.DATA_SOURCE_TYPE_FIRST_PARTY
            ),
            key_space=key_space,
            app_id=app_id,
        )
    else:
        raise ValueError(f"Unsupported upload key type: {upload_key_type}")

    user_list = datamanager_v1.UserList(
        # Required. The display name must be unique among all lists owned by the
        # account.
        display_name=(
            f"Customer Match ({upload_key_type.name}) - "
            f"{datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"
        ),
        description=f"Customer Match audience for {upload_key_type.name}",
        # Optional. The duration an audience member remains in the list after
        # being added. Must correspond to whole days (defaults to maximum if
        # not set).
        membership_duration=datetime.timedelta(days=30),
        # Required for a Customer Match audience.
        ingested_user_list_info=ingested_user_list_info,
    )

    # Creates a client for UserListService.
    user_list_client = datamanager_v1.UserListServiceClient()

    # Builds the request targeting the parent operating account.
    request = datamanager_v1.CreateUserListRequest(
        parent=f"accountTypes/{operating_account_type.name}/accounts/{operating_account_id}",
        user_list=user_list,
        # Sets validate_only. If true, then the Data Manager API only
        # validates the request but doesn't apply changes.
        validate_only=validate_only,
    )

    # Sends the request with any configured header metadata.
    response: datamanager_v1.UserList = user_list_client.create_user_list(
        request=request,
        metadata=headers,
    )

    # Logs the created user list. When validate_only is false, response.id
    # contains the created user list ID, which you pass as the
    # product_destination_id in subsequent ingest or remove requests.
    _logger.info("Response:\n%s", response)

リクエストを送信する

リクエストを送信します。必要に応じて、login-account や linked-account などのリクエスト ヘッダーを含めます。

リクエストが成功すると、レスポンスには、出力専用の id フィールドと name フィールドが入力された、作成された UserList が含まれます。

リクエストが失敗した場合は、エラーを調べて失敗の原因を特定し、リクエストとヘッダーを更新して問題を修正してから、更新されたリクエストとヘッダーを送信します。