@twilio/conversations 2.0.1-rc.9 → 2.1.0-rc.5

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.
Files changed (88) hide show
  1. package/CHANGELOG.md +74 -0
  2. package/NOTICE.txt +679 -0
  3. package/builds/browser.js +892 -619
  4. package/builds/browser.js.map +1 -1
  5. package/builds/lib.d.ts +371 -124
  6. package/builds/lib.js +892 -619
  7. package/builds/lib.js.map +1 -1
  8. package/builds/twilio-conversations.js +1067 -939
  9. package/builds/twilio-conversations.min.js +2 -14
  10. package/dist/aggregated-delivery-receipt.js +6 -1
  11. package/dist/aggregated-delivery-receipt.js.map +1 -1
  12. package/dist/client.js +165 -142
  13. package/dist/client.js.map +1 -1
  14. package/dist/command-executor.js +16 -14
  15. package/dist/command-executor.js.map +1 -1
  16. package/dist/configuration.js +14 -10
  17. package/dist/configuration.js.map +1 -1
  18. package/dist/conversation.js +232 -159
  19. package/dist/conversation.js.map +1 -1
  20. package/dist/data/conversations.js +82 -78
  21. package/dist/data/conversations.js.map +1 -1
  22. package/dist/data/messages.js +43 -39
  23. package/dist/data/messages.js.map +1 -1
  24. package/dist/data/participants.js +100 -78
  25. package/dist/data/participants.js.map +1 -1
  26. package/dist/data/users.js +24 -22
  27. package/dist/data/users.js.map +1 -1
  28. package/dist/detailed-delivery-receipt.js +1 -1
  29. package/dist/detailed-delivery-receipt.js.map +1 -1
  30. package/dist/index.js +1 -0
  31. package/dist/index.js.map +1 -1
  32. package/dist/interfaces/attributes.js +147 -0
  33. package/dist/interfaces/attributes.js.map +1 -0
  34. package/dist/interfaces/notification-types.js +5 -5
  35. package/dist/interfaces/notification-types.js.map +1 -1
  36. package/dist/logger.js +36 -15
  37. package/dist/logger.js.map +1 -1
  38. package/dist/media.js +21 -9
  39. package/dist/media.js.map +1 -1
  40. package/dist/message-builder.js +56 -3
  41. package/dist/message-builder.js.map +1 -1
  42. package/dist/message.js +158 -78
  43. package/dist/message.js.map +1 -1
  44. package/dist/packages/conversations/package.json.js +1 -1
  45. package/dist/participant.js +101 -50
  46. package/dist/participant.js.map +1 -1
  47. package/dist/push-notification.js.map +1 -1
  48. package/dist/rest-paginator.js +16 -6
  49. package/dist/rest-paginator.js.map +1 -1
  50. package/dist/services/network.js +18 -14
  51. package/dist/services/network.js.map +1 -1
  52. package/dist/services/typing-indicator.js +20 -17
  53. package/dist/services/typing-indicator.js.map +1 -1
  54. package/dist/unsent-message.js.map +1 -1
  55. package/dist/user.js +87 -60
  56. package/dist/user.js.map +1 -1
  57. package/dist/util/deferred.js +3 -1
  58. package/dist/util/deferred.js.map +1 -1
  59. package/dist/util/index.js +6 -6
  60. package/dist/util/index.js.map +1 -1
  61. package/docs/assets/js/search.js +1 -1
  62. package/docs/classes/AggregatedDeliveryReceipt.html +15 -0
  63. package/docs/classes/Client.html +39 -30
  64. package/docs/classes/Conversation.html +52 -30
  65. package/docs/classes/DetailedDeliveryReceipt.html +16 -1
  66. package/docs/classes/Media.html +15 -0
  67. package/docs/classes/Message.html +88 -7
  68. package/docs/classes/MessageBuilder.html +93 -2
  69. package/docs/classes/Participant.html +52 -8
  70. package/docs/classes/PushNotification.html +15 -0
  71. package/docs/classes/RestPaginator.html +15 -0
  72. package/docs/classes/UnsentMessage.html +15 -0
  73. package/docs/classes/User.html +22 -7
  74. package/docs/index.html +37 -3
  75. package/docs/interfaces/ClientOptions.html +15 -0
  76. package/docs/interfaces/ConversationBindings.html +3118 -0
  77. package/docs/interfaces/ConversationEmailBinding.html +3118 -0
  78. package/docs/interfaces/ConversationState.html +15 -0
  79. package/docs/interfaces/CreateConversationOptions.html +16 -1
  80. package/docs/interfaces/LastMessage.html +15 -0
  81. package/docs/interfaces/Paginator.html +15 -0
  82. package/docs/interfaces/ParticipantBindings.html +3118 -0
  83. package/docs/interfaces/ParticipantEmailBinding.html +3118 -0
  84. package/docs/interfaces/PushNotificationData.html +15 -0
  85. package/docs/interfaces/SendEmailOptions.html +15 -0
  86. package/docs/interfaces/SendMediaOptions.html +15 -0
  87. package/docs/modules.html +37 -3
  88. package/package.json +24 -18
