@trycourier/courier-js 1.2.0 → 1.4.2

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/README.md CHANGED
@@ -1,10 +1,73 @@
1
1
  [![Courier: Your Complete Communication Stack](https://www.courier.com/_next/image/?url=https%3A%2F%2Fimages.ctfassets.net%2Fz7iqk1q8njt4%2F1PZo9WNTdmoDoYH3yulXa0%2Fb10830f7bfb09af5e644a39ac3d20c41%2FCourierJS_header_alt2.png&w=1920&q=75)](https://courier.com)
2
2
 
3
- ## Requirements
3
+ # Overview
4
+ SDK used by client applications to interface with the Courier API.
5
+  
6
+ <table>
7
+ <thead>
8
+ <tr>
9
+ <th width="880px" align="left">Requirements</th>
10
+ <th width="120px" align="center"></th>
11
+ </tr>
12
+ </thead>
13
+ <tbody>
14
+ <tr width="600px">
15
+ <td align="left">Courier Account</td>
16
+ <td align="center">
17
+ <a href="https://app.courier.com/signup">
18
+ <code>Sign Up</code>
19
+ </a>
20
+ </td>
21
+ </tr>
22
+ <tr width="600px">
23
+ <td align="left">Client API Key</td>
24
+ <td align="center">
25
+ <a href="https://app.courier.com/settings/api-keys">
26
+ <code>Get key</code>
27
+ </a>
28
+ </td>
29
+ </tr>
30
+ </tbody>
31
+ </table>
32
+ &emsp;
4
33
 
5
- Sign up to [Courier](https://app.courier.com/signup) if you do not have an account with us and get your clientKey from [here](https://app.courier.com/settings/api-keys)
34
+ # Supported Interfaces
35
+ <table>
36
+ <thead>
37
+ <tr>
38
+ <th width="250px" align="left">Feature</th>
39
+ <th width="725px" align="left">Description</th>
40
+ </tr>
41
+ </thead>
42
+ <tbody>
43
+ <tr width="600px">
44
+ <td align="left">
45
+ <code>Identify</code>
46
+ </td>
47
+ <td align="left">
48
+ Event that triggers a user <a href="https://www.courier.com/docs/reference/profiles/create/"><code>Create</code></a> or <a href="https://www.courier.com/docs/reference/profiles/patch/"><code>Update</code></a> within Courier Profiles.
49
+ </td>
50
+ </tr>
51
+ <tr width="600px">
52
+ <td align="left">
53
+ <code>Track</code>
54
+ </td>
55
+ <td align="left">
56
+ Event ingested by Courier can be used to<a href="https://www.courier.com/docs/automations/designer/"> trigger an automation</a> or supply inline payloads within an <a href="https://app.courier.com/automations">existing</a> automation workflow.
57
+ </td>
58
+ </tr>
59
+ <tr width="600px">
60
+ <td align="left">
61
+ <code>GeneratePreferencesUrl</code>
62
+ </td>
63
+ <td align="left">
64
+ Generates URL that can be used to link users to <a href="https://www.courier.com/docs/courier-preferences/preference-center/introduction/">Preferences Center</a> to manage their notification preferences.
65
+ </td>
66
+ </tr>
67
+ </tbody>
68
+ </table>
6
69
 
7
- ## Installation
70
+ # Installation
8
71
 
9
72
  ```sh
10
73
  # npm
@@ -14,32 +77,47 @@ yarn add @trycourier/courier-js
14
77
  # pnpm
15
78
  pnpm add @trycourier/courier-js
16
79
  ```
80
+ &emsp;
81
+ # Usage
17
82
 
18
- ## Usage
19
-
83
+ ## Initializing Client
20
84
  ```ts
21
85
  import courier from "@trycourier/courier-js";
22
86
 
23
87
  courier.init({
24
88
  clientKey: "<REPLACE_WITH_YOUR_CLIENT_KEY>",
25
- debug: true,
89
+ debug: true, // debug enables client side logs for error catching
26
90
  });
27
-
28
- /*
29
- Upon initialization, you can use the SDK. All the methods are async and return a Promise `user | identify` means that you are identifying a user with a unique id in Courier and optionally passing in some user attributes like email, phone, etc. so that you can reach out to your users on right channels of their choice.
30
- */
31
- courier.identify("<your_user_id>", {
32
- email: "suhas+from+ui@courier.com",
91
+ ```
92
+ ## Identify
93
+ ```ts
94
+ await courierSDK.identify("purbleUserId", {
95
+ email: "customer@purbleplace.com",
96
+ favoriteColor: "purple",
33
97
  });
34
98
  ```
35
-
36
- ## Send User to Preference Center
37
-
38
- This method generates a URL that you can use to send your users to the Courier Preference Center to let them manage their notification preferences. You can use this URL in your application to send your users to the Preference Center.
39
-
99
+ ## Track
100
+ ### Basic
40
101
  ```ts
41
- const prefCenterLink = courier.generatePreferencesUrl("<your_user_id>", {
102
+ await courierSDK.track("user-signup");
103
+ ```
104
+ ### With data payload
105
+ ```ts
106
+ await courierSDK.track("bake-cake", {
107
+ cakeFlavor: "carrot",
108
+ frosting: "cream cheese"
109
+ });
110
+ ```
111
+ ## GeneratePreferencesUrl
112
+ ```ts
113
+ const prefCenterLink = courier.generatePreferencesUrl("<user-id>", {
42
114
  // optional
43
- brandId: "<your_brand_id>",
115
+ brandId: "<brand-id>",
44
116
  });
45
117
  ```
118
+ # **Share feedback with Courier**
119
+
120
+ We are building the best SDKs for handling notifications! Have an idea or feedback about our SDKs? Here are some links to contact us:
121
+
122
+ - [Courier Feedback](https://feedback.courier.com/)
123
+ - [Courier JS Issues](https://github.com/trycourier/courier-js/issues)
package/dist/index.d.ts CHANGED
@@ -8,6 +8,7 @@ type CourierOptions = {
8
8
  };
9
9
  type PreferenceLinkOptions = {
10
10
  brandId?: string;
11
+ tenantId?: string;
11
12
  };
12
13
  declare class Courier {
13
14
  private authorization?;
@@ -18,10 +19,11 @@ declare class Courier {
18
19
  private userSignature?;
19
20
  constructor({ authorization, baseUrl, clientKey, debug, userId, userSignature, }: CourierOptions);
20
21
  private getHeaders;
21
- post<T>(path: string, body: T): Promise<void>;
22
- put<T>(path: string, body?: T): Promise<void>;
23
- delete(path: string): Promise<void>;
22
+ post<T>(path: string, body: T, useClientPath?: boolean): Promise<void>;
23
+ put<T>(path: string, body?: T, useClientPath?: boolean): Promise<void>;
24
+ delete(path: string, useClientPath?: boolean): Promise<void>;
24
25
  generatePreferencesUrl(userId: string, options?: PreferenceLinkOptions): string;
26
+ private getPathURL;
25
27
  }
26
28
 
27
29
  declare const client: {
@@ -30,6 +32,7 @@ declare const client: {
30
32
  readonly instance: Courier;
31
33
  identify(userId: string, payload: Record<string, unknown>): Promise<void>;
32
34
  subscribe(userId: string, listId: string): Promise<void>;
35
+ track(event: string, properties?: Record<string, unknown>): Promise<void>;
33
36
  unsubscribe(userId: string, listId: string): Promise<void>;
34
37
  generatePreferencesUrl(userId: string, options?: PreferenceLinkOptions): string;
35
38
  };
package/dist/index.js CHANGED
@@ -25,7 +25,7 @@ __export(src_exports, {
25
25
  module.exports = __toCommonJS(src_exports);
26
26
 
27
27
  // package.json
28
- var version = "1.2.0";
28
+ var version = "1.4.2";
29
29
 
30
30
  // src/helpers/decode.ts
31
31
  function decode(clientKey) {
@@ -67,7 +67,7 @@ var Courier = class {
67
67
  throw new Error("Courier client key is required");
68
68
  }
69
69
  this.authorization = authorization;
70
- this.baseUrl = `${baseUrl != null ? baseUrl : "https://api.courier.com"}/client/`;
70
+ this.baseUrl = `${baseUrl != null ? baseUrl : "https://api.courier.com"}`;
71
71
  this.clientKey = clientKey;
72
72
  this.debug = debug;
73
73
  this.userId = userId;
@@ -86,9 +86,9 @@ var Courier = class {
86
86
  ...this.clientKey && { "x-courier-client-key": this.clientKey }
87
87
  });
88
88
  }
89
- async post(path, body) {
89
+ async post(path, body, useClientPath = true) {
90
90
  const postFn = () => {
91
- return fetch(`${this.baseUrl}${path}`, {
91
+ return fetch(this.getPathURL(path, useClientPath), {
92
92
  body: JSON.stringify(body),
93
93
  headers: this.getHeaders(),
94
94
  method: "POST"
@@ -96,9 +96,9 @@ var Courier = class {
96
96
  };
97
97
  await tryCatch(postFn, this.debug);
98
98
  }
99
- async put(path, body) {
99
+ async put(path, body, useClientPath = true) {
100
100
  const putFn = () => {
101
- return fetch(`${this.baseUrl}${path}`, {
101
+ return fetch(this.getPathURL(path, useClientPath), {
102
102
  ...body ? { body: JSON.stringify(body) } : {},
103
103
  headers: this.getHeaders(),
104
104
  method: "PUT"
@@ -106,9 +106,9 @@ var Courier = class {
106
106
  };
107
107
  await tryCatch(putFn, this.debug);
108
108
  }
109
- async delete(path) {
109
+ async delete(path, useClientPath = true) {
110
110
  const deleteFn = () => {
111
- return fetch(`${this.baseUrl}${path}`, {
111
+ return fetch(this.getPathURL(path, useClientPath), {
112
112
  headers: this.getHeaders(),
113
113
  method: "DELETE"
114
114
  });
@@ -122,9 +122,16 @@ var Courier = class {
122
122
  }
123
123
  const id = decode(this.clientKey);
124
124
  return `https://view.notificationcenter.app/p/${encode(
125
- `${id}#${(_a = options == null ? void 0 : options.brandId) != null ? _a : ""}#${userId}#${false}`
125
+ `${id}#${(_a = options == null ? void 0 : options.brandId) != null ? _a : ""}#${userId}${(options == null ? void 0 : options.tenantId) ? `#${options.tenantId}` : ""}#${false}`
126
126
  )}`;
127
127
  }
128
+ getPathURL(path, useClientPath) {
129
+ let pathUrl = this.baseUrl;
130
+ if (useClientPath) {
131
+ pathUrl = pathUrl.concat("/client");
132
+ }
133
+ return pathUrl.concat(path);
134
+ }
128
135
  };
129
136
 
130
137
  // src/index.ts
@@ -143,7 +150,7 @@ var client = {
143
150
  if (!userId) {
144
151
  throw new Error("userId is required");
145
152
  }
146
- await this.instance.post(`identify/${userId}`, {
153
+ await this.instance.post(`/identify/${userId}`, {
147
154
  profile: {
148
155
  ...payload
149
156
  }
@@ -153,13 +160,25 @@ var client = {
153
160
  if (!userId || !listId) {
154
161
  throw new Error("userId is required");
155
162
  }
156
- await this.instance.put(`lists/${listId}/subscribe/${userId}`);
163
+ await this.instance.put(`/lists/${listId}/subscribe/${userId}`);
164
+ },
165
+ async track(event, properties) {
166
+ if (!event) {
167
+ throw new Error("event is required");
168
+ }
169
+ let indempotentKey = self.crypto.randomUUID ? self.crypto.randomUUID() : Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
170
+ await this.instance.post(`/inbound/courier`, {
171
+ messageId: indempotentKey,
172
+ type: "track",
173
+ event,
174
+ properties: { ...properties }
175
+ }, false);
157
176
  },
158
177
  async unsubscribe(userId, listId) {
159
178
  if (!userId || !listId) {
160
179
  throw new Error("userId is required");
161
180
  }
162
- this.instance.delete(`lists/${listId}/unsubscribe/${userId}`);
181
+ this.instance.delete(`/lists/${listId}/unsubscribe/${userId}`);
163
182
  },
164
183
  generatePreferencesUrl(userId, options) {
165
184
  return this.instance.generatePreferencesUrl(userId, options);
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  // package.json
2
- var version = "1.2.0";
2
+ var version = "1.4.2";
3
3
 
4
4
  // src/helpers/decode.ts
5
5
  function decode(clientKey) {
@@ -41,7 +41,7 @@ var Courier = class {
41
41
  throw new Error("Courier client key is required");
42
42
  }
43
43
  this.authorization = authorization;
44
- this.baseUrl = `${baseUrl != null ? baseUrl : "https://api.courier.com"}/client/`;
44
+ this.baseUrl = `${baseUrl != null ? baseUrl : "https://api.courier.com"}`;
45
45
  this.clientKey = clientKey;
46
46
  this.debug = debug;
47
47
  this.userId = userId;
@@ -60,9 +60,9 @@ var Courier = class {
60
60
  ...this.clientKey && { "x-courier-client-key": this.clientKey }
61
61
  });
62
62
  }
63
- async post(path, body) {
63
+ async post(path, body, useClientPath = true) {
64
64
  const postFn = () => {
65
- return fetch(`${this.baseUrl}${path}`, {
65
+ return fetch(this.getPathURL(path, useClientPath), {
66
66
  body: JSON.stringify(body),
67
67
  headers: this.getHeaders(),
68
68
  method: "POST"
@@ -70,9 +70,9 @@ var Courier = class {
70
70
  };
71
71
  await tryCatch(postFn, this.debug);
72
72
  }
73
- async put(path, body) {
73
+ async put(path, body, useClientPath = true) {
74
74
  const putFn = () => {
75
- return fetch(`${this.baseUrl}${path}`, {
75
+ return fetch(this.getPathURL(path, useClientPath), {
76
76
  ...body ? { body: JSON.stringify(body) } : {},
77
77
  headers: this.getHeaders(),
78
78
  method: "PUT"
@@ -80,9 +80,9 @@ var Courier = class {
80
80
  };
81
81
  await tryCatch(putFn, this.debug);
82
82
  }
83
- async delete(path) {
83
+ async delete(path, useClientPath = true) {
84
84
  const deleteFn = () => {
85
- return fetch(`${this.baseUrl}${path}`, {
85
+ return fetch(this.getPathURL(path, useClientPath), {
86
86
  headers: this.getHeaders(),
87
87
  method: "DELETE"
88
88
  });
@@ -96,9 +96,16 @@ var Courier = class {
96
96
  }
97
97
  const id = decode(this.clientKey);
98
98
  return `https://view.notificationcenter.app/p/${encode(
99
- `${id}#${(_a = options == null ? void 0 : options.brandId) != null ? _a : ""}#${userId}#${false}`
99
+ `${id}#${(_a = options == null ? void 0 : options.brandId) != null ? _a : ""}#${userId}${(options == null ? void 0 : options.tenantId) ? `#${options.tenantId}` : ""}#${false}`
100
100
  )}`;
101
101
  }
102
+ getPathURL(path, useClientPath) {
103
+ let pathUrl = this.baseUrl;
104
+ if (useClientPath) {
105
+ pathUrl = pathUrl.concat("/client");
106
+ }
107
+ return pathUrl.concat(path);
108
+ }
102
109
  };
103
110
 
104
111
  // src/index.ts
@@ -117,7 +124,7 @@ var client = {
117
124
  if (!userId) {
118
125
  throw new Error("userId is required");
119
126
  }
120
- await this.instance.post(`identify/${userId}`, {
127
+ await this.instance.post(`/identify/${userId}`, {
121
128
  profile: {
122
129
  ...payload
123
130
  }
@@ -127,13 +134,25 @@ var client = {
127
134
  if (!userId || !listId) {
128
135
  throw new Error("userId is required");
129
136
  }
130
- await this.instance.put(`lists/${listId}/subscribe/${userId}`);
137
+ await this.instance.put(`/lists/${listId}/subscribe/${userId}`);
138
+ },
139
+ async track(event, properties) {
140
+ if (!event) {
141
+ throw new Error("event is required");
142
+ }
143
+ let indempotentKey = self.crypto.randomUUID ? self.crypto.randomUUID() : Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
144
+ await this.instance.post(`/inbound/courier`, {
145
+ messageId: indempotentKey,
146
+ type: "track",
147
+ event,
148
+ properties: { ...properties }
149
+ }, false);
131
150
  },
132
151
  async unsubscribe(userId, listId) {
133
152
  if (!userId || !listId) {
134
153
  throw new Error("userId is required");
135
154
  }
136
- this.instance.delete(`lists/${listId}/unsubscribe/${userId}`);
155
+ this.instance.delete(`/lists/${listId}/unsubscribe/${userId}`);
137
156
  },
138
157
  generatePreferencesUrl(userId, options) {
139
158
  return this.instance.generatePreferencesUrl(userId, options);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trycourier/courier-js",
3
- "version": "1.2.0",
3
+ "version": "1.4.2",
4
4
  "main": "./dist/index.js",
5
5
  "module": "./dist/index.mjs",
6
6
  "types": "./dist/index.d.ts",
@@ -13,8 +13,8 @@
13
13
  "eslint": "^7.32.0",
14
14
  "tsup": "^5.10.1",
15
15
  "typescript": "^4.5.3",
16
- "@trycourier/tsconfig": "1.0.0",
17
- "eslint-config-courier": "1.0.0"
16
+ "eslint-config-courier": "1.0.0",
17
+ "@trycourier/tsconfig": "1.0.0"
18
18
  },
19
19
  "publishConfig": {
20
20
  "access": "public"