@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
@@ -141,10 +141,10 @@ class Network {
141
141
  this.cleanupCache();
142
142
  }
143
143
  isExpired(timestamp) {
144
- return !this.cacheLifetime || (Date.now() - timestamp) > this.cacheLifetime;
144
+ return !this.cacheLifetime || Date.now() - timestamp > this.cacheLifetime;
145
145
  }
146
146
  cleanupCache() {
147
- for (let [k, v] of this.cache) {
147
+ for (const [k, v] of this.cache) {
148
148
  if (this.isExpired(v.timestamp)) {
149
149
  this.cache.delete(k);
150
150
  }
@@ -154,23 +154,25 @@ class Network {
154
154
  }
155
155
  }
156
156
  pokeTimer() {
157
- this.timer = this.timer || setInterval(() => this.cleanupCache(), this.cacheLifetime * 2);
157
+ this.timer =
158
+ this.timer ||
159
+ setInterval(() => this.cleanupCache(), this.cacheLifetime * 2);
158
160
  }
159
161
  executeWithRetry(request, retryWhenThrottled = false) {
160
162
  return new Promise((resolve, reject) => {
161
- let codesToRetryOn = [502, 503, 504];
163
+ const codesToRetryOn = [502, 503, 504];
162
164
  if (retryWhenThrottled) {
163
165
  codesToRetryOn.push(429);
164
166
  }
165
- let retrier = new operationRetrier.Retrier(this.configuration.backoffConfiguration);
166
- retrier.on('attempt', () => {
167
+ const retrier = new operationRetrier.Retrier(this.configuration.backoffConfiguration);
168
+ retrier.on("attempt", () => {
167
169
  request()
168
- .then(result => retrier.succeeded(result))
169
- .catch(err => {
170
+ .then((result) => retrier.succeeded(result))
171
+ .catch((err) => {
170
172
  if (codesToRetryOn.indexOf(err.status) > -1) {
171
173
  retrier.failed(err);
172
174
  }
173
- else if (err.message === 'Twilsock disconnected') {
175
+ else if (err.message === "Twilsock disconnected") {
174
176
  // Ugly hack. We must make a proper exceptions for twilsock
175
177
  retrier.failed(err);
176
178
  }
@@ -182,19 +184,21 @@ class Network {
182
184
  }
183
185
  });
184
186
  });
185
- retrier.on('succeeded', result => { resolve(result); });
186
- retrier.on('cancelled', err => reject(err));
187
- retrier.on('failed', err => reject(err));
187
+ retrier.on("succeeded", (result) => {
188
+ resolve(result);
189
+ });
190
+ retrier.on("cancelled", (err) => reject(err));
191
+ retrier.on("failed", (err) => reject(err));
188
192
  retrier.start();
189
193
  });
190
194
  }
191
195
  async get(url) {
192
- let cacheEntry = this.cache.get(url);
196
+ const cacheEntry = this.cache.get(url);
193
197
  if (cacheEntry && !this.isExpired(cacheEntry.timestamp)) {
194
198
  return cacheEntry.response;
195
199
  }
196
200
  const headers = {};
197
- let response = await this.executeWithRetry(() => this.services.transport.get(url, headers, this.configuration.productId), this.configuration.retryWhenThrottled);
201
+ const response = await this.executeWithRetry(() => this.services.transport.get(url, headers, this.configuration.productId), this.configuration.retryWhenThrottled);
198
202
  this.cache.set(url, { response, timestamp: Date.now() });
199
203
  this.pokeTimer();
200
204
  return response;
@@ -1 +1 @@
1
- {"version":3,"file":"network.js","sources":["../../src/services/network.ts"],"sourcesContent":["import { Retrier } from '@twilio/operation-retrier';\nimport { Transport } from 'twilsock';\nimport { Configuration } from '../configuration';\n\ninterface CacheEntry {\n response: Object;\n timestamp: number;\n}\n\nexport interface NetworkServices {\n transport: Transport;\n}\n\nclass Network {\n private readonly configuration: Configuration;\n private readonly services: NetworkServices;\n private cacheLifetime: number;\n\n private readonly cache: Map<string, CacheEntry>;\n private timer: any;\n\n constructor(configuration, services) {\n this.configuration = configuration;\n this.services = services;\n this.cache = new Map<string, CacheEntry>();\n this.cacheLifetime = this.configuration.httpCacheInterval * 100;\n this.cleanupCache();\n }\n\n private isExpired(timestamp: number): boolean {\n return !this.cacheLifetime || (Date.now() - timestamp) > this.cacheLifetime;\n }\n\n private cleanupCache() {\n for (let [k, v] of this.cache) {\n if (this.isExpired(v.timestamp)) {\n this.cache.delete(k);\n }\n }\n\n if (this.cache.size === 0) {\n clearInterval(this.timer);\n }\n }\n\n pokeTimer() {\n this.timer = this.timer || setInterval(() => this.cleanupCache(), this.cacheLifetime * 2);\n }\n\n private executeWithRetry(request, retryWhenThrottled = false): Promise<any> {\n return new Promise((resolve, reject) => {\n let codesToRetryOn = [502, 503, 504];\n if (retryWhenThrottled) {\n codesToRetryOn.push(429);\n }\n\n let retrier = new Retrier(this.configuration.backoffConfiguration);\n retrier.on('attempt', () => {\n request()\n .then(result => retrier.succeeded(result))\n .catch(err => {\n if (codesToRetryOn.indexOf(err.status) > -1) {\n retrier.failed(err);\n } else if (err.message === 'Twilsock disconnected') {\n // Ugly hack. We must make a proper exceptions for twilsock\n retrier.failed(err);\n } else {\n // Fatal error\n retrier.removeAllListeners();\n retrier.cancel();\n reject(err);\n }\n });\n });\n\n retrier.on('succeeded', result => { resolve(result); });\n retrier.on('cancelled', err => reject(err));\n retrier.on('failed', err => reject(err));\n\n retrier.start();\n });\n }\n\n async get(url: string) {\n let cacheEntry = this.cache.get(url);\n if (cacheEntry && !this.isExpired(cacheEntry.timestamp)) {\n return cacheEntry.response;\n }\n\n const headers = {};\n let response = await this.executeWithRetry(\n () => this.services.transport.get(\n url,\n headers,\n this.configuration.productId\n ),\n this.configuration.retryWhenThrottled\n );\n this.cache.set(url, { response, timestamp: Date.now() });\n this.pokeTimer();\n return response;\n }\n}\n\nexport { Network };\n"],"names":["Retrier"],"mappings":"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"}
1
+ {"version":3,"file":"network.js","sources":["../../src/services/network.ts"],"sourcesContent":["import { Retrier } from \"@twilio/operation-retrier\";\nimport { Transport, TransportResult } from \"twilsock\";\nimport { Configuration } from \"../configuration\";\n\nimport Timeout = NodeJS.Timeout;\n\ninterface CacheEntry {\n response: TransportResult<unknown>;\n timestamp: number;\n}\n\nexport interface NetworkServices {\n transport: Transport;\n}\n\nclass Network {\n private readonly configuration: Configuration;\n private readonly services: NetworkServices;\n private cacheLifetime: number;\n\n private readonly cache: Map<string, CacheEntry>;\n private timer!: number | NodeJS.Timeout;\n\n constructor(configuration, services) {\n this.configuration = configuration;\n this.services = services;\n this.cache = new Map<string, CacheEntry>();\n this.cacheLifetime = this.configuration.httpCacheInterval * 100;\n this.cleanupCache();\n }\n\n private isExpired(timestamp: number): boolean {\n return !this.cacheLifetime || Date.now() - timestamp > this.cacheLifetime;\n }\n\n private cleanupCache() {\n for (const [k, v] of this.cache) {\n if (this.isExpired(v.timestamp)) {\n this.cache.delete(k);\n }\n }\n\n if (this.cache.size === 0) {\n clearInterval(this.timer as Timeout);\n }\n }\n\n pokeTimer() {\n this.timer =\n this.timer ||\n setInterval(() => this.cleanupCache(), this.cacheLifetime * 2);\n }\n\n private executeWithRetry<T>(\n request,\n retryWhenThrottled = false\n ): Promise<TransportResult<T>> {\n return new Promise((resolve, reject) => {\n const codesToRetryOn = [502, 503, 504];\n if (retryWhenThrottled) {\n codesToRetryOn.push(429);\n }\n\n const retrier = new Retrier(this.configuration.backoffConfiguration);\n retrier.on(\"attempt\", () => {\n request()\n .then((result) => retrier.succeeded(result))\n .catch((err) => {\n if (codesToRetryOn.indexOf(err.status) > -1) {\n retrier.failed(err);\n } else if (err.message === \"Twilsock disconnected\") {\n // Ugly hack. We must make a proper exceptions for twilsock\n retrier.failed(err);\n } else {\n // Fatal error\n retrier.removeAllListeners();\n retrier.cancel();\n reject(err);\n }\n });\n });\n\n retrier.on(\"succeeded\", (result) => {\n resolve(result);\n });\n retrier.on(\"cancelled\", (err) => reject(err));\n retrier.on(\"failed\", (err) => reject(err));\n\n retrier.start();\n });\n }\n\n async get<T>(url: string): Promise<TransportResult<T>> {\n const cacheEntry = this.cache.get(url);\n if (cacheEntry && !this.isExpired(cacheEntry.timestamp)) {\n return cacheEntry.response as TransportResult<T>;\n }\n\n const headers = {};\n const response = await this.executeWithRetry<T>(\n () =>\n this.services.transport.get<T>(\n url,\n headers,\n this.configuration.productId\n ),\n this.configuration.retryWhenThrottled\n );\n this.cache.set(url, { response, timestamp: Date.now() });\n this.pokeTimer();\n return response;\n }\n}\n\nexport { Network };\n"],"names":["Retrier"],"mappings":"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"}
@@ -133,7 +133,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
133
133
  var logger = require('../logger.js');
134
134
  var notificationTypes = require('../interfaces/notification-types.js');
135
135
 
136
- const log = logger.Logger.scope('TypingIndicator');
136
+ const log = logger.Logger.scope("TypingIndicator");
137
137
  /**
138
138
  * An important note in regards to typing timeout timers. There are two places that the SDK can get the "typing_timeout" attribute from. The first
139
139
  * place that the attribute appears in is the response received from POST -> /v1/typing REST call. In the body of that response, the value of the
@@ -159,9 +159,9 @@ class TypingIndicator {
159
159
  this.sentUpdates = new Map();
160
160
  }
161
161
  get typingTimeout() {
162
- return this.configuration.typingIndicatorTimeoutOverride
163
- || this.serviceTypingTimeout
164
- || this.configuration.typingIndicatorTimeoutDefault;
162
+ return (this.configuration.typingIndicatorTimeoutOverride ||
163
+ this.serviceTypingTimeout ||
164
+ this.configuration.typingIndicatorTimeoutDefault);
165
165
  }
166
166
  /**
167
167
  * Initialize TypingIndicator controller
@@ -170,7 +170,7 @@ class TypingIndicator {
170
170
  */
171
171
  initialize() {
172
172
  // this.services.notificationClient.subscribe(NotificationTypes.TYPING_INDICATOR, 'twilsock');
173
- this.services.notificationClient.on('message', async (type, message) => {
173
+ this.services.notificationClient.on("message", async (type, message) => {
174
174
  if (type === notificationTypes.NotificationTypes.TYPING_INDICATOR) {
175
175
  await this._handleRemoteTyping(message);
176
176
  }
@@ -180,21 +180,23 @@ class TypingIndicator {
180
180
  * Remote participants typing events handler
181
181
  */
182
182
  async _handleRemoteTyping(message) {
183
- log.trace('Got new typing indicator ', message);
183
+ log.trace("Got new typing indicator ", message);
184
184
  this.getConversation(message.channel_sid)
185
- .then(conversation => {
185
+ .then((conversation) => {
186
186
  if (!conversation) {
187
187
  return;
188
188
  }
189
- conversation.participants.forEach(participant => {
189
+ conversation.participants.forEach((participant) => {
190
190
  if (participant.identity !== message.identity) {
191
191
  return;
192
192
  }
193
- const timeout = this.configuration.typingIndicatorTimeoutOverride + 1000 || message.typing_timeout * 1000;
193
+ const timeout = this.configuration.typingIndicatorTimeoutOverride
194
+ ? this.configuration.typingIndicatorTimeoutOverride + 1000
195
+ : message.typing_timeout * 1000;
194
196
  participant._startTyping(timeout);
195
197
  });
196
198
  })
197
- .catch(err => {
199
+ .catch((err) => {
198
200
  log.error(err);
199
201
  throw err;
200
202
  });
@@ -205,29 +207,30 @@ class TypingIndicator {
205
207
  */
206
208
  send(conversationSid) {
207
209
  const lastUpdate = this.sentUpdates.get(conversationSid);
208
- if (lastUpdate && lastUpdate > (Date.now() - this.typingTimeout)) {
210
+ if (lastUpdate && lastUpdate > Date.now() - this.typingTimeout) {
209
211
  return Promise.resolve();
210
212
  }
211
213
  this.sentUpdates.set(conversationSid, Date.now());
212
214
  return this._send(conversationSid);
213
215
  }
214
216
  _send(conversationSid) {
215
- log.trace('Sending typing indicator');
217
+ log.trace("Sending typing indicator");
216
218
  const url = this.configuration.links.typing;
217
219
  const headers = {
218
- 'Content-Type': 'application/x-www-form-urlencoded'
220
+ "Content-Type": "application/x-www-form-urlencoded",
219
221
  };
220
222
  const body = `ChannelSid=${conversationSid}`;
221
- return (this.services.twilsockClient.post(url, headers, body, this.configuration.productId)
223
+ return this.services.twilsockClient
224
+ .post(url, headers, body, this.configuration.productId)
222
225
  .then((response) => {
223
- if (response.body.hasOwnProperty('typing_timeout')) {
226
+ if (response.body.hasOwnProperty("typing_timeout")) {
224
227
  this.serviceTypingTimeout = response.body.typing_timeout * 1000;
225
228
  }
226
229
  })
227
230
  .catch((err) => {
228
- log.error('Failed to send typing indicator:', err);
231
+ log.error("Failed to send typing indicator:", err);
229
232
  throw err;
230
- }));
233
+ });
231
234
  }
232
235
  }
233
236
 
@@ -1 +1 @@
1
- {"version":3,"file":"typing-indicator.js","sources":["../../src/services/typing-indicator.ts"],"sourcesContent":["import { Logger } from '../logger';\n\nimport { Notifications } from '@twilio/notifications';\n\nimport { NotificationTypes } from '../interfaces/notification-types';\nimport { TwilsockClient } from 'twilsock';\nimport { Configuration } from '../configuration';\n\nconst log = Logger.scope('TypingIndicator');\n\nexport interface TypingIndicatorServices {\n twilsockClient: TwilsockClient;\n notificationClient: Notifications;\n}\n\n/**\n * An important note in regards to typing timeout timers. There are two places that the SDK can get the \"typing_timeout\" attribute from. The first\n * place that the attribute appears in is the response received from POST -> /v1/typing REST call. In the body of that response, the value of the\n * \"typing_timeout\" attribute will be exactly the same as defined in the console. The second place that the attribute appears in is from a\n * notification of type \"twilio.ipmsg.typing_indicator\". In this case, the \"typing_timeout\" value will be +1 of that in the console. This\n * intentional. The timeout returned from the POST -> /v1/typing call should be used to disable further calls for that period of time. On contrary,\n * the timeout returned from the notification should be used as the timeout for the \"typingEnded\" event, +1 is to account for latency.\n *\n * @private\n */\n\n/**\n * @class TypingIndicator\n *\n * @constructor\n * @private\n */\nclass TypingIndicator {\n private readonly services: TypingIndicatorServices;\n private readonly configuration: Configuration;\n\n private sentUpdates: Map<string, number>;\n private getConversation;\n private serviceTypingTimeout;\n\n constructor(getConversation, config: Configuration, services: TypingIndicatorServices) {\n this.configuration = config;\n this.services = services;\n this.getConversation = getConversation;\n\n this.serviceTypingTimeout = null;\n this.sentUpdates = new Map();\n }\n\n public get typingTimeout(): number {\n return this.configuration.typingIndicatorTimeoutOverride\n || this.serviceTypingTimeout\n || this.configuration.typingIndicatorTimeoutDefault;\n }\n\n /**\n * Initialize TypingIndicator controller\n * Registers for needed message types and sets listeners\n * @private\n */\n initialize(): void {\n // this.services.notificationClient.subscribe(NotificationTypes.TYPING_INDICATOR, 'twilsock');\n this.services.notificationClient.on('message', async (type, message) => {\n if (type === NotificationTypes.TYPING_INDICATOR) {\n await this._handleRemoteTyping(message);\n }\n });\n }\n\n /**\n * Remote participants typing events handler\n */\n private async _handleRemoteTyping(message) {\n log.trace('Got new typing indicator ', message);\n\n this.getConversation(message.channel_sid)\n .then(conversation => {\n if (!conversation) {\n return;\n }\n\n conversation.participants.forEach(participant => {\n if (participant.identity !== message.identity) {\n return;\n }\n\n const timeout = this.configuration.typingIndicatorTimeoutOverride + 1000 || message.typing_timeout * 1000;\n participant._startTyping(timeout);\n });\n })\n .catch(err => {\n log.error(err);\n throw err;\n });\n }\n\n /**\n * Send typing event for the given conversation sid\n * @param {String} conversationSid\n */\n send(conversationSid: string) {\n const lastUpdate = this.sentUpdates.get(conversationSid);\n if (lastUpdate && lastUpdate > (Date.now() - this.typingTimeout)) {\n return Promise.resolve();\n }\n\n this.sentUpdates.set(conversationSid, Date.now());\n return this._send(conversationSid);\n }\n\n private _send(conversationSid: string) {\n log.trace('Sending typing indicator');\n\n const url = this.configuration.links.typing;\n const headers = {\n 'Content-Type': 'application/x-www-form-urlencoded'\n };\n const body = `ChannelSid=${conversationSid}`;\n\n return (\n this.services.twilsockClient.post\n < { typing_timeout: number } >\n (url, headers, body, this.configuration.productId)\n .then((response) => {\n if (response.body.hasOwnProperty('typing_timeout')) {\n this.serviceTypingTimeout = response.body.typing_timeout * 1000;\n }\n })\n .catch((err) => {\n log.error('Failed to send typing indicator:', err);\n throw err;\n })\n );\n }\n}\n\nexport { TypingIndicator };\n"],"names":["Logger","NotificationTypes"],"mappings":"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"}
1
+ {"version":3,"file":"typing-indicator.js","sources":["../../src/services/typing-indicator.ts"],"sourcesContent":["import { Logger } from \"../logger\";\n\nimport { Notifications } from \"@twilio/notifications\";\n\nimport { NotificationTypes } from \"../interfaces/notification-types\";\nimport { TwilsockClient } from \"twilsock\";\nimport { Configuration } from \"../configuration\";\n\nconst log = Logger.scope(\"TypingIndicator\");\n\nexport interface TypingIndicatorServices {\n twilsockClient: TwilsockClient;\n notificationClient: Notifications;\n}\n\n/**\n * An important note in regards to typing timeout timers. There are two places that the SDK can get the \"typing_timeout\" attribute from. The first\n * place that the attribute appears in is the response received from POST -> /v1/typing REST call. In the body of that response, the value of the\n * \"typing_timeout\" attribute will be exactly the same as defined in the console. The second place that the attribute appears in is from a\n * notification of type \"twilio.ipmsg.typing_indicator\". In this case, the \"typing_timeout\" value will be +1 of that in the console. This\n * intentional. The timeout returned from the POST -> /v1/typing call should be used to disable further calls for that period of time. On contrary,\n * the timeout returned from the notification should be used as the timeout for the \"typingEnded\" event, +1 is to account for latency.\n *\n * @private\n */\n\n/**\n * @class TypingIndicator\n *\n * @constructor\n * @private\n */\nclass TypingIndicator {\n private readonly services: TypingIndicatorServices;\n private readonly configuration: Configuration;\n\n private sentUpdates: Map<string, number>;\n private getConversation;\n private serviceTypingTimeout;\n\n constructor(\n getConversation,\n config: Configuration,\n services: TypingIndicatorServices\n ) {\n this.configuration = config;\n this.services = services;\n this.getConversation = getConversation;\n\n this.serviceTypingTimeout = null;\n this.sentUpdates = new Map();\n }\n\n public get typingTimeout(): number {\n return (\n this.configuration.typingIndicatorTimeoutOverride ||\n this.serviceTypingTimeout ||\n this.configuration.typingIndicatorTimeoutDefault\n );\n }\n\n /**\n * Initialize TypingIndicator controller\n * Registers for needed message types and sets listeners\n * @private\n */\n initialize(): void {\n // this.services.notificationClient.subscribe(NotificationTypes.TYPING_INDICATOR, 'twilsock');\n this.services.notificationClient.on(\"message\", async (type, message) => {\n if (type === NotificationTypes.TYPING_INDICATOR) {\n await this._handleRemoteTyping(message);\n }\n });\n }\n\n /**\n * Remote participants typing events handler\n */\n private async _handleRemoteTyping(message) {\n log.trace(\"Got new typing indicator \", message);\n\n this.getConversation(message.channel_sid)\n .then((conversation) => {\n if (!conversation) {\n return;\n }\n\n conversation.participants.forEach((participant) => {\n if (participant.identity !== message.identity) {\n return;\n }\n\n const timeout = this.configuration.typingIndicatorTimeoutOverride\n ? this.configuration.typingIndicatorTimeoutOverride + 1000\n : message.typing_timeout * 1000;\n participant._startTyping(timeout);\n });\n })\n .catch((err) => {\n log.error(err);\n throw err;\n });\n }\n\n /**\n * Send typing event for the given conversation sid\n * @param {String} conversationSid\n */\n send(conversationSid: string) {\n const lastUpdate = this.sentUpdates.get(conversationSid);\n if (lastUpdate && lastUpdate > Date.now() - this.typingTimeout) {\n return Promise.resolve();\n }\n\n this.sentUpdates.set(conversationSid, Date.now());\n return this._send(conversationSid);\n }\n\n private _send(conversationSid: string) {\n log.trace(\"Sending typing indicator\");\n\n const url = this.configuration.links.typing;\n const headers = {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n };\n const body = `ChannelSid=${conversationSid}`;\n\n return this.services.twilsockClient\n .post<{ typing_timeout: number }>(\n url,\n headers,\n body,\n this.configuration.productId\n )\n .then((response) => {\n if (response.body.hasOwnProperty(\"typing_timeout\")) {\n this.serviceTypingTimeout = response.body.typing_timeout * 1000;\n }\n })\n .catch((err) => {\n log.error(\"Failed to send typing indicator:\", err);\n throw err;\n });\n }\n}\n\nexport { TypingIndicator };\n"],"names":["Logger","NotificationTypes"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"unsent-message.js","sources":["../src/unsent-message.ts"],"sourcesContent":["import { MediaCategory } from '@twilio/mcs-client';\nimport { parseToNumber } from './util';\nimport { SendEmailOptions, SendMediaOptions } from './conversation';\n\n/**\n * An unsent message. Returned from {@link MessageBuilder.build}.\n */\nclass UnsentMessage {\n public text?: string;\n public attributes: any = {};\n public mediaContent: [MediaCategory, FormData | SendMediaOptions][] = [];\n public emailOptions?: SendEmailOptions = {};\n\n /**\n * @internal\n */\n constructor(private messagesEntity: any) {}\n\n /**\n * Send the prepared message to the conversation.\n * @returns Index of the new message in the conversation.\n */\n async send(): Promise<number> {\n const response = await this.messagesEntity.sendV2(this);\n return parseToNumber(response.index);\n }\n}\n\nexport { UnsentMessage };\n"],"names":["parseToNumber"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAIA;;;AAGA,MAAM,aAAa;;;;IASjB,YAAoB,cAAmB;QAAnB,mBAAc,GAAd,cAAc,CAAK;QAPhC,eAAU,GAAQ,EAAE,CAAC;QACrB,iBAAY,GAAmD,EAAE,CAAC;QAClE,iBAAY,GAAsB,EAAE,CAAC;KAKD;;;;;IAM3C,MAAM,IAAI;QACR,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACxD,OAAOA,mBAAa,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;KACtC;;;;;"}
1
+ {"version":3,"file":"unsent-message.js","sources":["../src/unsent-message.ts"],"sourcesContent":["import { MediaCategory } from \"@twilio/mcs-client\";\nimport { parseToNumber } from \"./util\";\nimport { SendEmailOptions, SendMediaOptions } from \"./conversation\";\nimport { JSONValue } from \"./types\";\n\n/**\n * An unsent message. Returned from {@link MessageBuilder.build}.\n */\nclass UnsentMessage {\n public text?: string;\n public attributes: JSONValue = {};\n public mediaContent: [MediaCategory, FormData | SendMediaOptions][] = [];\n public emailOptions: SendEmailOptions = {};\n\n /**\n * @internal\n */\n constructor(private messagesEntity) {}\n\n /**\n * Send the prepared message to the conversation.\n * @returns Index of the new message in the conversation.\n */\n async send(): Promise<number | null> {\n const response = await this.messagesEntity.sendV2(this);\n return parseToNumber(response.index);\n }\n}\n\nexport { UnsentMessage };\n"],"names":["parseToNumber"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAKA;;;AAGA,MAAM,aAAa;;;;IASjB,YAAoB,cAAc;QAAd,mBAAc,GAAd,cAAc,CAAA;QAP3B,eAAU,GAAc,EAAE,CAAC;QAC3B,iBAAY,GAAmD,EAAE,CAAC;QAClE,iBAAY,GAAqB,EAAE,CAAC;KAKL;;;;;IAMtC,MAAM,IAAI;QACR,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACxD,OAAOA,mBAAa,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;KACtC;;;;;"}
package/dist/user.js CHANGED
@@ -134,6 +134,7 @@ var tslib_es6 = require('./node_modules/tslib/tslib.es6.js');
134
134
  var logger = require('./logger.js');
135
135
  var index = require('./util/index.js');
136
136
  var declarativeTypeValidator = require('@twilio/declarative-type-validator');
137
+ var attributes = require('./interfaces/attributes.js');
137
138
  var replayEventEmitter = require('@twilio/replay-event-emitter');
138
139
  var isEqual = require('lodash.isequal');
139
140
 
@@ -141,7 +142,7 @@ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'defau
141
142
 
142
143
  var isEqual__default = /*#__PURE__*/_interopDefaultLegacy(isEqual);
143
144
 
144
- const log = logger.Logger.scope('User');
145
+ const log = logger.Logger.scope("User");
145
146
  /**
146
147
  * Extended user information.
147
148
  * Note that `isOnline` and `isNotifiable` properties are eligible
@@ -164,7 +165,7 @@ class User extends replayEventEmitter.ReplayEventEmitter {
164
165
  * * {@link UserUpdateReason}[] `updateReasons` - array of reasons for the update
165
166
  * @event
166
167
  */
167
- this.updated = 'updated';
168
+ this.updated = "updated";
168
169
  /**
169
170
  * Fired when the client has subscribed to the user.
170
171
  *
@@ -172,7 +173,7 @@ class User extends replayEventEmitter.ReplayEventEmitter {
172
173
  * 1. {@link User} `user` - the user in question
173
174
  * @event
174
175
  */
175
- this.userSubscribed = 'userSubscribed';
176
+ this.userSubscribed = "userSubscribed";
176
177
  /**
177
178
  * Fired when the client has unsubscribed from the user.
178
179
  *
@@ -180,9 +181,9 @@ class User extends replayEventEmitter.ReplayEventEmitter {
180
181
  * 1. {@link User} `user` - the user in question
181
182
  * @event
182
183
  */
183
- this.userUnsubscribed = 'userUnsubscribed';
184
+ this.userUnsubscribed = "userUnsubscribed";
184
185
  this.services = services;
185
- this.subscribed = 'initializing';
186
+ this.subscribed = "initializing";
186
187
  this.setMaxListeners(0);
187
188
  this.state = {
188
189
  identity,
@@ -190,7 +191,7 @@ class User extends replayEventEmitter.ReplayEventEmitter {
190
191
  friendlyName: null,
191
192
  attributes: {},
192
193
  online: null,
193
- notifiable: null
194
+ notifiable: null,
194
195
  };
195
196
  this._initializationPromise = new Promise((resolve) => {
196
197
  this._resolveInitializationPromise = resolve;
@@ -202,63 +203,79 @@ class User extends replayEventEmitter.ReplayEventEmitter {
202
203
  /**
203
204
  * User identity.
204
205
  */
205
- get identity() { return this.state.identity; }
206
- set identity(identity) { this.state.identity = identity; }
207
- set entityName(name) { this.state.entityName = name; }
206
+ get identity() {
207
+ return this.state.identity;
208
+ }
209
+ set identity(identity) {
210
+ this.state.identity = identity;
211
+ }
212
+ set entityName(name) {
213
+ this.state.entityName = name;
214
+ }
208
215
  /**
209
216
  * Custom attributes of the user.
210
217
  */
211
- get attributes() { return this.state.attributes; }
218
+ get attributes() {
219
+ return this.state.attributes;
220
+ }
212
221
  /**
213
222
  * Friendly name of the user, null if not set.
214
223
  */
215
- get friendlyName() { return this.state.friendlyName; }
224
+ get friendlyName() {
225
+ return this.state.friendlyName;
226
+ }
216
227
  /**
217
228
  * Status of the real-time conversation connection of the user.
218
229
  */
219
- get isOnline() { return this.state.online; }
230
+ get isOnline() {
231
+ return this.state.online;
232
+ }
220
233
  /**
221
234
  * User push notification registration status.
222
235
  */
223
- get isNotifiable() { return this.state.notifiable; }
236
+ get isNotifiable() {
237
+ return this.state.notifiable;
238
+ }
224
239
  /**
225
240
  * True if this user is receiving real-time status updates.
226
241
  */
227
- get isSubscribed() { return this.subscribed == 'subscribed'; }
242
+ get isSubscribed() {
243
+ return this.subscribed == "subscribed";
244
+ }
228
245
  // Handles service updates
229
246
  async _update(key, value) {
230
247
  await this._initializationPromise;
231
- let updateReasons = [];
232
- log.debug('User for', this.state.identity, 'updated:', key, value);
248
+ const updateReasons = [];
249
+ log.debug("User for", this.state.identity, "updated:", key, value);
233
250
  switch (key) {
234
- case 'friendlyName':
251
+ case "friendlyName":
235
252
  if (this.state.friendlyName !== value.value) {
236
- updateReasons.push('friendlyName');
253
+ updateReasons.push("friendlyName");
237
254
  this.state.friendlyName = value.value;
238
255
  }
239
256
  break;
240
- case 'attributes':
257
+ case "attributes":
241
258
  const updateAttributes = index.parseAttributes(value.value, `Retrieved malformed attributes from the server for user: ${this.state.identity}`, log);
242
259
  if (!isEqual__default['default'](this.state.attributes, updateAttributes)) {
243
260
  this.state.attributes = updateAttributes;
244
- updateReasons.push('attributes');
261
+ updateReasons.push("attributes");
245
262
  }
246
263
  break;
247
- case 'reachability':
264
+ case "reachability":
248
265
  if (this.state.online !== value.online) {
249
266
  this.state.online = value.online;
250
- updateReasons.push('reachabilityOnline');
267
+ updateReasons.push("reachabilityOnline");
251
268
  }
252
269
  if (this.state.notifiable !== value.notifiable) {
253
270
  this.state.notifiable = value.notifiable;
254
- updateReasons.push('reachabilityNotifiable');
271
+ updateReasons.push("reachabilityNotifiable");
255
272
  }
256
273
  break;
257
274
  default:
258
275
  return;
259
276
  }
260
277
  if (updateReasons.length > 0) {
261
- this.emit('updated', { user: this, updateReasons: updateReasons });
278
+ this.emit("updated", { user: this, updateReasons: updateReasons });
262
279
  }
263
280
  }
264
281
  // Fetch reachability info
@@ -267,9 +284,12 @@ class User extends replayEventEmitter.ReplayEventEmitter {
267
284
  if (!this.configuration.reachabilityEnabled) {
268
285
  return Promise.resolve();
269
286
  }
270
- return map.get('reachability')
287
+ return map
288
+ .get("reachability")
271
289
  .then(update)
272
- .catch(err => { log.warn('Failed to get reachability info for ', this.state.identity, err); });
290
+ .catch((err) => {
291
+ log.warn("Failed to get reachability info for ", this.state.identity, err);
292
+ });
273
293
  }
274
294
  // Fetch user
275
295
  async _fetch() {
@@ -277,32 +297,39 @@ class User extends replayEventEmitter.ReplayEventEmitter {
277
297
  if (!this.state.entityName) {
278
298
  return this;
279
299
  }
280
- this.promiseToFetch = this.services.syncClient.map({
300
+ this.promiseToFetch = this.services.syncClient
301
+ .map({
281
302
  id: this.state.entityName,
282
- mode: 'open_existing',
283
- includeItems: true
303
+ mode: "open_existing",
304
+ includeItems: true,
284
305
  })
285
- .then(map => {
306
+ .then((map) => {
286
307
  this.entity = map;
287
- map.on('itemUpdated', args => {
288
- log.debug(this.state.entityName + ' (' + this.state.identity + ') itemUpdated: ' + args.item.key);
308
+ map.on("itemUpdated", (args) => {
309
+ log.debug(this.state.entityName +
310
+ " (" +
311
+ this.state.identity +
312
+ ") itemUpdated: " +
313
+ args.item.key);
289
314
  return this._update(args.item.key, args.item.data);
290
315
  });
291
316
  return Promise.all([
292
- map.get('friendlyName')
293
- .then(item => this._update(item.key, item.data)),
294
- map.get('attributes')
295
- .then(item => this._update(item.key, item.data)),
296
- this._updateReachabilityInfo(map, item => this._update(item.key, item.data))
317
+ map
318
+ .get("friendlyName")
319
+ .then((item) => this._update(item.key, item.data)),
320
+ map
321
+ .get("attributes")
322
+ .then((item) => this._update(item.key, item.data)),
323
+ this._updateReachabilityInfo(map, (item) => this._update(item.key, item.data)),
297
324
  ]);
298
325
  })
299
326
  .then(() => {
300
- log.debug('Fetched for', this.identity);
301
- this.subscribed = 'subscribed';
302
- this.emit('userSubscribed', this);
327
+ log.debug("Fetched for", this.identity);
328
+ this.subscribed = "subscribed";
329
+ this.emit("userSubscribed", this);
303
330
  return this;
304
331
  })
305
- .catch(err => {
332
+ .catch((err) => {
306
333
  this.promiseToFetch = null;
307
334
  throw err;
308
335
  });
@@ -318,11 +345,11 @@ class User extends replayEventEmitter.ReplayEventEmitter {
318
345
  */
319
346
  async updateAttributes(attributes) {
320
347
  await this._initializationPromise;
321
- if (this.subscribed == 'unsubscribed') {
322
- throw new Error('Can\'t modify unsubscribed object');
348
+ if (this.subscribed == "unsubscribed") {
349
+ throw new Error("Can't modify unsubscribed object");
323
350
  }
324
- await this.services.commandExecutor.mutateResource('post', this.links.self, {
325
- attributes: JSON.stringify(attributes)
351
+ await this.services.commandExecutor.mutateResource("post", this.links.self, {
352
+ attributes: JSON.stringify(attributes),
326
353
  });
327
354
  return this;
328
355
  }
@@ -332,11 +359,11 @@ class User extends replayEventEmitter.ReplayEventEmitter {
332
359
  */
333
360
  async updateFriendlyName(friendlyName) {
334
361
  await this._initializationPromise;
335
- if (this.subscribed == 'unsubscribed') {
336
- throw new Error('Can\'t modify unsubscribed object');
362
+ if (this.subscribed == "unsubscribed") {
363
+ throw new Error("Can't modify unsubscribed object");
337
364
  }
338
- await this.services.commandExecutor.mutateResource('post', this.links.self, {
339
- friendly_name: friendlyName
365
+ await this.services.commandExecutor.mutateResource("post", this.links.self, {
366
+ friendly_name: friendlyName,
340
367
  });
341
368
  return this;
342
369
  }
@@ -350,8 +377,8 @@ class User extends replayEventEmitter.ReplayEventEmitter {
350
377
  await this.promiseToFetch;
351
378
  this.entity.close();
352
379
  this.promiseToFetch = null;
353
- this.subscribed = 'unsubscribed';
354
- this.emit('userUnsubscribed', this);
380
+ this.subscribed = "unsubscribed";
381
+ this.emit("userUnsubscribed", this);
355
382
  }
356
383
  }
357
384
  _resolveInitialization(configuration, identity, entityName, emitUpdated) {
@@ -359,30 +386,30 @@ class User extends replayEventEmitter.ReplayEventEmitter {
359
386
  this.identity = identity;
360
387
  this.entityName = entityName;
361
388
  this.links = {
362
- self: `${this.configuration.links.users}/${this.identity}`
389
+ self: `${this.configuration.links.users}/${this.identity}`,
363
390
  };
364
391
  this._resolveInitializationPromise();
365
392
  if (emitUpdated) {
366
- this.emit('updated', {
393
+ this.emit("updated", {
367
394
  user: this,
368
395
  updateReasons: [
369
- 'friendlyName',
370
- 'attributes',
371
- 'reachabilityOnline',
372
- 'reachabilityNotifiable'
373
- ]
396
+ "friendlyName",
397
+ "attributes",
398
+ "reachabilityOnline",
399
+ "reachabilityNotifiable",
400
+ ],
374
401
  });
375
402
  }
376
403
  }
377
404
  }
378
405
  tslib_es6.__decorate([
379
- declarativeTypeValidator.validateTypesAsync(['string', 'number', 'boolean', 'object', declarativeTypeValidator.literal(null)]),
406
+ declarativeTypeValidator.validateTypesAsync(attributes.attributesValidator),
380
407
  tslib_es6.__metadata("design:type", Function),
381
408
  tslib_es6.__metadata("design:paramtypes", [Object]),
382
409
  tslib_es6.__metadata("design:returntype", Promise)
383
410
  ], User.prototype, "updateAttributes", null);
384
411
  tslib_es6.__decorate([
385
- declarativeTypeValidator.validateTypesAsync(['string']),
412
+ declarativeTypeValidator.validateTypesAsync(["string"]),
386
413
  tslib_es6.__metadata("design:type", Function),
387
414
  tslib_es6.__metadata("design:paramtypes", [String]),
388
415
  tslib_es6.__metadata("design:returntype", Promise)