การจับคู่ข้อมูลลูกค้าช่วยให้คุณนำข้อมูลออนไลน์และออฟไลน์มาใช้เพื่อเข้าถึงและสร้างการมีส่วนร่วมกับลูกค้าได้อีกครั้งผ่าน Search, แท็บ Shopping, Gmail, YouTube และ Display โดยใช้ข้อมูลที่ลูกค้าแชร์กับคุณเพื่อกำหนดเป้าหมายโฆษณาไปยังลูกค้าเหล่านั้นและลูกค้ารายอื่นๆ ที่คล้ายคลึงกัน คุณสามารถอัปโหลดข้อมูลการจัดการลูกค้าสัมพันธ์ (CRM) หลายรายการพร้อมกัน เพิ่มหรือนําข้อมูลออก หรือใช้รายชื่อผู้ใช้เหล่านี้เพื่อสร้าง logical_user_list
ดูภาพรวมของการจัดการกลุ่มเป้าหมายเพื่อดูรายการกลุ่มเป้าหมายประเภทต่างๆ เพื่อเปรียบเทียบการจับคู่ข้อมูลลูกค้ากับตัวเลือกรายชื่อผู้ใช้อื่นๆ
ดูข้อมูลเพิ่มเติมเกี่ยวกับการจับคู่ข้อมูลลูกค้าและการกำหนดกลุ่มเป้าหมาย
ข้อกำหนดเบื้องต้น
บัญชีบางบัญชีไม่มีสิทธิ์ใช้การจับคู่ข้อมูลลูกค้า ในการใช้การจับคู่ข้อมูลลูกค้า บัญชีของคุณต้องมีสิ่งต่อไปนี้
- ปฏิบัติตามนโยบายอย่างถูกต้องมาโดยตลอด
- ชำระเงินตรงตามกำหนดเสมอมา
เรามีฟีเจอร์ต่างๆ ให้ใช้งาน โดยขึ้นอยู่กับข้อกำหนดที่บัญชีของคุณผ่านเกณฑ์ โปรดอ่านนโยบายการจับคู่ข้อมูลลูกค้าเพื่อดูข้อกำหนดและข้อจำกัดของการได้รับสิทธิ์
ออกแบบการผสานรวมของคุณ
คุณสามารถออกแบบการผสานรวมได้
ขั้นตอนการใช้งาน
ขั้นตอนที่แนะนําในการสร้างและกําหนดเป้าหมายรายชื่อลูกค้ามีดังนี้
สร้างรายชื่อลูกค้าที่ว่างเปล่า
สร้าง
OfflineUserDataJob
การสร้างงานชิ้นเดียวที่มีขนาดใหญ่จะมีประสิทธิภาพมากกว่างานเล็กๆ หลายงานตรวจสอบว่าคุณป้อนข้อมูลในช่อง
consent
ของcustomer_match_user_list_metadata
ในคำขอOfflineUserDataJob
create
สำหรับคำขอremove
ไม่จำเป็นต้องขอความยินยอม API จะแสดงผลเป็นOfflineUserDataJobError.CUSTOMER_NOT_ACCEPTED_CUSTOMER_DATA_TERMS
หากมีการตั้งค่าconsent.ad_user_data
หรือconsent.ad_personalization
ของงานเป็นDENIED
หากผู้ใช้ปฏิเสธความยินยอม คุณจะสร้างงานด้วยการดำเนินการ
remove
เพื่อนำตัวระบุของผู้ใช้ออกจากรายการผู้ใช้ได้หากคุณไม่ได้รับความยินยอมสำหรับผู้ใช้บางราย ให้สร้างงานแยกต่างหากที่คุณไม่ได้ตั้งค่าช่อง
consent
ของงานcustomer_match_user_list_metadata
แล้วเพิ่มตัวระบุสำหรับผู้ใช้เหล่านั้นโดยใช้การดำเนินการcreate
สำหรับงานแยกต่างหากนั้นเพิ่มการดำเนินการโดยใช้วิธี
OfflineUserDataJobService.AddOfflineUserDataJobOperations
เราขอแนะนำให้เพิ่มตัวระบุทั้งหมดไม่เกิน 10,000 รายการในการเรียกใช้ครั้งเดียวเพื่อให้การประมวลผลมีประสิทธิภาพสูงสุด คำขอAddOfflineUserDataJobOperations
รายการเดียวมีตัวระบุได้สูงสุด 100,000 รายการในออบเจ็กต์UserData
ทั้งหมดในรายการการดำเนินการตัวอย่างเช่น หากออบเจ็กต์
UserData
แต่ละรายการมีUserIdentifier
1 รายการสำหรับhashed_email
และอีกUserIdentifier
รายการสำหรับhashed_phone_number
การส่งออบเจ็กต์UserData
5,000 รายการต่อคำขอถือเป็นการดำเนินการที่ดีที่สุด เนื่องจากแต่ละคำขอจะมีตัวระบุผู้ใช้รวม 10,000 รายการทำซ้ำขั้นตอนก่อนหน้าจนกว่าจะเพิ่มการดำเนินการทั้งหมด หรือจนกว่างานจะเต็ม ไม่มีการจํากัดจํานวนการดำเนินการที่เพิ่มลงในงานเดียว แต่เราขอแนะนําให้เพิ่มการดำเนินการไม่เกิน 1,000,000 รายการต่องานเพื่อให้การประมวลผลมีประสิทธิภาพสูงสุด
เรียกใช้งาน
แบบสำรวจเพื่อให้อัปโหลดได้สำเร็จ
ยืนยันอัตราการจับคู่
กําหนดเป้าหมายรายการ
OfflineUserDataJobService และ UserDataService
บริการสําหรับอัปโหลดข้อมูลการจับคู่ข้อมูลลูกค้ามีอยู่ 2 บริการ เลือกบริการตามกรณีการใช้งานเนื่องจากอาจมีข้อจำกัดสำหรับบริการ
บริการอัปโหลดการจับคู่ข้อมูลลูกค้า | |
---|---|
OfflineUserDataJobService (แนะนำ)
|
นักพัฒนาแอปส่วนใหญ่ใช้บริการนี้ เครื่องมือนี้เพิ่มประสิทธิภาพสำหรับการอัปโหลดขนาดใหญ่ที่มีปริมาณงานสูง และแสดงเมตริกความสําเร็จเมื่อดำเนินการเสร็จสมบูรณ์ คู่มือนี้จะเน้นที่บริการนี้เป็นหลัก |
UserDataService
|
บริการนี้ได้รับการเพิ่มประสิทธิภาพเพื่ออัปโหลดตัวระบุจำนวนน้อยพร้อมๆ กับการอัปเดตเป็นระยะๆ และไม่มีการเพิ่มประสิทธิภาพให้ทำงานอย่างต่อเนื่อง มีการจำกัดการดำเนินการไว้ที่ 10 รายการต่อคำขอ นอกจากนี้ คําขอเดียวต้องมีuser_identifiers ทั้งหมดไม่เกิน 100 รายการ
ดูคําแนะนําเกี่ยวกับการอัปโหลดด้วยบริการนี้ได้จากคู่มือสําหรับการจัดการการผสานรวมการจับคู่ข้อมูลลูกค้า ตั้งแต่เวอร์ชัน v15 ของ Google Ads API เป็นต้นไป คุณควรป้อนข้อมูลในช่อง |
แนวทางปฏิบัติแนะนำ
โปรดคำนึงถึงแนวทางปฏิบัติแนะนำต่อไปนี้เมื่อออกแบบการผสานรวมการจับคู่ข้อมูลลูกค้า
อย่าพยายามใช้หลายบัญชีเพื่อแก้ไขรายการผู้ใช้รายการเดียว บัญชี Google Ads หรือพาร์ทเนอร์ด้านข้อมูลที่สร้างรายการผู้ใช้เท่านั้นที่จะแก้ไขรายการได้
เพิ่มจำนวนการดำเนินการต่อ
AddOfflineUserDataJobOperationsRequest
สูงสุด 100,000 ตัวระบุเพื่อหลีกเลี่ยงข้อผิดพลาดRESOURCE_EXHAUSTED
อย่ารวมการดำเนินการ
create
และremove
เข้าด้วยกันในOfflineUserDataJob
เดียวกัน เนื่องจากอาจทำให้เกิดข้อผิดพลาดCONFLICTING_OPERATION
เปิดใช้
partial_failure
ในAddOfflineUserDataJobOperationsRequest
เพื่อตรวจหาการดำเนินการที่มีปัญหาก่อนที่จะเรียกใช้งาน ระบบจะตรวจสอบการดำเนินการเมื่ออัปโหลดไปยังOfflineUserDataJob
หลีกเลี่ยงการเรียกใช้กระบวนการ
OfflineUserDataJob
หลายรายการพร้อมกันซึ่งแก้ไขรายการผู้ใช้เดียวกัน (นั่นคือ งานหลายรายการที่CustomerMatchUserListMetadata.user_list
ชี้ไปยังชื่อทรัพยากรเดียวกัน) การดำเนินการดังกล่าวอาจส่งผลให้เกิดข้อผิดพลาดCONCURRENT_MODIFICATION
เนื่องจากระบบไม่อนุญาตให้มีงานหลายรายการทำงานในรายการเดียวกันพร้อมกัน ข้อผิดพลาดนี้ยังอาจเกิดขึ้นได้หากพยายามแก้ไขรายการผ่าน UI ของ Google Ads และ Google Ads API พร้อมกัน โปรดทราบว่าการดำเนินการนี้ไม่มีผลกับการเพิ่มการดำเนินการไปยังงานPENDING
ซึ่งดำเนินการได้ทุกเมื่อก่อนที่งานจะเริ่มต้นหากคุณมีการดำเนินการหลายพันรายการที่จะใช้ ให้สร้างการดำเนินการรายการเดียว
OfflineUserDataJob
ที่มีการดำเนินการทั้งหมด อย่าสร้างงานหลายงานด้วยการดำเนินการเพียงไม่กี่ร้อยงานในแต่ละงาน และเรียกใช้ตามลำดับหรือพร้อมกัน งานขนาดใหญ่งานเดียวที่มีการดำเนินการทั้งหมดมีประสิทธิภาพมากกว่างานขนาดเล็กหลายงาน และลดโอกาสที่คุณจะพบข้อผิดพลาดในเวิร์กโฟลว์
สำหรับแนวคิดเกี่ยวกับวิธีใช้ประโยชน์จากรายชื่อลูกค้าเพื่อการกำหนดเป้าหมายที่เหมาะสม โปรดไปที่ศูนย์ช่วยเหลือ
สร้างรายชื่อลูกค้า
ก่อนอื่นให้สร้างรายชื่อลูกค้าด้วยUserListService
คุณสามารถสร้างรายชื่อลูกค้าได้โดยการตั้งค่าช่อง crm_based_user_list
ในออบเจ็กต์ user_list
คุณจะตั้งค่าช่อง crm_based_user_list
ในประเภทแคมเปญที่รองรับการกำหนดเป้าหมายรายชื่อลูกค้าได้ ดังนี้
การจับคู่ข้อมูลลูกค้าในแคมเปญประเภทต่างๆ | |
---|---|
เครือข่าย Search | โฆษณาแสดงในเครือข่าย Search |
เครือข่ายดิสเพลย์ | โฆษณาจะแสดงบนเครือข่ายดิสเพลย์และใน Gmail ต่อเมื่อมีครีเอทีฟโฆษณา GSP เท่านั้น |
การขยายไปยังเครือข่าย Display ในแคมเปญ Search | โฆษณาจะแสดงในเครือข่าย Search และใน Gmail เฉพาะเมื่อมีครีเอทีฟโฆษณา GSP เท่านั้น |
แคมเปญวิดีโอ | โฆษณาจะแสดงบน YouTube เมื่อมีโฆษณาแบบ TrueView ในสตรีมเท่านั้น |
แคมเปญ Shopping | โฆษณาจะแสดงในแท็บ Shopping |
crm_based_user_list
มี 3 ช่อง ได้แก่
app_id
: สตริงที่ระบุแอปบนอุปกรณ์เคลื่อนที่ที่รวบรวมข้อมูลมาโดยไม่ซ้ำกัน ซึ่งจำเป็นเมื่อสร้างCrmBasedUserList
สำหรับการอัปโหลดรหัสโฆษณาบนอุปกรณ์เคลื่อนที่upload_key_type
: ประเภทคีย์ที่ตรงกันของรายการ ซึ่งอาจเป็นCONTACT_INFO
,CRM_ID
หรือMOBILE_ADVERTISING_ID
ไม่อนุญาตให้ใช้ข้อมูลหลายประเภทในรายการเดียวกัน ต้องระบุข้อมูลในช่องนี้สำหรับรายชื่อลูกค้าทั้งหมดdata_source_type
: แหล่งข้อมูลของรายการ ค่าเริ่มต้นคือFIRST_PARTY
ลูกค้าในรายการที่อนุญาตอาจสร้างรายชื่อลูกค้าที่มาจากบุคคลที่สาม
แอตทริบิวต์ membership_life_span
ของรายชื่อผู้ใช้ช่วยให้คุณกำหนดระยะเวลาเป็นจำนวนวันที่ระบบถือว่าผู้ใช้อยู่ในรายการได้ ประเภทรายชื่อลูกค้าช่วยให้คุณตั้งค่า membership_life_span
เป็น 10,000 เพื่อระบุว่าไม่มีวันหมดอายุได้
แอตทริบิวต์ membership_status
จะกำหนดว่ารายการยอมรับผู้ใช้ใหม่หรือไม่
ตัวอย่างโค้ดสำหรับสร้างรายชื่อลูกค้า
Java
private String createCustomerMatchUserList(GoogleAdsClient googleAdsClient, long customerId) { // Creates the new user list. UserList userList = UserList.newBuilder() .setName("Customer Match list #" + getPrintableDateTime()) .setDescription("A list of customers that originated from email addresses") // Customer Match user lists can use a membership life span of 10,000 to indicate // unlimited; otherwise normal values apply. // Sets the membership life span to 30 days. .setMembershipLifeSpan(30) // Sets the upload key type to indicate the type of identifier that will be used to // add users to the list. This field is immutable and required for a CREATE operation. .setCrmBasedUserList( CrmBasedUserListInfo.newBuilder() .setUploadKeyType(CustomerMatchUploadKeyType.CONTACT_INFO)) .build(); // Creates the operation. UserListOperation operation = UserListOperation.newBuilder().setCreate(userList).build(); // Creates the service client. try (UserListServiceClient userListServiceClient = googleAdsClient.getLatestVersion().createUserListServiceClient()) { // Adds the user list. MutateUserListsResponse response = userListServiceClient.mutateUserLists( Long.toString(customerId), ImmutableList.of(operation)); // Prints the response. System.out.printf( "Created Customer Match user list with resource name: %s.%n", response.getResults(0).getResourceName()); return response.getResults(0).getResourceName(); } }
C#
private string CreateCustomerMatchUserList(GoogleAdsClient client, long customerId) { // Get the UserListService. UserListServiceClient service = client.GetService(Services.V18.UserListService); // Creates the user list. UserList userList = new UserList() { Name = $"Customer Match list# {ExampleUtilities.GetShortRandomString()}", Description = "A list of customers that originated from email and physical" + " addresses", // Customer Match user lists can use a membership life span of 10000 to // indicate unlimited; otherwise normal values apply. // Sets the membership life span to 30 days. MembershipLifeSpan = 30, CrmBasedUserList = new CrmBasedUserListInfo() { UploadKeyType = CustomerMatchUploadKeyType.ContactInfo } }; // Creates the user list operation. UserListOperation operation = new UserListOperation() { Create = userList }; // Issues a mutate request to add the user list and prints some information. MutateUserListsResponse response = service.MutateUserLists( customerId.ToString(), new[] { operation }); string userListResourceName = response.Results[0].ResourceName; Console.WriteLine($"User list with resource name '{userListResourceName}' " + $"was created."); return userListResourceName; }
PHP
private static function createCustomerMatchUserList( GoogleAdsClient $googleAdsClient, int $customerId ): string { // Creates the user list. $userList = new UserList([ 'name' => 'Customer Match list #' . Helper::getPrintableDatetime(), 'description' => 'A list of customers that originated from email ' . 'and physical addresses', // Customer Match user lists can use a membership life span of 10000 to // indicate unlimited; otherwise normal values apply. // Sets the membership life span to 30 days. 'membership_life_span' => 30, 'crm_based_user_list' => new CrmBasedUserListInfo([ // Sets the upload key type to indicate the type of identifier that will be used to // add users to the list. This field is immutable and required for a CREATE // operation. 'upload_key_type' => CustomerMatchUploadKeyType::CONTACT_INFO ]) ]); // Creates the user list operation. $operation = new UserListOperation(); $operation->setCreate($userList); // Issues a mutate request to add the user list and prints some information. $userListServiceClient = $googleAdsClient->getUserListServiceClient(); $response = $userListServiceClient->mutateUserLists( MutateUserListsRequest::build($customerId, [$operation]) ); $userListResourceName = $response->getResults()[0]->getResourceName(); printf("User list with resource name '%s' was created.%s", $userListResourceName, PHP_EOL); return $userListResourceName; }
Python
def create_customer_match_user_list(client, customer_id): """Creates a Customer Match user list. Args: client: The Google Ads client. customer_id: The ID for the customer that owns the user list. Returns: The string resource name of the newly created user list. """ # Creates the UserListService client. user_list_service_client = client.get_service("UserListService") # Creates the user list operation. user_list_operation = client.get_type("UserListOperation") # Creates the new user list. user_list = user_list_operation.create user_list.name = f"Customer Match list #{uuid.uuid4()}" user_list.description = ( "A list of customers that originated from email and physical addresses" ) # Sets the upload key type to indicate the type of identifier that is used # to add users to the list. This field is immutable and required for a # CREATE operation. user_list.crm_based_user_list.upload_key_type = ( client.enums.CustomerMatchUploadKeyTypeEnum.CONTACT_INFO ) # Customer Match user lists can set an unlimited membership life span; # to do so, use the special life span value 10000. Otherwise, membership # life span must be between 0 and 540 days inclusive. See: # https://developers.devsite.corp.google.com/google-ads/api/reference/rpc/latest/UserList#membership_life_span # Sets the membership life span to 30 days. user_list.membership_life_span = 30 response = user_list_service_client.mutate_user_lists( customer_id=customer_id, operations=[user_list_operation] ) user_list_resource_name = response.results[0].resource_name print( f"User list with resource name '{user_list_resource_name}' was created." ) return user_list_resource_name
Ruby
def create_customer_match_user_list(client, customer_id) # Creates the user list. operation = client.operation.create_resource.user_list do |ul| ul.name = "Customer Match List #{(Time.new.to_f * 1000).to_i}" ul.description = "A list of customers that originated from email and " \ "physical addresses" # Customer Match user lists can use a membership life span of 10000 to # indicate unlimited; otherwise normal values apply. # Sets the membership life span to 30 days. ul.membership_life_span = 30 ul.crm_based_user_list = client.resource.crm_based_user_list_info do |crm| crm.upload_key_type = :CONTACT_INFO end end # Issues a mutate request to add the user list and prints some information. response = client.service.user_list.mutate_user_lists( customer_id: customer_id, operations: [operation], ) # Prints out some information about the newly created user list. resource_name = response.results.first.resource_name puts "User list with resource name #{resource_name} was created." resource_name end
Perl
sub create_customer_match_user_list { my ($api_client, $customer_id) = @_; # Create the user list. my $user_list = Google::Ads::GoogleAds::V18::Resources::UserList->new({ name => "Customer Match list #" . uniqid(), description => "A list of customers that originated from email and physical addresses", # Customer Match user lists can use a membership life span of 10000 to # indicate unlimited; otherwise normal values apply. # Set the membership life span to 30 days. membershipLifeSpan => 30, # Set the upload key type to indicate the type of identifier that will be # used to add users to the list. This field is immutable and required for # a CREATE operation. crmBasedUserList => Google::Ads::GoogleAds::V18::Common::CrmBasedUserListInfo->new({ uploadKeyType => CONTACT_INFO })}); # Create the user list operation. my $user_list_operation = Google::Ads::GoogleAds::V18::Services::UserListService::UserListOperation-> new({ create => $user_list }); # Issue a mutate request to add the user list and print some information. my $user_lists_response = $api_client->UserListService()->mutate({ customerId => $customer_id, operations => [$user_list_operation]}); my $user_list_resource_name = $user_lists_response->{results}[0]{resourceName}; printf "User list with resource name '%s' was created.\n", $user_list_resource_name; return $user_list_resource_name; }
เพิ่มข้อมูลลูกค้า
คีย์การจับคู่หลัก 3 รายการ ได้แก่ อีเมล ที่อยู่ไปรษณีย์ และหมายเลขโทรศัพท์ คุณใช้รหัสผู้ใช้และรหัสอุปกรณ์เคลื่อนที่เป็นคีย์การจับคู่ได้ แต่โซลูชันเหล่านี้รองรับการใช้งานในอนาคตน้อยกว่าเนื่องจากอาศัยคุกกี้และรหัสอุปกรณ์ ขอแนะนำให้อัปโหลดข้อมูลติดต่อของผู้ใช้ เช่น อีเมล ที่อยู่จัดส่ง และหมายเลขโทรศัพท์ แทน CRM หรือรหัสอุปกรณ์เคลื่อนที่
รายการผู้ใช้แต่ละรายการจะมีข้อมูลลูกค้าได้เพียงประเภทเดียวตามที่ระบุในช่อง CrmBasedUserListInfo.upload_key_type
นอกจากนี้ ออบเจ็กต์ UserData
ซึ่งแสดงถึงผู้ใช้รายเดียวอาจมีตัวระบุผู้ใช้ได้สูงสุด 20 รายการ โดยแต่ละรายการมีออบเจ็กต์ UserIdentifier
ของตัวเอง ตัวระบุมากกว่า 20 รายการทำให้เกิดข้อผิดพลาด TOO_MANY_USER_IDENTIFIERS
Google Ads จะใช้รายการผู้ใช้การจับคู่ข้อมูลลูกค้าสําหรับการกําหนดเป้าหมายก็ต่อเมื่อรายการดังกล่าวมีผู้ใช้ที่ใช้งานอยู่เป็นจํานวนตามเกณฑ์ขั้นต่ำในช่วงเวลาที่แสดงโฆษณา โดยผู้ใช้ที่ใช้งานอยู่คือจํานวนผู้ใช้ในรายการของคุณที่ใช้งานอยู่ใน Gmail, Search, YouTube หรือ Display อัปโหลดสมาชิกอย่างน้อย 5,000 คนเพื่อเพิ่มโอกาสที่จะมีผู้ใช้ที่ใช้งานอยู่ซึ่งตรงกันและเพียงพอสำหรับการกําหนดเป้าหมาย
อัปโหลดข้อมูลติดต่อของผู้ใช้
หากต้องการอัปโหลดอีเมล ที่อยู่ทางไปรษณีย์ หรือหมายเลขโทรศัพท์ของผู้ใช้ ให้ตั้งค่า upload_key_type
เป็น CONTACT_INFO
โปรดทราบว่าข้อมูลติดต่อต้องเชื่อมโยงกับบัญชี Google จึงจะตรงกัน และไม่สามารถกำหนดเป้าหมายบัญชีบริษัท เช่น Google Workspace ได้
อีเมล ชื่อนามสกุล และหมายเลขโทรศัพท์ต้องได้รับการแฮชโดยใช้อัลกอริทึม SHA-256 ก่อนที่จะอัปโหลด เพื่อไม่ให้เกิดข้อกังวลเกี่ยวกับความเป็นส่วนตัว เพื่อให้ผลลัพธ์แฮชเป็นมาตรฐาน โปรดตรวจสอบว่าคุณได้ดำเนินการต่อไปนี้ก่อนที่จะแฮชค่าใดค่าหนึ่ง
- นําช่องว่างขึ้นต้นและต่อท้ายออก
- สำหรับชื่อ อีเมล และที่อยู่จัดส่ง: แปลงข้อความเป็นตัวพิมพ์เล็ก
- สําหรับหมายเลขโทรศัพท์ ให้แปลงหมายเลขโทรศัพท์แต่ละหมายเลขเป็นรูปแบบ E164 ก่อนการแฮช รูปแบบนี้จะแสดงหมายเลขโทรศัพท์เป็นตัวเลขที่มีความยาวได้สูงสุด 15 หลัก โดยขึ้นต้นด้วยเครื่องหมาย
+
เช่น+12125650000
หรือ+442070313000
คุณจะไม่ใส่เครื่องหมาย+
ที่ขึ้นต้นก็ได้
สำหรับอีเมล คุณไม่จำเป็นต้องนำจุด (.
) ที่อยู่ก่อนชื่อโดเมนในอีเมล gmail.com
และ googlemail.com
ออกทั้งหมด เนื่องจากระบบยังคงยอมรับอีเมลดังกล่าว
หากข้อมูลติดต่อไม่ได้จัดรูปแบบอย่างถูกต้องก่อนแฮช API จะยังคงยอมรับข้อมูลที่แฮช แต่จะจับคู่กับลูกค้าไม่ได้
หากต้องการอัปโหลดข้อมูลที่อยู่จัดส่ง คุณต้องระบุข้อมูลต่อไปนี้เป็นอย่างน้อย
- รหัสประเทศ
- รหัสไปรษณีย์
- ชื่อที่ผ่านการแฮช
- นามสกุลที่แฮช
หากช่องใดช่องหนึ่งเหล่านี้ขาดหายไป ระบบจะจับคู่ที่อยู่ไม่ได้
แม้ว่ารายการลูกค้าจะมีได้เพียง upload_key_type
รายการ แต่คุณอัปโหลดข้อมูลติดต่อหลายประเภทสำหรับ upload_key_type
ของ CONTACT_INFO
ได้
ขอแนะนำให้ใช้วิธีนี้เพื่อเพิ่มอัตราการจับคู่
อัปโหลดรหัส CRM
หากต้องการป้อนข้อมูลรายชื่อลูกค้าด้วยรหัส CRM ให้ตั้งค่า upload_key_type
เป็น CRM_ID
ระบบจะจับคู่รหัส CRM จากรหัสผู้ใช้ที่สร้างขึ้นและกําหนดโดยผู้ลงโฆษณา
ซึ่งคล้ายกับการอัปโหลดอินสแตนซ์ MOBILE_ADVERTISING_ID
แต่คุณจะต้องป้อนข้อมูลในช่อง third_party_user_id
ของออบเจ็กต์ UserIdentifier
แทน
อัปโหลดรหัสอุปกรณ์เคลื่อนที่
คุณสามารถทําการจับคู่ข้อมูลลูกค้าโดยใช้รหัสอุปกรณ์เคลื่อนที่ของตัวระบุสําหรับการโฆษณา (IDFA) หรือรหัสโฆษณาของ Google (AAID) ได้ ซึ่งคล้ายกับการจับคู่ข้อมูลลูกค้าด้วยอีเมล โดยระบุพร็อพเพอร์ตี้ app_id
และตั้งค่า upload_key_type
เป็น MOBILE_ADVERTISING_ID
ก่อนใช้รายการผู้ใช้เพื่อจับคู่ข้อมูลลูกค้ากับรหัสอุปกรณ์เคลื่อนที่
ตัวอย่างโค้ด
ตัวอย่างต่อไปนี้ใช้ OfflineUserDataJobOperation
เพื่อเพิ่มข้อมูลติดต่อของลูกค้าลงในรายชื่อลูกค้า
Java
// Creates a raw input list of unhashed user information, where each element of the list // represents a single user and is a map containing a separate entry for the keys "email", // "phone", "firstName", "lastName", "countryCode", and "postalCode". In your application, this // data might come from a file or a database. List<Map<String, String>> rawRecords = new ArrayList<>(); // The first user data has an email address and a phone number. Map<String, String> rawRecord1 = ImmutableMap.<String, String>builder() .put("email", "dana@example.com") // Phone number to be converted to E.164 format, with a leading '+' as required. This // includes whitespace that will be removed later. .put("phone", "+1 800 5550101") .build(); // The second user data has an email address, a mailing address, and a phone number. Map<String, String> rawRecord2 = ImmutableMap.<String, String>builder() // Email address that includes a period (.) before the domain. .put("email", "alex.2@example.com") // Address that includes all four required elements: first name, last name, country // code, and postal code. .put("firstName", "Alex") .put("lastName", "Quinn") .put("countryCode", "US") .put("postalCode", "94045") // Phone number to be converted to E.164 format, with a leading '+' as required. .put("phone", "+1 800 5550102") .build(); // The third user data only has an email address. Map<String, String> rawRecord3 = ImmutableMap.<String, String>builder().put("email", "charlie@example.com").build(); // Adds the raw records to the raw input list. rawRecords.add(rawRecord1); rawRecords.add(rawRecord2); rawRecords.add(rawRecord3); // Iterates over the raw input list and creates a UserData object for each record. List<UserData> userDataList = new ArrayList<>(); for (Map<String, String> rawRecord : rawRecords) { // Creates a builder for the UserData object that represents a member of the user list. UserData.Builder userDataBuilder = UserData.newBuilder(); // Checks if the record has email, phone, or address information, and adds a SEPARATE // UserIdentifier object for each one found. For example, a record with an email address and a // phone number will result in a UserData with two UserIdentifiers. // IMPORTANT: Since the identifier attribute of UserIdentifier // (https://developers.google.com/google-ads/api/reference/rpc/latest/UserIdentifier) is a // oneof // (https://protobuf.dev/programming-guides/proto3/#oneof-features), you must set only ONE of // hashedEmail, hashedPhoneNumber, mobileId, thirdPartyUserId, or addressInfo. Setting more // than one of these attributes on the same UserIdentifier will clear all the other members // of the oneof. For example, the following code is INCORRECT and will result in a // UserIdentifier with ONLY a hashedPhoneNumber. // // UserIdentifier incorrectlyPopulatedUserIdentifier = // UserIdentifier.newBuilder() // .setHashedEmail("...") // .setHashedPhoneNumber("...") // .build(); // // The separate 'if' statements below demonstrate the correct approach for creating a UserData // for a member with multiple UserIdentifiers. // Checks if the record has an email address, and if so, adds a UserIdentifier for it. if (rawRecord.containsKey("email")) { UserIdentifier hashedEmailIdentifier = UserIdentifier.newBuilder() .setHashedEmail(normalizeAndHash(sha256Digest, rawRecord.get("email"), true)) .build(); // Adds the hashed email identifier to the UserData object's list. userDataBuilder.addUserIdentifiers(hashedEmailIdentifier); } // Checks if the record has a phone number, and if so, adds a UserIdentifier for it. if (rawRecord.containsKey("phone")) { UserIdentifier hashedPhoneNumberIdentifier = UserIdentifier.newBuilder() .setHashedPhoneNumber(normalizeAndHash(sha256Digest, rawRecord.get("phone"), true)) .build(); // Adds the hashed phone number identifier to the UserData object's list. userDataBuilder.addUserIdentifiers(hashedPhoneNumberIdentifier); } // Checks if the record has all the required mailing address elements, and if so, adds a // UserIdentifier for the mailing address. if (rawRecord.containsKey("firstName")) { // Checks if the record contains all the other required elements of a mailing address. Set<String> missingAddressKeys = new HashSet<>(); for (String addressKey : new String[] {"lastName", "countryCode", "postalCode"}) { if (!rawRecord.containsKey(addressKey)) { missingAddressKeys.add(addressKey); } } if (!missingAddressKeys.isEmpty()) { System.out.printf( "Skipping addition of mailing address information because the following required keys" + " are missing: %s%n", missingAddressKeys); } else { // Creates an OfflineUserAddressInfo object that contains all the required elements of a // mailing address. OfflineUserAddressInfo addressInfo = OfflineUserAddressInfo.newBuilder() .setHashedFirstName( normalizeAndHash(sha256Digest, rawRecord.get("firstName"), false)) .setHashedLastName( normalizeAndHash(sha256Digest, rawRecord.get("lastName"), false)) .setCountryCode(rawRecord.get("countryCode")) .setPostalCode(rawRecord.get("postalCode")) .build(); UserIdentifier addressIdentifier = UserIdentifier.newBuilder().setAddressInfo(addressInfo).build(); // Adds the address identifier to the UserData object's list. userDataBuilder.addUserIdentifiers(addressIdentifier); } } if (!userDataBuilder.getUserIdentifiersList().isEmpty()) { // Builds the UserData and adds it to the list. userDataList.add(userDataBuilder.build()); } } // Creates the operations to add users. List<OfflineUserDataJobOperation> operations = new ArrayList<>(); for (UserData userData : userDataList) { operations.add(OfflineUserDataJobOperation.newBuilder().setCreate(userData).build()); }
C#
// Creates a raw input list of unhashed user information, where each element of the list // represents a single user and is a map containing a separate entry for the keys // "email", "phone", "firstName", "lastName", "countryCode", and "postalCode". // In your application, this data might come from a file or a database. List<Dictionary<string, string>> rawRecords = new List<Dictionary<string, string>>(); // The first user data has an email address and a phone number. Dictionary<string, string> rawRecord1 = new Dictionary<string, string>(); rawRecord1.Add("email", "dana@example.com"); // Phone number to be converted to E.164 format, with a leading '+' as required. // This includes whitespace that will be removed later. rawRecord1.Add("phone", "+1 800 5550101"); // The second user data has an email address, a mailing address, and a phone number. Dictionary<string, string> rawRecord2 = new Dictionary<string, string>(); // Email address that includes a period (.) before the Gmail domain. rawRecord2.Add("email", "alex.2@example.com"); // Address that includes all four required elements: first name, last name, country // code, and postal code. rawRecord2.Add("firstName", "Alex"); rawRecord2.Add("lastName", "Quinn"); rawRecord2.Add("countryCode", "US"); rawRecord2.Add("postalCode", "94045"); // Phone number to be converted to E.164 format, with a leading '+' as required. // This includes whitespace that will be removed later. rawRecord2.Add("phone", "+1 800 5550102"); // The third user data only has an email address. Dictionary<string, string> rawRecord3 = new Dictionary<string, string>(); rawRecord3.Add("email", "charlie@example.com"); // Adds the raw records to the raw input list. rawRecords.Add(rawRecord1); rawRecords.Add(rawRecord2); rawRecords.Add(rawRecord3); // Iterates over the raw input list and creates a UserData object for each record. List<UserData> userDataList = new List<UserData>(); foreach (Dictionary<string, string> rawRecord in rawRecords) { // Creates a UserData object that represents a member of the user list. UserData userData = new UserData(); // Checks if the record has email, phone, or address information, and adds a // SEPARATE UserIdentifier object for each one found. // For example, a record with an email address and a phone number will result in a // UserData with two UserIdentifiers. // IMPORTANT: Since the identifier attribute of UserIdentifier // (https://developers.google.com/google-ads/api/reference/rpc/latest/UserIdentifier) // is a oneof // (https://protobuf.dev/programming-guides/proto3/#oneof-features), you must set // only ONE of hashedEmail, hashedPhoneNumber, mobileId, thirdPartyUserId, // or addressInfo. // Setting more than one of these attributes on the same UserIdentifier will clear // all the other members of the oneof. // For example, the following code is INCORRECT and will result in a UserIdentifier // with ONLY a hashedPhoneNumber. // // UserIdentifier incorrectlyPopulatedUserIdentifier = new UserIdentifier() // { // HashedEmail = "...", // HashedPhoneNumber = "..." // }; // // The separate 'if' statements below demonstrate the correct approach for creating // a UserData for a member with multiple UserIdentifiers. // Checks if the record has an email address, and if so, adds a UserIdentifier // for it. if (rawRecord.ContainsKey("email")) { UserIdentifier hashedEmailIdentifier = new UserIdentifier() { HashedEmail = NormalizeAndHash(rawRecord["email"], true) }; userData.UserIdentifiers.Add(hashedEmailIdentifier); } // Checks if the record has a phone number, and if so, adds a UserIdentifier for it. if (rawRecord.ContainsKey("phone")) { UserIdentifier hashedPhoneNumberIdentifier = new UserIdentifier() { HashedPhoneNumber = NormalizeAndHash(rawRecord["phone"], true) }; // Adds the hashed phone number identifier to the UserData object's list. userData.UserIdentifiers.Add(hashedPhoneNumberIdentifier); } // Checks if the record has all the required mailing address elements, and if so, // adds a UserIdentifier for the mailing address. if (rawRecord.ContainsKey("firstName")) { // Checks if the record contains all the other required elements of a mailing // address. HashSet<string> missingAddressKeys = new HashSet<string>(); foreach (string addressKey in new string[] {"lastName", "countryCode", "postalCode"}) { if (!rawRecord.ContainsKey(addressKey)) { missingAddressKeys.Add(addressKey); } } if (!missingAddressKeys.Any()) { Console.WriteLine( $"Skipping addition of mailing address information because the following " + "required keys are missing: {missingAddressKeys}"); } else { // Creates an OfflineUserAddressInfo object that contains all the required // elements of a mailing address. OfflineUserAddressInfo addressInfo = new OfflineUserAddressInfo() { HashedFirstName = NormalizeAndHash(rawRecord["firstName"]), HashedLastName = NormalizeAndHash(rawRecord["lastName"]), CountryCode = rawRecord["countryCode"], PostalCode = rawRecord["postalCode"] }; UserIdentifier addressIdentifier = new UserIdentifier() { AddressInfo = addressInfo }; // Adds the address identifier to the UserData object's list. userData.UserIdentifiers.Add(addressIdentifier); } } if (userData.UserIdentifiers.Any()) { userDataList.Add(userData); } } // Creates the operations to add the users. List<OfflineUserDataJobOperation> operations = new List<OfflineUserDataJobOperation>(); foreach(UserData userData in userDataList) { operations.Add(new OfflineUserDataJobOperation() { Create = userData }); }
PHP
// Creates a raw input list of unhashed user information, where each element of the list // represents a single user and is a map containing a separate entry for the keys 'email', // 'phone', 'firstName', 'lastName', 'countryCode', and 'postalCode'. In your application, // this data might come from a file or a database. $rawRecords = []; // The first user data has an email address and a phone number. $rawRecord1 = [ // The first user data has an email address and a phone number. 'email' => 'dana@example.com', // Phone number to be converted to E.164 format, with a leading '+' as required. This // includes whitespace that will be removed later. 'phone' => '+1 800 5550101' ]; $rawRecords[] = $rawRecord1; // The second user data has an email address, a mailing address, and a phone number. $rawRecord2 = [ // Email address that includes a period (.) before the Gmail domain. 'email' => 'alex.2@example.com', // Address that includes all four required elements: first name, last name, country // code, and postal code. 'firstName' => 'Alex', 'lastName' => 'Quinn', 'countryCode' => 'US', 'postalCode' => '94045', // Phone number to be converted to E.164 format, with a leading '+' as required. 'phone' => '+1 800 5550102', ]; $rawRecords[] = $rawRecord2; // The third user data only has an email address. $rawRecord3 = ['email' => 'charlie@example.com']; $rawRecords[] = $rawRecord3; // Iterates over the raw input list and creates a UserData object for each record. $userDataList = []; foreach ($rawRecords as $rawRecord) { // Checks if the record has email, phone, or address information, and adds a SEPARATE // UserIdentifier object for each one found. For example, a record with an email address // and a phone number will result in a UserData with two UserIdentifiers. // IMPORTANT: Since the identifier attribute of UserIdentifier // (https://developers.google.com/google-ads/api/reference/rpc/latest/UserIdentifier) is // a oneof // (https://protobuf.dev/programming-guides/proto3/#oneof-features), you must set only // ONE of 'hashed_email, 'hashed_phone_number', 'mobile_id', 'third_party_user_id', or // 'address_info'. // Setting more than one of these attributes on the same UserIdentifier will clear all // the other members of the oneof. For example, the following code is INCORRECT and will // result in a UserIdentifier with ONLY a 'hashed_phone_number'. // // $incorrectlyPopulatedUserIdentifier = new UserIdentifier(); // $incorrectlyPopulatedUserIdentifier->setHashedEmail('...'); // $incorrectlyPopulatedUserIdentifier->setHashedPhoneNumber('...'); // // The separate 'if' statements below demonstrate the correct approach for creating a // UserData for a member with multiple UserIdentifiers. $userIdentifiers = []; // Checks if the record has an email address, and if so, adds a UserIdentifier for it. if (array_key_exists('email', $rawRecord)) { $hashedEmailIdentifier = new UserIdentifier([ 'hashed_email' => self::normalizeAndHash($rawRecord['email'], true) ]); // Adds the hashed email identifier to the user identifiers list. $userIdentifiers[] = $hashedEmailIdentifier; } // Checks if the record has a phone number, and if so, adds a UserIdentifier for it. if (array_key_exists('phone', $rawRecord)) { $hashedPhoneNumberIdentifier = new UserIdentifier([ 'hashed_phone_number' => self::normalizeAndHash($rawRecord['phone'], true) ]); // Adds the hashed email identifier to the user identifiers list. $userIdentifiers[] = $hashedPhoneNumberIdentifier; } // Checks if the record has all the required mailing address elements, and if so, adds a // UserIdentifier for the mailing address. if (array_key_exists('firstName', $rawRecord)) { // Checks if the record contains all the other required elements of a mailing // address. $missingAddressKeys = []; foreach (['lastName', 'countryCode', 'postalCode'] as $addressKey) { if (!array_key_exists($addressKey, $rawRecord)) { $missingAddressKeys[] = $addressKey; } } if (!empty($missingAddressKeys)) { printf( "Skipping addition of mailing address information because the " . "following required keys are missing: %s%s", json_encode($missingAddressKeys), PHP_EOL ); } else { // Creates an OfflineUserAddressInfo object that contains all the required // elements of a mailing address. $addressIdentifier = new UserIdentifier([ 'address_info' => new OfflineUserAddressInfo([ 'hashed_first_name' => self::normalizeAndHash( $rawRecord['firstName'], false ), 'hashed_last_name' => self::normalizeAndHash( $rawRecord['lastName'], false ), 'country_code' => $rawRecord['countryCode'], 'postal_code' => $rawRecord['postalCode'] ]) ]); // Adds the address identifier to the user identifiers list. $userIdentifiers[] = $addressIdentifier; } } if (!empty($userIdentifiers)) { // Builds the UserData and adds it to the list. $userDataList[] = new UserData(['user_identifiers' => $userIdentifiers]); } } // Creates the operations to add users. $operations = array_map( function (UserData $userData) { return new OfflineUserDataJobOperation(['create' => $userData]); }, $userDataList );
Python
def build_offline_user_data_job_operations(client): """Creates a raw input list of unhashed user information. Each element of the list represents a single user and is a dict containing a separate entry for the keys "email", "phone", "first_name", "last_name", "country_code", and "postal_code". In your application, this data might come from a file or a database. Args: client: The Google Ads client. Returns: A list containing the operations. """ # The first user data has an email address and a phone number. raw_record_1 = { "email": "dana@example.com", # Phone number to be converted to E.164 format, with a leading '+' as # required. This includes whitespace that will be removed later. "phone": "+1 800 5550101", } # The second user data has an email address, a mailing address, and a phone # number. raw_record_2 = { # Email address that includes a period (.) before the email domain. "email": "alex.2@example.com", # Address that includes all four required elements: first name, last # name, country code, and postal code. "first_name": "Alex", "last_name": "Quinn", "country_code": "US", "postal_code": "94045", # Phone number to be converted to E.164 format, with a leading '+' as # required. "phone": "+1 800 5550102", } # The third user data only has an email address. raw_record_3 = {"email": "charlie@example.com"} # Adds the raw records to a raw input list. raw_records = [raw_record_1, raw_record_2, raw_record_3] operations = [] # Iterates over the raw input list and creates a UserData object for each # record. for record in raw_records: # Creates a UserData object that represents a member of the user list. user_data = client.get_type("UserData") # Checks if the record has email, phone, or address information, and # adds a SEPARATE UserIdentifier object for each one found. For example, # a record with an email address and a phone number will result in a # UserData with two UserIdentifiers. # IMPORTANT: Since the identifier attribute of UserIdentifier # (https://developers.google.com/google-ads/api/reference/rpc/latest/UserIdentifier) # is a oneof # (https://protobuf.dev/programming-guides/proto3/#oneof-features), you # must set only ONE of hashed_email, hashed_phone_number, mobile_id, # third_party_user_id, or address-info. Setting more than one of these # attributes on the same UserIdentifier will clear all the other members # of the oneof. For example, the following code is INCORRECT and will # result in a UserIdentifier with ONLY a hashed_phone_number: # incorrect_user_identifier = client.get_type("UserIdentifier") # incorrect_user_identifier.hashed_email = "..." # incorrect_user_identifier.hashed_phone_number = "..." # The separate 'if' statements below demonstrate the correct approach # for creating a UserData object for a member with multiple # UserIdentifiers. # Checks if the record has an email address, and if so, adds a # UserIdentifier for it. if "email" in record: user_identifier = client.get_type("UserIdentifier") user_identifier.hashed_email = normalize_and_hash( record["email"], True ) # Adds the hashed email identifier to the UserData object's list. user_data.user_identifiers.append(user_identifier) # Checks if the record has a phone number, and if so, adds a # UserIdentifier for it. if "phone" in record: user_identifier = client.get_type("UserIdentifier") user_identifier.hashed_phone_number = normalize_and_hash( record["phone"], True ) # Adds the hashed phone number identifier to the UserData object's # list. user_data.user_identifiers.append(user_identifier) # Checks if the record has all the required mailing address elements, # and if so, adds a UserIdentifier for the mailing address. if "first_name" in record: required_keys = ("last_name", "country_code", "postal_code") # Checks if the record contains all the other required elements of # a mailing address. if not all(key in record for key in required_keys): # Determines which required elements are missing from the # record. missing_keys = record.keys() - required_keys print( "Skipping addition of mailing address information " "because the following required keys are missing: " f"{missing_keys}" ) else: user_identifier = client.get_type("UserIdentifier") address_info = user_identifier.address_info address_info.hashed_first_name = normalize_and_hash( record["first_name"], False ) address_info.hashed_last_name = normalize_and_hash( record["last_name"], False ) address_info.country_code = record["country_code"] address_info.postal_code = record["postal_code"] user_data.user_identifiers.append(user_identifier) # If the user_identifiers repeated field is not empty, create a new # OfflineUserDataJobOperation and add the UserData to it. if user_data.user_identifiers: operation = client.get_type("OfflineUserDataJobOperation") operation.create = user_data operations.append(operation)
Ruby
# Create a list of unhashed user data records that we will format in the # following steps to prepare for the API. raw_records = [ # The first user data has an email address and a phone number. { email: 'dana@example.com', # Phone number to be converted to E.164 format, with a leading '+' as # required. This includes whitespace that will be removed later. phone: '+1 800 5550100', }, # The second user data has an email address, a phone number, and an address. { # Email address that includes a period (.) before the Gmail domain. email: 'alex.2@example.com', # Address that includes all four required elements: first name, last # name, country code, and postal code. first_name: 'Alex', last_name: 'Quinn', country_code: 'US', postal_code: '94045', # Phone number to be converted to E.164 format, with a leading '+' as # required. phone: '+1 800 5550102', }, # The third user data only has an email address. { email: 'charlie@example.com', }, ] # Create a UserData for each entry in the raw records. user_data_list = raw_records.map do |record| client.resource.user_data do |data| if record[:email] data.user_identifiers << client.resource.user_identifier do |ui| ui.hashed_email = normalize_and_hash(record[:email], true) end end if record[:phone] data.user_identifiers << client.resource.user_identifier do |ui| ui.hashed_phone_number = normalize_and_hash(record[:phone], true) end end if record[:first_name] # Check that we have all the required information. missing_keys = [:last_name, :country_code, :postal_code].reject {|key| record[key].nil? } if missing_keys.empty? # If nothing is missing, add the address. data.user_identifiers << client.resource.user_identifier do |ui| ui.address_identifier = client.resource.offline_user_address_info do |address| address.hashed_first_name = normalize_and_hash(record[:first_name]) address.hashed_last_name = normalize_and_hash(record[:last_name]) address.country_code = record[:country_code] address.postal_code = record[:postal_code] end end else # If some data is missing, skip this entry. puts "Skipping addition of mailing information because the following keys are missing:" \ "#{missing_keys}" end end end end operations = user_data_list.map do |user_data| client.operation.create_resource.offline_user_data_job(user_data) end
Perl
# The first user data has an email address and a phone number. my $raw_record_1 = { email => 'dana@example.com', # Phone number to be converted to E.164 format, with a leading '+' as # required. This includes whitespace that will be removed later. phone => '+1 800 5550101', }; # The second user data has an email address, a mailing address, and a phone # number. my $raw_record_2 = { # Email address that includes a period (.) before the Gmail domain. email => 'alex.2@example.com', # Address that includes all four required elements: first name, last # name, country code, and postal code. firstName => 'Alex', lastName => 'Quinn', countryCode => 'US', postalCode => '94045', # Phone number to be converted to E.164 format, with a leading '+' as # required. phone => '+1 800 5550102', }; # The third user data only has an email address. my $raw_record_3 = {email => 'charlie@example.com',}; my $raw_records = [$raw_record_1, $raw_record_2, $raw_record_3]; my $operations = []; foreach my $record (@$raw_records) { # Check if the record has email, phone, or address information, and adds a # SEPARATE UserIdentifier object for each one found. For example, a record # with an email address and a phone number will result in a UserData with two # UserIdentifiers. # # IMPORTANT: Since the identifier attribute of UserIdentifier # (https://developers.google.com/google-ads/api/reference/rpc/latest/UserIdentifier) # is a oneof # (https://protobuf.dev/programming-guides/proto3/#oneof-features), you must set # only ONE of hashed_email, hashed_phone_number, mobile_id, third_party_user_id, # or address-info. Setting more than one of these attributes on the same UserIdentifier # will clear all the other members of the oneof. For example, the following code is # INCORRECT and will result in a UserIdentifier with ONLY a hashed_phone_number: # # my $incorrect_user_identifier = Google::Ads::GoogleAds::V18::Common::UserIdentifier->new({ # hashedEmail => '...', # hashedPhoneNumber => '...', # }); # # The separate 'if' statements below demonstrate the correct approach for creating a # UserData object for a member with multiple UserIdentifiers. my $user_identifiers = []; # Check if the record has an email address, and if so, add a UserIdentifier for it. if (defined $record->{email}) { # Add the hashed email identifier to the list of UserIdentifiers. push( @$user_identifiers, Google::Ads::GoogleAds::V18::Common::UserIdentifier->new({ hashedEmail => normalize_and_hash($record->{email}, 1)})); } # Check if the record has a phone number, and if so, add a UserIdentifier for it. if (defined $record->{phone}) { # Add the hashed phone number identifier to the list of UserIdentifiers. push( @$user_identifiers, Google::Ads::GoogleAds::V18::Common::UserIdentifier->new({ hashedPhoneNumber => normalize_and_hash($record->{phone}, 1)})); } # Check if the record has all the required mailing address elements, and if so, add # a UserIdentifier for the mailing address. if (defined $record->{firstName}) { my $required_keys = ["lastName", "countryCode", "postalCode"]; my $missing_keys = []; foreach my $key (@$required_keys) { if (!defined $record->{$key}) { push(@$missing_keys, $key); } } if (@$missing_keys) { print "Skipping addition of mailing address information because the following" . "keys are missing: " . join(",", @$missing_keys); } else { push( @$user_identifiers, Google::Ads::GoogleAds::V18::Common::UserIdentifier->new({ addressInfo => Google::Ads::GoogleAds::V18::Common::OfflineUserAddressInfo-> new({ # First and last name must be normalized and hashed. hashedFirstName => normalize_and_hash($record->{firstName}), hashedLastName => normalize_and_hash($record->{lastName}), # Country code and zip code are sent in plain text. countryCode => $record->{countryCode}, postalCode => $record->{postalCode}, })})); } } # If the user_identifiers array is not empty, create a new # OfflineUserDataJobOperation and add the UserData to it. if (@$user_identifiers) { my $user_data = Google::Ads::GoogleAds::V18::Common::UserData->new({ userIdentifiers => [$user_identifiers]}); push( @$operations, Google::Ads::GoogleAds::V18::Services::OfflineUserDataJobService::OfflineUserDataJobOperation ->new({ create => $user_data })); } }
ยืนยันการอัปโหลดรายการและอัตราการจับคู่
เมื่อ OfflineUserDataJob
มี SUCCESS
สถานะ อัตราการทำงานของคีย์เวิร์ดโดยประมาณจะแสดงในช่อง operation_metadata.match_rate_range
หากคุณค้นหาช่องนี้ก่อนที่งานจะเสร็จสมบูรณ์ ค่าในช่องนี้อาจเป็น 0 เราขอแนะนำให้คุณสำรวจงานให้เสร็จสมบูรณ์เพื่อให้อัตราการจับคู่พร้อมสำหรับการยืนยันและเพื่อให้รายการพร้อมกำหนดเป้าหมาย การดำเนินการอาจใช้เวลาเพียง 10 นาทีหรือสูงสุด 24 ชั่วโมงจึงจะเสร็จสมบูรณ์
ตัวอย่างโค้ดสำหรับตรวจสอบสถานะงาน
Java
private void checkJobStatus( GoogleAdsClient googleAdsClient, long customerId, String offlineUserDataJobResourceName) { try (GoogleAdsServiceClient googleAdsServiceClient = googleAdsClient.getLatestVersion().createGoogleAdsServiceClient()) { String query = String.format( "SELECT offline_user_data_job.resource_name, " + "offline_user_data_job.id, " + "offline_user_data_job.status, " + "offline_user_data_job.type, " + "offline_user_data_job.failure_reason, " + "offline_user_data_job.customer_match_user_list_metadata.user_list " + "FROM offline_user_data_job " + "WHERE offline_user_data_job.resource_name = '%s'", offlineUserDataJobResourceName); // Issues the query and gets the GoogleAdsRow containing the job from the response. GoogleAdsRow googleAdsRow = googleAdsServiceClient .search(Long.toString(customerId), query) .iterateAll() .iterator() .next(); OfflineUserDataJob offlineUserDataJob = googleAdsRow.getOfflineUserDataJob(); System.out.printf( "Offline user data job ID %d with type '%s' has status: %s%n", offlineUserDataJob.getId(), offlineUserDataJob.getType(), offlineUserDataJob.getStatus()); OfflineUserDataJobStatus jobStatus = offlineUserDataJob.getStatus(); if (OfflineUserDataJobStatus.SUCCESS == jobStatus) { // Prints information about the user list. printCustomerMatchUserListInfo( googleAdsClient, customerId, offlineUserDataJob.getCustomerMatchUserListMetadata().getUserList()); } else if (OfflineUserDataJobStatus.FAILED == jobStatus) { System.out.printf(" Failure reason: %s%n", offlineUserDataJob.getFailureReason()); } else if (OfflineUserDataJobStatus.PENDING == jobStatus || OfflineUserDataJobStatus.RUNNING == jobStatus) { System.out.println(); System.out.printf( "To check the status of the job periodically, use the following GAQL query with" + " GoogleAdsService.search:%n%s%n", query); } } }
C#
private static void CheckJobStatusAndPrintResults(GoogleAdsClient client, long customerId, string offlineUserDataJobResourceName) { // Get the GoogleAdsService. GoogleAdsServiceClient service = client.GetService(Services.V18.GoogleAdsService); string query = "SELECT offline_user_data_job.resource_name, " + "offline_user_data_job.id, offline_user_data_job.status, " + "offline_user_data_job.type, offline_user_data_job.failure_reason " + "offline_user_data_job.customer_match_user_list_metadata_user_list " + "FROM offline_user_data_job WHERE " + $"offline_user_data_job.resource_name = '{offlineUserDataJobResourceName}'"; // Issues the query and gets the GoogleAdsRow containing the job from the response. GoogleAdsRow googleAdsRow = service.Search(customerId.ToString(), query).First(); OfflineUserDataJob offlineUserDataJob = googleAdsRow.OfflineUserDataJob; Console.WriteLine($"Offline user data job ID {offlineUserDataJob.Id} with type " + $"'{offlineUserDataJob.Type}' has status: {offlineUserDataJob.Status}"); switch (offlineUserDataJob.Status) { case OfflineUserDataJobStatus.Success: // Prints information about the user list. PrintCustomerMatchUserListInfo(client, customerId, offlineUserDataJob.CustomerMatchUserListMetadata.UserList); break; case OfflineUserDataJobStatus.Failed: Console.WriteLine($" Failure reason: {offlineUserDataJob.FailureReason}"); break; case OfflineUserDataJobStatus.Pending: case OfflineUserDataJobStatus.Running: Console.WriteLine("To check the status of the job periodically, use the " + $"following GAQL query with GoogleAdsService.search:\n\n{query}"); break; } }
PHP
private static function checkJobStatus( GoogleAdsClient $googleAdsClient, int $customerId, string $offlineUserDataJobResourceName ) { $googleAdsServiceClient = $googleAdsClient->getGoogleAdsServiceClient(); // Creates a query that retrieves the offline user data job. $query = "SELECT offline_user_data_job.resource_name, " . "offline_user_data_job.id, " . "offline_user_data_job.status, " . "offline_user_data_job.type, " . "offline_user_data_job.failure_reason, " . "offline_user_data_job.customer_match_user_list_metadata.user_list " . "FROM offline_user_data_job " . "WHERE offline_user_data_job.resource_name = '$offlineUserDataJobResourceName'"; // Issues a search request to get the GoogleAdsRow containing the job from the response. /** @var GoogleAdsRow $googleAdsRow */ $googleAdsRow = $googleAdsServiceClient->search(SearchGoogleAdsRequest::build($customerId, $query)) ->getIterator() ->current(); $offlineUserDataJob = $googleAdsRow->getOfflineUserDataJob(); // Prints out some information about the offline user data job. $offlineUserDataJobStatus = $offlineUserDataJob->getStatus(); printf( "Offline user data job ID %d with type '%s' has status: %s.%s", $offlineUserDataJob->getId(), OfflineUserDataJobType::name($offlineUserDataJob->getType()), OfflineUserDataJobStatus::name($offlineUserDataJobStatus), PHP_EOL ); if ($offlineUserDataJobStatus === OfflineUserDataJobStatus::SUCCESS) { // Prints information about the user list. self::printCustomerMatchUserListInfo( $googleAdsClient, $customerId, $offlineUserDataJob->getCustomerMatchUserListMetadata()->getUserList() ); } elseif ($offlineUserDataJobStatus === OfflineUserDataJobStatus::FAILED) { printf(" Failure reason: %s.%s", $offlineUserDataJob->getFailureReason(), PHP_EOL); } elseif ( $offlineUserDataJobStatus === OfflineUserDataJobStatus::PENDING || $offlineUserDataJobStatus === OfflineUserDataJobStatus::RUNNING ) { printf( '%1$sTo check the status of the job periodically, use the following GAQL query with' . ' GoogleAdsService.search:%1$s%2$s%1$s', PHP_EOL, $query ); } }
Python
def check_job_status(client, customer_id, offline_user_data_job_resource_name): """Retrieves, checks, and prints the status of the offline user data job. If the job is completed successfully, information about the user list is printed. Otherwise, a GAQL query will be printed, which can be used to check the job status at a later date. Offline user data jobs may take 6 hours or more to complete, so checking the status periodically, instead of waiting, can be more efficient. Args: client: The Google Ads client. customer_id: The ID for the customer that owns the user list. offline_user_data_job_resource_name: The resource name of the offline user data job to get the status of. """ query = f""" SELECT offline_user_data_job.resource_name, offline_user_data_job.id, offline_user_data_job.status, offline_user_data_job.type, offline_user_data_job.failure_reason, offline_user_data_job.customer_match_user_list_metadata.user_list FROM offline_user_data_job WHERE offline_user_data_job.resource_name = '{offline_user_data_job_resource_name}' LIMIT 1""" # Issues a search request using streaming. google_ads_service = client.get_service("GoogleAdsService") results = google_ads_service.search(customer_id=customer_id, query=query) offline_user_data_job = next(iter(results)).offline_user_data_job status_name = offline_user_data_job.status.name user_list_resource_name = ( offline_user_data_job.customer_match_user_list_metadata.user_list ) print( f"Offline user data job ID '{offline_user_data_job.id}' with type " f"'{offline_user_data_job.type_.name}' has status: {status_name}" ) if status_name == "SUCCESS": print_customer_match_user_list_info( client, customer_id, user_list_resource_name ) elif status_name == "FAILED": print(f"\tFailure Reason: {offline_user_data_job.failure_reason}") elif status_name in ("PENDING", "RUNNING"): print( "To check the status of the job periodically, use the following " f"GAQL query with GoogleAdsService.Search: {query}" )
Ruby
def check_job_status(client, customer_id, offline_user_data_job) query = <<~QUERY SELECT offline_user_data_job.id, offline_user_data_job.status, offline_user_data_job.type, offline_user_data_job.failure_reason, offline_user_data_job.customer_match_user_list_metadata.user_list FROM offline_user_data_job WHERE offline_user_data_job.resource_name = '#{offline_user_data_job}' QUERY row = client.service.google_ads.search( customer_id: customer_id, query: query, ).first job = row.offline_user_data_job puts "Offline user data job ID #{job.id} with type '#{job.type}' has status: #{job.status}." case job.status when :SUCCESS print_customer_match_user_list(client, customer_id, job.customer_match_user_list_metadata.user_list) when :FAILED puts " Failure reason: #{job.failure_reason}" else puts " To check the status of the job periodically, use the following GAQL " \ "query with GoogleAdsService.search:" puts query end end
Perl
sub check_job_status() { my ($api_client, $customer_id, $offline_user_data_job_resource_name) = @_; my $search_query = "SELECT offline_user_data_job.resource_name, " . "offline_user_data_job.id, offline_user_data_job.status, " . "offline_user_data_job.type, offline_user_data_job.failure_reason, " . "offline_user_data_job.customer_match_user_list_metadata.user_list " . "FROM offline_user_data_job " . "WHERE offline_user_data_job.resource_name = " . "$offline_user_data_job_resource_name LIMIT 1"; my $search_request = Google::Ads::GoogleAds::V18::Services::GoogleAdsService::SearchGoogleAdsRequest ->new({ customerId => $customer_id, query => $search_query }); # Get the GoogleAdsService. my $google_ads_service = $api_client->GoogleAdsService(); my $iterator = Google::Ads::GoogleAds::Utils::SearchGoogleAdsIterator->new({ service => $google_ads_service, request => $search_request }); # The results have exactly one row. my $google_ads_row = $iterator->next; my $offline_user_data_job = $google_ads_row->{offlineUserDataJob}; my $status = $offline_user_data_job->{status}; printf "Offline user data job ID %d with type %s has status: %s.\n", $offline_user_data_job->{id}, $offline_user_data_job->{type}, $status; if ($status eq SUCCESS) { print_customer_match_user_list_info($api_client, $customer_id, $offline_user_data_job->{customerMatchUserListMetadata}{userList}); } elsif ($status eq FAILED) { print "Failure reason: $offline_user_data_job->{failure_reason}"; } elsif (grep /$status/, (PENDING, RUNNING)) { print "To check the status of the job periodically, use the following GAQL " . "query with the GoogleAdsService->search() method:\n$search_query\n"; } return 1; }
หากต้องการยืนยันขนาดรายการ ให้ค้นหาแหล่งข้อมูล user_list
ตัวอย่างโค้ดสำหรับค้นหาทรัพยากร user_list
Java
try (GoogleAdsServiceClient googleAdsServiceClient = googleAdsClient.getLatestVersion().createGoogleAdsServiceClient()) { // Creates a query that retrieves the user list. String query = String.format( "SELECT user_list.size_for_display, user_list.size_for_search " + "FROM user_list " + "WHERE user_list.resource_name = '%s'", userListResourceName); // Constructs the SearchGoogleAdsStreamRequest. SearchGoogleAdsStreamRequest request = SearchGoogleAdsStreamRequest.newBuilder() .setCustomerId(Long.toString(customerId)) .setQuery(query) .build(); // Issues the search stream request. ServerStream<SearchGoogleAdsStreamResponse> stream = googleAdsServiceClient.searchStreamCallable().call(request);
C#
// Get the GoogleAdsService. GoogleAdsServiceClient service = client.GetService(Services.V18.GoogleAdsService); // Creates a query that retrieves the user list. string query = "SELECT user_list.size_for_display, user_list.size_for_search " + "FROM user_list " + $"WHERE user_list.resource_name = '{userListResourceName}'"; // Issues a search stream request. service.SearchStream(customerId.ToString(), query, delegate (SearchGoogleAdsStreamResponse resp) { // Display the results. foreach (GoogleAdsRow userListRow in resp.Results) { UserList userList = userListRow.UserList; Console.WriteLine("The estimated number of users that the user list " + $"'{userList.ResourceName}' has is {userList.SizeForDisplay}" + $" for Display and {userList.SizeForSearch} for Search."); } } );
PHP
$googleAdsServiceClient = $googleAdsClient->getGoogleAdsServiceClient(); // Creates a query that retrieves the user list. $query = "SELECT user_list.size_for_display, user_list.size_for_search " . "FROM user_list " . "WHERE user_list.resource_name = '$userListResourceName'"; // Issues a search stream request. /** @var GoogleAdsServerStreamDecorator $stream */ $stream = $googleAdsServiceClient->searchStream( SearchGoogleAdsStreamRequest::build($customerId, $query) );
Python
googleads_service_client = client.get_service("GoogleAdsService") # Creates a query that retrieves the user list. query = f""" SELECT user_list.size_for_display, user_list.size_for_search FROM user_list WHERE user_list.resource_name = '{user_list_resource_name}'""" # Issues a search request. search_results = googleads_service_client.search( customer_id=customer_id, query=query )
Ruby
query = <<~EOQUERY SELECT user_list.size_for_display, user_list.size_for_search FROM user_list WHERE user_list.resource_name = #{user_list} EOQUERY response = client.service.google_ads.search_stream( customer_id: customer_id, query: query, )
Perl
# Create a query that retrieves the user list. my $search_query = "SELECT user_list.size_for_display, user_list.size_for_search " . "FROM user_list " . "WHERE user_list.resource_name = '$user_list_resource_name'"; # Create a search Google Ads stream request that will retrieve the user list. my $search_stream_request = Google::Ads::GoogleAds::V18::Services::GoogleAdsService::SearchGoogleAdsStreamRequest ->new({ customerId => $customer_id, query => $search_query, }); # Get the GoogleAdsService. my $google_ads_service = $api_client->GoogleAdsService(); my $search_stream_handler = Google::Ads::GoogleAds::Utils::SearchStreamHandler->new({ service => $google_ads_service, request => $search_stream_request });
เพื่อความเป็นส่วนตัว ขนาดรายชื่อผู้ใช้จะแสดงเป็น 0 จนกว่ารายการจะมีสมาชิกอย่างน้อย 1,000 คน หลังจากนั้น ระบบจะปัดเศษขนาดเป็นตัวเลขที่มีนัยสำคัญมากที่สุด 2 หลัก
คุณสามารถดึงข้อมูลข้อผิดพลาดระหว่างการเรียกใช้ OfflineUserDataJob
ผ่านแหล่งข้อมูล offline_user_data_job
โดยใช้ภาษาการค้นหาของ Google Ads อย่างไรก็ตาม โปรดทราบว่ารายงานนี้ไม่มีข้อมูลเกี่ยวกับการจับคู่ที่ล้มเหลว เนื่องจากระบบจะเปรียบเทียบเฉพาะแฮชเมื่อจับคู่อย่างมีประสิทธิภาพ ดูคู่มือการแก้ปัญหาหากพบปัญหาเกี่ยวกับรายชื่อลูกค้า
เปรียบเทียบกับ UI ของ Google Ads
รายการอาจปรากฏน้อยกว่าที่คาดไว้เมื่อดูในตัวจัดการกลุ่มเป้าหมายจาก UI ของ Google Ads มุมมองนี้แสดงจํานวนผู้ใช้ที่ใช้งานอยู่ในรายการ โปรดดูข้อมูลเพิ่มเติมที่คู่มือการแก้ปัญหานี้
เนื่องจากระบบอาจใช้เวลาถึง 24 ชั่วโมงในการสร้างรายชื่อสมาชิก คุณจึงอาจเห็นสถานะ In Progress
ใน UI ของ Google Ads หากคุณอัปโหลดไปยังรายการกลุ่มเป้าหมายบ่อยกว่าทุกๆ 12 ชั่วโมง
กำหนดเป้าหมายรายการของฉัน
คุณสามารถกําหนดเป้าหมายรายการที่ระดับกลุ่มโฆษณาหรือระดับแคมเปญ กระบวนการนี้คล้ายกับเกณฑ์การกําหนดเป้าหมายประเภทอื่นๆ ใน API
ตัวอย่างโค้ดสำหรับกำหนดเป้าหมายโฆษณาในกลุ่มโฆษณาให้ไปยังรายการผู้ใช้
Java
private String targetAdsInAdGroupToUserList( GoogleAdsClient googleAdsClient, long customerId, long adGroupId, String userList) { // Creates the ad group criterion targeting members of the user list. AdGroupCriterion adGroupCriterion = AdGroupCriterion.newBuilder() .setAdGroup(ResourceNames.adGroup(customerId, adGroupId)) .setUserList(UserListInfo.newBuilder().setUserList(userList).build()) .build(); // Creates the operation. AdGroupCriterionOperation operation = AdGroupCriterionOperation.newBuilder().setCreate(adGroupCriterion).build(); // Creates the ad group criterion service. try (AdGroupCriterionServiceClient adGroupCriterionServiceClient = googleAdsClient.getLatestVersion().createAdGroupCriterionServiceClient()) { // Adds the ad group criterion. MutateAdGroupCriteriaResponse response = adGroupCriterionServiceClient.mutateAdGroupCriteria( Long.toString(customerId), ImmutableList.of(operation)); // Gets and prints the results. String adGroupCriterionResourceName = response.getResults(0).getResourceName(); System.out.printf( "Successfully created ad group criterion with resource name '%s' " + "targeting user list with resource name '%s' with ad group with ID %d.%n", adGroupCriterionResourceName, userList, adGroupId); return adGroupCriterionResourceName; } }
C#
private string TargetAdsInAdGroupToUserList( GoogleAdsClient client, long customerId, long adGroupId, string userListResourceName) { // Get the AdGroupCriterionService client. AdGroupCriterionServiceClient adGroupCriterionServiceClient = client.GetService (Services.V18.AdGroupCriterionService); // Create the ad group criterion targeting members of the user list. AdGroupCriterion adGroupCriterion = new AdGroupCriterion { AdGroup = ResourceNames.AdGroup(customerId, adGroupId), UserList = new UserListInfo { UserList = userListResourceName } }; // Create the operation. AdGroupCriterionOperation adGroupCriterionOperation = new AdGroupCriterionOperation { Create = adGroupCriterion }; // Add the ad group criterion, then print and return the new criterion's resource name. MutateAdGroupCriteriaResponse mutateAdGroupCriteriaResponse = adGroupCriterionServiceClient.MutateAdGroupCriteria(customerId.ToString(), new[] { adGroupCriterionOperation }); string adGroupCriterionResourceName = mutateAdGroupCriteriaResponse.Results.First().ResourceName; Console.WriteLine("Successfully created ad group criterion with resource name " + $"'{adGroupCriterionResourceName}' targeting user list with resource name " + $"'{userListResourceName}' with ad group with ID {adGroupId}."); return adGroupCriterionResourceName; }
PHP
private static function targetAdsInAdGroupToUserList( GoogleAdsClient $googleAdsClient, int $customerId, int $adGroupId, string $userListResourceName ): string { // Creates the ad group criterion targeting members of the user list. $adGroupCriterion = new AdGroupCriterion([ 'ad_group' => ResourceNames::forAdGroup($customerId, $adGroupId), 'user_list' => new UserListInfo(['user_list' => $userListResourceName]) ]); // Creates the operation. $operation = new AdGroupCriterionOperation(); $operation->setCreate($adGroupCriterion); // Issues a mutate request to add an ad group criterion. $adGroupCriterionServiceClient = $googleAdsClient->getAdGroupCriterionServiceClient(); /** @var MutateAdGroupCriteriaResponse $adGroupCriterionResponse */ $adGroupCriterionResponse = $adGroupCriterionServiceClient->mutateAdGroupCriteria( MutateAdGroupCriteriaRequest::build($customerId, [$operation]) ); $adGroupCriterionResourceName = $adGroupCriterionResponse->getResults()[0]->getResourceName(); printf( "Successfully created ad group criterion with resource name '%s' " . "targeting user list with resource name '%s' with ad group with ID %d.%s", $adGroupCriterionResourceName, $userListResourceName, $adGroupId, PHP_EOL ); return $adGroupCriterionResourceName; }
Python
def target_ads_in_ad_group_to_user_list( client, customer_id, ad_group_id, user_list_resource_name ): """Creates an ad group criterion that targets a user list with an ad group. Args: client: an initialized GoogleAdsClient instance. customer_id: a str client customer ID used to create an ad group criterion. ad_group_id: a str ID for an ad group used to create an ad group criterion that targets members of a user list. user_list_resource_name: a str resource name for a user list. Returns: a str resource name for an ad group criterion. """ ad_group_criterion_operation = client.get_type("AdGroupCriterionOperation") # Creates the ad group criterion targeting members of the user list. ad_group_criterion = ad_group_criterion_operation.create ad_group_criterion.ad_group = client.get_service( "AdGroupService" ).ad_group_path(customer_id, ad_group_id) ad_group_criterion.user_list.user_list = user_list_resource_name ad_group_criterion_service = client.get_service("AdGroupCriterionService") response = ad_group_criterion_service.mutate_ad_group_criteria( customer_id=customer_id, operations=[ad_group_criterion_operation] ) resource_name = response.results[0].resource_name print( "Successfully created ad group criterion with resource name: " f"'{resource_name}' targeting user list with resource name: " f"'{user_list_resource_name}' and with ad group with ID " f"{ad_group_id}." ) return resource_name
Ruby
def target_ads_in_ad_group_to_user_list( client, customer_id, ad_group_id, user_list ) # Creates the ad group criterion targeting members of the user list. operation = client.operation.create_resource.ad_group_criterion do |agc| agc.ad_group = client.path.ad_group(customer_id, ad_group_id) agc.user_list = client.resource.user_list_info do |info| info.user_list = user_list end end # Issues a mutate request to create the ad group criterion. response = client.service.ad_group_criterion.mutate_ad_group_criteria( customer_id: customer_id, operations: [operation], ) ad_group_criterion_resource_name = response.results.first.resource_name puts "Successfully created ad group criterion with resource name " \ "'#{ad_group_criterion_resource_name}' targeting user list with resource name " \ "'#{user_list}' with ad group with ID #{ad_group_id}" ad_group_criterion_resource_name end
Perl
sub target_ads_in_ad_group_to_user_list { my ($api_client, $customer_id, $ad_group_id, $user_list_resource_name) = @_; # Create the ad group criterion targeting members of the user list. my $ad_group_criterion = Google::Ads::GoogleAds::V18::Resources::AdGroupCriterion->new({ adGroup => Google::Ads::GoogleAds::V18::Utils::ResourceNames::ad_group( $customer_id, $ad_group_id ), userList => Google::Ads::GoogleAds::V18::Common::UserListInfo->new({ userList => $user_list_resource_name })}); # Create the operation. my $ad_group_criterion_operation = Google::Ads::GoogleAds::V18::Services::AdGroupCriterionService::AdGroupCriterionOperation ->new({ create => $ad_group_criterion }); # Add the ad group criterion, then print and return the new criterion's resource name. my $ad_group_criteria_response = $api_client->AdGroupCriterionService()->mutate({ customerId => $customer_id, operations => [$ad_group_criterion_operation]}); my $ad_group_criterion_resource_name = $ad_group_criteria_response->{results}[0]{resourceName}; printf "Successfully created ad group criterion with resource name '%s' " . "targeting user list with resource name '%s' with ad group with ID %d.\n", $ad_group_criterion_resource_name, $user_list_resource_name, $ad_group_id; return $ad_group_criterion_resource_name; }
กําหนดเป้าหมายรายชื่อลูกค้าหลายรายการ
สามารถรวม crm_based_user_list
กับ crm_based_user_list
อื่นได้เฉพาะเมื่อใช้ logical_user_list
เท่านั้น
นโยบายทั้งหมดสำหรับ crm_based_user_list
จะมีผลกับรายชื่อผู้ใช้ที่ได้