@trycourier/courier 3.12.0 → 3.14.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/CHANGELOG.md CHANGED
@@ -5,6 +5,14 @@ This project adheres to [Semantic Versioning](http://semver.org/).
5
5
 
6
6
  ## [Unreleased][unreleased]
7
7
 
8
+ ## [3.14.0]
9
+
10
+ - adds support for token management
11
+
12
+ ## [3.13.1] - 2022-06-03
13
+
14
+ - adds provider and channel timeout
15
+
8
16
  ## [3.12.0] - 2022-03-31
9
17
 
10
18
  - adds support for message trace id (`message.metadata.trace_id`)
@@ -13,11 +21,12 @@ This project adheres to [Semantic Versioning](http://semver.org/).
13
21
 
14
22
  - adds support for `audiences`
15
23
 
16
-
17
24
  ## [3.10.1] - 2022-03-20
25
+
18
26
  - adds support for messages timeout (`message.timeout`)
19
27
 
20
28
  ## [3.10.0] - 2020-03-24
29
+
21
30
  - adds support for messages brand_id (`message.brand_id`)
22
31
 
23
32
  ## [3.9.0] - 2022-03-17
package/README.md CHANGED
@@ -240,6 +240,70 @@ async function run() {
240
240
  });
241
241
  console.log(requestId);
242
242
 
243
+ // Example: send message with utm metadata
244
+ const { requestId } = await courier.send({
245
+ message: {
246
+ template: "<TEMPLATE_OR_EVENT_ID>",
247
+ to: {...},
248
+ routing: {
249
+ method: "single",
250
+ channels: ["email"],
251
+ },
252
+ channels: {
253
+ email: {
254
+ routing_method: "all",
255
+ providers: ["sendgrid", "sns"],
256
+ metadata: {
257
+ utm: {
258
+ medium: "f",
259
+ campaign: "g",
260
+ },
261
+ },
262
+ },
263
+ },
264
+ providers: {
265
+ sns: {
266
+ metadata: {
267
+ utm: {
268
+ medium: "h",
269
+ },
270
+ },
271
+ },
272
+ }, // optional
273
+ metadata: {
274
+ utm: {
275
+ source: "a",
276
+ medium: "b",
277
+ campaign: "c",
278
+ },
279
+ },
280
+ timeout: {
281
+ message: 300000,
282
+ channel: {
283
+ email: 1000 // 1 second
284
+ }
285
+ }
286
+ },
287
+ });
288
+
289
+ /**
290
+ * If the template or content contains any action blocks, the hyperlinks will be augmented with utm compliant query parameters.
291
+ *
292
+ * The resulting link of an action block sent through sendgrid would be:
293
+ * www.example.com?utm_source=a&utm_medium=f&utm_campaign=g
294
+ *
295
+ * While the resulting link of an action block sent through sns would be:
296
+ * www.example.com?utm_source=a&utm_medium=h&utm_campaign=g
297
+ *
298
+ * Notice that provider metadata supersedes channel metadata and channel metadata supersedes message metadata
299
+ *
300
+ **/
301
+
302
+ /**
303
+ * If the message includes a timeout property we will start timing out messages after the first attempt.
304
+ * We are able to timeout complete channels or specific providers.
305
+ **/
306
+
243
307
  // Example: get a message status
244
308
  const messageStatus = await courier.getMessage(requestId);
245
309
  console.log(messageStatus);
@@ -651,9 +715,9 @@ Audiences APIs are used to create, get, update, and delete audiences. A Courier
651
715
  const { audienceId } = await courier.audiences.put({
652
716
  id: "<AUDIENCE_ID>",
653
717
  filter: {
654
- "operator": "EQ",
655
- "path": "title",
656
- "value": "Software Engineer",
718
+ operator: "EQ",
719
+ path: "title",
720
+ value: "Software Engineer",
657
721
  },
658
722
  });
659
723
 
@@ -104,5 +104,5 @@ exports.audiences = function (options) { return ({
104
104
  get: getAudience(options),
105
105
  listAudiences: listAudiences(options),
106
106
  listMembers: listMembers(options),
107
- put: putAudience(options),
107
+ put: putAudience(options)
108
108
  }); };
@@ -1,3 +1,4 @@
1
+ import { Message } from "../send/types";
1
2
  export declare type AutomationStepAction = "cancel" | "delay" | "send" | "send-list" | "update-profile";
2
3
  export declare type MergeAlgorithm = "replace" | "none" | "overwrite" | "soft-merge";
3
4
  export interface IAutomationStep {
@@ -23,6 +24,10 @@ export interface IAutomationSendStep extends IAutomationStep {
23
24
  recipient?: string;
24
25
  template?: string;
25
26
  }
27
+ export interface IAutomationV2SendStep extends IAutomationStep {
28
+ action: "send";
29
+ message: Message;
30
+ }
26
31
  export interface IAutomationSendListStep extends IAutomationStep {
27
32
  action: "send-list";
28
33
  brand?: string;
@@ -37,7 +42,7 @@ export interface IAutomationUpdateProfileStep extends IAutomationStep {
37
42
  profile: object;
38
43
  merge: MergeAlgorithm;
39
44
  }
40
- export declare type AutomationStep = IAutomationCancelStep | IAutomationDelayStep | IAutomationSendStep | IAutomationSendListStep | IAutomationUpdateProfileStep;
45
+ export declare type AutomationStep = IAutomationCancelStep | IAutomationDelayStep | IAutomationSendStep | IAutomationV2SendStep | IAutomationSendListStep | IAutomationUpdateProfileStep;
41
46
  export interface IAutomation {
42
47
  cancelation_token?: string;
43
48
  steps: AutomationStep[];
package/lib/client.js CHANGED
@@ -46,6 +46,7 @@ var notifications_1 = require("./notifications");
46
46
  var preferences_1 = require("./preferences");
47
47
  var profile_1 = require("./profile");
48
48
  var send_1 = require("./send");
49
+ var token_management_1 = require("./token-management");
49
50
  var getMessage = function (options) {
50
51
  return function (messageId) { return __awaiter(void 0, void 0, void 0, function () {
51
52
  var res;
@@ -99,8 +100,8 @@ var getMessages = function (options) {
99
100
  notification: params === null || params === void 0 ? void 0 : params.notificationId,
100
101
  recipient: params === null || params === void 0 ? void 0 : params.recipientId,
101
102
  status: params === null || params === void 0 ? void 0 : params.status,
102
- tags: params === null || params === void 0 ? void 0 : params.tags,
103
- },
103
+ tags: params === null || params === void 0 ? void 0 : params.tags
104
+ }
104
105
  })];
105
106
  case 1:
106
107
  res = _a.sent();
@@ -134,5 +135,6 @@ exports.client = function (options) {
134
135
  replaceBrand: brands_1.replaceBrand(options),
135
136
  replaceProfile: profile_1.replaceProfile(options),
136
137
  send: send_1.send(options),
138
+ tokenManagement: token_management_1.tokenManagement(options)
137
139
  };
138
140
  };
@@ -241,8 +241,12 @@ export interface ElementalContentSugar {
241
241
  title?: string;
242
242
  }
243
243
  export interface Timeout {
244
- provider?: number;
245
- channel?: number;
244
+ provider?: {
245
+ [provider: string]: number;
246
+ };
247
+ channel?: {
248
+ [channel: string]: number;
249
+ };
246
250
  message?: number;
247
251
  escalation?: number;
248
252
  criteria?: "no-escalation" | "delivered" | "viewed" | "engaged";
@@ -311,6 +315,9 @@ export interface MessageChannels {
311
315
  channel?: number;
312
316
  };
313
317
  override?: MessageChannelEmailOverride | MessageChannelPushOverride;
318
+ metadata?: {
319
+ utm?: UTM;
320
+ };
314
321
  };
315
322
  }
316
323
  export interface Routing {
@@ -329,17 +336,21 @@ export interface RoutingStrategyProvider<T = Record<string, any>> {
329
336
  name: string;
330
337
  config?: T;
331
338
  if?: string;
339
+ metadata?: {
340
+ utm?: UTM;
341
+ };
342
+ }
343
+ export interface UTM {
344
+ source?: string;
345
+ medium?: string;
346
+ campaign?: string;
347
+ term?: string;
348
+ content?: string;
332
349
  }
333
350
  export interface MessageMetadata {
334
351
  event?: string;
335
352
  tags?: string[];
336
- utm?: {
337
- source?: string;
338
- medium?: string;
339
- campaign?: string;
340
- term?: string;
341
- content?: string;
342
- };
353
+ utm?: UTM;
343
354
  trace_id?: string;
344
355
  }
345
356
  export interface ContentMessage extends BaseMessage {
@@ -0,0 +1,12 @@
1
+ import { ICourierClientConfiguration } from "../types";
2
+ import { IDeleteUserTokenOpts, IGetUserTokenOpts, IGetUserTokenResponse, IGetUserTokensOpts, IPatchUserTokenOpts, IPutUserTokenOpts, IPutUserTokensOpts } from "./types";
3
+ export declare const tokenManagement: (options: ICourierClientConfiguration) => {
4
+ deleteUserToken: (opts: IDeleteUserTokenOpts) => Promise<void>;
5
+ getUserToken: (opts: IGetUserTokenOpts) => Promise<IGetUserTokenResponse>;
6
+ getUserTokens: (opts: IGetUserTokensOpts) => Promise<{
7
+ tokens: IGetUserTokenResponse[];
8
+ }>;
9
+ patchUserToken: (opts: IPatchUserTokenOpts) => Promise<void>;
10
+ putUserToken: (opts: IPutUserTokenOpts) => Promise<void>;
11
+ putUserTokens: (opts: IPutUserTokensOpts) => Promise<void>;
12
+ };
@@ -0,0 +1,127 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __generator = (this && this.__generator) || function (thisArg, body) {
12
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
13
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
+ function verb(n) { return function (v) { return step([n, v]); }; }
15
+ function step(op) {
16
+ if (f) throw new TypeError("Generator is already executing.");
17
+ while (_) try {
18
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
19
+ if (y = 0, t) op = [op[0] & 2, t.value];
20
+ switch (op[0]) {
21
+ case 0: case 1: t = op; break;
22
+ case 4: _.label++; return { value: op[1], done: false };
23
+ case 5: _.label++; y = op[1]; op = [0]; continue;
24
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
+ default:
26
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
+ if (t[2]) _.ops.pop();
31
+ _.trys.pop(); continue;
32
+ }
33
+ op = body.call(thisArg, _);
34
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
+ }
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.tokenManagement = void 0;
40
+ /** Associate a group of tokens with the supplied :user_id. Will overwrite any existing tokens associated with that user. */
41
+ var putUserTokens = function (options) {
42
+ return function (opts) { return __awaiter(void 0, void 0, void 0, function () {
43
+ return __generator(this, function (_a) {
44
+ switch (_a.label) {
45
+ case 0: return [4 /*yield*/, options.httpClient.put("/users/" + opts.user_id + "/tokens", {
46
+ tokens: opts.tokens
47
+ })];
48
+ case 1:
49
+ _a.sent();
50
+ return [2 /*return*/];
51
+ }
52
+ });
53
+ }); };
54
+ };
55
+ /** Associate a token with the supplied :user_id. If token exists it's value will be replaced with the passed body, otherwise the token will be created. */
56
+ var putUserToken = function (options) {
57
+ return function (opts) { return __awaiter(void 0, void 0, void 0, function () {
58
+ return __generator(this, function (_a) {
59
+ switch (_a.label) {
60
+ case 0: return [4 /*yield*/, options.httpClient.put("/users/" + opts.user_id + "/tokens/" + opts.token.token, opts.token)];
61
+ case 1:
62
+ _a.sent();
63
+ return [2 /*return*/];
64
+ }
65
+ });
66
+ }); };
67
+ };
68
+ var patchUserToken = function (options) {
69
+ return function (opts) { return __awaiter(void 0, void 0, void 0, function () {
70
+ return __generator(this, function (_a) {
71
+ switch (_a.label) {
72
+ case 0: return [4 /*yield*/, options.httpClient.patch("/users/" + opts.user_id + "/tokens/" + opts.token, { patch: opts.patch })];
73
+ case 1:
74
+ _a.sent();
75
+ return [2 /*return*/];
76
+ }
77
+ });
78
+ }); };
79
+ };
80
+ var getUserToken = function (options) {
81
+ return function (opts) { return __awaiter(void 0, void 0, void 0, function () {
82
+ var res;
83
+ return __generator(this, function (_a) {
84
+ switch (_a.label) {
85
+ case 0: return [4 /*yield*/, options.httpClient.get("/users/" + opts.user_id + "/tokens/" + opts.token)];
86
+ case 1:
87
+ res = _a.sent();
88
+ return [2 /*return*/, res.data];
89
+ }
90
+ });
91
+ }); };
92
+ };
93
+ var getUserTokens = function (options) {
94
+ return function (opts) { return __awaiter(void 0, void 0, void 0, function () {
95
+ var res;
96
+ return __generator(this, function (_a) {
97
+ switch (_a.label) {
98
+ case 0: return [4 /*yield*/, options.httpClient.get("/users/" + opts.user_id + "/tokens")];
99
+ case 1:
100
+ res = _a.sent();
101
+ return [2 /*return*/, res.data];
102
+ }
103
+ });
104
+ }); };
105
+ };
106
+ var deleteUserToken = function (options) {
107
+ return function (opts) { return __awaiter(void 0, void 0, void 0, function () {
108
+ return __generator(this, function (_a) {
109
+ switch (_a.label) {
110
+ case 0: return [4 /*yield*/, options.httpClient.delete("/users/" + opts.user_id + "/tokens/" + opts.token)];
111
+ case 1:
112
+ _a.sent();
113
+ return [2 /*return*/];
114
+ }
115
+ });
116
+ }); };
117
+ };
118
+ exports.tokenManagement = function (options) {
119
+ return {
120
+ deleteUserToken: deleteUserToken(options),
121
+ getUserToken: getUserToken(options),
122
+ getUserTokens: getUserTokens(options),
123
+ patchUserToken: patchUserToken(options),
124
+ putUserToken: putUserToken(options),
125
+ putUserTokens: putUserTokens(options)
126
+ };
127
+ };
@@ -0,0 +1,56 @@
1
+ export interface IUserToken {
2
+ token: string;
3
+ provider_key: "firebase-fcm" | "apn" | "expo" | "onesignal";
4
+ /** ISO 8601 Date. Set to false to disable expiration */
5
+ expiry_date?: string | false;
6
+ /** Additional properties to be passed to provider or to be generically associated with the token */
7
+ properties?: {
8
+ [key: string]: any;
9
+ };
10
+ device?: {
11
+ app_id?: string;
12
+ ad_id?: string;
13
+ device_id?: string;
14
+ platform?: string;
15
+ manufacturer?: string;
16
+ model?: string;
17
+ };
18
+ tracking?: {
19
+ os_version?: string;
20
+ ip?: string;
21
+ lat?: string;
22
+ long?: string;
23
+ };
24
+ }
25
+ export interface IGetUserTokenResponse extends IUserToken {
26
+ status: "active" | "unknown" | "failed" | "revoked";
27
+ status_reason?: string;
28
+ }
29
+ export interface IPutUserTokensOpts {
30
+ user_id: string;
31
+ tokens: IUserToken[];
32
+ }
33
+ export interface IPutUserTokenOpts {
34
+ user_id: string;
35
+ token: IUserToken;
36
+ }
37
+ export interface IPatchUserTokenOpts {
38
+ user_id: string;
39
+ token: string;
40
+ patch: Array<{
41
+ op: "replace" | "add" | "remove" | "copy" | "move" | "test";
42
+ path: string;
43
+ value?: string;
44
+ }>;
45
+ }
46
+ export interface IGetUserTokenOpts {
47
+ user_id: string;
48
+ token: string;
49
+ }
50
+ export interface IGetUserTokensOpts {
51
+ user_id: string;
52
+ }
53
+ export interface IDeleteUserTokenOpts {
54
+ user_id: string;
55
+ token: string;
56
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/lib/types.d.ts CHANGED
@@ -6,6 +6,7 @@ import { ICourierClientLists, ICourierList, ICourierRecipientSubscriptionsRespon
6
6
  import { ICourierClientNotifications } from "./notifications/types";
7
7
  import { ICourierClientPreferences, IRecipientPreferences } from "./preferences/types";
8
8
  import { Message } from "./send/types";
9
+ import { tokenManagement } from "./token-management";
9
10
  export declare type HttpMethodClient = <T>(url: string, body?: object, config?: AxiosRequestConfig) => Promise<{
10
11
  data: T;
11
12
  }>;
@@ -311,5 +312,6 @@ export interface ICourierClient {
311
312
  replaceBrand: (params: ICourierBrandPutParameters) => Promise<ICourierBrand>;
312
313
  replaceProfile: (params: ICourierProfilePutParameters) => Promise<ICourierProfilePutResponse>;
313
314
  send: <T extends ICourierSendParameters | ICourierSendMessageParameters>(params: T, config?: ICourierSendConfig) => Promise<SendResponse<T>>;
315
+ tokenManagement: ReturnType<typeof tokenManagement>;
314
316
  }
315
317
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trycourier/courier",
3
- "version": "3.12.0",
3
+ "version": "3.14.1",
4
4
  "description": "A node.js module for communicating with the Courier REST API.",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",