@@ -154,6 +154,8 @@ class MessageBuilder {
154
154
  constructor(limits, messagesEntity) {
155
155
  this.limits = limits;
156
156
  this.message = new unsentMessage.UnsentMessage(messagesEntity);
157
+ this.emailBodies = new Map();
158
+ this.emailHistories = new Map();
157
159
  }
158
160
  /**
159
161
  * Sets the message body.
@@ -179,27 +181,78 @@ class MessageBuilder {
179
181
  this.message.attributes = attributes;
180
182
  return this;
181
183
  }
184
+ /**
185
+ * Set email body with given MIME-type.
186
+ * @param mimeType Format of the body to set (text/plain or text/html).
187
+ * @param body Body payload in selected format.
188
+ */
189
+ setEmailBody(mimeType, body) {
190
+ this.emailBodies.set(mimeType, body);
191
+ return this;
192
+ }
193
+ /**
194
+ * Set email history with given MIME-type.
195
+ * @param mimeType Format of the history to set (text/plain or text/html).
196
+ * @param history History payload in selected format.
197
+ */
198
+ setEmailHistory(mimeType, history) {
199
+ this.emailHistories.set(mimeType, history);
200
+ return this;
201
+ }
182
202
  /**
183
203
  * Adds media to the message.
184
204
  * @param payload Media to add.
185
205
  */
186
206
  addMedia(payload) {
187
- this.message.mediaContent.push(['media', payload]);
207
+ if (typeof FormData === "undefined" && payload instanceof FormData) {
208
+ throw new Error("Could not add FormData content whilst not in a browser");
209
+ }
210
+ if (!(payload instanceof FormData)) {
211
+ const mediaOptions = payload;
212
+ if (!mediaOptions.contentType || !mediaOptions.media) {
213
+ throw new Error("Media content in SendMediaOptions must contain non-empty contentType and media");
214
+ }
215
+ }
216
+ this.message.mediaContent.push(["media", payload]);
188
217
  return this;
189
218
  }
190
219
  /**
191
220
  * Builds the message, making it ready to be sent.
192
221
  */
193
222
  build() {
223
+ this.emailBodies.forEach((_, key) => {
224
+ if (!this.limits.emailBodiesAllowedMimeTypes.includes(key)) {
225
+ throw new Error(`Unsupported email body MIME type ${key}`);
226
+ }
227
+ });
228
+ this.emailHistories.forEach((_, key) => {
229
+ if (!this.limits.emailHistoriesAllowedMimeTypes.includes(key)) {
230
+ throw new Error(`Unsupported email history MIME type ${key}`);
231
+ }
232
+ });
233
+ if (this.emailBodies.size > this.limits.emailBodiesAllowedMimeTypes.length) {
234
+ throw new Error(`Too many email bodies attached to the message (${this.emailBodies.size} > ${this.limits.emailBodiesAllowedMimeTypes.length})`);
235
+ }
236
+ if (this.emailHistories.size >
237
+ this.limits.emailHistoriesAllowedMimeTypes.length) {
238
+ throw new Error(`Too many email histories attached to the message (${this.emailHistories.size} > ${this.limits.emailHistoriesAllowedMimeTypes.length})`);
239
+ }
194
240
  if (this.message.mediaContent.length > this.limits.mediaAttachmentsCountLimit) {
195
241
  throw new Error(`Too many media attachments in the message (${this.message.mediaContent.length} > ${this.limits.mediaAttachmentsCountLimit})`);
196
242
  }
197
243
  // @todo we don't know the sizes of the attachments in FormData
244
+ // @todo insertion below makes build() method non-repeatable - probably move to UnsentMessage.send() or even sendV2()?
245
+ this.emailBodies.forEach((body) => {
246
+ this.message.mediaContent.push(["body", body]);
247
+ });
248
+ this.emailHistories.forEach((history) => {
249
+ this.message.mediaContent.push(["history", history]);
250
+ });
198
251
  return this.message;
199
252
  }
200
253
  getPayloadContentType(payload) {
201
- if (typeof FormData !== 'undefined' && (payload instanceof FormData)) {
202
- return payload.get('Content-Type');
254
+ if (typeof FormData !== "undefined" && payload instanceof FormData) {
255
+ return payload.get("Content-Type");
203
256
  }
204
257
  return payload.contentType;
205
258
  }
@@ -1 +1 @@
1
- {"version":3,"file":"message-builder.js","sources":["../src/message-builder.ts"],"sourcesContent":["import { Limits } from './interfaces/limits';\nimport { SendMediaOptions } from './conversation';\nimport { UnsentMessage } from './unsent-message';\n\n/**\n * Message builder. Allows the message to be built and sent via method chaining.\n *\n * Example:\n *\n * ```ts\n * await testConversation.prepareMessage()\n * .setBody('Hello!')\n * .setAttributes({foo: 'bar'})\n * .addMedia(media1)\n * .addMedia(media2)\n * .build()\n * .send();\n * ```\n */\nclass MessageBuilder {\n private readonly message: UnsentMessage;\n\n /**\n * @internal\n */\n constructor(private readonly limits: Limits, messagesEntity: any) {\n this.message = new UnsentMessage(messagesEntity);\n }\n\n /**\n * Sets the message body.\n * @param text Contents of the body.\n */\n setBody(text: string): MessageBuilder {\n this.message.text = text;\n return this;\n }\n\n /**\n * Sets the message subject.\n * @param subject Contents of the subject.\n */\n setSubject(subject: string): MessageBuilder {\n this.message.emailOptions.subject = subject;\n return this;\n }\n\n /**\n * Sets the message attributes.\n * @param attributes Message attributes.\n */\n setAttributes(attributes: any): MessageBuilder {\n this.message.attributes = attributes;\n return this;\n }\n\n /**\n * Adds media to the message.\n * @param payload Media to add.\n */\n addMedia(payload: FormData | SendMediaOptions): MessageBuilder {\n this.message.mediaContent.push(['media', payload]);\n return this;\n }\n\n /**\n * Builds the message, making it ready to be sent.\n */\n build(): UnsentMessage {\n if (this.message.mediaContent.length > this.limits.mediaAttachmentsCountLimit) {\n throw new Error(`Too many media attachments in the message (${this.message.mediaContent.length} > ${this.limits.mediaAttachmentsCountLimit})`);\n }\n\n // @todo we don't know the sizes of the attachments in FormData\n\n return this.message;\n }\n\n private getPayloadContentType(payload: FormData | SendMediaOptions): string {\n if (typeof FormData !== 'undefined' && (payload instanceof FormData)) {\n return payload.get('Content-Type') as string;\n }\n return (payload as SendMediaOptions).contentType;\n }\n}\n\nexport { MessageBuilder };\n"],"names":["UnsentMessage"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAIA;;;;;;;;;;;;;;;AAeA,MAAM,cAAc;;;;IAMlB,YAA6B,MAAc,EAAE,cAAmB;QAAnC,WAAM,GAAN,MAAM,CAAQ;QACzC,IAAI,CAAC,OAAO,GAAG,IAAIA,2BAAa,CAAC,cAAc,CAAC,CAAC;KAClD;;;;;IAMD,OAAO,CAAC,IAAY;QAClB,IAAI,CAAC,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;QACzB,OAAO,IAAI,CAAC;KACb;;;;;IAMD,UAAU,CAAC,OAAe;QACxB,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,OAAO,GAAG,OAAO,CAAC;QAC5C,OAAO,IAAI,CAAC;KACb;;;;;IAMD,aAAa,CAAC,UAAe;QAC3B,IAAI,CAAC,OAAO,CAAC,UAAU,GAAG,UAAU,CAAC;QACrC,OAAO,IAAI,CAAC;KACb;;;;;IAMD,QAAQ,CAAC,OAAoC;QAC3C,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;QACnD,OAAO,IAAI,CAAC;KACb;;;;IAKD,KAAK;QACH,IAAI,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,0BAA0B,EAAE;YAC7E,MAAM,IAAI,KAAK,CAAC,8CAA8C,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,MAAM,MAAM,IAAI,CAAC,MAAM,CAAC,0BAA0B,GAAG,CAAC,CAAC;SAChJ;;QAID,OAAO,IAAI,CAAC,OAAO,CAAC;KACrB;IAEO,qBAAqB,CAAC,OAAoC;QAChE,IAAI,OAAO,QAAQ,KAAK,WAAW,KAAK,OAAO,YAAY,QAAQ,CAAC,EAAE;YACpE,OAAO,OAAO,CAAC,GAAG,CAAC,cAAc,CAAW,CAAC;SAC9C;QACD,OAAQ,OAA4B,CAAC,WAAW,CAAC;KAClD;;;;;"}
1
+ {"version":3,"file":"message-builder.js","sources":["../src/message-builder.ts"],"sourcesContent":["import { Limits } from \"./interfaces/limits\";\nimport { SendMediaOptions } from \"./conversation\";\nimport { UnsentMessage } from \"./unsent-message\";\nimport { JSONValue } from \"./types\";\nimport { Messages } from \"./data/messages\";\n\n/**\n * Message builder. Allows the message to be built and sent via method chaining.\n *\n * Example:\n *\n * ```ts\n * await testConversation.prepareMessage()\n * .setBody('Hello!')\n * .setAttributes({foo: 'bar'})\n * .addMedia(media1)\n * .addMedia(media2)\n * .build()\n * .send();\n * ```\n */\nclass MessageBuilder {\n private readonly message: UnsentMessage;\n private emailBodies: Map<string, FormData | SendMediaOptions>;\n private emailHistories: Map<string, FormData | SendMediaOptions>;\n\n /**\n * @internal\n */\n constructor(private readonly limits: Limits, messagesEntity: Messages) {\n this.message = new UnsentMessage(messagesEntity);\n this.emailBodies = new Map<string, FormData | SendMediaOptions>();\n this.emailHistories = new Map<string, FormData | SendMediaOptions>();\n }\n\n /**\n * Sets the message body.\n * @param text Contents of the body.\n */\n setBody(text: string): MessageBuilder {\n this.message.text = text;\n return this;\n }\n\n /**\n * Sets the message subject.\n * @param subject Contents of the subject.\n */\n setSubject(subject: string): MessageBuilder {\n this.message.emailOptions.subject = subject;\n return this;\n }\n\n /**\n * Sets the message attributes.\n * @param attributes Message attributes.\n */\n setAttributes(attributes: JSONValue): MessageBuilder {\n this.message.attributes = attributes;\n return this;\n }\n\n /**\n * Set email body with given MIME-type.\n * @param mimeType Format of the body to set (text/plain or text/html).\n * @param body Body payload in selected format.\n */\n setEmailBody(\n mimeType: string,\n body: FormData | SendMediaOptions\n ): MessageBuilder {\n this.emailBodies.set(mimeType, body);\n return this;\n }\n\n /**\n * Set email history with given MIME-type.\n * @param mimeType Format of the history to set (text/plain or text/html).\n * @param history History payload in selected format.\n */\n setEmailHistory(\n mimeType: string,\n history: FormData | SendMediaOptions\n ): MessageBuilder {\n this.emailHistories.set(mimeType, history);\n return this;\n }\n\n /**\n * Adds media to the message.\n * @param payload Media to add.\n */\n addMedia(payload: FormData | SendMediaOptions): MessageBuilder {\n if (typeof FormData === \"undefined\" && payload instanceof FormData) {\n throw new Error(\"Could not add FormData content whilst not in a browser\");\n }\n if (!(payload instanceof FormData)) {\n const mediaOptions = payload as SendMediaOptions;\n if (!mediaOptions.contentType || !mediaOptions.media) {\n throw new Error(\n \"Media content in SendMediaOptions must contain non-empty contentType and media\"\n );\n }\n }\n this.message.mediaContent.push([\"media\", payload]);\n return this;\n }\n\n /**\n * Builds the message, making it ready to be sent.\n */\n build(): UnsentMessage {\n this.emailBodies.forEach((_, key) => {\n if (!this.limits.emailBodiesAllowedMimeTypes.includes(key)) {\n throw new Error(`Unsupported email body MIME type ${key}`);\n }\n });\n this.emailHistories.forEach((_, key) => {\n if (!this.limits.emailHistoriesAllowedMimeTypes.includes(key)) {\n throw new Error(`Unsupported email history MIME type ${key}`);\n }\n });\n if (\n this.emailBodies.size > this.limits.emailBodiesAllowedMimeTypes.length\n ) {\n throw new Error(\n `Too many email bodies attached to the message (${this.emailBodies.size} > ${this.limits.emailBodiesAllowedMimeTypes.length})`\n );\n }\n if (\n this.emailHistories.size >\n this.limits.emailHistoriesAllowedMimeTypes.length\n ) {\n throw new Error(\n `Too many email histories attached to the message (${this.emailHistories.size} > ${this.limits.emailHistoriesAllowedMimeTypes.length})`\n );\n }\n\n if (\n this.message.mediaContent.length > this.limits.mediaAttachmentsCountLimit\n ) {\n throw new Error(\n `Too many media attachments in the message (${this.message.mediaContent.length} > ${this.limits.mediaAttachmentsCountLimit})`\n );\n }\n\n // @todo we don't know the sizes of the attachments in FormData\n // @todo insertion below makes build() method non-repeatable - probably move to UnsentMessage.send() or even sendV2()?\n\n this.emailBodies.forEach((body) => {\n this.message.mediaContent.push([\"body\", body]);\n });\n\n this.emailHistories.forEach((history) => {\n this.message.mediaContent.push([\"history\", history]);\n });\n\n return this.message;\n }\n\n private getPayloadContentType(\n payload: FormData | SendMediaOptions\n ): string | null {\n if (typeof FormData !== \"undefined\" && payload instanceof FormData) {\n return payload.get(\"Content-Type\") as string;\n }\n return (payload as SendMediaOptions).contentType;\n }\n}\n\nexport { MessageBuilder };\n"],"names":["UnsentMessage"],"mappings":"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"}
package/dist/message.js CHANGED
@@ -136,6 +136,7 @@ var logger = require('./logger.js');
136
136
  var media = require('./media.js');
137
137
  var aggregatedDeliveryReceipt = require('./aggregated-delivery-receipt.js');
138
138
  var declarativeTypeValidator = require('@twilio/declarative-type-validator');
139
+ var attributes = require('./interfaces/attributes.js');
139
140
  var restPaginator = require('./rest-paginator.js');
140
141
  var detailedDeliveryReceipt = require('./detailed-delivery-receipt.js');
141
142
  var replayEventEmitter = require('@twilio/replay-event-emitter');
@@ -145,7 +146,7 @@ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'defau
145
146
 
146
147
  var isEqual__default = /*#__PURE__*/_interopDefaultLegacy(isEqual);
147
148
 
148
- const log = logger.Logger.scope('Message');
149
+ const log = logger.Logger.scope("Message");
149
150
  /**
150
151
  * A message in a conversation.
151
152
  */
@@ -154,7 +155,7 @@ class Message extends replayEventEmitter.ReplayEventEmitter {
154
155
  * @internal
155
156
  */
156
157
  constructor(index$1, data, conversation, links, configuration, services) {
157
- var _a, _b, _c, _d, _e;
158
+ var _a, _b, _c, _d;
158
159
  super();
159
160
  this.conversation = conversation;
160
161
  this.links = links;
@@ -163,42 +164,56 @@ class Message extends replayEventEmitter.ReplayEventEmitter {
163
164
  this.state = {
164
165
  sid: data.sid,
165
166
  index: index$1,
166
- author: (_a = data.author) !== null && _a !== void 0 ? _a : null,
167
- subject: (_b = data.subject) !== null && _b !== void 0 ? _b : null,
168
- body: data.text,
167
+ author: data.author,
168
+ subject: data.subject,
169
+ body: (_a = data.text) !== null && _a !== void 0 ? _a : null,
169
170
  timestamp: data.timestamp ? new Date(data.timestamp) : null,
170
171
  dateUpdated: data.dateUpdated ? new Date(data.dateUpdated) : null,
171
- lastUpdatedBy: (_c = data.lastUpdatedBy) !== null && _c !== void 0 ? _c : null,
172
+ lastUpdatedBy: (_b = data.lastUpdatedBy) !== null && _b !== void 0 ? _b : null,
172
173
  attributes: index.parseAttributes(data.attributes, `Got malformed attributes for the message ${data.sid}`, log),
173
- type: (_d = data.type) !== null && _d !== void 0 ? _d : 'text',
174
- media: (data.type && data.type === 'media' && data.media)
175
- ? new media.Media(data.media, this.services) : null,
176
- medias: (data.type && data.type === 'media' && data.medias)
177
- ? data.medias.map((m) => new media.Media(m, this.services)) : null,
178
- participantSid: (_e = data.memberSid) !== null && _e !== void 0 ? _e : null,
179
- aggregatedDeliveryReceipt: data.delivery ? new aggregatedDeliveryReceipt.AggregatedDeliveryReceipt(data.delivery) : null
174
+ type: (_c = data.type) !== null && _c !== void 0 ? _c : "text",
175
+ media: data.type && data.type === "media" && data.media
176
+ ? new media.Media(data.media, this.services)
177
+ : null,
178
+ medias: data.type && data.type === "media" && data.medias
179
+ ? data.medias.map((m) => new media.Media(m, this.services))
180
+ : null,
181
+ participantSid: (_d = data.memberSid) !== null && _d !== void 0 ? _d : null,
182
+ aggregatedDeliveryReceipt: data.delivery
183
+ ? new aggregatedDeliveryReceipt.AggregatedDeliveryReceipt(data.delivery)
184
+ : null,
180
185
  };
181
186
  }
182
187
  /**
183
188
  * The server-assigned unique identifier for the message.
184
189
  */
185
- get sid() { return this.state.sid; }
190
+ get sid() {
191
+ return this.state.sid;
192
+ }
186
193
  /**
187
194
  * Name of the user that sent the message.
188
195
  */
189
- get author() { return this.state.author; }
196
+ get author() {
197
+ return this.state.author;
198
+ }
190
199
  /**
191
200
  * Message subject. Used only in email conversations.
192
201
  */
193
- get subject() { return this.state.subject; }
202
+ get subject() {
203
+ return this.state.subject;
204
+ }
194
205
  /**
195
206
  * Body of the message.
196
207
  */
197
- get body() { return this.state.body; }
208
+ get body() {
209
+ return this.state.body;
210
+ }
198
211
  /**
199
212
  * Date this message was last updated on.
200
213
  */
201
- get dateUpdated() { return this.state.dateUpdated; }
214
+ get dateUpdated() {
215
+ return this.state.dateUpdated;
216
+ }
202
217
  /**
203
218
  * Index of the message in the conversation's messages list.
204
219
  * By design of the Conversations system, the message indices may have arbitrary gaps between them,
@@ -210,36 +225,53 @@ class Message extends replayEventEmitter.ReplayEventEmitter {
210
225
  * To calculate the number of unread messages it is better to use the read horizon API.
211
226
  * See {@link Conversation.getUnreadMessagesCount} for details.
212
227
  */
213
- get index() { return this.state.index; }
228
+ get index() {
229
+ return this.state.index;
230
+ }
214
231
  /**
215
232
  * Identity of the last user that updated the message.
216
233
  */
217
- get lastUpdatedBy() { return this.state.lastUpdatedBy; }
234
+ get lastUpdatedBy() {
235
+ return this.state.lastUpdatedBy;
236
+ }
218
237
  /**
219
238
  * Date this message was created on.
220
239
  */
221
- get dateCreated() { return this.state.timestamp; }
240
+ get dateCreated() {
241
+ return this.state.timestamp;
242
+ }
222
243
  /**
223
244
  * Custom attributes of the message.
224
245
  */
225
- get attributes() { return this.state.attributes; }
246
+ get attributes() {
247
+ return this.state.attributes;
248
+ }
226
249
  /**
227
- * Push notification type of the message.
250
+ * Type of the message.
228
251
  */
229
- get type() { return this.state.type; }
252
+ get type() {
253
+ return this.state.type;
254
+ }
230
255
  /**
231
- * One of the attached media.
256
+ * One of the attached media (if present).
232
257
  * @deprecated Use attachedMedia instead. Note that the latter is now an array.
233
258
  */
234
- get media() { return this.state.media; }
259
+ get media() {
260
+ return this.state.media;
261
+ }
235
262
  /**
236
263
  * Return all media attachments, except email body/history attachments, without temporary urls.
237
264
  */
238
- get attachedMedia() { return this.getMediaByCategory(['media']); }
265
+ get attachedMedia() {
266
+ return this.getMediaByCategory(["media"]);
267
+ }
239
268
  /**
240
269
  * The server-assigned unique identifier of the authoring participant.
241
270
  */
242
- get participantSid() { return this.state.participantSid; }
271
+ get participantSid() {
272
+ var _a;
273
+ return (_a = this.state.participantSid) !== null && _a !== void 0 ? _a : "";
274
+ }
243
275
  /**
244
276
  * Aggregated information about the message delivery statuses across all participants of a conversation..
245
277
  */
@@ -254,58 +286,83 @@ class Message extends replayEventEmitter.ReplayEventEmitter {
254
286
  */
255
287
  getMediaByCategory(categories) {
256
288
  var _a;
257
- return (_a = this.state.medias) === null || _a === void 0 ? void 0 : _a.filter((m) => categories.includes(m.category));
289
+ return ((_a = this.state.medias) !== null && _a !== void 0 ? _a : []).filter((m) => categories.includes(m.category));
290
+ }
291
+ /**
292
+ * Get a media descriptor for an email body attachment of a provided type.
293
+ * Allowed body types are returned in the Conversation.limits().emailBodiesAllowedMimeTypes array.
294
+ * @param type Type of email body to request, defaults to `text/plain`.
295
+ */
296
+ getEmailBody(type = "text/plain") {
297
+ var _a, _b;
298
+ return ((_b = (_a = this.getMediaByCategory(["body"])) === null || _a === void 0 ? void 0 : _a.filter((m) => m.contentType == type).shift()) !== null && _b !== void 0 ? _b : null);
299
+ }
300
+ /**
301
+ * Get a media descriptor for an email history attachment of a provided type.
302
+ * Allowed body types are returned in the Conversation.limits().emailHistoriesAllowedMimeTypes array.
303
+ * @param type Type of email history to request, defaults to `text/plain`.
304
+ */
305
+ getEmailHistory(type = "text/plain") {
306
+ var _a, _b;
307
+ return ((_b = (_a = this.getMediaByCategory(["history"])) === null || _a === void 0 ? void 0 : _a.filter((m) => m.contentType == type).shift()) !== null && _b !== void 0 ? _b : null);
258
308
  }
259
309
  _update(data) {
260
- let updateReasons = [];
261
- if ((data.text || ((typeof data.text) === 'string')) && data.text !== this.state.body) {
310
+ const updateReasons = [];
311
+ if ((data.text || typeof data.text === "string") &&
312
+ data.text !== this.state.body) {
262
313
  this.state.body = data.text;
263
- updateReasons.push('body');
314
+ updateReasons.push("body");
264
315
  }
265
316
  if (data.subject && data.subject !== this.state.subject) {
266
317
  this.state.subject = data.subject;
267
- updateReasons.push('subject');
318
+ updateReasons.push("subject");
268
319
  }
269
320
  if (data.lastUpdatedBy && data.lastUpdatedBy !== this.state.lastUpdatedBy) {
270
321
  this.state.lastUpdatedBy = data.lastUpdatedBy;
271
- updateReasons.push('lastUpdatedBy');
322
+ updateReasons.push("lastUpdatedBy");
272
323
  }
273
324
  if (data.author && data.author !== this.state.author) {
274
325
  this.state.author = data.author;
275
- updateReasons.push('author');
326
+ updateReasons.push("author");
276
327
  }
277
328
  if (data.dateUpdated &&
278
- new Date(data.dateUpdated).getTime() !== (this.state.dateUpdated && this.state.dateUpdated.getTime())) {
329
+ new Date(data.dateUpdated).getTime() !==
330
+ (this.state.dateUpdated && this.state.dateUpdated.getTime())) {
279
331
  this.state.dateUpdated = new Date(data.dateUpdated);
280
- updateReasons.push('dateUpdated');
332
+ updateReasons.push("dateUpdated");
281
333
  }
282
334
  if (data.timestamp &&
283
- new Date(data.timestamp).getTime() !== (this.state.timestamp && this.state.timestamp.getTime())) {
335
+ new Date(data.timestamp).getTime() !==
336
+ (this.state.timestamp && this.state.timestamp.getTime())) {
284
337
  this.state.timestamp = new Date(data.timestamp);
285
- updateReasons.push('dateCreated');
338
+ updateReasons.push("dateCreated");
286
339
  }
287
- let updatedAttributes = index.parseAttributes(data.attributes, `Got malformed attributes for the message ${this.sid}`, log);
340
+ const updatedAttributes = index.parseAttributes(data.attributes, `Got malformed attributes for the message ${this.sid}`, log);
288
341
  if (!isEqual__default['default'](this.state.attributes, updatedAttributes)) {
289
342
  this.state.attributes = updatedAttributes;
290
- updateReasons.push('attributes');
343
+ updateReasons.push("attributes");
291
344
  }
292
- let updatedAggregatedDelivery = data.delivery;
293
- let currentAggregatedDelivery = this.state.aggregatedDeliveryReceipt;
294
- let isUpdatedAggregateDeliveryValid = !!updatedAggregatedDelivery && !!updatedAggregatedDelivery.total &&
295
- !!updatedAggregatedDelivery.delivered && !!updatedAggregatedDelivery.failed && !!updatedAggregatedDelivery.read &&
296
- !!updatedAggregatedDelivery.sent && !!updatedAggregatedDelivery.undelivered;
345
+ const updatedAggregatedDelivery = data.delivery;
346
+ const currentAggregatedDelivery = this.state.aggregatedDeliveryReceipt;
347
+ const isUpdatedAggregateDeliveryValid = !!updatedAggregatedDelivery &&
348
+ !!updatedAggregatedDelivery.total &&
349
+ !!updatedAggregatedDelivery.delivered &&
350
+ !!updatedAggregatedDelivery.failed &&
351
+ !!updatedAggregatedDelivery.read &&
352
+ !!updatedAggregatedDelivery.sent &&
353
+ !!updatedAggregatedDelivery.undelivered;
297
354
  if (isUpdatedAggregateDeliveryValid) {
298
355
  if (!currentAggregatedDelivery) {
299
356
  this.state.aggregatedDeliveryReceipt = new aggregatedDeliveryReceipt.AggregatedDeliveryReceipt(updatedAggregatedDelivery);
300
- updateReasons.push('deliveryReceipt');
357
+ updateReasons.push("deliveryReceipt");
301
358
  }
302
359
  else if (!currentAggregatedDelivery._isEquals(updatedAggregatedDelivery)) {
303
360
  currentAggregatedDelivery._update(updatedAggregatedDelivery);
304
- updateReasons.push('deliveryReceipt');
361
+ updateReasons.push("deliveryReceipt");
305
362
  }
306
363
  }
307
364
  if (updateReasons.length > 0) {
308
- this.emit('updated', { message: this, updateReasons: updateReasons });
365
+ this.emit("updated", { message: this, updateReasons: updateReasons });
309
366
  }
310
367
  }
311
368
  /**
@@ -314,14 +371,16 @@ class Message extends replayEventEmitter.ReplayEventEmitter {
314
371
  async getParticipant() {
315
372
  let participant = null;
316
373
  if (this.state.participantSid) {
317
- participant = await this.conversation.getParticipantBySid(this.participantSid)
374
+ participant = await this.conversation
375
+ .getParticipantBySid(this.participantSid)
318
376
  .catch(() => {
319
377
  log.debug(`Participant with sid "${this.participantSid}" not found for message ${this.sid}`);
320
378
  return null;
321
379
  });
322
380
  }
323
381
  if (!participant && this.state.author) {
324
- participant = await this.conversation.getParticipantByIdentity(this.state.author)
382
+ participant = await this.conversation
383
+ .getParticipantByIdentity(this.state.author)
325
384
  .catch(() => {
326
385
  log.debug(`Participant with identity "${this.author}" not found for message ${this.sid}`);
327
386
  return null;
@@ -330,20 +389,20 @@ class Message extends replayEventEmitter.ReplayEventEmitter {
330
389
  if (participant) {
331
390
  return participant;
332
391
  }
333
- let errorMesage = 'Participant with ';
392
+ let errorMesage = "Participant with ";
334
393
  if (this.state.participantSid) {
335
- errorMesage += 'SID \'' + this.state.participantSid + '\' ';
394
+ errorMesage += "SID '" + this.state.participantSid + "' ";
336
395
  }
337
396
  if (this.state.author) {
338
397
  if (this.state.participantSid) {
339
- errorMesage += 'or ';
398
+ errorMesage += "or ";
340
399
  }
341
- errorMesage += 'identity \'' + this.state.author + '\' ';
400
+ errorMesage += "identity '" + this.state.author + "' ";
342
401
  }
343
- if (errorMesage === 'Participant with ') {
344
- errorMesage = 'Participant ';
402
+ if (errorMesage === "Participant with ") {
403
+ errorMesage = "Participant ";
345
404
  }
346
- errorMesage += 'was not found';
405
+ errorMesage += "was not found";
347
406
  throw new Error(errorMesage);
348
407
  }
349
408
  /**
@@ -353,7 +412,10 @@ class Message extends replayEventEmitter.ReplayEventEmitter {
353
412
  let paginator = await this._getDetailedDeliveryReceiptsPaginator();
354
413
  let detailedDeliveryReceipts = [];
355
414
  while (true) {
356
- detailedDeliveryReceipts = [...detailedDeliveryReceipts, ...paginator.items];
415
+ detailedDeliveryReceipts = [
416
+ ...detailedDeliveryReceipts,
417
+ ...paginator.items,
418
+ ];
357
419
  if (!paginator.hasNextPage) {
358
420
  break;
359
421
  }
@@ -365,7 +427,7 @@ class Message extends replayEventEmitter.ReplayEventEmitter {
365
427
  * Remove the message.
366
428
  */
367
429
  async remove() {
368
- await this.services.commandExecutor.mutateResource('delete', this.links.self);
430
+ await this.services.commandExecutor.mutateResource("delete", this.links.self);
369
431
  return this;
370
432
  }
371
433
  /**
@@ -373,8 +435,8 @@ class Message extends replayEventEmitter.ReplayEventEmitter {
373
435
  * @param body New body of the message.
374
436
  */
375
437
  async updateBody(body) {
376
- await this.services.commandExecutor.mutateResource('post', this.links.self, {
377
- body
438
+ await this.services.commandExecutor.mutateResource("post", this.links.self, {
439
+ body,
378
440
  });
379
441
  return this;
380
442
  }
@@ -383,8 +445,10 @@ class Message extends replayEventEmitter.ReplayEventEmitter {
383
445
  * @param attributes New attributes.
384
446
  */
385
447
  async updateAttributes(attributes) {
386
- await this.services.commandExecutor.mutateResource('post', this.links.self, {
387
- attributes: typeof attributes !== 'undefined' ? JSON.stringify(attributes) : undefined
448
+ await this.services.commandExecutor.mutateResource("post", this.links.self, {
449
+ attributes: typeof attributes !== "undefined"
450
+ ? JSON.stringify(attributes)
451
+ : undefined,
388
452
  });
389
453
  return this;
390
454
  }
@@ -395,21 +459,23 @@ class Message extends replayEventEmitter.ReplayEventEmitter {
395
459
  async attachTemporaryUrlsFor(contentSet) {
396
460
  // We ignore existing mcsMedia members of each of the media entries.
397
461
  // Instead we just collect their sids and pull new descriptors from a mediaSet GET endpoint.
398
- const sids = contentSet.map((m) => m.sid);
399
- if (this.services.mcsClient) {
400
- return (await this.services.mcsClient.mediaSetGet(sids)).map((item) => { return new media.Media(item, this.services); });
462
+ const sids = contentSet === null || contentSet === void 0 ? void 0 : contentSet.map((m) => m.sid);
463
+ if (this.services.mcsClient && sids) {
464
+ return (await this.services.mcsClient.mediaSetGet(sids)).map((item) => {
465
+ return new media.Media(item, this.services);
466
+ });
401
467
  }
402
468
  else {
403
- throw new Error('Media Content Service is unavailable');
469
+ throw new Error("Media Content Service is unavailable");
404
470
  }
405
471
  }
406
472
  async _getDetailedDeliveryReceiptsPaginator(options) {
407
473
  const messagesReceiptsUrl = this.configuration.links.messagesReceipts
408
- .replace('%s', this.conversation.sid)
409
- .replace('%s', this.sid);
474
+ .replace("%s", this.conversation.sid)
475
+ .replace("%s", this.sid);
410
476
  const url = new index.UriBuilder(messagesReceiptsUrl)
411
- .arg('PageToken', options === null || options === void 0 ? void 0 : options.pageToken)
412
- .arg('PageSize', options === null || options === void 0 ? void 0 : options.pageSize)
477
+ .arg("PageToken", options === null || options === void 0 ? void 0 : options.pageToken)
478
+ .arg("PageSize", options === null || options === void 0 ? void 0 : options.pageSize)
413
479
  .build();
414
480
  const response = await this.services.network.get(url);
415
481
  return new restPaginator.RestPaginator(response.body.delivery_receipts.map((x) => new detailedDeliveryReceipt.DetailedDeliveryReceipt(x)), (pageToken, pageSize) => this._getDetailedDeliveryReceiptsPaginator({ pageToken, pageSize }), response.body.meta.previous_token, response.body.meta.next_token);
@@ -423,23 +489,37 @@ class Message extends replayEventEmitter.ReplayEventEmitter {
423
489
  * * {@link Message} message - the message in question
424
490
  * * {@link MessageUpdateReason}[] updateReasons - array of reasons for the update
425
491
  */
426
- Message.updated = 'updated';
492
+ Message.updated = "updated";
493
+ tslib_es6.__decorate([
494
+ declarativeTypeValidator.validateTypes(declarativeTypeValidator.nonEmptyString),
495
+ tslib_es6.__metadata("design:type", Function),
496
+ tslib_es6.__metadata("design:paramtypes", [Object]),
497
+ tslib_es6.__metadata("design:returntype", media.Media)
498
+ ], Message.prototype, "getEmailBody", null);
499
+ tslib_es6.__decorate([
500
+ declarativeTypeValidator.validateTypes(declarativeTypeValidator.nonEmptyString),
501
+ tslib_es6.__metadata("design:type", Function),
502
+ tslib_es6.__metadata("design:paramtypes", [Object]),
503
+ tslib_es6.__metadata("design:returntype", media.Media)
504
+ ], Message.prototype, "getEmailHistory", null);
427
505
  tslib_es6.__decorate([
428
- declarativeTypeValidator.validateTypesAsync('string'),
506
+ declarativeTypeValidator.validateTypesAsync("string"),
429
507
  tslib_es6.__metadata("design:type", Function),
430
508
  tslib_es6.__metadata("design:paramtypes", [String]),
431
509
  tslib_es6.__metadata("design:returntype", Promise)
432
510
  ], Message.prototype, "updateBody", null);
433
511
  tslib_es6.__decorate([
434
- declarativeTypeValidator.validateTypesAsync(['string', 'number', 'boolean', 'object', declarativeTypeValidator.literal(null)]),
512
+ declarativeTypeValidator.validateTypesAsync(attributes.attributesValidator),
435
513
  tslib_es6.__metadata("design:type", Function),
436
514
  tslib_es6.__metadata("design:paramtypes", [Object]),
437
515
  tslib_es6.__metadata("design:returntype", Promise)
438
516
  ], Message.prototype, "updateAttributes", null);
439
517
  tslib_es6.__decorate([
440
- declarativeTypeValidator.validateTypesAsync(declarativeTypeValidator.custom(value => [
441
- value instanceof Array && value.length > 0 && value.reduce((a, c) => a && c instanceof media.Media),
442
- 'a non-empty array of Media'
518
+ declarativeTypeValidator.validateTypesAsync(declarativeTypeValidator.custom((value) => [
519
+ value instanceof Array &&
520
+ value.length > 0 &&
521
+ value.reduce((a, c) => a && c instanceof media.Media, true),
522
+ "a non-empty array of Media",
443
523
  ])),
444
524
  tslib_es6.__metadata("design:type", Function),
445
525
  tslib_es6.__metadata("design:paramtypes", [Array]),