@twilio/conversations 2.0.1 → 2.1.0-rc.6

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 (86) hide show
  1. package/CHANGELOG.md +74 -0
  2. package/NOTICE.txt +679 -0
  3. package/builds/browser.js +889 -619
  4. package/builds/browser.js.map +1 -1
  5. package/builds/lib.d.ts +384 -129
  6. package/builds/lib.js +889 -619
  7. package/builds/lib.js.map +1 -1
  8. package/builds/twilio-conversations.js +1065 -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/interfaces/attributes.js +147 -0
  31. package/dist/interfaces/attributes.js.map +1 -0
  32. package/dist/interfaces/notification-types.js +5 -5
  33. package/dist/interfaces/notification-types.js.map +1 -1
  34. package/dist/logger.js +36 -15
  35. package/dist/logger.js.map +1 -1
  36. package/dist/media.js +21 -9
  37. package/dist/media.js.map +1 -1
  38. package/dist/message-builder.js +56 -3
  39. package/dist/message-builder.js.map +1 -1
  40. package/dist/message.js +157 -78
  41. package/dist/message.js.map +1 -1
  42. package/dist/packages/conversations/package.json.js +1 -1
  43. package/dist/participant.js +101 -50
  44. package/dist/participant.js.map +1 -1
  45. package/dist/push-notification.js.map +1 -1
  46. package/dist/rest-paginator.js +16 -6
  47. package/dist/rest-paginator.js.map +1 -1
  48. package/dist/services/network.js +18 -14
  49. package/dist/services/network.js.map +1 -1
  50. package/dist/services/typing-indicator.js +20 -17
  51. package/dist/services/typing-indicator.js.map +1 -1
  52. package/dist/unsent-message.js.map +1 -1
  53. package/dist/user.js +87 -60
  54. package/dist/user.js.map +1 -1
  55. package/dist/util/deferred.js +3 -1
  56. package/dist/util/deferred.js.map +1 -1
  57. package/dist/util/index.js +6 -6
  58. package/dist/util/index.js.map +1 -1
  59. package/docs/assets/js/search.js +1 -1
  60. package/docs/classes/AggregatedDeliveryReceipt.html +0 -102
  61. package/docs/classes/Client.html +24 -132
  62. package/docs/classes/Conversation.html +37 -132
  63. package/docs/classes/DetailedDeliveryReceipt.html +1 -103
  64. package/docs/classes/Media.html +0 -102
  65. package/docs/classes/Message.html +73 -109
  66. package/docs/classes/MessageBuilder.html +78 -104
  67. package/docs/classes/Participant.html +37 -110
  68. package/docs/classes/PushNotification.html +0 -102
  69. package/docs/classes/RestPaginator.html +0 -102
  70. package/docs/classes/UnsentMessage.html +0 -102
  71. package/docs/classes/User.html +7 -109
  72. package/docs/index.html +93 -3
  73. package/docs/interfaces/ClientOptions.html +0 -102
  74. package/docs/interfaces/ConversationBindings.html +3001 -0
  75. package/docs/interfaces/ConversationEmailBinding.html +3001 -0
  76. package/docs/interfaces/ConversationState.html +0 -102
  77. package/docs/interfaces/CreateConversationOptions.html +1 -103
  78. package/docs/interfaces/LastMessage.html +0 -102
  79. package/docs/interfaces/Paginator.html +0 -102
  80. package/docs/interfaces/ParticipantBindings.html +3001 -0
  81. package/docs/interfaces/ParticipantEmailBinding.html +3001 -0
  82. package/docs/interfaces/PushNotificationData.html +0 -102
  83. package/docs/interfaces/SendEmailOptions.html +0 -102
  84. package/docs/interfaces/SendMediaOptions.html +0 -102
  85. package/docs/modules.html +93 -3
  86. package/package.json +23 -17
@@ -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 { ConversationLimits } from \"./interfaces/conversation-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(\n private readonly limits: ConversationLimits,\n messagesEntity: Messages\n ) {\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,52 @@ 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
+ return this.state.participantSid;
273
+ }
243
274
  /**
244
275
  * Aggregated information about the message delivery statuses across all participants of a conversation..
245
276
  */
