skyeye-svc-common-utils 1.0.80 → 1.0.82

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/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import SendGridClient, { ISgMessage, ISgCategoryStatistics, SgCategoryStatisticsItem, SgCategoryStatisticsMetricsItem } from './lib/sendGridClient';
1
2
  export * from './utils/appConfig';
2
3
  export * from './utils/appConst';
3
4
  export * from './utils/commonUtils';
@@ -23,7 +24,7 @@ export * from './utils/monitoring/apm';
23
24
  export * from './models/baseControllerParameter';
24
25
  export * from './models';
25
26
  export * from './lib/redisClient';
26
- export * from './lib/sendGridClient';
27
27
  export * from './interfaces/grpcServiceResponse';
28
28
  export * from './interfaces/grpcListRequest';
29
29
  export * from './utils/commonUtils/appConfigKeyRetriever';
30
+ export { SendGridClient, ISgMessage, ISgCategoryStatistics, SgCategoryStatisticsItem, SgCategoryStatisticsMetricsItem };
package/dist/index.js CHANGED
@@ -13,7 +13,13 @@ var __createBinding = (this && this.__createBinding) || (Object.create ? (functi
13
13
  var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
+ var __importDefault = (this && this.__importDefault) || function (mod) {
17
+ return (mod && mod.__esModule) ? mod : { "default": mod };
18
+ };
16
19
  Object.defineProperty(exports, "__esModule", { value: true });
20
+ exports.SendGridClient = void 0;
21
+ const sendGridClient_1 = __importDefault(require("./lib/sendGridClient"));
22
+ exports.SendGridClient = sendGridClient_1.default;
17
23
  __exportStar(require("./utils/appConfig"), exports);
18
24
  __exportStar(require("./utils/appConst"), exports);
19
25
  __exportStar(require("./utils/commonUtils"), exports);
@@ -39,7 +45,6 @@ __exportStar(require("./utils/monitoring/apm"), exports);
39
45
  __exportStar(require("./models/baseControllerParameter"), exports);
40
46
  __exportStar(require("./models"), exports);
41
47
  __exportStar(require("./lib/redisClient"), exports);
42
- __exportStar(require("./lib/sendGridClient"), exports);
43
48
  __exportStar(require("./interfaces/grpcServiceResponse"), exports);
44
49
  __exportStar(require("./interfaces/grpcListRequest"), exports);
45
50
  __exportStar(require("./utils/commonUtils/appConfigKeyRetriever"), exports);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,oDAAkC;AAClC,mDAAiC;AACjC,sDAAoC;AACpC,8DAA4C;AAC5C,wDAAsC;AACtC,8DAA4C;AAC5C,iEAA+C;AAC/C,kEAAgD;AAChD,oEAAkD;AAClD,uEAAqD;AACrD,mEAAiD;AACjD,gEAA8C;AAC9C,qDAAmC;AACnC,4DAA0C;AAC1C,oEAAkD;AAClD,gEAA8C;AAC9C,mEAAiD;AACjD,gEAA8C;AAC9C,+DAA6C;AAC7C,gEAA8C;AAC9C,mDAAiC;AACjC,yDAAuC;AACvC,mEAAiD;AACjD,2CAAyB;AACzB,oDAAkC;AAClC,uDAAqC;AACrC,mEAAiD;AACjD,+DAA6C;AAC7C,4EAA0D"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA,0EAAoJ;AA8B3I,yBA9BF,wBAAc,CA8BE;AA5BvB,oDAAkC;AAClC,mDAAiC;AACjC,sDAAoC;AACpC,8DAA4C;AAC5C,wDAAsC;AACtC,8DAA4C;AAC5C,iEAA+C;AAC/C,kEAAgD;AAChD,oEAAkD;AAClD,uEAAqD;AACrD,mEAAiD;AACjD,gEAA8C;AAC9C,qDAAmC;AACnC,4DAA0C;AAC1C,oEAAkD;AAClD,gEAA8C;AAC9C,mEAAiD;AACjD,gEAA8C;AAC9C,+DAA6C;AAC7C,gEAA8C;AAC9C,mDAAiC;AACjC,yDAAuC;AACvC,mEAAiD;AACjD,2CAAyB;AACzB,oDAAkC;AAClC,mEAAiD;AACjD,+DAA6C;AAC7C,4EAA0D"}
@@ -1,18 +1,54 @@
1
- import { MailDataRequired } from '@sendgrid/mail';
1
+ import { MailDataRequired, ClientResponse } from '@sendgrid/mail';
2
+ import { SendGridEmailFeedStatus } from '../utils/appConst';
3
+ export interface ISgMessage {
4
+ from_email: string;
5
+ to_email: string;
6
+ msg_id: string;
7
+ subject: string;
8
+ status: string;
9
+ opens_count: number;
10
+ clicks_count: number;
11
+ last_event_time: string;
12
+ }
13
+ export interface ISgCategoryStatistics {
14
+ date: string;
15
+ stats: SgCategoryStatisticsItem[];
16
+ }
17
+ export type SgCategoryStatisticsItem = {
18
+ type: string;
19
+ name: string;
20
+ metrics: SgCategoryStatisticsMetricsItem;
21
+ };
22
+ export type SgCategoryStatisticsMetricsItem = {
23
+ blocks: number;
24
+ bounce_drops: number;
25
+ bounces: number;
26
+ clicks: number;
27
+ deferred: number;
28
+ delivered: number;
29
+ invalid_emails: number;
30
+ opens: number;
31
+ processed: number;
32
+ requests: number;
33
+ spam_report_drops: number;
34
+ spam_reports: number;
35
+ unique_clicks: number;
36
+ unique_opens: number;
37
+ unsubscribe_drops: number;
38
+ unsubscribes: number;
39
+ };
2
40
  /**
3
41
  * A SendGrid client class
4
42
  */
5
- declare class SendGridClient {
43
+ export default class SendGridClient {
6
44
  private mailService;
45
+ private officialClient;
46
+ private static BASE_URL;
7
47
  /**
8
48
  * @constructor
9
49
  * @param {string} [apiKey] - SendGrid API key (optional)
10
50
  */
11
- constructor();
12
- /**
13
- * Initializes the SendGrid client with the API key retrieved from Azure Key Vault.
14
- */
15
- private initialize;
51
+ constructor(sendGridClientSecret: string);
16
52
  /**
17
53
  * It sends an email.
18
54
  * @param {string} from - The email address of the sender.
@@ -21,7 +57,29 @@ declare class SendGridClient {
21
57
  * @param {string} htmlBodyText - The HTML body of the email.
22
58
  * @param {any} [options] - Extra settings for the email
23
59
  */
24
- send(from: string, to: string[], subject: string, htmlBodyText: string, options?: Partial<MailDataRequired>): Promise<void> | never;
60
+ sendEmail(from: string, to: string[], subject: string, htmlBodyText: string, options?: Partial<MailDataRequired>): Promise<ClientResponse> | never;
61
+ getEmailActivity(lastEventStartDate?: Date, lastEventEndDate?: Date, category?: string, status?: SendGridEmailFeedStatus): Promise<ISgMessage[]>;
62
+ getQueryParams(batchSize?: number, lastEventStartDate?: Date, lastEventEndDate?: Date, category?: string, status?: SendGridEmailFeedStatus): {
63
+ limit: number;
64
+ query: string;
65
+ } | {
66
+ limit: number;
67
+ query?: undefined;
68
+ };
69
+ /**
70
+ * The function getCategoryStats retrieves category statistics with optional parameters such as
71
+ * limit, skip, startDate, category, aggregatedBy, and endDate.
72
+ * @param {string} startDate - The starting date of the statistics to retrieve. Must follow format YYYY-MM-DD.
73
+ * @param {string} category - The `category` parameter is a parameter that allows you
74
+ * to specify a category for which you want to retrieve statistics. It is a string type parameter.
75
+ * If provided, the function will return statistics specific to the specified category. If not
76
+ * provided, the function will return statistics for all categories.
77
+ * @param {string} aggregatedBy - How to group the statistics. Must be either "day", "week", or "month".
78
+ * @param {number} [limit=1000] - The number of results to return.
79
+ * @param {number} [skip=0] - The point in the list to begin retrieving results.
80
+ * @param {string} [endDate] - The end date of the statistics to retrieve. Defaults to today. Must follow format YYYY-MM-DD.
81
+ *
82
+ * https://www.twilio.com/docs/sendgrid/api-reference/stats/retrieve-global-email-statistics#operation-details
83
+ */
84
+ getCategoryStats(startDate: string, category: string, aggregatedBy: "day" | "week" | "month", limit?: number, offset?: number, endDate?: string): Promise<ISgCategoryStatistics[]>;
25
85
  }
26
- export declare const sendGridClient: SendGridClient;
27
- export {};
@@ -9,11 +9,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  });
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.sendGridClient = void 0;
13
12
  const mail_1 = require("@sendgrid/mail");
