@google-cloud/nodejs-common 1.0.2 → 1.0.4
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.
- package/bin/install_functions.sh +15 -4
- package/package.json +1 -1
- package/src/apis/google_ads.js +43 -28
package/bin/install_functions.sh
CHANGED
|
@@ -1337,10 +1337,13 @@ do_authentication(){
|
|
|
1337
1337
|
do_oauth(){
|
|
1338
1338
|
# Base url of Google OAuth service.
|
|
1339
1339
|
OAUTH_BASE_URL="https://accounts.google.com/o/oauth2/"
|
|
1340
|
+
# Redirect uri.
|
|
1341
|
+
# Must be the same for requests of authorization code and refresh token.
|
|
1342
|
+
REDIRECT_URI="http%3A//127.0.0.1%3A8887"
|
|
1340
1343
|
# Defaulat parameters of OAuth requests.
|
|
1341
1344
|
OAUTH_PARAMETERS=(
|
|
1342
1345
|
"access_type=offline"
|
|
1343
|
-
"redirect_uri
|
|
1346
|
+
"redirect_uri=${REDIRECT_URI}"
|
|
1344
1347
|
"response_type=code"
|
|
1345
1348
|
)
|
|
1346
1349
|
while [ ${#ENABLED_OAUTH_SCOPES[@]} -eq 0 ]; do
|
|
@@ -1409,18 +1412,26 @@ EOF
|
|
|
1409
1412
|
printf '%s\n' "3. Open the link in browser and finish authentication: \
|
|
1410
1413
|
${auth_url}"
|
|
1411
1414
|
cat <<EOF
|
|
1412
|
-
Note:
|
|
1415
|
+
Note:
|
|
1416
|
+
If the OAuth client is not for a native application, there will be an \
|
|
1413
1417
|
"Error 400: redirect_uri_mismatch" shown up on the page. In this case, press \
|
|
1414
1418
|
"Enter" to start again with a native application OAuth client ID.
|
|
1419
|
+
If there is no local web server serving at ${REDIRECT_URI}, the \
|
|
1420
|
+
succeeded OAuth flow will land the browser on an error page ("This site can't \
|
|
1421
|
+
be reached"). This is an expected behavior. Copy the whole URL and continue.
|
|
1422
|
+
|
|
1415
1423
|
EOF
|
|
1416
|
-
printf '%s' "4. Copy the authorization code
|
|
1424
|
+
printf '%s' "4. Copy the authorization code or complete url from browser \
|
|
1425
|
+
and paste here: "
|
|
1417
1426
|
read -r auth_code
|
|
1418
1427
|
if [[ -z ${auth_code} ]]; then
|
|
1419
1428
|
printf '%s\n\n' "No authorization code. Starting from beginning again..."
|
|
1420
1429
|
continue
|
|
1421
1430
|
fi
|
|
1431
|
+
auth_code=$(printf "%s" "${auth_code}" | sed 's/^.*code=//;s/&.*//')
|
|
1432
|
+
printf '%s\n' "Got authorization code: ${auth_code}"
|
|
1422
1433
|
auth_response=$(curl -s -d "code=${auth_code}" -d "client_id=${client_id}" \
|
|
1423
|
-
-d "grant_type=authorization_code" -d "redirect_uri
|
|
1434
|
+
-d "grant_type=authorization_code" -d "redirect_uri=${REDIRECT_URI}" \
|
|
1424
1435
|
-d "client_secret=${client_secret}" "${OAUTH_BASE_URL}token")
|
|
1425
1436
|
auth_error=$(node -e "console.log(!!JSON.parse(process.argv[1]).error)" \
|
|
1426
1437
|
"${auth_response}")
|
package/package.json
CHANGED
package/src/apis/google_ads.js
CHANGED
|
@@ -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:(!
|
|
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
|
|
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
|
|
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
|
-
*
|
|
145
|
-
*
|
|
146
|
-
*
|
|
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
|
|
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:
|
|
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
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
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
|
/**
|