@dawntech/blip-tools 0.1.11 → 0.3.0

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.
@@ -1,12 +1,10 @@
1
- function normalizeValue(value) {
2
- return String(value).replaceAll(' ', '%20');
3
- }
1
+ import encodeString from './encode-strings.js';
4
2
  export default function encodeBlipParams(params) {
5
3
  //This function does not uses any of the standard methods of URI parsing because Blip does not follow any of them
6
4
  const parsedParams = [];
7
5
  for (const [key, value] of Object.entries(params)) {
8
6
  if (value && key) {
9
- parsedParams.push(`${normalizeValue(key)}=${normalizeValue(value)}`);
7
+ parsedParams.push(`${encodeString(key)}=${encodeString(value)}`);
10
8
  }
11
9
  }
12
10
  return parsedParams.join('&');
@@ -0,0 +1 @@
1
+ export default function encodeString(value: unknown): string;
@@ -0,0 +1,3 @@
1
+ export default function encodeString(value) {
2
+ return String(value).replaceAll(' ', '%20');
3
+ }
package/dist/index.d.ts CHANGED
@@ -1,4 +1,3 @@
1
- import { AxiosInstance } from 'axios';
2
1
  import { Template } from './types/template.js';
3
2
  import { Contact } from './types/contact.js';
4
3
  import { BlipConstructor } from './types/blip-constructor.js';
@@ -7,9 +6,13 @@ import { AttendanceHourContainer } from './types/attendance-hour-container.js';
7
6
  import { Ticket } from './types/ticket.js';
8
7
  import { CampaignNotification } from './types/campaign-notification.js';
9
8
  import { CampaignNotificationStatus } from './types/campaign-notification-status.js';
9
+ import BlipBucket from './modules/blip-bucket.js';
10
+ import BlipMedia from './modules/blip-media.js';
10
11
  export { BlipError, type Ticket, type AttendanceHourContainer, type Contact, type Template };
11
12
  export default class Blip {
12
- api: AxiosInstance;
13
+ private api;
14
+ bucket: BlipBucket;
15
+ media: BlipMedia;
13
16
  constructor(params: BlipConstructor);
14
17
  /**
15
18
  * Sends a template-based message to any user. For sending messages to clients who are active, use `sendTemplateMessage` instead.
@@ -37,21 +40,39 @@ export default class Blip {
37
40
  /**
38
41
  * Sends a template-based message to an active user. For sending messages to clients who have never interacted or are inactive, use `sendTemplate` instead.
39
42
  */
40
- sendTemplateMessage({ identity, template }: {
43
+ sendTemplateMessage({ identity, template, metadata, }: {
41
44
  identity: string;
42
45
  template: Template;
46
+ metadata?: string;
43
47
  }): Promise<void>;
44
48
  /**
45
49
  * Sends a simple text message to an active user. For sending messages to clients who have never interacted or are inactive, use `sendTemplate` instead.
46
50
  */
47
- sendSimpleMessage({ identity, content }: {
51
+ sendSimpleMessage({ identity, content, metadata }: {
48
52
  identity: string;
49
53
  content: string;
54
+ metadata?: string;
50
55
  }): Promise<void>;
51
- sendMessageWithButtons({ identity, message, buttons, }: {
56
+ /**
57
+ * Sends a text message to an active user with a midia. For sending messages to clients who have never interacted or are inactive, use `sendTemplate` instead.
58
+ */
59
+ sendMediaMessage({ identity, text, metadata, uri, type, title, aspectRatio, size, previewUri, }: {
60
+ type?: string;
61
+ uri: string;
62
+ identity: string;
63
+ text: string;
64
+ metadata?: string;
65
+ title: string;
66
+ aspectRatio?: string;
67
+ size?: number;
68
+ previewUri?: string;
69
+ previewType?: string;
70
+ }): Promise<void>;
71
+ sendMessageWithButtons({ identity, message, buttons, metadata, }: {
52
72
  identity: string;
53
73
  message: string;
54
74
  buttons: string[];
75
+ metadata?: string;
55
76
  }): Promise<void>;
56
77
  updateContact({ identity, contactData }: {
57
78
  identity: string;
@@ -66,6 +87,12 @@ export default class Blip {
66
87
  value: unknown;
67
88
  identity: string;
68
89
  }): Promise<void>;
90
+ moveUser({ identity, botIdentity, botFlowId, botStateId, }: {
91
+ identity: string;
92
+ botIdentity: string;
93
+ botFlowId: string;
94
+ botStateId: string;
95
+ }): Promise<void>;
69
96
  getWhatsAppIdentity(phone: string): Promise<string>;
70
97
  createTrackEvent({ category, action, identity }: {
71
98
  category: string;
package/dist/index.js CHANGED
@@ -6,9 +6,13 @@ import formatTemplateParams from './helpers/format-template-params.js';
6
6
  import validateInstance from './helpers/validate-instance.js';
7
7
  import BlipError from './exceptions/blip-error.js';
8
8
  import encodeBlipParams from './helpers/encode-blip-params.js';
9
+ import BlipBucket from './modules/blip-bucket.js';
10
+ import BlipMedia from './modules/blip-media.js';
9
11
  export { BlipError };
10
12
  export default class Blip {
11
13
  api;
14
+ bucket;
15
+ media;
12
16
  constructor(params) {
13
17
  validateInstance(params);
14
18
  this.api = axios.create({
@@ -18,6 +22,8 @@ export default class Blip {
18
22
  },
19
23
  timeout: 30000,
20
24
  });
25
+ this.bucket = new BlipBucket(this.api);
26
+ this.media = new BlipMedia(this.api);
21
27
  }
22
28
  /**
23
29
  * Sends a template-based message to any user. For sending messages to clients who are active, use `sendTemplateMessage` instead.
@@ -108,7 +114,7 @@ export default class Blip {
108
114
  /**
109
115
  * Sends a template-based message to an active user. For sending messages to clients who have never interacted or are inactive, use `sendTemplate` instead.
110
116
  */
111
- async sendTemplateMessage({ identity, template }) {
117
+ async sendTemplateMessage({ identity, template, metadata, }) {
112
118
  try {
113
119
  const response = await this.api.post('/messages', {
114
120
  id: randomUUID(),
@@ -118,6 +124,7 @@ export default class Blip {
118
124
  type: 'template',
119
125
  template,
120
126
  },
127
+ metadata,
121
128
  });
122
129
  validateResponse(response);
123
130
  }
@@ -128,13 +135,14 @@ export default class Blip {
128
135
  /**
129
136
  * Sends a simple text message to an active user. For sending messages to clients who have never interacted or are inactive, use `sendTemplate` instead.
130
137
  */
131
- async sendSimpleMessage({ identity, content }) {
138
+ async sendSimpleMessage({ identity, content, metadata }) {
132
139
  try {
133
140
  const response = await this.api.post('/messages', {
134
141
  id: randomUUID(),
135
142
  to: identity,
136
143
  type: 'text/plain',
137
144
  content,
145
+ metadata,
138
146
  });
139
147
  validateResponse(response);
140
148
  }
@@ -142,7 +150,33 @@ export default class Blip {
142
150
  handleError(error);
143
151
  }
144
152
  }
145
- async sendMessageWithButtons({ identity, message, buttons, }) {
153
+ /**
154
+ * Sends a text message to an active user with a midia. For sending messages to clients who have never interacted or are inactive, use `sendTemplate` instead.
155
+ */
156
+ async sendMediaMessage({ identity, text, metadata, uri, type, title, aspectRatio = '1:1', size, previewUri, }) {
157
+ try {
158
+ const response = await this.api.post('/messages', {
159
+ id: randomUUID(),
160
+ to: identity,
161
+ type: 'application/vnd.lime.media-link+json',
162
+ content: {
163
+ text,
164
+ uri,
165
+ type,
166
+ title,
167
+ aspectRatio,
168
+ size,
169
+ previewUri,
170
+ },
171
+ metadata,
172
+ });
173
+ validateResponse(response);
174
+ }
175
+ catch (error) {
176
+ handleError(error);
177
+ }
178
+ }
179
+ async sendMessageWithButtons({ identity, message, buttons, metadata, }) {
146
180
  try {
147
181
  const response = await this.api.post('/messages', {
148
182
  id: randomUUID(),
@@ -153,6 +187,7 @@ export default class Blip {
153
187
  text: message,
154
188
  options: buttons.map((button, index) => ({ order: index + 1, text: button })),
155
189
  },
190
+ metadata,
156
191
  });
157
192
  validateResponse(response);
158
193
  }
@@ -225,6 +260,12 @@ export default class Blip {
225
260
  handleError(error);
226
261
  }
227
262
  }
263
+ async moveUser({ identity, botIdentity, botFlowId, botStateId, }) {
264
+ await Promise.all([
265
+ this.setContextVariable({ identity, variableName: 'master-state', value: botIdentity }),
266
+ this.setContextVariable({ identity, variableName: `stateid@${botFlowId}`, value: botStateId }),
267
+ ]);
268
+ }
228
269
  async getWhatsAppIdentity(phone) {
229
270
  try {
230
271
  const response = await this.api.post('/commands', {
@@ -251,11 +292,9 @@ export default class Blip {
251
292
  resource: {
252
293
  category,
253
294
  action,
295
+ contact: identity ? { identity } : undefined,
254
296
  },
255
297
  };
256
- if (identity && body.resource) {
257
- body.resource.contact = { identity };
258
- }
259
298
  const response = await this.api.post('/commands', body);
260
299
  validateResponse(response);
261
300
  }
@@ -0,0 +1,21 @@
1
+ import { AxiosInstance } from 'axios';
2
+ export default class BlipBucket {
3
+ private api;
4
+ constructor(api: AxiosInstance);
5
+ /**
6
+ Stores JSON content in a bucket provided by Blip. The content can be updaded or retrieved using the same id used in the update.
7
+ You can optionally provide a expiration time (in milliseconds) to delete the document after a certain amount of time.
8
+ */
9
+ storeContentInBucket(id: string, content: unknown, opts?: {
10
+ expiresInMs?: number;
11
+ }): Promise<void>;
12
+ /**
13
+ Retrieves a document from the Blip bucket.
14
+ */
15
+ getContentFromBucket<T>(id: string): Promise<T>;
16
+ getAllContentIdsFromBucket(): Promise<string[]>;
17
+ /**
18
+ Deletes a JSON document from the Blip bucket.
19
+ */
20
+ deleteContentFromBucket(id: string): Promise<void>;
21
+ }
@@ -0,0 +1,88 @@
1
+ import encodeString from '../helpers/encode-strings.js';
2
+ import { randomUUID } from 'crypto';
3
+ import encodeBlipParams from '../helpers/encode-blip-params.js';
4
+ import validateResponse from '../helpers/validate-response.js';
5
+ import handleError from '../helpers/handle-error.js';
6
+ export default class BlipBucket {
7
+ api;
8
+ constructor(api) {
9
+ this.api = api;
10
+ }
11
+ /**
12
+ Stores JSON content in a bucket provided by Blip. The content can be updaded or retrieved using the same id used in the update.
13
+ You can optionally provide a expiration time (in milliseconds) to delete the document after a certain amount of time.
14
+ */
15
+ async storeContentInBucket(id, content, opts) {
16
+ try {
17
+ let uri = `/buckets/${encodeString(id)}`;
18
+ const params = {};
19
+ if (opts?.expiresInMs) {
20
+ params.expiration = opts?.expiresInMs;
21
+ uri += `?${encodeBlipParams(params)}`;
22
+ }
23
+ const body = {
24
+ id: randomUUID(),
25
+ method: 'set',
26
+ type: 'application/json',
27
+ uri,
28
+ resource: content,
29
+ };
30
+ const response = await this.api.post('/commands', body);
31
+ validateResponse(response);
32
+ }
33
+ catch (error) {
34
+ throw handleError(error);
35
+ }
36
+ }
37
+ /**
38
+ Retrieves a document from the Blip bucket.
39
+ */
40
+ async getContentFromBucket(id) {
41
+ try {
42
+ const body = {
43
+ id: randomUUID(),
44
+ method: 'get',
45
+ uri: `/buckets/${encodeString(id)}`,
46
+ };
47
+ const response = await this.api.post('/commands', body);
48
+ validateResponse(response);
49
+ return response.data.resource;
50
+ }
51
+ catch (error) {
52
+ throw handleError(error);
53
+ }
54
+ }
55
+ async getAllContentIdsFromBucket() {
56
+ try {
57
+ const body = {
58
+ id: randomUUID(),
59
+ method: 'get',
60
+ uri: `/buckets`,
61
+ };
62
+ const response = await this.api.post('/commands', body);
63
+ validateResponse(response);
64
+ return response.data.resource.items;
65
+ }
66
+ catch (error) {
67
+ throw handleError(error);
68
+ }
69
+ }
70
+ /**
71
+ Deletes a JSON document from the Blip bucket.
72
+ */
73
+ async deleteContentFromBucket(id) {
74
+ try {
75
+ const body = {
76
+ id: randomUUID(),
77
+ method: 'delete',
78
+ uri: `/buckets/${encodeString(id)}`,
79
+ to: 'postmaster@msging.net',
80
+ };
81
+ const response = await this.api.post('/commands', body);
82
+ validateResponse(response);
83
+ }
84
+ catch (error) {
85
+ throw handleError(error);
86
+ }
87
+ }
88
+ }
@@ -0,0 +1,11 @@
1
+ import { AxiosInstance } from 'axios';
2
+ export default class BlipMedia {
3
+ private api;
4
+ constructor(api: AxiosInstance);
5
+ /**
6
+ * Uploads an media file to Blip storage to be used later when sending messages
7
+ * @param content A Blob containing a image, PDF or video
8
+ * @returns A public URL
9
+ */
10
+ uploadMedia(content: Blob): Promise<string>;
11
+ }
@@ -0,0 +1,33 @@
1
+ import axios from 'axios';
2
+ import { randomUUID } from 'crypto';
3
+ import validateResponse from '../helpers/validate-response.js';
4
+ import handleError from '../helpers/handle-error.js';
5
+ export default class BlipMedia {
6
+ api;
7
+ constructor(api) {
8
+ this.api = api;
9
+ }
10
+ /**
11
+ * Uploads an media file to Blip storage to be used later when sending messages
12
+ * @param content A Blob containing a image, PDF or video
13
+ * @returns A public URL
14
+ */
15
+ async uploadMedia(content) {
16
+ try {
17
+ const response = await this.api.post('/commands', {
18
+ id: randomUUID(),
19
+ to: 'postmaster@media.msging.net',
20
+ method: 'get',
21
+ uri: '/upload-media-uri',
22
+ });
23
+ validateResponse(response);
24
+ const uploadResponse = await axios.post(response.data.resource, content, {
25
+ headers: { 'Content-Type': 'application/octet-stream' },
26
+ });
27
+ return uploadResponse.data.mediaUri;
28
+ }
29
+ catch (error) {
30
+ throw handleError(error);
31
+ }
32
+ }
33
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dawntech/blip-tools",
3
- "version": "0.1.11",
3
+ "version": "0.3.0",
4
4
  "description": "Node package for Blip API",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",