13
+ const client_1 = require("@sendgrid/client");
14
14
  const logger_1 = require("./../utils/logger/logger");
15
- const appConfigKeyRetriever_1 = require("./../utils/commonUtils/appConfigKeyRetriever");
16
- const appConfig_1 = require("./../utils/appConfig");
15
+ const lodash_1 = require("lodash");
17
16
  /**
18
17
  * A SendGrid client class
19
18
  */
@@ -22,18 +21,12 @@ class SendGridClient {
22
21
  * @constructor
23
22
  * @param {string} [apiKey] - SendGrid API key (optional)
24
23
  */
25
- constructor() {
24
+ constructor(sendGridClientSecret) {
26
25
  this.mailService = new mail_1.MailService();
27
- this.initialize();
28
- }
29
- /**
30
- * Initializes the SendGrid client with the API key retrieved from Azure Key Vault.
31
- */
32
- initialize() {
33
- return __awaiter(this, void 0, void 0, function* () {
34
- const sendGridClientSecret = yield appConfigKeyRetriever_1.AppConfigKeyRetriever.getSendgridClientSecret();
35
- this.mailService.setApiKey(sendGridClientSecret);
36
- });
26
+ this.officialClient = new client_1.Client();
27
+ // set API key
28
+ this.mailService.setApiKey(sendGridClientSecret);
29
+ this.officialClient.setApiKey(sendGridClientSecret);
37
30
  }
38
31
  /**
39
32
  * It sends an email.
@@ -43,13 +36,14 @@ class SendGridClient {
43
36
  * @param {string} htmlBodyText - The HTML body of the email.
44
37
  * @param {any} [options] - Extra settings for the email
45
38
  */
46
- send(from, to, subject, htmlBodyText, options) {
39
+ sendEmail(from, to, subject, htmlBodyText, options) {
47
40
  return __awaiter(this, void 0, void 0, function* () {
48
41
  const msg = Object.assign({ from,
49
42
  to,
50
43
  subject, html: htmlBodyText }, options);
51
44
  try {
52
- yield this.mailService.send(msg);
45
+ const response = yield this.mailService.send(msg);
46
+ return response[0];
53
47
  }
54
48
  catch (err) {
55
49
  logger_1.logger.error(`SendGridClient/send with error, ${err}`);
@@ -57,6 +51,122 @@ class SendGridClient {
57
51
  }
58
52
  });
59
53
  }
54
+ /*
55
+ SendGrid v3 API has a pagination limitation on GET /messages
56
+ it only accepts limit as query param, not offset
57
+ https://www.twilio.com/docs/sendgrid/api-reference/how-to-use-the-sendgrid-v3-api/requests#pagination
58
+ */
59
+ getEmailActivity(lastEventStartDate, lastEventEndDate, category, status) {
60
+ return __awaiter(this, void 0, void 0, function* () {
61
+ const method = 'GET';
62
+ const url = '/v3/messages';
63
+ const baseUrl = SendGridClient.BASE_URL;
64
+ const request = this.officialClient.createRequest({
65
+ baseUrl,
66
+ url,
67
+ method
68
+ });
69
+ const batchSize = 1000;
70
+ // store all unique records
71
+ const map = new Map();
72
+ // as the records are returned in DESC order of lastEventDate, keep update nextLastEventEndDate within the loop
73
+ let nextLastEventEndDate = lastEventEndDate;
74
+ let count = 0;
75
+ do {
76
+ request.qs = this.getQueryParams(batchSize, lastEventStartDate, nextLastEventEndDate, category, status);
77
+ logger_1.logger.info(`Sending ${method} request to ${baseUrl + url} with body: ${JSON.stringify(request)}`);
78
+ const [response, body] = yield this.officialClient.request(request);
79
+ const statusCode = response.statusCode;
80
+ if (statusCode == 200) {
81
+ const messages = body.messages;
82
+ count = messages.length;
83
+ if (count > 0) {
84
+ for (const msg of messages) {
85
+ if (!map.has(msg.msg_id)) {
86
+ map.set(msg.msg_id, msg);
87
+ }
88
+ }
89
+ const lastItem = messages[messages.length - 1];
90
+ nextLastEventEndDate = new Date(lastItem.last_event_time);
91
+ }
92
+ }
93
+ else {
94
+ break;
95
+ }
96
+ } while (count >= batchSize);
97
+ return Array.from(map.values());
98
+ });
99
+ }
100
+ /*
101
+ https://www.twilio.com/docs/sendgrid/for-developers/sending-email/getting-started-email-activity-api
102
+ can add more query params
103
+ */
104
+ getQueryParams(batchSize, lastEventStartDate, lastEventEndDate, category, status) {
105
+ let query = '';
106
+ if (!((0, lodash_1.isNil)(lastEventStartDate) && (0, lodash_1.isNil)(lastEventEndDate))) {
107
+ query = `(last_event_time BETWEEN TIMESTAMP "${lastEventStartDate.toISOString()}" AND TIMESTAMP "${lastEventEndDate.toISOString()}")`;
108
+ }
109
+ if (!(0, lodash_1.isNil)(category)) {
110
+ query += ` AND (Contains(categories,"${category}"))`;
111
+ }
112
+ if (!(0, lodash_1.isNil)(status)) {
113
+ query += ` AND (status IN ("${status}"))`;
114
+ }
115
+ return query.length > 0 ? {
116
+ 'limit': (0, lodash_1.isNil)(batchSize) ? 1000 : batchSize,
117
+ 'query': query
118
+ } : {
119
+ 'limit': (0, lodash_1.isNil)(batchSize) ? 1000 : batchSize
120
+ };
121
+ }
122
+ /**
123
+ * The function getCategoryStats retrieves category statistics with optional parameters such as
124
+ * limit, skip, startDate, category, aggregatedBy, and endDate.
125
+ * @param {string} startDate - The starting date of the statistics to retrieve. Must follow format YYYY-MM-DD.
126
+ * @param {string} category - The `category` parameter is a parameter that allows you
127
+ * to specify a category for which you want to retrieve statistics. It is a string type parameter.
128
+ * If provided, the function will return statistics specific to the specified category. If not
129
+ * provided, the function will return statistics for all categories.
130
+ * @param {string} aggregatedBy - How to group the statistics. Must be either "day", "week", or "month".
131
+ * @param {number} [limit=1000] - The number of results to return.
132
+ * @param {number} [skip=0] - The point in the list to begin retrieving results.
133
+ * @param {string} [endDate] - The end date of the statistics to retrieve. Defaults to today. Must follow format YYYY-MM-DD.
134
+ *
135
+ * https://www.twilio.com/docs/sendgrid/api-reference/stats/retrieve-global-email-statistics#operation-details
136
+ */
137
+ getCategoryStats(startDate, category, aggregatedBy, limit = 1000, offset = 0, endDate) {
138
+ return __awaiter(this, void 0, void 0, function* () {
139
+ const method = 'GET';
140
+ const url = '/v3/categories/stats';
141
+ const baseUrl = SendGridClient.BASE_URL;
142
+ const request = this.officialClient.createRequest({
143
+ baseUrl,
144
+ url,
145
+ method
146
+ });
147
+ const queryParams = {
148
+ 'limit': limit,
149
+ 'offset': offset,
150
+ 'start_date': startDate,
151
+ 'categories': category,
152
+ 'aggregated_by': aggregatedBy
153
+ };
154
+ if (!(0, lodash_1.isNil)(endDate)) {
155
+ queryParams.end_date = endDate;
156
+ }
157
+ request.qs = queryParams;
158
+ logger_1.logger.info(`Sending ${method} request to ${baseUrl + url} with body: ${JSON.stringify(request)}`);
159
+ const [response, body] = yield this.officialClient.request(request);
160
+ const statusCode = response.statusCode;
161
+ if (statusCode == 200) {
162
+ return response.body;
163
+ }
164
+ else {
165
+ return [];
166
+ }
167
+ });
168
+ }
60
169
  }
61
- exports.sendGridClient = appConfig_1.commonAppConfig.SendgridClientSecretKey ? new SendGridClient() : null;
170
+ exports.default = SendGridClient;
171
+ SendGridClient.BASE_URL = 'https://api.sendgrid.com';
62
172
  //# sourceMappingURL=sendGridClient.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sendGridClient.js","sourceRoot":"","sources":["../../src/lib/sendGridClient.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,yCAA+D;AAC/D,qDAAkD;AAClD,wFAAqF;AACrF,oDAAuD;AAEvD;;GAEG;AACH,MAAM,cAAc;IAIhB;;;OAGG;IACH;QACI,IAAI,CAAC,WAAW,GAAG,IAAI,kBAAW,EAAE,CAAC;QACrC,IAAI,CAAC,UAAU,EAAE,CAAC;IACtB,CAAC;IAED;;OAEG;IACW,UAAU;;YACpB,MAAM,oBAAoB,GAAG,MAAM,6CAAqB,CAAC,uBAAuB,EAAE,CAAC;YACnF,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC;QACrD,CAAC;KAAA;IAGD;;;;;;;OAOG;IACG,IAAI,CAAC,IAAY,EAAE,EAAY,EAAE,OAAe,EAAE,YAAoB,EAAE,OAAmC;;YAC7G,MAAM,GAAG,mBACL,IAAI;gBACJ,EAAE;gBACF,OAAO,EACP,IAAI,EAAE,YAAY,IACf,OAAO,CACb,CAAC;YAEF,IAAI;gBACA,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;aACpC;YAAC,OAAO,GAAG,EAAE;gBACV,eAAM,CAAC,KAAK,CAAC,mCAAmC,GAAG,EAAE,CAAC,CAAC;gBACvD,MAAM,GAAG,CAAC;aACb;QACL,CAAC;KAAA;CACJ;AAEY,QAAA,cAAc,GAAG,2BAAe,CAAC,uBAAuB,CAAC,CAAC,CAAC,IAAI,cAAc,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC"}
1
+ {"version":3,"file":"sendGridClient.js","sourceRoot":"","sources":["../../src/lib/sendGridClient.ts"],"names":[],"mappings":"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"}
@@ -140,3 +140,8 @@ export declare enum CAMPAIGN_USER_STATUS {
140
140
  REJECTED = 3
141
141
  }
142
142
  export declare const exitErrorMessage: Record<string, string>;
143
+ export declare enum SendGridEmailFeedStatus {
144
+ Delivered = "delivered",
145
+ NotDelivered = "not_delivered",
146
+ Processing = "processing"
147
+ }
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.exitErrorMessage = exports.CAMPAIGN_USER_STATUS = exports.CAMPAIGN_EVENT_USER_STATUS = exports.entityType = exports.jsonContentTypeHeaders = exports.ScoutAITrainingMethod = exports.ScoutAIType = exports.AllDeletedStatus = exports.DeletedStatus = exports.FeatureType = exports.commonAppConst = void 0;
3
+ exports.SendGridEmailFeedStatus = exports.exitErrorMessage = exports.CAMPAIGN_USER_STATUS = exports.CAMPAIGN_EVENT_USER_STATUS = exports.entityType = exports.jsonContentTypeHeaders = exports.ScoutAITrainingMethod = exports.ScoutAIType = exports.AllDeletedStatus = exports.DeletedStatus = exports.FeatureType = exports.commonAppConst = void 0;
4
4
  exports.commonAppConst = {
5
5
  emptyGuid: '00000000-0000-0000-0000-000000000000',
6
6
  sampleStatus: {
@@ -160,4 +160,10 @@ exports.exitErrorMessage = {
160
160
  UnknownTimeout: `operation timed out for an unknown reason`,
161
161
  AuthenticationError: `Authentication error`
162
162
  };
163
+ var SendGridEmailFeedStatus;
164
+ (function (SendGridEmailFeedStatus) {
165
+ SendGridEmailFeedStatus["Delivered"] = "delivered";
166
+ SendGridEmailFeedStatus["NotDelivered"] = "not_delivered";
167
+ SendGridEmailFeedStatus["Processing"] = "processing";
168
+ })(SendGridEmailFeedStatus = exports.SendGridEmailFeedStatus || (exports.SendGridEmailFeedStatus = {}));
163
169
  //# sourceMappingURL=appConst.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"appConst.js","sourceRoot":"","sources":["../../src/utils/appConst.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"appConst.js","sourceRoot":"","sources":["../../src/utils/appConst.ts"],"names":[],"mappings":";;;AAAa,QAAA,cAAc,GAAG;IAC7B,SAAS,EAAE,sCAAsC;IACjD,YAAY,EAAE;QACb,GAAG,EAAE,KAAK;QACV,OAAO,EAAE,SAAS;QAClB,OAAO,EAAE,SAAS;KAClB;IACD,YAAY,EAAE;QACb,IAAI,EAAE,MAAM;QACZ,GAAG,EAAE,KAAK;QACV,IAAI,EAAE,MAAM;QACZ,KAAK,EAAE,OAAO;KACd;IACD,UAAU,EAAE;QACX,GAAG,EAAE,KAAK;QACV,IAAI,EAAE,MAAM;QACZ,GAAG,EAAE,KAAK;QACV,MAAM,EAAE,QAAQ;KAChB;IACD,UAAU,EAAE;QACX,SAAS,EAAE,WAAW;QACtB,aAAa,EAAE,eAAe;QAC9B,MAAM,EAAE,QAAQ;QAChB,OAAO,EAAE,SAAS;QAChB,mBAAmB,EAAE,SAAS;QAChC,eAAe,EAAE,kBAAkB;KACnC;IACD,KAAK,EAAE;QACN,GAAG,EAAE,KAAK;QACV,IAAI,EAAE,MAAM;KACZ;IACD,cAAc,EAAE;QACf,EAAE,EAAE,IAAI;QACR,WAAW,EAAE,aAAa;QAC1B,gBAAgB,EAAE,kBAAkB;KACpC;IACD,KAAK,EAAE;QACN,UAAU,EAAE;YACX,SAAS,EAAE,IAAI;SACf;QACD,UAAU,EAAE,GAAG;QACf,OAAO,EAAE;YACR,aAAa,EAAE,IAAI;SACnB;KACD;IACD,WAAW,EAAE;QACZ,8BAA8B,EAAE,IAAI;KACpC;IACD,UAAU,EAAE;QACX,eAAe,EAAE;YAChB,WAAW,EAAE,kBAAkB;YAC/B;;eAEG;YACH,eAAe,EAAE,IAAI;YACrB,eAAe,EAAE,GAAG;SACpB;QACD,aAAa,EAAE;YACd,WAAW,EAAE,kBAAkB;SAC/B;KACD;IACD,IAAI,EAAE;QACL,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,UAAU;QACpB,eAAe,EAAE;YAChB,0BAA0B;YAC1B,4BAA4B;SAC5B;QACD,IAAI,EAAE;YACL,iCAAiC,EAAE,mCAAmC;YACtE,OAAO,EAAE,SAAS;SAClB;QACD,IAAI,EAAE;YACL,GAAG,EAAE,KAAK;YACV,GAAG,EAAE,KAAK;SACV;KACD;IACD,MAAM,EAAE;QACP,IAAI,EAAE,MAAM;QACZ,YAAY,EAAE,cAAc;QAC5B,IAAI,EAAE,MAAM;QACZ,YAAY,EAAE,cAAc;QAC5B,QAAQ,EAAE,UAAU;QACpB,OAAO,EAAE,SAAS;QAClB,MAAM,EAAE,QAAQ;QAChB,MAAM,EAAE,QAAQ;QAChB,WAAW,EAAE,aAAa;QAC1B,YAAY,EAAE,cAAc;QAC5B,IAAI,EAAE,MAAM;KACZ;IACD,OAAO,EAAE;QACR,IAAI,EAAE,wBAAwB;QAC9B,YAAY,EAAE,wBAAwB;QACtC,IAAI,EAAE,wBAAwB;QAC9B,YAAY,EAAE,wBAAwB;QACtC,QAAQ,EAAE,wBAAwB;QAClC,OAAO,EAAE,wBAAwB;QACjC,MAAM,EAAE,wBAAwB;QAChC,MAAM,EAAE,wBAAwB;QAChC,WAAW,EAAE,wBAAwB;QACrC,YAAY,EAAE,wBAAwB;QACtC,IAAI,EAAE,wBAAwB;KAC9B;CACD,CAAA;AAED,IAAY,WAGX;AAHD,WAAY,WAAW;IACtB,kCAAmB,CAAA;IACnB,gCAAiB,CAAA;AAClB,CAAC,EAHW,WAAW,GAAX,mBAAW,KAAX,mBAAW,QAGtB;AAED,IAAY,aAIX;AAJD,WAAY,aAAa;IACxB,qDAAM,CAAA;IACN,uDAAO,CAAA;IACP,iEAAY,CAAA;AACb,CAAC,EAJW,aAAa,GAAb,qBAAa,KAAb,qBAAa,QAIxB;AACY,QAAA,gBAAgB,GAAa,CAAC,aAAa,CAAC,MAAM,EAAE,aAAa,CAAC,OAAO,EAAE,aAAa,CAAC,YAAY,CAAC,CAAC;AAEpH,IAAY,WAIX;AAJD,WAAY,WAAW;IACtB,oCAAqB,CAAA;IACrB,gCAAiB,CAAA;IACjB,sCAAuB,CAAA;AACxB,CAAC,EAJW,WAAW,GAAX,mBAAW,KAAX,mBAAW,QAItB;AAED,IAAY,qBAEX;AAFD,WAAY,qBAAqB;IAChC,sCAAa,CAAA;AACd,CAAC,EAFW,qBAAqB,GAArB,6BAAqB,KAArB,6BAAqB,QAEhC;AAGD,SAAgB,sBAAsB;IACrC,OAAO;QACN,cAAc,EAAE,kBAAkB;KAClC,CAAC;AACH,CAAC;AAJD,wDAIC;AAED,IAAY,UAKX;AALD,WAAY,UAAU;IACrB,+BAAiB,CAAA;IACjB,iCAAmB,CAAA;IACnB,iCAAmB,CAAA;IACnB,kCAAoB,CAAA;AACrB,CAAC,EALW,UAAU,GAAV,kBAAU,KAAV,kBAAU,QAKrB;AAED,IAAY,0BAMX;AAND,WAAY,0BAA0B;IACrC,qFAAS,CAAA;IACT,mFAAQ,CAAA;IACR,mFAAQ,CAAA;IACR,mFAAQ,CAAA;IACR,yFAAW,CAAA;AACZ,CAAC,EANW,0BAA0B,GAA1B,kCAA0B,KAA1B,kCAA0B,QAMrC;AAED,IAAY,oBAKX;AALD,WAAY,oBAAoB;IAC/B,qEAAO,CAAA;IACP,yEAAS,CAAA;IACT,uEAAQ,CAAA;IACR,uEAAQ,CAAA;AACT,CAAC,EALW,oBAAoB,GAApB,4BAAoB,KAApB,4BAAoB,QAK/B;AAEY,QAAA,gBAAgB,GAA0B;IACtD,cAAc,EAAE,kFAAkF;IAClG,cAAc,EAAE,2CAA2C;IAC3D,mBAAmB,EAAE,sBAAsB;CAC3C,CAAA;AAED,IAAY,uBAIX;AAJD,WAAY,uBAAuB;IAClC,kDAAuB,CAAA;IACvB,yDAA8B,CAAA;IAC9B,oDAAyB,CAAA;AAC1B,CAAC,EAJW,uBAAuB,GAAvB,+BAAuB,KAAvB,+BAAuB,QAIlC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skyeye-svc-common-utils",
3
- "version": "1.0.80",
3
+ "version": "1.0.82",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -29,6 +29,8 @@
29
29
  "@azure/core-rest-pipeline": "1.12.2",
30
30
  "@azure/core-lro": "2.6.0",
31
31
  "@azure/logger": "1.0.4",
32
+ "@sendgrid/client": "^8.1.3",
33
+ "@sendgrid/helpers": "^8.0.0",
32
34
  "@sendgrid/mail": "^7.7.0",
33
35
  "@types/chai": "^4.2.11",
34
36
  "@types/express": "4.17.14",
package/src/index.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import SendGridClient, { ISgMessage, ISgCategoryStatistics, SgCategoryStatisticsItem, SgCategoryStatisticsMetricsItem } from './lib/sendGridClient';
2
+
1
3
  export * from './utils/appConfig';
2
4
  export * from './utils/appConst';
3
5
  export * from './utils/commonUtils';
@@ -23,7 +25,7 @@ export * from './utils/monitoring/apm';
23
25
  export * from './models/baseControllerParameter';
24
26
  export * from './models';
25
27
  export * from './lib/redisClient';
26
- export * from './lib/sendGridClient';
27
28
  export * from './interfaces/grpcServiceResponse';
28
29
  export * from './interfaces/grpcListRequest';
29
30
  export * from './utils/commonUtils/appConfigKeyRetriever';
31
+ export { SendGridClient, ISgMessage, ISgCategoryStatistics, SgCategoryStatisticsItem, SgCategoryStatisticsMetricsItem };
@@ -1,33 +1,72 @@
1
- import { MailService, MailDataRequired } from '@sendgrid/mail';
1
+ import { MailService, MailDataRequired, ClientResponse } from '@sendgrid/mail';
2
+ import { Client as OfficialClient } from '@sendgrid/client';
3
+ import helpers from '@sendgrid/helpers';
2
4
  import { logger } from './../utils/logger/logger';
3
- import { AppConfigKeyRetriever } from './../utils/commonUtils/appConfigKeyRetriever';
4
- import { commonAppConfig } from './../utils/appConfig';
5
+ import { isEmpty, isNil } from 'lodash';
6
+ import { SendGridEmailFeedStatus, commonAppConst } from '../utils/appConst';
7
+
8
+ export interface ISgMessage {
9
+ from_email: string;
10
+ to_email: string;
11
+ msg_id: string;
12
+ subject: string;
13
+ status: string; // Possible values: processed, delivered, not_delivered
14
+ opens_count: number;
15
+ clicks_count: number;
16
+ last_event_time: string; //ISO 8601 format
17
+ }
18
+
19
+ export interface ISgCategoryStatistics {
20
+ date: string;
21
+ stats: SgCategoryStatisticsItem[]
22
+ }
23
+
24
+ export type SgCategoryStatisticsItem = {
25
+ type: string;
26
+ name: string;
27
+ metrics: SgCategoryStatisticsMetricsItem;
28
+ }
29
+
30
+ export type SgCategoryStatisticsMetricsItem = {
31
+ blocks: number;
32
+ bounce_drops: number;
33
+ bounces: number;
34
+ clicks: number;
35
+ deferred: number;
36
+ delivered: number;
37
+ invalid_emails: number;
38
+ opens: number;
39
+ processed: number;
40
+ requests: number;
41
+ spam_report_drops: number;
42
+ spam_reports: number;
43
+ unique_clicks: number;
44
+ unique_opens: number;
45
+ unsubscribe_drops: number;
46
+ unsubscribes: number;
47
+ }
5
48
 
6
49
  /**
7
50
  * A SendGrid client class
8
51
  */
9
- class SendGridClient {
52
+ export default class SendGridClient {
10
53
 
11
54
  private mailService: MailService;
55
+ private officialClient: OfficialClient;
56
+ private static BASE_URL: string = 'https://api.sendgrid.com';
12
57
 
13
58
  /**
14
59
  * @constructor
15
60
  * @param {string} [apiKey] - SendGrid API key (optional)
16
61
  */
17
- constructor() {
62
+ constructor(sendGridClientSecret: string) {
18
63
  this.mailService = new MailService();
19
- this.initialize();
20
- }
21
-
22
- /**
23
- * Initializes the SendGrid client with the API key retrieved from Azure Key Vault.
24
- */
25
- private async initialize(): Promise<void> {
26
- const sendGridClientSecret = await AppConfigKeyRetriever.getSendgridClientSecret();
64
+ this.officialClient = new OfficialClient();
65
+ // set API key
27
66
  this.mailService.setApiKey(sendGridClientSecret);
67
+ this.officialClient.setApiKey(sendGridClientSecret);
28
68
  }
29
69
 
30
-
31
70
  /**
32
71
  * It sends an email.
33
72
  * @param {string} from - The email address of the sender.
@@ -36,7 +75,7 @@ class SendGridClient {
36
75
  * @param {string} htmlBodyText - The HTML body of the email.
37
76
  * @param {any} [options] - Extra settings for the email
38
77
  */
39
- async send(from: string, to: string[], subject: string, htmlBodyText: string, options?: Partial<MailDataRequired>): Promise<void> | never {
78
+ public async sendEmail(from: string, to: string[], subject: string, htmlBodyText: string, options?: Partial<MailDataRequired>): Promise<ClientResponse> | never {
40
79
  const msg: MailDataRequired = {
41
80
  from,
42
81
  to,
@@ -46,12 +85,150 @@ class SendGridClient {
46
85
  };
47
86
 
48
87
  try {
49
- await this.mailService.send(msg);
88
+ const response = await this.mailService.send(msg);
89
+ return response[0];
50
90
  } catch (err) {
51
91
  logger.error(`SendGridClient/send with error, ${err}`);
52
92
  throw err;
53
93
  }
54
94
  }
55
- }
56
95
 
57
- export const sendGridClient = commonAppConfig.SendgridClientSecretKey ? new SendGridClient() : null;
96
+ /*
97
+ SendGrid v3 API has a pagination limitation on GET /messages
98
+ it only accepts limit as query param, not offset
99
+ https://www.twilio.com/docs/sendgrid/api-reference/how-to-use-the-sendgrid-v3-api/requests#pagination
100
+ */
101
+ public async getEmailActivity(
102
+ lastEventStartDate?: Date,
103
+ lastEventEndDate?: Date,
104
+ category?: string,
105
+ status?: SendGridEmailFeedStatus
106
+ ): Promise<ISgMessage[]> {
107
+
108
+ const method = 'GET';
109
+ const url = '/v3/messages';
110
+ const baseUrl = SendGridClient.BASE_URL;
111
+ const request = this.officialClient.createRequest({
112
+ baseUrl,
113
+ url,
114
+ method
115
+ });
116
+
117
+ const batchSize = 1000;
118
+ // store all unique records
119
+ const map: Map<string, ISgMessage> = new Map ();
120
+ // as the records are returned in DESC order of lastEventDate, keep update nextLastEventEndDate within the loop
121
+ let nextLastEventEndDate = lastEventEndDate;
122
+ let count = 0;
123
+ do {
124
+ request.qs = this.getQueryParams(batchSize, lastEventStartDate, nextLastEventEndDate, category, status);
125
+ logger.info(`Sending ${method} request to ${baseUrl + url} with body: ${JSON.stringify(request)}`);
126
+ const [ response, body ]: [helpers.classes.Response, any] = await this.officialClient.request(request);
127
+ const statusCode = response.statusCode;
128
+ if (statusCode == 200) {
129
+ const messages: ISgMessage[] = body.messages;
130
+ count = messages.length;
131
+ if (count > 0) {
132
+ for (const msg of messages) {
133
+ if (!map.has(msg.msg_id)) {
134
+ map.set(msg.msg_id, msg)
135
+ }
136
+ }
137
+ const lastItem = messages[messages.length - 1];
138
+ nextLastEventEndDate = new Date(lastItem.last_event_time);
139
+ }
140
+ }
141
+ else {
142
+ break;
143
+ }
144
+ }
145
+ while (count >= batchSize);
146
+
147
+ return Array.from(map.values());
148
+ }
149
+
150
+ /*
151
+ https://www.twilio.com/docs/sendgrid/for-developers/sending-email/getting-started-email-activity-api
152
+ can add more query params
153
+ */
154
+ public getQueryParams(
155
+ batchSize?: number,
156
+ lastEventStartDate?: Date,
157
+ lastEventEndDate?: Date,
158
+ category?: string,
159
+ status?: SendGridEmailFeedStatus
160
+ ) {
161
+ let query = '';
162
+ if (!(isNil(lastEventStartDate) && isNil(lastEventEndDate))) {
163
+ query = `(last_event_time BETWEEN TIMESTAMP "${lastEventStartDate.toISOString()}" AND TIMESTAMP "${lastEventEndDate.toISOString()}")`;
164
+ }
165
+ if (!isNil(category)) {
166
+ query += ` AND (Contains(categories,"${category}"))`;
167
+ }
168
+ if (!isNil(status)) {
169
+ query += ` AND (status IN ("${status}"))`;
170
+ }
171
+
172
+ return query.length > 0 ? {
173
+ 'limit': isNil(batchSize) ? 1000 : batchSize,
174
+ 'query': query
175
+ } : {
176
+ 'limit': isNil(batchSize) ? 1000 : batchSize
177
+ }
178
+ }
179
+
180
+ /**
181
+ * The function getCategoryStats retrieves category statistics with optional parameters such as
182
+ * limit, skip, startDate, category, aggregatedBy, and endDate.
183
+ * @param {string} startDate - The starting date of the statistics to retrieve. Must follow format YYYY-MM-DD.
184
+ * @param {string} category - The `category` parameter is a parameter that allows you
185
+ * to specify a category for which you want to retrieve statistics. It is a string type parameter.
186
+ * If provided, the function will return statistics specific to the specified category. If not
187
+ * provided, the function will return statistics for all categories.
188
+ * @param {string} aggregatedBy - How to group the statistics. Must be either "day", "week", or "month".
189
+ * @param {number} [limit=1000] - The number of results to return.
190
+ * @param {number} [skip=0] - The point in the list to begin retrieving results.
191
+ * @param {string} [endDate] - The end date of the statistics to retrieve. Defaults to today. Must follow format YYYY-MM-DD.
192
+ *
193
+ * https://www.twilio.com/docs/sendgrid/api-reference/stats/retrieve-global-email-statistics#operation-details
194
+ */
195
+ public async getCategoryStats(
196
+ startDate: string,
197
+ category: string,
198
+ aggregatedBy: "day" | "week" | "month",
199
+ limit: number = 1000,
200
+ offset: number = 0,
201
+ endDate?: string
202
+ ): Promise<ISgCategoryStatistics[]> {
203
+ const method = 'GET';
204
+ const url = '/v3/categories/stats';
205
+ const baseUrl = SendGridClient.BASE_URL;
206
+ const request = this.officialClient.createRequest({
207
+ baseUrl,
208
+ url,
209
+ method
210
+ });
211
+
212
+ const queryParams: any = {
213
+ 'limit': limit,
214
+ 'offset': offset,
215
+ 'start_date': startDate,
216
+ 'categories': category,
217
+ 'aggregated_by': aggregatedBy
218
+ };
219
+ if (!isNil(endDate)) {
220
+ queryParams.end_date = endDate;
221
+ }
222
+ request.qs = queryParams;
223
+
224
+ logger.info(`Sending ${method} request to ${baseUrl + url} with body: ${JSON.stringify(request)}`);
225
+ const [ response, body ]: [helpers.classes.Response, any] = await this.officialClient.request(request);
226
+ const statusCode = response.statusCode;
227
+ if (statusCode == 200) {
228
+ return response.body as ISgCategoryStatistics[];
229
+ }
230
+ else {
231
+ return [];
232
+ }
233
+ }
234
+ }
@@ -159,3 +159,9 @@ export const exitErrorMessage:Record<string, string> = {
159
159
  UnknownTimeout: `operation timed out for an unknown reason`,
160
160
  AuthenticationError: `Authentication error`
161
161
  }
162
+
163
+ export enum SendGridEmailFeedStatus {
164
+ Delivered = "delivered",
165
+ NotDelivered = "not_delivered",
166
+ Processing = "processing"
167
+ }