@@ -254,58 +285,83 @@ class Message extends replayEventEmitter.ReplayEventEmitter {
254
285
  */
255
286
  getMediaByCategory(categories) {
256
287
  var _a;
257
- return (_a = this.state.medias) === null || _a === void 0 ? void 0 : _a.filter((m) => categories.includes(m.category));
288
+ return ((_a = this.state.medias) !== null && _a !== void 0 ? _a : []).filter((m) => categories.includes(m.category));
289
+ }
290
+ /**
291
+ * Get a media descriptor for an email body attachment of a provided type.
292
+ * Allowed body types are returned in the Conversation.limits().emailBodiesAllowedMimeTypes array.
293
+ * @param type Type of email body to request, defaults to `text/plain`.
294
+ */
295
+ getEmailBody(type = "text/plain") {
296
+ var _a, _b;
297
+ 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);
298
+ }
299
+ /**
300
+ * Get a media descriptor for an email history attachment of a provided type.
301
+ * Allowed body types are returned in the Conversation.limits().emailHistoriesAllowedMimeTypes array.
302
+ * @param type Type of email history to request, defaults to `text/plain`.
303
+ */
304
+ getEmailHistory(type = "text/plain") {
305
+ var _a, _b;
306
+ 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
307
  }
259
308
  _update(data) {
260
- let updateReasons = [];
261
- if ((data.text || ((typeof data.text) === 'string')) && data.text !== this.state.body) {
309
+ const updateReasons = [];
310
+ if ((data.text || typeof data.text === "string") &&
311
+ data.text !== this.state.body) {
262
312
  this.state.body = data.text;
263
- updateReasons.push('body');
313
+ updateReasons.push("body");
264
314
  }
265
315
  if (data.subject && data.subject !== this.state.subject) {
266
316
  this.state.subject = data.subject;
267
- updateReasons.push('subject');
317
+ updateReasons.push("subject");
268
318
  }
269
319
  if (data.lastUpdatedBy && data.lastUpdatedBy !== this.state.lastUpdatedBy) {
270
320
  this.state.lastUpdatedBy = data.lastUpdatedBy;
271
- updateReasons.push('lastUpdatedBy');
321
+ updateReasons.push("lastUpdatedBy");
272
322
  }
273
323
  if (data.author && data.author !== this.state.author) {
274
324
  this.state.author = data.author;
275
- updateReasons.push('author');
325
+ updateReasons.push("author");
276
326
  }
277
327
  if (data.dateUpdated &&
278
- new Date(data.dateUpdated).getTime() !== (this.state.dateUpdated && this.state.dateUpdated.getTime())) {
328
+ new Date(data.dateUpdated).getTime() !==
329
+ (this.state.dateUpdated && this.state.dateUpdated.getTime())) {
279
330
  this.state.dateUpdated = new Date(data.dateUpdated);
280
- updateReasons.push('dateUpdated');
331
+ updateReasons.push("dateUpdated");
281
332
  }
282
333
  if (data.timestamp &&
283
- new Date(data.timestamp).getTime() !== (this.state.timestamp && this.state.timestamp.getTime())) {
334
+ new Date(data.timestamp).getTime() !==
335
+ (this.state.timestamp && this.state.timestamp.getTime())) {
284
336
  this.state.timestamp = new Date(data.timestamp);
285
- updateReasons.push('dateCreated');
337
+ updateReasons.push("dateCreated");
286
338
  }
287
- let updatedAttributes = index.parseAttributes(data.attributes, `Got malformed attributes for the message ${this.sid}`, log);
339
+ const updatedAttributes = index.parseAttributes(data.attributes, `Got malformed attributes for the message ${this.sid}`, log);
288
340
  if (!isEqual__default['default'](this.state.attributes, updatedAttributes)) {
289
341
  this.state.attributes = updatedAttributes;
290
- updateReasons.push('attributes');
342
+ updateReasons.push("attributes");
291
343
  }
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;
344
+ const updatedAggregatedDelivery = data.delivery;
345
+ const currentAggregatedDelivery = this.state.aggregatedDeliveryReceipt;
346
+ const isUpdatedAggregateDeliveryValid = !!updatedAggregatedDelivery &&
347
+ !!updatedAggregatedDelivery.total &&
348
+ !!updatedAggregatedDelivery.delivered &&
349
+ !!updatedAggregatedDelivery.failed &&
350
+ !!updatedAggregatedDelivery.read &&
351
+ !!updatedAggregatedDelivery.sent &&
352
+ !!updatedAggregatedDelivery.undelivered;
297
353
  if (isUpdatedAggregateDeliveryValid) {
298
354
  if (!currentAggregatedDelivery) {
299
355
  this.state.aggregatedDeliveryReceipt = new aggregatedDeliveryReceipt.AggregatedDeliveryReceipt(updatedAggregatedDelivery);
300
- updateReasons.push('deliveryReceipt');
356
+ updateReasons.push("deliveryReceipt");
301
357
  }
302
358
  else if (!currentAggregatedDelivery._isEquals(updatedAggregatedDelivery)) {
303
359
  currentAggregatedDelivery._update(updatedAggregatedDelivery);
304
- updateReasons.push('deliveryReceipt');
360
+ updateReasons.push("deliveryReceipt");
305
361
  }
306
362
  }
307
363
  if (updateReasons.length > 0) {
308
- this.emit('updated', { message: this, updateReasons: updateReasons });
364
+ this.emit("updated", { message: this, updateReasons: updateReasons });
309
365
  }
310
366
  }
311
367
  /**
@@ -314,14 +370,16 @@ class Message extends replayEventEmitter.ReplayEventEmitter {
314
370
  async getParticipant() {
315
371
  let participant = null;
316
372
  if (this.state.participantSid) {
317
- participant = await this.conversation.getParticipantBySid(this.participantSid)
373
+ participant = await this.conversation
374
+ .getParticipantBySid(this.state.participantSid)
318
375
  .catch(() => {
319
376
  log.debug(`Participant with sid "${this.participantSid}" not found for message ${this.sid}`);
320
377
  return null;
321
378
  });
322
379
  }
323
380
  if (!participant && this.state.author) {
324
- participant = await this.conversation.getParticipantByIdentity(this.state.author)
381
+ participant = await this.conversation
382
+ .getParticipantByIdentity(this.state.author)
325
383
  .catch(() => {
326
384
  log.debug(`Participant with identity "${this.author}" not found for message ${this.sid}`);
327
385
  return null;
@@ -330,20 +388,20 @@ class Message extends replayEventEmitter.ReplayEventEmitter {
330
388
  if (participant) {
331
389
  return participant;
332
390
  }
333
- let errorMesage = 'Participant with ';
391
+ let errorMesage = "Participant with ";
334
392
  if (this.state.participantSid) {
335
- errorMesage += 'SID \'' + this.state.participantSid + '\' ';
393
+ errorMesage += "SID '" + this.state.participantSid + "' ";
336
394
  }
337
395
  if (this.state.author) {
338
396
  if (this.state.participantSid) {
339
- errorMesage += 'or ';
397
+ errorMesage += "or ";
340
398
  }
341
- errorMesage += 'identity \'' + this.state.author + '\' ';
399
+ errorMesage += "identity '" + this.state.author + "' ";
342
400
  }
343
- if (errorMesage === 'Participant with ') {
344
- errorMesage = 'Participant ';
401
+ if (errorMesage === "Participant with ") {
402
+ errorMesage = "Participant ";
345
403
  }
346
- errorMesage += 'was not found';
404
+ errorMesage += "was not found";
347
405
  throw new Error(errorMesage);
348
406
  }
349
407
  /**
@@ -353,7 +411,10 @@ class Message extends replayEventEmitter.ReplayEventEmitter {
353
411
  let paginator = await this._getDetailedDeliveryReceiptsPaginator();
354
412
  let detailedDeliveryReceipts = [];
355
413
  while (true) {
356
- detailedDeliveryReceipts = [...detailedDeliveryReceipts, ...paginator.items];
414
+ detailedDeliveryReceipts = [
415
+ ...detailedDeliveryReceipts,
416
+ ...paginator.items,
417
+ ];
357
418
  if (!paginator.hasNextPage) {
358
419
  break;
359
420
  }
@@ -365,7 +426,7 @@ class Message extends replayEventEmitter.ReplayEventEmitter {
365
426
  * Remove the message.
366
427
  */
367
428
  async remove() {
368
- await this.services.commandExecutor.mutateResource('delete', this.links.self);
429
+ await this.services.commandExecutor.mutateResource("delete", this.links.self);
369
430
  return this;
370
431
  }
371
432
  /**
@@ -373,8 +434,8 @@ class Message extends replayEventEmitter.ReplayEventEmitter {
373
434
  * @param body New body of the message.
374
435
  */
375
436
  async updateBody(body) {
376
- await this.services.commandExecutor.mutateResource('post', this.links.self, {
377
- body
437
+ await this.services.commandExecutor.mutateResource("post", this.links.self, {
438
+ body,
378
439
  });
379
440
  return this;
380
441
  }
@@ -383,8 +444,10 @@ class Message extends replayEventEmitter.ReplayEventEmitter {
383
444
  * @param attributes New attributes.
384
445
  */
385
446
  async updateAttributes(attributes) {
386
- await this.services.commandExecutor.mutateResource('post', this.links.self, {
387
- attributes: typeof attributes !== 'undefined' ? JSON.stringify(attributes) : undefined
447
+ await this.services.commandExecutor.mutateResource("post", this.links.self, {
448
+ attributes: typeof attributes !== "undefined"
449
+ ? JSON.stringify(attributes)
450
+ : undefined,
388
451
  });
389
452
  return this;
390
453
  }
@@ -395,21 +458,23 @@ class Message extends replayEventEmitter.ReplayEventEmitter {
395
458
  async attachTemporaryUrlsFor(contentSet) {
396
459
  // We ignore existing mcsMedia members of each of the media entries.
397
460
  // 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); });
461
+ const sids = contentSet === null || contentSet === void 0 ? void 0 : contentSet.map((m) => m.sid);
462
+ if (this.services.mcsClient && sids) {
463
+ return (await this.services.mcsClient.mediaSetGet(sids)).map((item) => {
464
+ return new media.Media(item, this.services);
465
+ });
401
466
  }
402
467
  else {
403
- throw new Error('Media Content Service is unavailable');
468
+ throw new Error("Media Content Service is unavailable");
404
469
  }
405
470
  }
406
471
  async _getDetailedDeliveryReceiptsPaginator(options) {
407
472
  const messagesReceiptsUrl = this.configuration.links.messagesReceipts
408
- .replace('%s', this.conversation.sid)
409
- .replace('%s', this.sid);
473
+ .replace("%s", this.conversation.sid)
474
+ .replace("%s", this.sid);
410
475
  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)
476
+ .arg("PageToken", options === null || options === void 0 ? void 0 : options.pageToken)
477
+ .arg("PageSize", options === null || options === void 0 ? void 0 : options.pageSize)
413
478
  .build();
414
479
  const response = await this.services.network.get(url);
415
480
  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 +488,37 @@ class Message extends replayEventEmitter.ReplayEventEmitter {
423
488
  * * {@link Message} message - the message in question
424
489
  * * {@link MessageUpdateReason}[] updateReasons - array of reasons for the update
425
490
  */
426
- Message.updated = 'updated';
491
+ Message.updated = "updated";
492
+ tslib_es6.__decorate([
493
+ declarativeTypeValidator.validateTypes(declarativeTypeValidator.nonEmptyString),
494
+ tslib_es6.__metadata("design:type", Function),
495
+ tslib_es6.__metadata("design:paramtypes", [Object]),
496
+ tslib_es6.__metadata("design:returntype", media.Media)
497
+ ], Message.prototype, "getEmailBody", null);
498
+ tslib_es6.__decorate([
499
+ declarativeTypeValidator.validateTypes(declarativeTypeValidator.nonEmptyString),
500
+ tslib_es6.__metadata("design:type", Function),
501
+ tslib_es6.__metadata("design:paramtypes", [Object]),
502
+ tslib_es6.__metadata("design:returntype", media.Media)
503
+ ], Message.prototype, "getEmailHistory", null);
427
504
  tslib_es6.__decorate([
428
- declarativeTypeValidator.validateTypesAsync('string'),
505
+ declarativeTypeValidator.validateTypesAsync("string"),
429
506
  tslib_es6.__metadata("design:type", Function),
430
507
  tslib_es6.__metadata("design:paramtypes", [String]),
431
508
  tslib_es6.__metadata("design:returntype", Promise)
432
509
  ], Message.prototype, "updateBody", null);
433
510
  tslib_es6.__decorate([
434
- declarativeTypeValidator.validateTypesAsync(['string', 'number', 'boolean', 'object', declarativeTypeValidator.literal(null)]),
511
+ declarativeTypeValidator.validateTypesAsync(attributes.attributesValidator),
435
512
  tslib_es6.__metadata("design:type", Function),
436
513
  tslib_es6.__metadata("design:paramtypes", [Object]),
437
514
  tslib_es6.__metadata("design:returntype", Promise)
438
515
  ], Message.prototype, "updateAttributes", null);
439
516
  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'
517
+ declarativeTypeValidator.validateTypesAsync(declarativeTypeValidator.custom((value) => [
518
+ value instanceof Array &&
519
+ value.length > 0 &&
520
+ value.reduce((a, c) => a && c instanceof media.Media, true),
521
+ "a non-empty array of Media",
443
522
  ])),
444
523
  tslib_es6.__metadata("design:type", Function),
445
524
  tslib_es6.__metadata("design:paramtypes", [Array]),