@google-cloud/nodejs-common 2.2.2 → 2.3.1
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/package.json +15 -17
- package/src/apis/auth_client.js +10 -10
- package/src/apis/base/ads_api_common.js +1 -1
- package/src/apis/base/google_api_client.js +1 -1
- package/src/apis/doubleclick_bidmanager.js +3 -3
- package/src/apis/gmail.js +113 -0
- package/src/apis/google_ads_api.js +17 -17
- package/src/apis/index.js +10 -15
- package/src/apis/sendgrid.js +62 -1
- package/src/apis/spreadsheets.js +27 -6
- package/src/apis/youtube.js +0 -284
- package/src/components/firestore/access_base.js +3 -3
- package/src/components/firestore/data_access_object.js +4 -4
- package/src/components/firestore/datastore_mode_access.js +3 -3
- package/src/components/pubsub.js +1 -1
- package/src/components/scheduler.js +1 -1
- package/src/components/storage.js +1 -1
- package/src/components/utils.js +1 -1
- package/src/apis/google_ads.js +0 -1145
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@google-cloud/nodejs-common",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.1",
|
|
4
4
|
"description": "A NodeJs common library for solutions based on Cloud Functions",
|
|
5
5
|
"author": "Google Inc.",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -16,28 +16,26 @@
|
|
|
16
16
|
},
|
|
17
17
|
"homepage": "https://github.com/GoogleCloudPlatform/cloud-for-marketing/blob/master/marketing-analytics/activation/common-libs/nodejs-common/README.md",
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@google-cloud/aiplatform": "^3.
|
|
19
|
+
"@google-cloud/aiplatform": "^3.25.0",
|
|
20
20
|
"@google-cloud/automl": "^4.0.1",
|
|
21
|
-
"@google-cloud/bigquery": "^7.
|
|
22
|
-
"@google-cloud/datastore": "^
|
|
23
|
-
"@google-cloud/firestore": "^7.
|
|
21
|
+
"@google-cloud/bigquery": "^7.8.0",
|
|
22
|
+
"@google-cloud/datastore": "^9.1.0",
|
|
23
|
+
"@google-cloud/firestore": "^7.9.0",
|
|
24
24
|
"@google-cloud/logging-winston": "^6.0.0",
|
|
25
|
-
"@google-cloud/pubsub": "^4.
|
|
26
|
-
"@google-cloud/storage": "^7.
|
|
27
|
-
"@google-cloud/scheduler": "^4.
|
|
28
|
-
"@google-cloud/secret-manager": "^5.
|
|
29
|
-
"gaxios": "^6.
|
|
25
|
+
"@google-cloud/pubsub": "^4.5.0",
|
|
26
|
+
"@google-cloud/storage": "^7.12.0",
|
|
27
|
+
"@google-cloud/scheduler": "^4.3.0",
|
|
28
|
+
"@google-cloud/secret-manager": "^5.6.0",
|
|
29
|
+
"gaxios": "^6.7.0",
|
|
30
30
|
"google-ads-nodejs-client": "16.0.0",
|
|
31
|
-
"google-
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"winston": "^3.13.0",
|
|
36
|
-
"@grpc/grpc-js": "^1.10.5",
|
|
31
|
+
"google-auth-library": "^9.11.0",
|
|
32
|
+
"googleapis": "^140.0.1",
|
|
33
|
+
"winston": "^3.13.1",
|
|
34
|
+
"@grpc/grpc-js": "^1.11.1",
|
|
37
35
|
"lodash": "^4.17.21"
|
|
38
36
|
},
|
|
39
37
|
"devDependencies": {
|
|
40
|
-
"jasmine": "^5.
|
|
38
|
+
"jasmine": "^5.2.0"
|
|
41
39
|
},
|
|
42
40
|
"scripts": {
|
|
43
41
|
"test": "node node_modules/jasmine/bin/jasmine"
|
package/src/apis/auth_client.js
CHANGED
|
@@ -48,23 +48,23 @@ const DEFAULT_ENV_KEYFILE = 'API_SERVICE_ACCOUNT';
|
|
|
48
48
|
*
|
|
49
49
|
* There are two use cases for this authentication helper class:
|
|
50
50
|
* 1. The user only has OAuth access due to some reasons, so ADC can't be used;
|
|
51
|
-
* 2. User-managed service account is
|
|
51
|
+
* 2. User-managed service account is required for external APIs for some
|
|
52
52
|
* specific considerations, e.g. security. In this case, a file based key file
|
|
53
53
|
* can be used to generate a JWT auth client.
|
|
54
54
|
*
|
|
55
55
|
* To solve these challenges, this class tries to probe the settings from
|
|
56
|
-
*
|
|
56
|
+
* environment variables, starts from the name of secret (Secret Manager), OAuth
|
|
57
57
|
* token file (deprecated), then service account key file (deprecated). It will
|
|
58
58
|
* fallback to ADC if those probing failed.
|
|
59
|
-
* Note, Secret Manager is the
|
|
59
|
+
* Note, Secret Manager is the recommended way to store tokens because it is a
|
|
60
60
|
* secure and convenient central storage system to manage access across Google
|
|
61
61
|
* Cloud.
|
|
62
62
|
*
|
|
63
63
|
* The recommended environment variable is:
|
|
64
64
|
* SECRET_NAME: the name of secret. The secret can be a oauth token file or a
|
|
65
65
|
* service account key file. This env var is used to offer a global auth for a
|
|
66
|
-
* solution. If different
|
|
67
|
-
* set
|
|
66
|
+
* solution. If different authentications are required, the value of passed
|
|
67
|
+
* `env` can be set by the runtime.
|
|
68
68
|
*
|
|
69
69
|
* Alternative environment variable but not recommended for prod environment:
|
|
70
70
|
* OAUTH2_TOKEN_JSON : the oauth token key files, refresh token and proper API
|
|
@@ -88,7 +88,7 @@ class AuthClient {
|
|
|
88
88
|
|
|
89
89
|
/**
|
|
90
90
|
* Prepares the `oauthToken` object and/or `serviceAccountKey` based on the
|
|
91
|
-
* settings in
|
|
91
|
+
* settings in environment object.
|
|
92
92
|
* A secret name is preferred to offer the token of the OAuth or key of a
|
|
93
93
|
* service account.
|
|
94
94
|
* To be compatible, this function also checks the env for oauth token file
|
|
@@ -100,10 +100,10 @@ class AuthClient {
|
|
|
100
100
|
return;
|
|
101
101
|
}
|
|
102
102
|
if (this.env[DEFAULT_ENV_SECRET]) {
|
|
103
|
-
const
|
|
103
|
+
const secretManager = new SecretManager({
|
|
104
104
|
projectId: this.env.GCP_PROJECT,
|
|
105
105
|
});
|
|
106
|
-
const secret = await
|
|
106
|
+
const secret = await secretManager.access(this.env[DEFAULT_ENV_SECRET]);
|
|
107
107
|
if (secret) {
|
|
108
108
|
const secretObj = JSON.parse(secret);
|
|
109
109
|
if (secretObj.token) this.oauthToken = secretObj;
|
|
@@ -127,7 +127,7 @@ class AuthClient {
|
|
|
127
127
|
}
|
|
128
128
|
|
|
129
129
|
/**
|
|
130
|
-
* Factory method to offer a prepared AuthClient
|
|
130
|
+
* Factory method to offer a prepared AuthClient instance in an async way.
|
|
131
131
|
* @param {string|!Array<string>|!ReadonlyArray<string>} scopes
|
|
132
132
|
* @param {!Object<string,string>=} env The environment object to hold env
|
|
133
133
|
* variables.
|
|
@@ -163,7 +163,7 @@ class AuthClient {
|
|
|
163
163
|
* steps:
|
|
164
164
|
* 1. Checks environment variable GOOGLE_APPLICATION_CREDENTIALS to get
|
|
165
165
|
* service account. Returns a JWT if it exists;
|
|
166
|
-
* 2. Uses default service account of Computer Engine/
|
|
166
|
+
* 2. Uses default service account of Computer Engine/AppEngine/Cloud
|
|
167
167
|
* Functions
|
|
168
168
|
* 3. Otherwise, an error occurs.
|
|
169
169
|
* @see https://cloud.google.com/docs/authentication/production#obtaining_and_providing_service_account_credentials_manually
|
|
@@ -38,7 +38,7 @@ const END_TAG = '"requestId"';
|
|
|
38
38
|
|
|
39
39
|
/**
|
|
40
40
|
* A stream.Transform that can extract properties and convert naming of the
|
|
41
|
-
*
|
|
41
|
+
* response of Google/Search Ads report from REST interface.
|
|
42
42
|
*/
|
|
43
43
|
class RestSearchStreamTransform extends Transform {
|
|
44
44
|
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* @fileoverview A base class for Google Api client library class.
|
|
17
17
|
*/
|
|
18
18
|
const { google } = require('googleapis');
|
|
19
|
-
const { getLogger
|
|
19
|
+
const { getLogger } = require('../../components/utils.js');
|
|
20
20
|
const { AuthRestfulApi } = require('./auth_restful_api.js');
|
|
21
21
|
|
|
22
22
|
/**
|
|
@@ -94,13 +94,13 @@ class DoubleClickBidManager extends GoogleApiClient {
|
|
|
94
94
|
* Gets a query metadata.
|
|
95
95
|
* See https://developers.google.com/bid-manager/reference/rest/v2/queries/get
|
|
96
96
|
* @param {number} queryId Id of the query.
|
|
97
|
-
* @return {!Promise<!
|
|
98
|
-
* https://developers.google.com/bid-manager/reference/rest/v2/queries#
|
|
97
|
+
* @return {!Promise<!Query>} Query, see
|
|
98
|
+
* https://developers.google.com/bid-manager/reference/rest/v2/queries#Query
|
|
99
99
|
*/
|
|
100
100
|
async getQuery(queryId) {
|
|
101
101
|
const doubleclickbidmanager = await this.getApiClient();
|
|
102
102
|
const response = await doubleclickbidmanager.queries.get({ queryId });
|
|
103
|
-
return response.data
|
|
103
|
+
return response.data;
|
|
104
104
|
}
|
|
105
105
|
|
|
106
106
|
/**
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
// Copyright 2024 Google Inc.
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
|
|
15
|
+
/** @fileoverview Gmail API Client Library. */
|
|
16
|
+
|
|
17
|
+
'use strict';
|
|
18
|
+
|
|
19
|
+
const { GoogleApiClient } = require('./base/google_api_client.js');
|
|
20
|
+
|
|
21
|
+
const API_SCOPES =
|
|
22
|
+
Object.freeze(['https://www.googleapis.com/auth/gmail.send']);
|
|
23
|
+
const API_VERSION = 'v1';
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* @typedef {{
|
|
27
|
+
* from: string|undefined,
|
|
28
|
+
* to: string|Array<string>,
|
|
29
|
+
* cc: string|Array<string>|undefined,
|
|
30
|
+
* bcc: string|Array<string>|undefined,
|
|
31
|
+
* 'reply-to': string|Array<string>|undefined,
|
|
32
|
+
* subject: string,
|
|
33
|
+
* content: string,
|
|
34
|
+
* type: 'text/plain'|'text/html'|undefined,
|
|
35
|
+
* }}
|
|
36
|
+
*/
|
|
37
|
+
let EmailOptions;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Email sending class based on Gmail API.
|
|
41
|
+
*/
|
|
42
|
+
class Gmail extends GoogleApiClient {
|
|
43
|
+
|
|
44
|
+
constructor(env = process.env) {
|
|
45
|
+
super(env);
|
|
46
|
+
this.googleApi = 'gmail';
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** @override */
|
|
50
|
+
getScope() {
|
|
51
|
+
return API_SCOPES;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** @override */
|
|
55
|
+
getVersion() {
|
|
56
|
+
return API_VERSION;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Generates a string for an email in RFC 2822 format.
|
|
61
|
+
* If 'from' is different from the OAuth token's owner account, it would be
|
|
62
|
+
* ignored.
|
|
63
|
+
* @param {!EmailOptions} options
|
|
64
|
+
* @return {string}
|
|
65
|
+
* @private
|
|
66
|
+
*/
|
|
67
|
+
getRawEmail_(options = {}) {
|
|
68
|
+
const message = [];
|
|
69
|
+
['from', 'to', 'cc', 'bcc', 'reply-to', 'subject'].forEach((key) => {
|
|
70
|
+
if (options[key]) {
|
|
71
|
+
const value = Array.isArray(options[key])
|
|
72
|
+
? options[key].join(',') : options[key];
|
|
73
|
+
message.push(`${key}: ${value}`);
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
if (message.length === 0)
|
|
77
|
+
throw new Error(`Can not get email from ${options}`);
|
|
78
|
+
message.push('\n');
|
|
79
|
+
message.push(options.content);
|
|
80
|
+
return message.join('\n');
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Sends a simple email (no attachment).
|
|
85
|
+
* @see https://developers.google.com/gmail/api/reference/rest/v1/users.messages/send
|
|
86
|
+
* @param {!EmailOptions} options
|
|
87
|
+
* @return {!Message}
|
|
88
|
+
*/
|
|
89
|
+
async sendSimpleEmail(options) {
|
|
90
|
+
const email = this.getRawEmail_(options);
|
|
91
|
+
|
|
92
|
+
const gmail = await this.getApiClient();
|
|
93
|
+
const message = {
|
|
94
|
+
userId: 'me',
|
|
95
|
+
requestBody: { raw: Buffer.from(email).toString('base64') }
|
|
96
|
+
};
|
|
97
|
+
try {
|
|
98
|
+
const response = await gmail.users.messages.send(message);
|
|
99
|
+
return { responseStatus: response.status };
|
|
100
|
+
} catch (error) {
|
|
101
|
+
this.logger.error('Result of sending an email', JSON.stringify(error));
|
|
102
|
+
return { responseStatus: error.status };
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
module.exports = {
|
|
109
|
+
Gmail,
|
|
110
|
+
EmailOptions,
|
|
111
|
+
API_SCOPES,
|
|
112
|
+
API_VERSION,
|
|
113
|
+
};
|
|
@@ -211,7 +211,7 @@ const MAX_IDENTIFIERS = {
|
|
|
211
211
|
};
|
|
212
212
|
|
|
213
213
|
/**
|
|
214
|
-
* Configuration for uploading click conversions, call
|
|
214
|
+
* Configuration for uploading click conversions, call conversions or conversion
|
|
215
215
|
* adjustments for Google Ads, includes:
|
|
216
216
|
* gclid, conversionAction, conversionDateTime, conversionValue,
|
|
217
217
|
* currencyCode, orderId, externalAttributionData,
|
|
@@ -598,7 +598,7 @@ class GoogleAdsApi {
|
|
|
598
598
|
* e.g. wrong conversion Id, wrong gclid, etc.
|
|
599
599
|
* `Status` has a property `message` that has the general information of the
|
|
600
600
|
* error, however, the detailed information (e.g. the failed conversions and
|
|
601
|
-
* their reasons) lies in the property named `
|
|
601
|
+
* their reasons) lies in the property named `details` (an array of
|
|
602
602
|
* `GoogleAdsFailure`). Each `GoogleAdsFailure` is related to a failed
|
|
603
603
|
* conversion. The function `extraFailedLines_` is used to extract the
|
|
604
604
|
* details.
|
|
@@ -612,8 +612,8 @@ class GoogleAdsApi {
|
|
|
612
612
|
* @param {string} customerId
|
|
613
613
|
* @param {string} loginCustomerId Login customer account ID (Mcc Account id).
|
|
614
614
|
* @param {!ConversionConfig} conversionConfig Default conversion parameters.
|
|
615
|
-
* @param {string} functionName The name of sending
|
|
616
|
-
* be `uploadClickConversions`, `uploadCallConversions` or
|
|
615
|
+
* @param {string} functionName The name of sending conversions function,
|
|
616
|
+
* could be `uploadClickConversions`, `uploadCallConversions` or
|
|
617
617
|
* `uploadConversionAdjustments`.
|
|
618
618
|
* @param {string} propertyForDebug The name of property for debug info.
|
|
619
619
|
* @return {!SendSingleBatch} Function which can send a batch of hits to
|
|
@@ -945,8 +945,8 @@ class GoogleAdsApi {
|
|
|
945
945
|
AND user_list.membership_status = OPEN
|
|
946
946
|
AND user_list.crm_based_user_list.upload_key_type = ${uploadKeyType}
|
|
947
947
|
`;
|
|
948
|
-
const
|
|
949
|
-
return
|
|
948
|
+
const userLists = await this.getReport(customerId, loginCustomerId, query);
|
|
949
|
+
return userLists.length === 0 ? undefined : userLists[0].userList.id;
|
|
950
950
|
}
|
|
951
951
|
|
|
952
952
|
/**
|
|
@@ -954,8 +954,8 @@ class GoogleAdsApi {
|
|
|
954
954
|
* Id. The user list would be a CRM_BASED type.
|
|
955
955
|
* Trying to create a list with an used name will fail.
|
|
956
956
|
* The Google Ads service behind this function (UserListService) supports
|
|
957
|
-
* `partial_failure`. Here, we only create one
|
|
958
|
-
* `partial_failure` is disabled to simplified the error
|
|
957
|
+
* `partial_failure`. Here, we only create one user list at one time, so
|
|
958
|
+
* `partial_failure` is disabled to simplified the error handling process.
|
|
959
959
|
* @see getUploadConversionFnBase_ for more details of error handling.
|
|
960
960
|
* @param {!CustomerMatchConfig} customerMatchConfig
|
|
961
961
|
* @return {number} The created user list id. Note this is not the resource
|
|
@@ -973,7 +973,7 @@ class GoogleAdsApi {
|
|
|
973
973
|
customerId: getCleanCid(customerId),
|
|
974
974
|
operations: [{ create: userList }],
|
|
975
975
|
validateOnly: this.debugMode, // when true makes no changes
|
|
976
|
-
partialFailure: false, // Simplify error handling in creating
|
|
976
|
+
partialFailure: false, // Simplify error handling in creating user list
|
|
977
977
|
});
|
|
978
978
|
const client = await this.getUserListServiceClient_();
|
|
979
979
|
const options = this.getCallOptions_(loginCustomerId);
|
|
@@ -984,7 +984,7 @@ class GoogleAdsApi {
|
|
|
984
984
|
*/
|
|
985
985
|
const [response] = await client.mutateUserLists(request, options);
|
|
986
986
|
const { results } = response; // No `partialFailureError` here.
|
|
987
|
-
this.logger.debug(`Created crm
|
|
987
|
+
this.logger.debug(`Created crm user list from`, customerMatchConfig);
|
|
988
988
|
if (!results[0]) {
|
|
989
989
|
if (this.debugMode) {
|
|
990
990
|
throw new Error('No UserList was created in DEBUG mode.');
|
|
@@ -1139,7 +1139,7 @@ class GoogleAdsApi {
|
|
|
1139
1139
|
/**
|
|
1140
1140
|
* Creates a OfflineUserDataJob and returns resource name.
|
|
1141
1141
|
* @param {OfflineUserDataJobConfig} offlineUserDataJobConfig
|
|
1142
|
-
* @return {string} The
|
|
1142
|
+
* @return {string} The resource name of the created job.
|
|
1143
1143
|
*/
|
|
1144
1144
|
async createOfflineUserDataJob(offlineUserDataJobConfig) {
|
|
1145
1145
|
const config = this.getCamelConfig_(offlineUserDataJobConfig);
|
|
@@ -1231,7 +1231,7 @@ class GoogleAdsApi {
|
|
|
1231
1231
|
this.logger.debug(`Add operation to job batch[${batchId}]`, response);
|
|
1232
1232
|
const { partialFailureError: failed } = response;
|
|
1233
1233
|
if (failed) {
|
|
1234
|
-
this.logger.info(`Job[${jobResourceName}]
|
|
1234
|
+
this.logger.info(`Job[${jobResourceName}] fail:`, failed.message);
|
|
1235
1235
|
const failures = failed.details.map(
|
|
1236
1236
|
({ value }) => GoogleAdsFailure.decode(value));
|
|
1237
1237
|
this.extraFailedLines_(batchResult, failures, lines, 0);
|
|
@@ -1331,7 +1331,7 @@ class GoogleAdsApi {
|
|
|
1331
1331
|
|
|
1332
1332
|
/**
|
|
1333
1333
|
* Returns a HTTP header object contains the authentication information for
|
|
1334
|
-
* Google Ads API, include: `developer-token` and `
|
|
1334
|
+
* Google Ads API, include: `developer-token` and `login-customer-id`.
|
|
1335
1335
|
* @param {string} loginCustomerId
|
|
1336
1336
|
* @return {object} The HTTP header object.
|
|
1337
1337
|
* @private
|
|
@@ -1360,7 +1360,7 @@ class GoogleAdsApi {
|
|
|
1360
1360
|
}
|
|
1361
1361
|
|
|
1362
1362
|
/**
|
|
1363
|
-
* Prepares the
|
|
1363
|
+
* Prepares the fetch data service client instance.
|
|
1364
1364
|
* @return {!GoogleAdsServiceClient}
|
|
1365
1365
|
* @private
|
|
1366
1366
|
*/
|
|
@@ -1447,8 +1447,8 @@ class GoogleAdsApi {
|
|
|
1447
1447
|
}
|
|
1448
1448
|
|
|
1449
1449
|
/**
|
|
1450
|
-
* Returns an
|
|
1451
|
-
* @param {Object} record An object contains user
|
|
1450
|
+
* Returns an array of UserIdentifier object based the given JSON object.
|
|
1451
|
+
* @param {Object} record An object contains user identifier information.
|
|
1452
1452
|
* @param {!Array<string>} identifierTypes An list of user identifier types that
|
|
1453
1453
|
* are supported by the target service.
|
|
1454
1454
|
* @param {number} maximumNumOfIdentifiers The maximum number of user
|
|
@@ -1541,7 +1541,7 @@ const buildConversionJsonList = (lines, config, conversionFields,
|
|
|
1541
1541
|
})
|
|
1542
1542
|
}
|
|
1543
1543
|
/**
|
|
1544
|
-
* Returns an
|
|
1544
|
+
* Returns an array of UserData object based on the given arran of JSON strings.
|
|
1545
1545
|
* @param {!Array<string>} lines An array of JSON strings of UserData.
|
|
1546
1546
|
* @param {{
|
|
1547
1547
|
* additionalAttributes: (!UserIdentifierSource|undefined)
|
package/src/apis/index.js
CHANGED
|
@@ -99,18 +99,6 @@ exports.doubleclickbidmanager = require('./doubleclick_bidmanager.js');
|
|
|
99
99
|
*/
|
|
100
100
|
exports.bigquery = require('./bigquery.js');
|
|
101
101
|
|
|
102
|
-
/**
|
|
103
|
-
* APIs integration class for Google Ads.
|
|
104
|
-
* @const {{
|
|
105
|
-
* GoogleAds:!GoogleAds,
|
|
106
|
-
* ConversionConfig:!ConversionConfig,
|
|
107
|
-
* CustomerMatchConfig: !CustomerMatchConfig,
|
|
108
|
-
* CustomerMatchRecord: !CustomerMatchRecord,
|
|
109
|
-
* ReportQueryConfig:!ReportQueryConfig,
|
|
110
|
-
* }}
|
|
111
|
-
*/
|
|
112
|
-
exports.googleads = require('./google_ads.js');
|
|
113
|
-
|
|
114
102
|
/**
|
|
115
103
|
* APIs integration class for Google Ads with Google API library.
|
|
116
104
|
* @const {{
|
|
@@ -146,9 +134,7 @@ exports.measurementprotocolga4 = require('./measurement_protocol_ga4.js');
|
|
|
146
134
|
/**
|
|
147
135
|
* APIs integration class for YouTube.
|
|
148
136
|
* @const {{
|
|
149
|
-
* YouTube:!YouTube
|
|
150
|
-
* ListChannelsConfig: !ListChannelsConfig,
|
|
151
|
-
* ListVideosConfig: !ListVideosConfig,
|
|
137
|
+
* YouTube:!YouTube
|
|
152
138
|
* }}
|
|
153
139
|
*/
|
|
154
140
|
exports.youtube = require('./youtube.js');
|
|
@@ -162,3 +148,12 @@ exports.youtube = require('./youtube.js');
|
|
|
162
148
|
* }}
|
|
163
149
|
*/
|
|
164
150
|
exports.sendgrid = require('./sendgrid.js');
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* APIs integration class for Gmail.
|
|
154
|
+
* @const {{
|
|
155
|
+
* Gmail:!Gmail,
|
|
156
|
+
* API_VERSION: string,
|
|
157
|
+
* }}
|
|
158
|
+
*/
|
|
159
|
+
exports.gmail = require('./gmail.js');
|
package/src/apis/sendgrid.js
CHANGED
|
@@ -18,12 +18,33 @@
|
|
|
18
18
|
|
|
19
19
|
'use strict';
|
|
20
20
|
|
|
21
|
+
const { EmailOptions } = require('./gmail.js');
|
|
21
22
|
const { RestfulApiBase } = require('./base/restful_api_base.js');
|
|
22
23
|
const { getLogger } = require('../components/utils.js');
|
|
23
24
|
|
|
24
25
|
const API_VERSION = 'v3';
|
|
25
26
|
const API_ENDPOINT = 'https://api.sendgrid.com';
|
|
26
27
|
|
|
28
|
+
/**
|
|
29
|
+
* Returns a SendGrid email object based on a given RFC 2822 `mailbox` string.
|
|
30
|
+
* For `mailbox` @see https://www.rfc-editor.org/rfc/rfc2822#page-15
|
|
31
|
+
* @param {string} mailbox
|
|
32
|
+
* @return {{name: string, email: string}} A SendGrid email object.
|
|
33
|
+
*/
|
|
34
|
+
function getSendGridEmail(mailbox) {
|
|
35
|
+
if (typeof mailbox === 'string') {
|
|
36
|
+
if (mailbox.indexOf('<') > -1) {
|
|
37
|
+
const name = mailbox.substring(0, mailbox.indexOf('<')).trim();
|
|
38
|
+
const email =
|
|
39
|
+
mailbox.substring(mailbox.indexOf('<') + 1, mailbox.indexOf('>'));
|
|
40
|
+
return { name, email };
|
|
41
|
+
} else {
|
|
42
|
+
return { email: mailbox.trim() };
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return mailbox;
|
|
46
|
+
}
|
|
47
|
+
|
|
27
48
|
/**
|
|
28
49
|
* SendGrid API access class.
|
|
29
50
|
* @see https://docs.sendgrid.com/api-reference/how-to-use-the-sendgrid-v3-api/authentication
|
|
@@ -48,11 +69,51 @@ class SendGrid extends RestfulApiBase {
|
|
|
48
69
|
});
|
|
49
70
|
}
|
|
50
71
|
|
|
72
|
+
/**
|
|
73
|
+
* Generates an email object for Sendgrid.
|
|
74
|
+
* @param {!EmailOptions} options
|
|
75
|
+
* @return {object}
|
|
76
|
+
* @see https://www.twilio.com/docs/sendgrid/api-reference/mail-send/mail-send#reques
|
|
77
|
+
* @private
|
|
78
|
+
*/
|
|
79
|
+
getEmail_(options = {}) {
|
|
80
|
+
const {
|
|
81
|
+
from,
|
|
82
|
+
'reply-to': reply_to,
|
|
83
|
+
subject,
|
|
84
|
+
content,
|
|
85
|
+
type = 'text/plain',
|
|
86
|
+
} = options;
|
|
87
|
+
const recipientObject = {};
|
|
88
|
+
['to', 'cc', 'bcc'].forEach((key) => {
|
|
89
|
+
if (options[key]) {
|
|
90
|
+
recipientObject[key] = [options[key]].flat().map(getSendGridEmail);
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
const email = {
|
|
94
|
+
subject,
|
|
95
|
+
content: [{ type, value: content }],
|
|
96
|
+
personalizations: [recipientObject],
|
|
97
|
+
};
|
|
98
|
+
if (from) email.from = getSendGridEmail(from);
|
|
99
|
+
//@see https://www.twilio.com/docs/sendgrid/api-reference/mail-send/mail-send#reques
|
|
100
|
+
if (reply_to) {
|
|
101
|
+
if (Array.isArray(reply_to)) {
|
|
102
|
+
email.reply_to_list = reply_to.map(getSendGridEmail);
|
|
103
|
+
} else {
|
|
104
|
+
email.reply_to = getSendGridEmail(reply_to);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return email;
|
|
108
|
+
}
|
|
109
|
+
|
|
51
110
|
/**
|
|
52
111
|
* Sends an email.
|
|
112
|
+
* @param {!EmailOptions} options
|
|
53
113
|
* @see https://docs.sendgrid.com/api-reference/mail-send/mail-send
|
|
54
114
|
*/
|
|
55
|
-
async sendMail(
|
|
115
|
+
async sendMail(options) {
|
|
116
|
+
const email = this.getEmail_(options);
|
|
56
117
|
const response = await this.request('mail/send', 'POST', email);
|
|
57
118
|
return response;
|
|
58
119
|
}
|
package/src/apis/spreadsheets.js
CHANGED
|
@@ -67,15 +67,19 @@ let DimensionRange;
|
|
|
67
67
|
class Spreadsheets extends GoogleApiClient {
|
|
68
68
|
/**
|
|
69
69
|
* Init Spreadsheets API client.
|
|
70
|
-
* @param {string}
|
|
70
|
+
* @param {string} spreadsheetIdOrUrl
|
|
71
71
|
* @param {!Object<string,string>=} env The environment object to hold env
|
|
72
72
|
* variables.
|
|
73
73
|
*/
|
|
74
|
-
constructor(
|
|
74
|
+
constructor(spreadsheetIdOrUrl, env = process.env) {
|
|
75
75
|
super(env);
|
|
76
76
|
this.googleApi = 'sheets';
|
|
77
77
|
/** @const {string} */
|
|
78
|
-
|
|
78
|
+
if (spreadsheetIdOrUrl.startsWith('https://')) {
|
|
79
|
+
this.spreadsheetId = /spreadsheets\/d\/([^/]*)/.exec(spreadsheetIdOrUrl)[1];
|
|
80
|
+
} else {
|
|
81
|
+
this.spreadsheetId = spreadsheetIdOrUrl;
|
|
82
|
+
}
|
|
79
83
|
this.logger = getLogger('API.GS');
|
|
80
84
|
}
|
|
81
85
|
|
|
@@ -109,7 +113,7 @@ class Spreadsheets extends GoogleApiClient {
|
|
|
109
113
|
}
|
|
110
114
|
|
|
111
115
|
/**
|
|
112
|
-
* Returns whether the sheet with
|
|
116
|
+
* Returns whether the sheet with specified name exists.
|
|
113
117
|
* @param {string} sheetName
|
|
114
118
|
* @return {boolean}
|
|
115
119
|
*/
|
|
@@ -122,7 +126,7 @@ class Spreadsheets extends GoogleApiClient {
|
|
|
122
126
|
}
|
|
123
127
|
|
|
124
128
|
/**
|
|
125
|
-
* Creates a sheet with the
|
|
129
|
+
* Creates a sheet with the given name.
|
|
126
130
|
*
|
|
127
131
|
* @param {string} sheetName
|
|
128
132
|
*/
|
|
@@ -137,7 +141,7 @@ class Spreadsheets extends GoogleApiClient {
|
|
|
137
141
|
}
|
|
138
142
|
|
|
139
143
|
/**
|
|
140
|
-
* Deletes a sheet with the
|
|
144
|
+
* Deletes a sheet with the given name.
|
|
141
145
|
*
|
|
142
146
|
* @param {string} sheetName
|
|
143
147
|
*/
|
|
@@ -289,6 +293,23 @@ class Spreadsheets extends GoogleApiClient {
|
|
|
289
293
|
}
|
|
290
294
|
return batchResult;
|
|
291
295
|
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Gets values of first row of the specified sheet.
|
|
299
|
+
* @param {string} sheetName
|
|
300
|
+
* @return {!Array<string>}
|
|
301
|
+
*/
|
|
302
|
+
async getHeadline(sheetName) {
|
|
303
|
+
const request = {
|
|
304
|
+
spreadsheetId: this.spreadsheetId,
|
|
305
|
+
range: `'${sheetName}'!1:1`,
|
|
306
|
+
};
|
|
307
|
+
const sheets = await this.getApiClient();
|
|
308
|
+
const response = await sheets.spreadsheets.values.get(request);
|
|
309
|
+
const data = response.data;
|
|
310
|
+
this.logger.debug(`Get: `, data);
|
|
311
|
+
return data.values[0];
|
|
312
|
+
}
|
|
292
313
|
}
|
|
293
314
|
|
|
294
315
|
module.exports = {
|