@google-cloud/nodejs-common 1.0.1 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1877,7 +1877,7 @@ https://cloud.google.com/firestore/docs/firestore-or-datastore#choosing_a_databa
1877
1877
  confirm_firestore() {
1878
1878
  (( STEP += 1 ))
1879
1879
  printf '%s\n' "Step ${STEP}: Checking the status of Firestore..."
1880
- check_firestore_existence
1880
+ check_firestore_existence "$@"
1881
1881
  }
1882
1882
 
1883
1883
  #######################################
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@google-cloud/nodejs-common",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "A NodeJs common library for solutions based on Cloud Functions",
5
5
  "author": "Google Inc.",
6
6
  "license": "Apache-2.0",
@@ -80,6 +80,13 @@ const IDENTIFIERS = [
80
80
  'address_info',
81
81
  ];
82
82
 
83
+ /**
84
+ * Maximum number of user identifiers in single UserData.
85
+ * @see https://ads-developers.googleblog.com/2021/10/userdata-enforcement-in-google-ads-api.html
86
+ * @type {number}
87
+ */
88
+ const MAX_IDENTIFIERS_PER_USER = 20;
89
+
83
90
  /**
84
91
  * Configuration for uploading click conversions for Google Ads, includes:
85
92
  * gclid, conversion_action, conversion_date_time, conversion_value,
@@ -111,43 +118,34 @@ const IDENTIFIERS = [
111
118
  * order_id: (string|undefined),
112
119
  * user_identifier_source:(UserIdentifierSource|undefined),
113
120
  * custom_variable_tags:(!Array<string>|undefined),
114
- * customVariables:(!object<string,string>|undefined),
121
+ * customVariables:(!Object<string,string>|undefined),
115
122
  * }}
116
123
  */
117
124
  let ClickConversionConfig;
118
125
 
119
126
  /**
120
127
  * Configuration for uploading customer match to Google Ads, includes:
121
- * customer_id, login_customer_id, list_id, list_type and operation
122
- * list_type must be one of the following: hashed_email,
123
- * hashed_phone_number, mobile_id, third_party_user_id or address_info;
128
+ * customer_id, login_customer_id, list_id and operation.
124
129
  * operation must be one of the two: 'create' or 'remove';
125
130
  * @see https://developers.google.com/google-ads/api/reference/rpc/latest/UserDataOperation
126
131
  * @typedef {{
127
132
  * customer_id: string,
128
133
  * login_customer_id: string,
129
134
  * list_id: string,
130
- * list_type: 'hashed_email'|'hashed_phone_number'|'mobile_id'|
131
- * 'third_party_user_id'|'address_info',
132
135
  * operation: 'create'|'remove',
133
136
  * }}
134
137
  */
135
138
  let CustomerMatchConfig;
136
139
 
137
140
  /**
138
- * Configuration for uploading customer match data for Google Ads, includes one of:
139
- * hashed_email, hashed_phone_number, mobile_id, third_party_user_id or address_info
141
+ * Configuration for uploading customer match data for Google Ads.
140
142
  * @see https://developers.google.com/google-ads/api/reference/rpc/latest/UserIdentifier
141
143
  * @typedef {{
142
- * hashed_email: string,
143
- * }|{
144
- * hashed_phone_number: string,
145
- * }|{
146
- * mobile_id: string,
147
- * }|{
148
- * third_party_user_id: string,
149
- * }|{
150
- * address_info: GoogleAdsApi.OfflineUserAddressInfo,
144
+ * hashed_email: (string|Array<string>|undefined),
145
+ * hashed_phone_number: (string|Array<string>|undefined),
146
+ * mobile_id: (string|Array<string>|undefined),
147
+ * third_party_user_id: (string|Array<string>|undefined),
148
+ * address_info: (GoogleAdsApi.OfflineUserAddressInfo|undefined),
151
149
  * }}
152
150
  */
153
151
  let CustomerMatchRecord;
@@ -530,18 +528,17 @@ class GoogleAds {
530
528
  const customerId = customerMatchConfig.customer_id.replace(/-/g, '');
531
529
  const loginCustomerId = customerMatchConfig.login_customer_id.replace(/-/g,
532
530
  '');
533
- const userListType = customerMatchConfig.list_type;
534
531
  const userListId = customerMatchConfig.list_id;
535
532
  const operation = customerMatchConfig.operation;
536
533
 
537
534
  const customer = this.getGoogleAdsApiCustomer_(loginCustomerId, customerId);
538
535
  const operationsList = this.buildOperationsList_(operation,
539
- customerMatchRecords, userListType);
536
+ customerMatchRecords);
540
537
  const metadata = this.buildCustomerMatchUserListMetadata_(customerId,
541
538
  userListId);
542
539
  const request = UploadUserDataRequest.create({
543
540
  customer_id: customerId,
544
- operations: [operationsList],
541
+ operations: operationsList,
545
542
  customer_match_user_list_metadata: metadata,
546
543
  });
547
544
  const response = await customer.userData.uploadUserData(request);
@@ -556,18 +553,36 @@ class GoogleAds {
556
553
  * @see https://developers.google.com/google-ads/api/reference/rpc/latest/UserDataOperation
557
554
  * @param {string} operationType either 'create' or 'remove'
558
555
  * @param {Array<CustomerMatchRecord>} customerMatchRecords userIds
559
- * @param {string} userListType One of the following hashed_email, hashed_phone_number,
560
- * mobile_id, third_party_user_id or address_info
561
556
  * @return {Array<UserDataOperation>}
562
557
  * @private
563
558
  */
564
- buildOperationsList_(operationType, customerMatchRecords, userListType) {
565
- const userIdentifiers = customerMatchRecords.map((customerMatchRecord) => {
566
- return UserIdentifier.create(
567
- {[userListType]: customerMatchRecord[userListType]});
559
+ buildOperationsList_(operationType, customerMatchRecords) {
560
+ return customerMatchRecords.map((customerMatchRecord) => {
561
+ const userIdentifiers = [];
562
+ IDENTIFIERS.forEach((idType) => {
563
+ const idValue = customerMatchRecord[idType];
564
+ if (idValue) {
565
+ if (Array.isArray(idValue)) {
566
+ idValue.forEach((user) => {
567
+ userIdentifiers.push(UserIdentifier.create({[idType]: user}));
568
+ });
569
+ } else {
570
+ userIdentifiers.push(UserIdentifier.create({[idType]: idValue}));
571
+ }
572
+ }
573
+ });
574
+ let userData;
575
+ if (userIdentifiers.length <= MAX_IDENTIFIERS_PER_USER) {
576
+ userData = UserData.create({user_identifiers: userIdentifiers});
577
+ } else {
578
+ this.logger.warn(
579
+ `Too many user identifiers, will only send ${MAX_IDENTIFIERS_PER_USER}:`,
580
+ JSON.stringify(customerMatchRecord));
581
+ userData = UserData.create({user_identifiers: userIdentifiers}.slice(0,
582
+ MAX_IDENTIFIERS_PER_USER));
583
+ }
584
+ return UserDataOperation.create({[operationType]: userData});
568
585
  });
569
- const userData = UserData.create({user_identifiers: userIdentifiers});
570
- return UserDataOperation.create({[operationType]: userData});
571
586
  }
572
587
 
573
588
  /**