@twilio/conversations 1.3.0-rc8 → 2.0.0-rc.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +210 -0
- package/README.md +22 -17
- package/dist/browser.js +7873 -0
- package/dist/browser.js.map +1 -0
- package/dist/docs/assets/css/main.css +2660 -0
- package/dist/docs/assets/images/icons.png +0 -0
- package/dist/docs/assets/images/icons@2x.png +0 -0
- package/dist/docs/assets/images/widgets.png +0 -0
- package/dist/docs/assets/images/widgets@2x.png +0 -0
- package/dist/docs/assets/js/main.js +248 -0
- package/dist/docs/assets/js/search.js +1 -0
- package/dist/docs/classes/AggregatedDeliveryReceipt.html +3286 -0
- package/dist/docs/classes/Client.html +4181 -0
- package/dist/docs/classes/Conversation.html +4397 -0
- package/dist/docs/classes/DetailedDeliveryReceipt.html +3265 -0
- package/dist/docs/classes/Media.html +3295 -0
- package/dist/docs/classes/Message.html +3713 -0
- package/dist/docs/classes/MessageBuilder.html +3280 -0
- package/dist/docs/classes/Participant.html +3517 -0
- package/dist/docs/classes/PushNotification.html +3232 -0
- package/dist/docs/classes/RestPaginator.html +3262 -0
- package/dist/docs/classes/UnsentMessage.html +3144 -0
- package/dist/docs/classes/User.html +3451 -0
- package/dist/docs/index.html +3394 -212
- package/dist/docs/interfaces/ClientOptions.html +3136 -0
- package/dist/docs/interfaces/ConversationState.html +3152 -0
- package/dist/docs/interfaces/CreateConversationOptions.html +3168 -0
- package/dist/docs/interfaces/LastMessage.html +3152 -0
- package/dist/docs/interfaces/Paginator.html +3243 -0
- package/dist/docs/interfaces/PushNotificationData.html +3168 -0
- package/dist/docs/interfaces/SendEmailOptions.html +3136 -0
- package/dist/docs/interfaces/SendMediaOptions.html +3170 -0
- package/dist/docs/modules.html +3425 -0
- package/dist/lib.d.ts +1952 -0
- package/dist/lib.js +7873 -0
- package/dist/lib.js.map +1 -0
- package/dist/post-install.js +29 -0
- package/dist/react-native.js +4038 -0
- package/dist/react-native.js.map +1 -0
- package/dist/twilio-conversations.js +40912 -0
- package/dist/twilio-conversations.min.js +156 -0
- package/package.json +59 -48
- package/.circleci/config.yml +0 -650
- package/.deepsource.toml +0 -6
- package/.env.example +0 -13
- package/browser/aggregateddeliveryreceipt.js +0 -152
- package/browser/client.js +0 -991
- package/browser/configuration.js +0 -80
- package/browser/conversation.js +0 -1826
- package/browser/data/conversations.js +0 -632
- package/browser/data/messages.js +0 -522
- package/browser/data/participants.js +0 -411
- package/browser/data/users.js +0 -281
- package/browser/detaileddeliveryreceipt.js +0 -44
- package/browser/index.js +0 -4
- package/browser/interfaces/limits.js +0 -3
- package/browser/interfaces/notificationtypes.js +0 -21
- package/browser/interfaces/paginator.js +0 -53
- package/browser/interfaces/responsecodes.js +0 -20
- package/browser/interfaces/transport.js +0 -3
- package/browser/logger.js +0 -141
- package/browser/media.js +0 -198
- package/browser/message.js +0 -685
- package/browser/participant.js +0 -415
- package/browser/pushnotification.js +0 -49
- package/browser/restpaginator.js +0 -74
- package/browser/services/network.js +0 -223
- package/browser/services/readhorizon.js +0 -181
- package/browser/services/typingindicator.js +0 -142
- package/browser/session.js +0 -505
- package/browser/sessionerror.js +0 -93
- package/browser/sri.json +0 -1
- package/browser/synclist.js +0 -90
- package/browser/synclistdescriptor.js +0 -29
- package/browser/syncpaginator.js +0 -63
- package/browser/user.js +0 -431
- package/browser/util/deferred.js +0 -56
- package/browser/util/index.js +0 -108
- package/dist/@twilio/conversations.js +0 -35533
- package/dist/@twilio/conversations.min.js +0 -204
- package/dist/docs/AggregatedDeliveryReceipt.html +0 -948
- package/dist/docs/Client.html +0 -5075
- package/dist/docs/Conversation.html +0 -6018
- package/dist/docs/DetailedDeliveryReceipt.html +0 -641
- package/dist/docs/Media.html +0 -694
- package/dist/docs/Message.html +0 -1934
- package/dist/docs/Paginator.html +0 -605
- package/dist/docs/Participant.html +0 -1510
- package/dist/docs/PushNotification.html +0 -836
- package/dist/docs/SessionError.html +0 -379
- package/dist/docs/User.html +0 -1315
- package/dist/docs/classes.list.html +0 -4431
- package/dist/docs/fonts/glyphicons-halflings-regular.eot +0 -0
- package/dist/docs/fonts/glyphicons-halflings-regular.svg +0 -288
- package/dist/docs/fonts/glyphicons-halflings-regular.ttf +0 -0
- package/dist/docs/fonts/glyphicons-halflings-regular.woff +0 -0
- package/dist/docs/fonts/glyphicons-halflings-regular.woff2 +0 -0
- package/dist/docs/img/glyphicons-halflings-white.png +0 -0
- package/dist/docs/img/glyphicons-halflings.png +0 -0
- package/dist/docs/quicksearch.html +0 -31
- package/dist/docs/scripts/docstrap.lib.js +0 -11
- package/dist/docs/scripts/fulltext-search-ui.js +0 -89
- package/dist/docs/scripts/fulltext-search.js +0 -36
- package/dist/docs/scripts/lunr.min.js +0 -6
- package/dist/docs/scripts/prettify/Apache-License-2.0.txt +0 -202
- package/dist/docs/scripts/prettify/jquery.min.js +0 -6
- package/dist/docs/scripts/prettify/lang-css.js +0 -21
- package/dist/docs/scripts/prettify/prettify.js +0 -496
- package/dist/docs/scripts/sunlight.js +0 -1157
- package/dist/docs/scripts/toc.js +0 -203
- package/dist/docs/styles/darkstrap.css +0 -960
- package/dist/docs/styles/prettify-tomorrow.css +0 -132
- package/dist/docs/styles/site.cerulean.css +0 -7008
- package/dist/docs/styles/site.cosmo.css +0 -7061
- package/dist/docs/styles/site.cyborg.css +0 -7048
- package/dist/docs/styles/site.darkly.css +0 -7171
- package/dist/docs/styles/site.darkstrap.css +0 -5638
- package/dist/docs/styles/site.dibs-bootstrap.css +0 -5899
- package/dist/docs/styles/site.flatly.css +0 -7147
- package/dist/docs/styles/site.journal.css +0 -6973
- package/dist/docs/styles/site.lumen.css +0 -7298
- package/dist/docs/styles/site.paper.css +0 -7623
- package/dist/docs/styles/site.readable.css +0 -6997
- package/dist/docs/styles/site.sandstone.css +0 -7035
- package/dist/docs/styles/site.simplex.css +0 -7023
- package/dist/docs/styles/site.slate.css +0 -7343
- package/dist/docs/styles/site.spacelab.css +0 -7055
- package/dist/docs/styles/site.superhero.css +0 -7131
- package/dist/docs/styles/site.united.css +0 -6895
- package/dist/docs/styles/site.yeti.css +0 -7195
- package/dist/docs/styles/sunlight.dark.css +0 -345
- package/dist/docs/styles/sunlight.default.css +0 -344
- package/dist/sri.json +0 -1
- package/lib/aggregateddeliveryreceipt.d.ts +0 -98
- package/lib/aggregateddeliveryreceipt.js +0 -112
- package/lib/client.d.ts +0 -317
- package/lib/client.js +0 -633
- package/lib/configuration.d.ts +0 -21
- package/lib/configuration.js +0 -41
- package/lib/conversation.d.ts +0 -460
- package/lib/conversation.js +0 -940
- package/lib/data/conversations.d.ts +0 -57
- package/lib/data/conversations.js +0 -296
- package/lib/data/messages.d.ts +0 -75
- package/lib/data/messages.js +0 -208
- package/lib/data/participants.d.ts +0 -94
- package/lib/data/participants.js +0 -204
- package/lib/data/users.d.ts +0 -42
- package/lib/data/users.js +0 -113
- package/lib/detaileddeliveryreceipt.d.ts +0 -45
- package/lib/detaileddeliveryreceipt.js +0 -34
- package/lib/index.d.ts +0 -1
- package/lib/index.js +0 -3
- package/lib/interfaces/limits.d.ts +0 -8
- package/lib/interfaces/limits.js +0 -2
- package/lib/interfaces/notificationtypes.d.ts +0 -8
- package/lib/interfaces/notificationtypes.js +0 -11
- package/lib/interfaces/paginator.d.ts +0 -52
- package/lib/interfaces/paginator.js +0 -28
- package/lib/interfaces/responsecodes.d.ts +0 -8
- package/lib/interfaces/responsecodes.js +0 -10
- package/lib/interfaces/transport.d.ts +0 -13
- package/lib/interfaces/transport.js +0 -2
- package/lib/logger.d.ts +0 -18
- package/lib/logger.js +0 -35
- package/lib/media.d.ts +0 -52
- package/lib/media.js +0 -69
- package/lib/message.d.ts +0 -136
- package/lib/message.js +0 -305
- package/lib/participant.d.ts +0 -142
- package/lib/participant.js +0 -219
- package/lib/pushnotification.d.ts +0 -48
- package/lib/pushnotification.js +0 -39
- package/lib/restpaginator.d.ts +0 -19
- package/lib/restpaginator.js +0 -36
- package/lib/services/network.d.ts +0 -22
- package/lib/services/network.js +0 -87
- package/lib/services/readhorizon.d.ts +0 -28
- package/lib/services/readhorizon.js +0 -112
- package/lib/services/typingindicator.d.ts +0 -50
- package/lib/services/typingindicator.js +0 -102
- package/lib/session.d.ts +0 -63
- package/lib/session.js +0 -213
- package/lib/sessionerror.d.ts +0 -12
- package/lib/sessionerror.js +0 -24
- package/lib/sri.json +0 -1
- package/lib/synclist.d.ts +0 -24
- package/lib/synclist.js +0 -28
- package/lib/synclistdescriptor.d.ts +0 -27
- package/lib/synclistdescriptor.js +0 -19
- package/lib/syncpaginator.d.ts +0 -22
- package/lib/syncpaginator.js +0 -37
- package/lib/user.d.ts +0 -98
- package/lib/user.js +0 -219
- package/lib/util/deferred.d.ts +0 -12
- package/lib/util/deferred.js +0 -22
- package/lib/util/index.d.ts +0 -28
- package/lib/util/index.js +0 -82
- package/tools/rtd-sdk-cdn-pin/.gitrepo +0 -12
- package/tools/rtd-sdk-cdn-pin/README.md +0 -54
- package/tools/rtd-sdk-cdn-pin/bintray-settings.xml.template +0 -16
- package/tools/rtd-sdk-cdn-pin/cdn-common/cdn-prepare.sh +0 -67
- package/tools/rtd-sdk-cdn-pin/cdn-pin-latest.sh +0 -19
- package/tools/rtd-sdk-cdn-pin/cdn-pin.sh +0 -19
- package/tools/rtd-sdk-cdn-pin/cdn-upload.sh +0 -13
- package/tools/rtd-sdk-cdn-pin/fetch/common/fetch-bintray-android.sh +0 -34
- package/tools/rtd-sdk-cdn-pin/fetch/common/fetch-npm.sh +0 -18
- package/tools/rtd-sdk-cdn-pin/fetch/twilio-chat-android.sh +0 -5
- package/tools/rtd-sdk-cdn-pin/fetch/twilio-chat-js.sh +0 -5
- package/tools/rtd-sdk-cdn-pin/fetch/twilio-conversations-android.sh +0 -6
- package/tools/rtd-sdk-cdn-pin/fetch/twilio-conversations-js.sh +0 -5
- package/tools/rtd-sdk-cdn-pin/fetch/twilio-sync-android.sh +0 -5
- package/tools/rtd-sdk-cdn-pin/fetch/twilio-sync-js.sh +0 -5
- package/tools/rtd-sdk-cdn-pin/fetch-artifact.sh +0 -26
- package/tools/sdk-release-tool/.gitrepo +0 -12
- package/tools/sdk-release-tool/Makefile +0 -49
- package/tools/sdk-release-tool/README.md +0 -275
- package/tools/sdk-release-tool/delete +0 -3
- package/tools/sdk-release-tool/download +0 -3
- package/tools/sdk-release-tool/get-cors +0 -3
- package/tools/sdk-release-tool/list +0 -3
- package/tools/sdk-release-tool/pin +0 -3
- package/tools/sdk-release-tool/pin-latest +0 -3
- package/tools/sdk-release-tool/requirements.txt +0 -4
- package/tools/sdk-release-tool/sdk-release-tool +0 -3
- package/tools/sdk-release-tool/sdk_release_tools/__init__.py +0 -0
- package/tools/sdk-release-tool/sdk_release_tools/__main__.py +0 -110
- package/tools/sdk-release-tool/sdk_release_tools/aws.py +0 -70
- package/tools/sdk-release-tool/sdk_release_tools/cli.py +0 -181
- package/tools/sdk-release-tool/sdk_release_tools/log.py +0 -24
- package/tools/sdk-release-tool/sdk_release_tools/ops.py +0 -295
- package/tools/sdk-release-tool/sdk_release_tools/rpm.py +0 -28
- package/tools/sdk-release-tool/sdk_release_tools/util.py +0 -186
- package/tools/sdk-release-tool/sdk_release_tools/versions.py +0 -362
- package/tools/sdk-release-tool/signal-sdk-js.json +0 -28
- package/tools/sdk-release-tool/tests/test_versions.py +0 -94
- package/tools/sdk-release-tool/twilio-accessmanager-android.json +0 -19
- package/tools/sdk-release-tool/twilio-accessmanager-ios.json +0 -26
- package/tools/sdk-release-tool/twilio-auth-ios.json +0 -29
- package/tools/sdk-release-tool/twilio-authenticator-ios.json +0 -29
- package/tools/sdk-release-tool/twilio-chat-android-2.json +0 -19
- package/tools/sdk-release-tool/twilio-chat-android.json +0 -22
- package/tools/sdk-release-tool/twilio-chat-ios.json +0 -26
- package/tools/sdk-release-tool/twilio-chat-js.json +0 -27
- package/tools/sdk-release-tool/twilio-client-android-aar.json +0 -22
- package/tools/sdk-release-tool/twilio-client-android.json +0 -22
- package/tools/sdk-release-tool/twilio-client-ios.json +0 -20
- package/tools/sdk-release-tool/twilio-client-js.json +0 -17
- package/tools/sdk-release-tool/twilio-client-sounds-js.json +0 -14
- package/tools/sdk-release-tool/twilio-common-android-maven.json +0 -16
- package/tools/sdk-release-tool/twilio-common-android.json +0 -22
- package/tools/sdk-release-tool/twilio-common-ios-rtc.json +0 -25
- package/tools/sdk-release-tool/twilio-common-ios.json +0 -25
- package/tools/sdk-release-tool/twilio-common-js.json +0 -19
- package/tools/sdk-release-tool/twilio-conversations-android.json +0 -22
- package/tools/sdk-release-tool/twilio-conversations-ios.json +0 -26
- package/tools/sdk-release-tool/twilio-conversations-js.json +0 -27
- package/tools/sdk-release-tool/twilio-flex-js.json +0 -20
- package/tools/sdk-release-tool/twilio-flex-webchat-js.json +0 -16
- package/tools/sdk-release-tool/twilio-frame-chat-android.json +0 -22
- package/tools/sdk-release-tool/twilio-frame-chat-ios.json +0 -23
- package/tools/sdk-release-tool/twilio-frame-chat-js.json +0 -23
- package/tools/sdk-release-tool/twilio-ip-messaging-android-maven.json +0 -16
- package/tools/sdk-release-tool/twilio-ip-messaging-android.json +0 -22
- package/tools/sdk-release-tool/twilio-ip-messaging-ios.json +0 -25
- package/tools/sdk-release-tool/twilio-ip-messaging-js.json +0 -21
- package/tools/sdk-release-tool/twilio-sync-android.json +0 -22
- package/tools/sdk-release-tool/twilio-sync-ios.json +0 -26
- package/tools/sdk-release-tool/twilio-sync-js.json +0 -39
- package/tools/sdk-release-tool/twilio-taskrouter-js.json +0 -17
- package/tools/sdk-release-tool/twilio-video-android.json +0 -22
- package/tools/sdk-release-tool/twilio-video-cpp-linux-cross-rootfs.json +0 -13
- package/tools/sdk-release-tool/twilio-video-cpp.json +0 -33
- package/tools/sdk-release-tool/twilio-video-ios.json +0 -25
- package/tools/sdk-release-tool/twilio-video-js.json +0 -19
- package/tools/sdk-release-tool/twilio-video-jsdocs.json +0 -14
- package/tools/sdk-release-tool/twilio-voice-android.json +0 -22
- package/tools/sdk-release-tool/twilio-voice-ios.json +0 -29
- package/tools/sdk-release-tool/unpin +0 -3
- package/tools/sdk-release-tool/unpin-latest +0 -3
- package/tools/sdk-release-tool/upload +0 -3
- package/twilio-chat.js.iml +0 -9
package/lib/conversation.js
DELETED
@@ -1,940 +0,0 @@
|
|
1
|
-
"use strict";
|
2
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
3
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
4
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
5
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
6
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
7
|
-
};
|
8
|
-
var __metadata = (this && this.__metadata) || function (k, v) {
|
9
|
-
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
10
|
-
};
|
11
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
12
|
-
const events_1 = require("events");
|
13
|
-
const logger_1 = require("./logger");
|
14
|
-
const participants_1 = require("./data/participants");
|
15
|
-
const participant_1 = require("./participant");
|
16
|
-
const messages_1 = require("./data/messages");
|
17
|
-
const util_1 = require("./util");
|
18
|
-
const twilio_sdk_type_validator_1 = require("twilio-sdk-type-validator");
|
19
|
-
const log = logger_1.Logger.scope('Conversation');
|
20
|
-
const fieldMappings = {
|
21
|
-
lastMessage: 'lastMessage',
|
22
|
-
attributes: 'attributes',
|
23
|
-
createdBy: 'createdBy',
|
24
|
-
dateCreated: 'dateCreated',
|
25
|
-
dateUpdated: 'dateUpdated',
|
26
|
-
friendlyName: 'friendlyName',
|
27
|
-
lastConsumedMessageIndex: 'lastConsumedMessageIndex',
|
28
|
-
notificationLevel: 'notificationLevel',
|
29
|
-
sid: 'sid',
|
30
|
-
status: 'status',
|
31
|
-
uniqueName: 'uniqueName',
|
32
|
-
state: 'state',
|
33
|
-
bindings: 'bindings'
|
34
|
-
};
|
35
|
-
function parseTime(timeString) {
|
36
|
-
try {
|
37
|
-
return new Date(timeString);
|
38
|
-
}
|
39
|
-
catch (e) {
|
40
|
-
return null;
|
41
|
-
}
|
42
|
-
}
|
43
|
-
class UnsentMessage {
|
44
|
-
constructor(messagesEntity) {
|
45
|
-
this.messagesEntity = messagesEntity;
|
46
|
-
this.attributes = {};
|
47
|
-
this.mediaContent = [];
|
48
|
-
this.emailOptions = {};
|
49
|
-
}
|
50
|
-
/**
|
51
|
-
* Send the prepared message to the conversation.
|
52
|
-
* @returns {Promise<number>} new Message's index in the Conversation's messages list
|
53
|
-
*/
|
54
|
-
async send() {
|
55
|
-
const response = await this.messagesEntity.sendV2(this);
|
56
|
-
return util_1.parseToNumber(response.messageId);
|
57
|
-
}
|
58
|
-
}
|
59
|
-
exports.UnsentMessage = UnsentMessage;
|
60
|
-
class MessageBuilder {
|
61
|
-
constructor(limits, messagesEntity) {
|
62
|
-
this.limits = limits;
|
63
|
-
this.message = new UnsentMessage(messagesEntity);
|
64
|
-
this.emailBodies = new Map();
|
65
|
-
this.emailHistories = new Map();
|
66
|
-
}
|
67
|
-
setBody(text) {
|
68
|
-
this.message.text = text;
|
69
|
-
return this;
|
70
|
-
}
|
71
|
-
setSubject(subject) {
|
72
|
-
this.message.emailOptions.subject = subject;
|
73
|
-
return this;
|
74
|
-
}
|
75
|
-
setAttributes(attributes) {
|
76
|
-
this.message.attributes = attributes;
|
77
|
-
return this;
|
78
|
-
}
|
79
|
-
setEmailBody(mimeType, body) {
|
80
|
-
this.emailBodies.set(mimeType, body);
|
81
|
-
return this;
|
82
|
-
}
|
83
|
-
setEmailHistory(mimeType, history) {
|
84
|
-
this.emailHistories.set(mimeType, history);
|
85
|
-
return this;
|
86
|
-
}
|
87
|
-
addMedia(payload) {
|
88
|
-
this.message.mediaContent.push(['media', payload]);
|
89
|
-
return this;
|
90
|
-
}
|
91
|
-
build() {
|
92
|
-
this.emailBodies.forEach((_, key) => {
|
93
|
-
if (!this.limits.emailBodiesAllowedMimeTypes.includes(key)) {
|
94
|
-
throw new Error(`Unsupported email body MIME type ${key}`);
|
95
|
-
}
|
96
|
-
});
|
97
|
-
this.emailHistories.forEach((_, key) => {
|
98
|
-
if (!this.limits.emailHistoriesAllowedMimeTypes.includes(key)) {
|
99
|
-
throw new Error(`Unsupported email history MIME type ${key}`);
|
100
|
-
}
|
101
|
-
});
|
102
|
-
if (this.emailBodies.size > this.limits.emailBodiesAllowedMimeTypes.length) {
|
103
|
-
throw new Error(`Email bodies set is too large`);
|
104
|
-
}
|
105
|
-
if (this.emailHistories.size > this.limits.emailHistoriesAllowedMimeTypes.length) {
|
106
|
-
throw new Error(`Email histories set is too large`);
|
107
|
-
}
|
108
|
-
if (this.message.mediaContent.length > this.limits.mediaAttachmentsCountLimit) {
|
109
|
-
throw new Error(`Too many media attachments in the message (${this.message.mediaContent.length} > ${this.limits.mediaAttachmentsCountLimit})`);
|
110
|
-
}
|
111
|
-
// @todo we don't know the sizes of the attachments in FormData
|
112
|
-
// @todo insertion below makes build() method non-repeatable - probably move to UnsentMessage.send() or even sendV2()?
|
113
|
-
// @todo specify CATEGORY
|
114
|
-
this.emailBodies.forEach((body) => {
|
115
|
-
this.message.mediaContent.push(['body', body]);
|
116
|
-
});
|
117
|
-
this.emailHistories.forEach((body) => {
|
118
|
-
this.message.mediaContent.push(['history', body]);
|
119
|
-
});
|
120
|
-
return this.message;
|
121
|
-
}
|
122
|
-
getPayloadContentType(payload) {
|
123
|
-
if (typeof FormData !== 'undefined' && (payload instanceof FormData)) {
|
124
|
-
return payload.get('Content-Type');
|
125
|
-
}
|
126
|
-
return payload.contentType;
|
127
|
-
}
|
128
|
-
}
|
129
|
-
/**
|
130
|
-
* @classdesc A Conversation represents communication between multiple Conversations Clients
|
131
|
-
* @property {any} attributes - The Conversation's custom attributes
|
132
|
-
* @property {String} createdBy - The identity of the User that created this Conversation
|
133
|
-
* @property {Date} dateCreated - The Date this Conversation was created
|
134
|
-
* @property {Date} dateUpdated - The Date this Conversation was last updated
|
135
|
-
* @property {String} [friendlyName] - The Conversation's name
|
136
|
-
* @property {Number|null} lastReadMessageIndex - Index of the last Message the User has read in this Conversation
|
137
|
-
* @property {Conversation#LastMessage} lastMessage - Last Message sent to this Conversation
|
138
|
-
* @property {Conversation#NotificationLevel} notificationLevel - User Notification level for this Conversation
|
139
|
-
* @property {String} sid - The Conversation's unique system identifier
|
140
|
-
* @property {Conversation#Status} status - The Conversation's status
|
141
|
-
* @property {Conversation#State} state - The Conversation's state
|
142
|
-
* @property {String} uniqueName - The Conversation's unique name
|
143
|
-
* @fires Conversation#participantJoined
|
144
|
-
* @fires Conversation#participantLeft
|
145
|
-
* @fires Conversation#participantUpdated
|
146
|
-
* @fires Conversation#messageAdded
|
147
|
-
* @fires Conversation#messageRemoved
|
148
|
-
* @fires Conversation#messageUpdated
|
149
|
-
* @fires Conversation#typingEnded
|
150
|
-
* @fires Conversation#typingStarted
|
151
|
-
* @fires Conversation#updated
|
152
|
-
* @fires Conversation#removed
|
153
|
-
*/
|
154
|
-
class Conversation extends events_1.EventEmitter {
|
155
|
-
constructor(services, descriptor, sid) {
|
156
|
-
var _a;
|
157
|
-
super();
|
158
|
-
this.services = services;
|
159
|
-
let attributes = descriptor.attributes || {};
|
160
|
-
let createdBy = descriptor.createdBy;
|
161
|
-
let dateCreated = parseTime(descriptor.dateCreated);
|
162
|
-
let dateUpdated = parseTime(descriptor.dateUpdated);
|
163
|
-
let friendlyName = descriptor.friendlyName || null;
|
164
|
-
let lastReadMessageIndex = Number.isInteger(descriptor.lastConsumedMessageIndex) ? descriptor.lastConsumedMessageIndex : null;
|
165
|
-
let uniqueName = descriptor.uniqueName || null;
|
166
|
-
try {
|
167
|
-
JSON.stringify(attributes);
|
168
|
-
}
|
169
|
-
catch (e) {
|
170
|
-
throw new Error('Attributes must be a valid JSON object.');
|
171
|
-
}
|
172
|
-
this.sid = sid;
|
173
|
-
this.entityName = descriptor.channel;
|
174
|
-
this.channelState = {
|
175
|
-
uniqueName,
|
176
|
-
status: 'notParticipating',
|
177
|
-
attributes,
|
178
|
-
createdBy,
|
179
|
-
dateCreated,
|
180
|
-
dateUpdated,
|
181
|
-
friendlyName,
|
182
|
-
lastReadMessageIndex,
|
183
|
-
bindings: (_a = descriptor.bindings, (_a !== null && _a !== void 0 ? _a : {})),
|
184
|
-
};
|
185
|
-
if (descriptor.notificationLevel) {
|
186
|
-
this.channelState.notificationLevel = descriptor.notificationLevel;
|
187
|
-
}
|
188
|
-
this.participants = new Map();
|
189
|
-
this.participantsEntity = new participants_1.Participants(this, this.services, this.participants);
|
190
|
-
this.participantsEntity.on('participantJoined', this.emit.bind(this, 'participantJoined'));
|
191
|
-
this.participantsEntity.on('participantLeft', this.emit.bind(this, 'participantLeft'));
|
192
|
-
this.participantsEntity.on('participantUpdated', (args) => this.emit('participantUpdated', args));
|
193
|
-
this.messagesEntity = new messages_1.Messages(this, services);
|
194
|
-
this.messagesEntity.on('messageAdded', message => this._onMessageAdded(message));
|
195
|
-
this.messagesEntity.on('messageUpdated', (args) => this.emit('messageUpdated', args));
|
196
|
-
this.messagesEntity.on('messageRemoved', this.emit.bind(this, 'messageRemoved'));
|
197
|
-
}
|
198
|
-
/**
|
199
|
-
* These options can be passed to {@link Conversation#sendMessage}.
|
200
|
-
* @typedef {Object} Conversation#SendMediaOptions
|
201
|
-
* @property {String} contentType - content type of media
|
202
|
-
* @property {String | Buffer} media - content to post
|
203
|
-
*/
|
204
|
-
/**
|
205
|
-
* These options can be passed to {@link Conversation#sendMessage}.
|
206
|
-
* @typedef {Object} Conversation#SendEmailOptions
|
207
|
-
* @property {String} subject - subject for the message. Ignored for media messages.
|
208
|
-
*/
|
209
|
-
/**
|
210
|
-
* The update reason for <code>updated</code> event emitted on Conversation
|
211
|
-
* @typedef {('attributes' | 'createdBy' | 'dateCreated' | 'dateUpdated' |
|
212
|
-
'friendlyName' | 'lastReadMessageIndex' | 'state' | 'status' | 'uniqueName' | 'lastMessage' |
|
213
|
-
'notificationLevel' | 'bindings')} Conversation#UpdateReason
|
214
|
-
*/
|
215
|
-
/**
|
216
|
-
* The status of the Conversation, relative to the Client: whether the Conversation has been <code>joined</code> or the Client is
|
217
|
-
* <code>notParticipating</code> in the Conversation.
|
218
|
-
* @typedef {('notParticipating' | 'joined')} Conversation#Status
|
219
|
-
*/
|
220
|
-
/**
|
221
|
-
* The User's Notification level for Conversation, determines whether the currently logged-in User will receive
|
222
|
-
* pushes for events in this Conversation. Can be either <code>muted</code> or <code>default</code>,
|
223
|
-
* where <code>default</code> defers to global Service push configuration.
|
224
|
-
* @typedef {('default' | 'muted')} Conversation#NotificationLevel
|
225
|
-
*/
|
226
|
-
/**
|
227
|
-
* The Conversation's state.
|
228
|
-
* @typedef {Object} Conversation#State
|
229
|
-
* @property {('active' | 'inactive' | 'closed')} current - the current state
|
230
|
-
* @property {Date} dateUpdated - date at which the latest conversation state update happened
|
231
|
-
*/
|
232
|
-
get uniqueName() { return this.channelState.uniqueName; }
|
233
|
-
get status() { return this.channelState.status; }
|
234
|
-
get friendlyName() { return this.channelState.friendlyName; }
|
235
|
-
get dateUpdated() { return this.channelState.dateUpdated; }
|
236
|
-
get dateCreated() { return this.channelState.dateCreated; }
|
237
|
-
get createdBy() { return this.channelState.createdBy; }
|
238
|
-
get attributes() { return this.channelState.attributes; }
|
239
|
-
get lastReadMessageIndex() { return this.channelState.lastReadMessageIndex; }
|
240
|
-
get lastMessage() { return this.channelState.lastMessage; }
|
241
|
-
get notificationLevel() { return this.channelState.notificationLevel; }
|
242
|
-
get state() { return this.channelState.state; }
|
243
|
-
get bindings() { return this.channelState.bindings; }
|
244
|
-
get limits() { return this.services.limits; }
|
245
|
-
/**
|
246
|
-
* The Conversation's last message's information.
|
247
|
-
* @typedef {Object} Conversation#LastMessage
|
248
|
-
* @property {Number} index - Message's index
|
249
|
-
* @property {Date} dateCreated - Message's creation date
|
250
|
-
*/
|
251
|
-
/**
|
252
|
-
* Load and Subscribe to this Conversation and do not subscribe to its Participants and Messages.
|
253
|
-
* This or _subscribeStreams will need to be called before any events on Conversation will fire.
|
254
|
-
* @returns {Promise}
|
255
|
-
* @private
|
256
|
-
*/
|
257
|
-
_subscribe() {
|
258
|
-
var _a;
|
259
|
-
return this.entityPromise = (_a = this.entityPromise, (_a !== null && _a !== void 0 ? _a : this.services.syncClient.document({ id: this.entityName, mode: 'open_existing' })
|
260
|
-
.then(entity => {
|
261
|
-
this.entity = entity;
|
262
|
-
this.entity.on('updated', args => { this._update(args.data); });
|
263
|
-
this.entity.on('removed', () => this.emit('removed', this));
|
264
|
-
this._update(this.entity.data);
|
265
|
-
return entity;
|
266
|
-
})
|
267
|
-
.catch(err => {
|
268
|
-
this.entity = null;
|
269
|
-
this.entityPromise = null;
|
270
|
-
if (this.services.syncClient.connectionState != 'disconnected') {
|
271
|
-
log.error('Failed to get conversation object', err);
|
272
|
-
}
|
273
|
-
log.debug('ERROR: Failed to get conversation object', err);
|
274
|
-
throw err;
|
275
|
-
})));
|
276
|
-
}
|
277
|
-
/**
|
278
|
-
* Load the attributes of this Conversation and instantiate its Participants and Messages.
|
279
|
-
* This or _subscribe will need to be called before any events on Conversation will fire.
|
280
|
-
* This will need to be called before any events on Participants or Messages will fire
|
281
|
-
* @returns {Promise}
|
282
|
-
* @private
|
283
|
-
*/
|
284
|
-
async _subscribeStreams() {
|
285
|
-
try {
|
286
|
-
await this._subscribe();
|
287
|
-
log.trace('_subscribeStreams, this.entity.data=', this.entity.data);
|
288
|
-
const messagesObjectName = this.entity.data.messages;
|
289
|
-
const rosterObjectName = this.entity.data.roster;
|
290
|
-
await Promise.all([
|
291
|
-
this.messagesEntity.subscribe(messagesObjectName),
|
292
|
-
this.participantsEntity.subscribe(rosterObjectName)
|
293
|
-
]);
|
294
|
-
}
|
295
|
-
catch (err) {
|
296
|
-
if (this.services.syncClient.connectionState !== 'disconnected') {
|
297
|
-
log.error('Failed to subscribe on conversation objects', this.sid, err);
|
298
|
-
}
|
299
|
-
log.debug('ERROR: Failed to subscribe on conversation objects', this.sid, err);
|
300
|
-
throw err;
|
301
|
-
}
|
302
|
-
}
|
303
|
-
/**
|
304
|
-
* Stop listening for and firing events on this Conversation.
|
305
|
-
* @returns {Promise}
|
306
|
-
* @private
|
307
|
-
*/
|
308
|
-
async _unsubscribe() {
|
309
|
-
if (this.entity) {
|
310
|
-
await this.entity.close();
|
311
|
-
this.entity = null;
|
312
|
-
this.entityPromise = null;
|
313
|
-
}
|
314
|
-
return Promise.all([
|
315
|
-
this.participantsEntity.unsubscribe(),
|
316
|
-
this.messagesEntity.unsubscribe()
|
317
|
-
]);
|
318
|
-
}
|
319
|
-
/**
|
320
|
-
* Set conversation status
|
321
|
-
* @private
|
322
|
-
*/
|
323
|
-
_setStatus(status, source) {
|
324
|
-
this.statusSource = source;
|
325
|
-
if (this.channelState.status === status) {
|
326
|
-
return;
|
327
|
-
}
|
328
|
-
this.channelState.status = status;
|
329
|
-
if (status === 'joined') {
|
330
|
-
this._subscribeStreams()
|
331
|
-
.catch(err => {
|
332
|
-
log.debug('ERROR while setting conversation status ' + status, err);
|
333
|
-
if (this.services.syncClient.connectionState !== 'disconnected') {
|
334
|
-
throw err;
|
335
|
-
}
|
336
|
-
});
|
337
|
-
}
|
338
|
-
else if (this.entityPromise) {
|
339
|
-
this._unsubscribe().catch(err => {
|
340
|
-
log.debug('ERROR while setting conversation status ' + status, err);
|
341
|
-
if (this.services.syncClient.connectionState !== 'disconnected') {
|
342
|
-
throw err;
|
343
|
-
}
|
344
|
-
});
|
345
|
-
}
|
346
|
-
}
|
347
|
-
/**
|
348
|
-
* If conversation's status update source
|
349
|
-
* @private
|
350
|
-
* @return {Conversations.DataSource}
|
351
|
-
*/
|
352
|
-
_statusSource() {
|
353
|
-
return this.statusSource;
|
354
|
-
}
|
355
|
-
static preprocessUpdate(update, conversationSid) {
|
356
|
-
try {
|
357
|
-
if (typeof update.attributes === 'string') {
|
358
|
-
update.attributes = JSON.parse(update.attributes);
|
359
|
-
}
|
360
|
-
else if (update.attributes) {
|
361
|
-
JSON.stringify(update.attributes);
|
362
|
-
}
|
363
|
-
}
|
364
|
-
catch (e) {
|
365
|
-
log.warn('Retrieved malformed attributes from the server for conversation: ' + conversationSid);
|
366
|
-
update.attributes = {};
|
367
|
-
}
|
368
|
-
try {
|
369
|
-
if (update.dateCreated) {
|
370
|
-
update.dateCreated = new Date(update.dateCreated);
|
371
|
-
}
|
372
|
-
}
|
373
|
-
catch (e) {
|
374
|
-
log.warn('Retrieved malformed dateCreated from the server for conversation: ' + conversationSid);
|
375
|
-
delete update.dateCreated;
|
376
|
-
}
|
377
|
-
try {
|
378
|
-
if (update.dateUpdated) {
|
379
|
-
update.dateUpdated = new Date(update.dateUpdated);
|
380
|
-
}
|
381
|
-
}
|
382
|
-
catch (e) {
|
383
|
-
log.warn('Retrieved malformed dateUpdated from the server for conversation: ' + conversationSid);
|
384
|
-
delete update.dateUpdated;
|
385
|
-
}
|
386
|
-
try {
|
387
|
-
if (update.lastMessage && update.lastMessage.timestamp) {
|
388
|
-
update.lastMessage.timestamp = new Date(update.lastMessage.timestamp);
|
389
|
-
}
|
390
|
-
}
|
391
|
-
catch (e) {
|
392
|
-
log.warn('Retrieved malformed lastMessage.timestamp from the server for conversation: ' + conversationSid);
|
393
|
-
delete update.lastMessage.timestamp;
|
394
|
-
}
|
395
|
-
}
|
396
|
-
/**
|
397
|
-
* Updates local conversation object with new values
|
398
|
-
* @private
|
399
|
-
*/
|
400
|
-
_update(update) {
|
401
|
-
var _a, _b, _c, _d, _e;
|
402
|
-
log.trace('_update', update);
|
403
|
-
Conversation.preprocessUpdate(update, this.sid);
|
404
|
-
const updateReasons = new Set();
|
405
|
-
for (const key of Object.keys(update)) {
|
406
|
-
const localKey = fieldMappings[key];
|
407
|
-
if (!localKey) {
|
408
|
-
continue;
|
409
|
-
}
|
410
|
-
switch (localKey) {
|
411
|
-
case fieldMappings.status:
|
412
|
-
if (!update.status || update.status === 'unknown'
|
413
|
-
|| this.channelState.status === update.status) {
|
414
|
-
break;
|
415
|
-
}
|
416
|
-
this.channelState.status = update.status;
|
417
|
-
updateReasons.add(localKey);
|
418
|
-
break;
|
419
|
-
case fieldMappings.attributes:
|
420
|
-
if (util_1.isDeepEqual(this.channelState.attributes, update.attributes)) {
|
421
|
-
break;
|
422
|
-
}
|
423
|
-
this.channelState.attributes = update.attributes;
|
424
|
-
updateReasons.add(localKey);
|
425
|
-
break;
|
426
|
-
case fieldMappings.lastConsumedMessageIndex:
|
427
|
-
if (update.lastConsumedMessageIndex === undefined
|
428
|
-
|| update.lastConsumedMessageIndex === this.channelState.lastReadMessageIndex) {
|
429
|
-
break;
|
430
|
-
}
|
431
|
-
this.channelState.lastReadMessageIndex = update.lastConsumedMessageIndex;
|
432
|
-
updateReasons.add('lastReadMessageIndex');
|
433
|
-
break;
|
434
|
-
case fieldMappings.lastMessage:
|
435
|
-
if (this.channelState.lastMessage && !update.lastMessage) {
|
436
|
-
delete this.channelState.lastMessage;
|
437
|
-
updateReasons.add(localKey);
|
438
|
-
break;
|
439
|
-
}
|
440
|
-
this.channelState.lastMessage = this.channelState.lastMessage || {};
|
441
|
-
if (((_a = update.lastMessage) === null || _a === void 0 ? void 0 : _a.index) !== undefined
|
442
|
-
&& update.lastMessage.index !== this.channelState.lastMessage.index) {
|
443
|
-
this.channelState.lastMessage.index = update.lastMessage.index;
|
444
|
-
updateReasons.add(localKey);
|
445
|
-
}
|
446
|
-
if (((_b = update.lastMessage) === null || _b === void 0 ? void 0 : _b.timestamp) !== undefined
|
447
|
-
&& ((_d = (_c = this.channelState.lastMessage) === null || _c === void 0 ? void 0 : _c.dateCreated) === null || _d === void 0 ? void 0 : _d.getTime()) !== update.lastMessage.timestamp.getTime()) {
|
448
|
-
this.channelState.lastMessage.dateCreated = update.lastMessage.timestamp;
|
449
|
-
updateReasons.add(localKey);
|
450
|
-
}
|
451
|
-
if (util_1.isDeepEqual(this.channelState.lastMessage, {})) {
|
452
|
-
delete this.channelState.lastMessage;
|
453
|
-
}
|
454
|
-
break;
|
455
|
-
case fieldMappings.state:
|
456
|
-
const state = update.state || undefined;
|
457
|
-
if (state !== undefined) {
|
458
|
-
state.dateUpdated = new Date(state.dateUpdated);
|
459
|
-
}
|
460
|
-
if (util_1.isDeepEqual(this.channelState.state, state)) {
|
461
|
-
break;
|
462
|
-
}
|
463
|
-
this.channelState.state = state;
|
464
|
-
updateReasons.add(localKey);
|
465
|
-
break;
|
466
|
-
case fieldMappings.bindings:
|
467
|
-
if (util_1.isDeepEqual(this.channelState.bindings, update.bindings)) {
|
468
|
-
break;
|
469
|
-
}
|
470
|
-
this.channelState.bindings = update.bindings;
|
471
|
-
updateReasons.add(localKey);
|
472
|
-
break;
|
473
|
-
default:
|
474
|
-
const isDate = update[key] instanceof Date;
|
475
|
-
const keysMatchAsDates = isDate && ((_e = this.channelState[localKey]) === null || _e === void 0 ? void 0 : _e.getTime()) === update[key].getTime();
|
476
|
-
const keysMatchAsNonDates = !isDate && this[localKey] === update[key];
|
477
|
-
if (keysMatchAsDates || keysMatchAsNonDates) {
|
478
|
-
break;
|
479
|
-
}
|
480
|
-
this.channelState[localKey] = update[key];
|
481
|
-
updateReasons.add(localKey);
|
482
|
-
}
|
483
|
-
}
|
484
|
-
if (updateReasons.size > 0) {
|
485
|
-
this.emit('updated', { conversation: this, updateReasons: [...updateReasons] });
|
486
|
-
}
|
487
|
-
}
|
488
|
-
/**
|
489
|
-
* @private
|
490
|
-
*/
|
491
|
-
_onMessageAdded(message) {
|
492
|
-
for (let participant of this.participants.values()) {
|
493
|
-
if (participant.identity === message.author) {
|
494
|
-
participant._endTyping();
|
495
|
-
break;
|
496
|
-
}
|
497
|
-
}
|
498
|
-
this.emit('messageAdded', message);
|
499
|
-
}
|
500
|
-
/**
|
501
|
-
* Add a participant to the Conversation by its Identity.
|
502
|
-
* @param {String} identity - Identity of the Client to add
|
503
|
-
* @param {any} [attributes] Attributes to be attached to the participant
|
504
|
-
* @returns {Promise<void>}
|
505
|
-
*/
|
506
|
-
async add(identity, attributes) {
|
507
|
-
return this.participantsEntity.add(identity, attributes);
|
508
|
-
}
|
509
|
-
/**
|
510
|
-
* Add a non-chat participant to the Conversation.
|
511
|
-
*
|
512
|
-
* @param {String} proxyAddress Proxy (Twilio) address of the participant
|
513
|
-
* @param {String} address User address of the participant
|
514
|
-
* @param {any} [attributes] Attributes to be attached to the participant
|
515
|
-
* @returns {Promise<void>}
|
516
|
-
*/
|
517
|
-
async addNonChatParticipant(proxyAddress, address, attributes = {}) {
|
518
|
-
return this.participantsEntity.addNonChatParticipant(proxyAddress, address, attributes);
|
519
|
-
}
|
520
|
-
/**
|
521
|
-
* Advance Conversation's last read Message index to current read horizon.
|
522
|
-
* Rejects if User is not Participant of Conversation.
|
523
|
-
* Last read Message index is updated only if new index value is higher than previous.
|
524
|
-
* @param {Number} index - Message index to advance to as last read
|
525
|
-
* @returns {Promise<number>} resulting unread messages count in the conversation
|
526
|
-
*/
|
527
|
-
async advanceLastReadMessageIndex(index) {
|
528
|
-
await this._subscribeStreams();
|
529
|
-
return this.services.readHorizon.advanceLastReadMessageIndexForConversation(this.sid, index, this.lastReadMessageIndex);
|
530
|
-
}
|
531
|
-
/**
|
532
|
-
* Delete the Conversation and unsubscribe from its events.
|
533
|
-
* @returns {Promise<Conversation>}
|
534
|
-
*/
|
535
|
-
async delete() {
|
536
|
-
await this.services.session.addCommand('destroyChannel', {
|
537
|
-
channelSid: this.sid
|
538
|
-
});
|
539
|
-
return this;
|
540
|
-
}
|
541
|
-
/**
|
542
|
-
* Get the custom attributes of this Conversation.
|
543
|
-
* @returns {Promise<any>} attributes of this Conversation
|
544
|
-
*/
|
545
|
-
async getAttributes() {
|
546
|
-
await this._subscribe();
|
547
|
-
return this.attributes;
|
548
|
-
}
|
549
|
-
/**
|
550
|
-
* Returns messages from conversation using paginator interface.
|
551
|
-
* @param {Number} [pageSize=30] Number of messages to return in single chunk
|
552
|
-
* @param {Number} [anchor] - Index of newest Message to fetch. From the end by default
|
553
|
-
* @param {('backwards'|'forward')} [direction=backwards] - Query direction. By default it query backwards
|
554
|
-
* from newer to older. 'forward' will query in opposite direction
|
555
|
-
* @returns {Promise<Paginator<Message>>} page of messages
|
556
|
-
*/
|
557
|
-
async getMessages(pageSize, anchor, direction) {
|
558
|
-
await this._subscribeStreams();
|
559
|
-
return this.messagesEntity.getMessages(pageSize, anchor, direction);
|
560
|
-
}
|
561
|
-
/**
|
562
|
-
* Get a list of all Participants joined to this Conversation.
|
563
|
-
* @returns {Promise<Participant[]>}
|
564
|
-
*/
|
565
|
-
async getParticipants() {
|
566
|
-
await this._subscribeStreams();
|
567
|
-
return this.participantsEntity.getParticipants();
|
568
|
-
}
|
569
|
-
/**
|
570
|
-
* Get conversation participants count.
|
571
|
-
* <br/>
|
572
|
-
* This method is semi-realtime. This means that this data will be eventually correct,
|
573
|
-
* but will also possibly be incorrect for a few seconds. The Conversation system does not
|
574
|
-
* provide real time events for counter values changes.
|
575
|
-
* <br/>
|
576
|
-
* So this is quite useful for any UI badges, but is not recommended
|
577
|
-
* to build any core application logic based on these counters being accurate in real time.
|
578
|
-
* @returns {Promise<number>}
|
579
|
-
*/
|
580
|
-
async getParticipantsCount() {
|
581
|
-
let links = await this.services.session.getSessionLinks();
|
582
|
-
let url = new util_1.UriBuilder(links.publicChannelsUrl).path(this.sid).build();
|
583
|
-
let response = await this.services.network.get(url);
|
584
|
-
return response.body.members_count;
|
585
|
-
}
|
586
|
-
/**
|
587
|
-
* Get a Participant by its SID.
|
588
|
-
* @param {String} participantSid - Participant sid
|
589
|
-
* @returns {Promise<Participant>}
|
590
|
-
*/
|
591
|
-
async getParticipantBySid(participantSid) {
|
592
|
-
return this.participantsEntity.getParticipantBySid(participantSid);
|
593
|
-
}
|
594
|
-
/**
|
595
|
-
* Get a Participant by its identity.
|
596
|
-
* @param {String} identity - Participant identity
|
597
|
-
* @returns {Promise<Participant>}
|
598
|
-
*/
|
599
|
-
async getParticipantByIdentity(identity) {
|
600
|
-
return this.participantsEntity.getParticipantByIdentity(identity);
|
601
|
-
}
|
602
|
-
/**
|
603
|
-
* Get total message count in a conversation.
|
604
|
-
* <br/>
|
605
|
-
* This method is semi-realtime. This means that this data will be eventually correct,
|
606
|
-
* but will also possibly be incorrect for a few seconds. The Conversations system does not
|
607
|
-
* provide real time events for counter values changes.
|
608
|
-
* <br/>
|
609
|
-
* So this is quite useful for any UI badges, but is not recommended
|
610
|
-
* to build any core application logic based on these counters being accurate in real time.
|
611
|
-
* @returns {Promise<number>}
|
612
|
-
*/
|
613
|
-
async getMessagesCount() {
|
614
|
-
let links = await this.services.session.getSessionLinks();
|
615
|
-
let url = new util_1.UriBuilder(links.publicChannelsUrl).path(this.sid).build();
|
616
|
-
let response = await this.services.network.get(url);
|
617
|
-
return response.body.messages_count;
|
618
|
-
}
|
619
|
-
/**
|
620
|
-
* Get unread messages count for the User if they are a Participant of this Conversation.
|
621
|
-
* Rejects if the User is not a Participant of the Conversation.
|
622
|
-
* <br/>
|
623
|
-
* Use this method to obtain the number of unread messages together with
|
624
|
-
* updateLastReadMessageIndex() instead of relying on the
|
625
|
-
* Message indices which may have gaps. See Message.index for details.
|
626
|
-
* <br/>
|
627
|
-
* This method is semi-realtime. This means that this data will be eventually correct,
|
628
|
-
* but will also possibly be incorrect for a few seconds. The Chat system does not
|
629
|
-
* provide real time events for counter values changes.
|
630
|
-
* <br/>
|
631
|
-
* This is quite useful for any “unread messages count” badges, but is not recommended
|
632
|
-
* to build any core application logic based on these counters being accurate in real time.
|
633
|
-
* @returns {Promise<number|null>}
|
634
|
-
*/
|
635
|
-
async getUnreadMessagesCount() {
|
636
|
-
let links = await this.services.session.getSessionLinks();
|
637
|
-
let url = new util_1.UriBuilder(links.myChannelsUrl).arg('ChannelSid', this.sid).build();
|
638
|
-
let response = await this.services.network.get(url);
|
639
|
-
if (response.body.channels.length && response.body.channels[0].channel_sid == this.sid) {
|
640
|
-
if ((typeof response.body.channels[0].unread_messages_count !== 'undefined') && response.body.channels[0].unread_messages_count != null) {
|
641
|
-
return response.body.channels[0].unread_messages_count;
|
642
|
-
}
|
643
|
-
return null;
|
644
|
-
}
|
645
|
-
throw new Error('Conversation is not in user conversations list');
|
646
|
-
}
|
647
|
-
/**
|
648
|
-
* Join the Conversation and subscribe to its events.
|
649
|
-
* @returns {Promise<Conversation>}
|
650
|
-
*/
|
651
|
-
async join() {
|
652
|
-
await this.services.session.addCommand('joinChannelV2', { channelSid: this.sid });
|
653
|
-
return this;
|
654
|
-
}
|
655
|
-
/**
|
656
|
-
* Leave the Conversation.
|
657
|
-
* @returns {Promise<Conversation>}
|
658
|
-
*/
|
659
|
-
async leave() {
|
660
|
-
if (this.channelState.status === 'joined') {
|
661
|
-
await this.services.session.addCommand('leaveChannel', { channelSid: this.sid });
|
662
|
-
}
|
663
|
-
return this;
|
664
|
-
}
|
665
|
-
/**
|
666
|
-
* Remove a Participant from the Conversation. When a string is passed as the argument, it will assume that the string is an identity.
|
667
|
-
* @param {String|Participant} participant - identity or participant object to remove
|
668
|
-
* @returns {Promise<void>}
|
669
|
-
*/
|
670
|
-
async removeParticipant(participant) {
|
671
|
-
if (participant instanceof participant_1.Participant) {
|
672
|
-
await this.participantsEntity.removeBySid(participant.sid);
|
673
|
-
return;
|
674
|
-
}
|
675
|
-
await this.participantsEntity.removeByIdentity(participant);
|
676
|
-
}
|
677
|
-
/**
|
678
|
-
* Send a Message in the Conversation.
|
679
|
-
* @param {String|FormData|Conversation#SendMediaOptions|null} message - The message body for text message,
|
680
|
-
* FormData or MediaOptions for media content. Sending FormData supported only with browser engine
|
681
|
-
* @param {any} [messageAttributes] - attributes for the message
|
682
|
-
* @param {Conversation#SendEmailOptions} [emailOptions] - email options for the message
|
683
|
-
* @returns {Promise<number>} new Message's index in the Conversation's messages list
|
684
|
-
*/
|
685
|
-
async sendMessage(message, messageAttributes, emailOptions) {
|
686
|
-
if (typeof message === 'string' || message === null) {
|
687
|
-
let response = await this.messagesEntity.send(message, messageAttributes, emailOptions);
|
688
|
-
return util_1.parseToNumber(response.messageId);
|
689
|
-
}
|
690
|
-
let response = await this.messagesEntity.sendMedia(message, messageAttributes, emailOptions);
|
691
|
-
return util_1.parseToNumber(response.messageId);
|
692
|
-
}
|
693
|
-
prepareMessage() {
|
694
|
-
return new MessageBuilder(this.limits, this.messagesEntity);
|
695
|
-
}
|
696
|
-
/**
|
697
|
-
* Set last read Conversation's Message index to last known Message's index in this Conversation.
|
698
|
-
* @returns {Promise<number>} resulting unread messages count in the conversation
|
699
|
-
*/
|
700
|
-
async setAllMessagesRead() {
|
701
|
-
await this._subscribeStreams();
|
702
|
-
let messagesPage = await this.getMessages(1);
|
703
|
-
if (messagesPage.items.length > 0) {
|
704
|
-
return this.advanceLastReadMessageIndex(messagesPage.items[0].index);
|
705
|
-
}
|
706
|
-
return Promise.resolve(0);
|
707
|
-
}
|
708
|
-
/**
|
709
|
-
* Set all messages in the conversation unread.
|
710
|
-
* @returns {Promise<number>} resulting unread messages count in the conversation
|
711
|
-
*/
|
712
|
-
async setAllMessagesUnread() {
|
713
|
-
await this._subscribeStreams();
|
714
|
-
return this.services.readHorizon.updateLastReadMessageIndexForConversation(this.sid, null);
|
715
|
-
}
|
716
|
-
/**
|
717
|
-
* Set User Notification level for this conversation.
|
718
|
-
* @param {Conversation#NotificationLevel} notificationLevel - The new user notification level
|
719
|
-
* @returns {Promise<void>}
|
720
|
-
*/
|
721
|
-
async setUserNotificationLevel(notificationLevel) {
|
722
|
-
await this.services.session.addCommand('editNotificationLevel', { channelSid: this.sid, notificationLevel: notificationLevel });
|
723
|
-
}
|
724
|
-
/**
|
725
|
-
* Send a notification to the server indicating that this Client is currently typing in this Conversation.
|
726
|
-
* Typing ended notification is sent after a while automatically, but by calling again this method you ensure typing ended is not received.
|
727
|
-
* @returns {Promise<void>}
|
728
|
-
*/
|
729
|
-
typing() {
|
730
|
-
return this.services.typingIndicator.send(this.sid);
|
731
|
-
}
|
732
|
-
/**
|
733
|
-
* Update the Conversation's attributes.
|
734
|
-
* @param {any} attributes - The new attributes object
|
735
|
-
* @returns {Promise<Conversation>}
|
736
|
-
*/
|
737
|
-
async updateAttributes(attributes) {
|
738
|
-
await this.services.session.addCommand('editAttributes', {
|
739
|
-
channelSid: this.sid,
|
740
|
-
attributes: JSON.stringify(attributes)
|
741
|
-
});
|
742
|
-
return this;
|
743
|
-
}
|
744
|
-
/**
|
745
|
-
* Update the Conversation's friendlyName.
|
746
|
-
* @param {String|null} name - The new Conversation friendlyName
|
747
|
-
* @returns {Promise<Conversation>}
|
748
|
-
*/
|
749
|
-
async updateFriendlyName(name) {
|
750
|
-
if (this.channelState.friendlyName !== name) {
|
751
|
-
await this.services.session.addCommand('editFriendlyName', {
|
752
|
-
channelSid: this.sid,
|
753
|
-
friendlyName: name
|
754
|
-
});
|
755
|
-
}
|
756
|
-
return this;
|
757
|
-
}
|
758
|
-
/**
|
759
|
-
* Set Conversation's last read Message index to current read horizon.
|
760
|
-
* @param {Number|null} index - Message index to set as last read.
|
761
|
-
* If null provided, then the behavior is identical to {@link Conversation#setAllMessagesUnread}
|
762
|
-
* @returns {Promise<number>} resulting unread messages count in the conversation
|
763
|
-
*/
|
764
|
-
async updateLastReadMessageIndex(index) {
|
765
|
-
await this._subscribeStreams();
|
766
|
-
return this.services.readHorizon.updateLastReadMessageIndexForConversation(this.sid, index);
|
767
|
-
}
|
768
|
-
/**
|
769
|
-
* Update the Conversation's unique name.
|
770
|
-
* @param {String|null} uniqueName - New unique name for the Conversation. Setting unique name to null removes it.
|
771
|
-
* @returns {Promise<Conversation>}
|
772
|
-
*/
|
773
|
-
async updateUniqueName(uniqueName) {
|
774
|
-
if (this.channelState.uniqueName !== uniqueName) {
|
775
|
-
if (!uniqueName) {
|
776
|
-
uniqueName = '';
|
777
|
-
}
|
778
|
-
await this.services.session.addCommand('editUniqueName', {
|
779
|
-
channelSid: this.sid,
|
780
|
-
uniqueName: uniqueName
|
781
|
-
});
|
782
|
-
}
|
783
|
-
return this;
|
784
|
-
}
|
785
|
-
}
|
786
|
-
__decorate([
|
787
|
-
twilio_sdk_type_validator_1.validateTypesAsync(twilio_sdk_type_validator_1.nonEmptyString, ['undefined', 'string', 'number', 'boolean', 'object', twilio_sdk_type_validator_1.literal(null)]),
|
788
|
-
__metadata("design:type", Function),
|
789
|
-
__metadata("design:paramtypes", [String, Object]),
|
790
|
-
__metadata("design:returntype", Promise)
|
791
|
-
], Conversation.prototype, "add", null);
|
792
|
-
__decorate([
|
793
|
-
twilio_sdk_type_validator_1.validateTypesAsync(twilio_sdk_type_validator_1.nonEmptyString, twilio_sdk_type_validator_1.nonEmptyString, ['undefined', 'object']),
|
794
|
-
__metadata("design:type", Function),
|
795
|
-
__metadata("design:paramtypes", [String, String, Object]),
|
796
|
-
__metadata("design:returntype", Promise)
|
797
|
-
], Conversation.prototype, "addNonChatParticipant", null);
|
798
|
-
__decorate([
|
799
|
-
twilio_sdk_type_validator_1.validateTypesAsync(twilio_sdk_type_validator_1.nonNegativeInteger),
|
800
|
-
__metadata("design:type", Function),
|
801
|
-
__metadata("design:paramtypes", [Number]),
|
802
|
-
__metadata("design:returntype", Promise)
|
803
|
-
], Conversation.prototype, "advanceLastReadMessageIndex", null);
|
804
|
-
__decorate([
|
805
|
-
twilio_sdk_type_validator_1.validateTypesAsync(['undefined', twilio_sdk_type_validator_1.nonNegativeInteger], ['undefined', twilio_sdk_type_validator_1.nonNegativeInteger], ['undefined', twilio_sdk_type_validator_1.literal('backwards', 'forward')]),
|
806
|
-
__metadata("design:type", Function),
|
807
|
-
__metadata("design:paramtypes", [Number, Number, String]),
|
808
|
-
__metadata("design:returntype", Promise)
|
809
|
-
], Conversation.prototype, "getMessages", null);
|
810
|
-
__decorate([
|
811
|
-
twilio_sdk_type_validator_1.validateTypesAsync(twilio_sdk_type_validator_1.nonEmptyString),
|
812
|
-
__metadata("design:type", Function),
|
813
|
-
__metadata("design:paramtypes", [String]),
|
814
|
-
__metadata("design:returntype", Promise)
|
815
|
-
], Conversation.prototype, "getParticipantBySid", null);
|
816
|
-
__decorate([
|
817
|
-
twilio_sdk_type_validator_1.validateTypesAsync(twilio_sdk_type_validator_1.nonEmptyString),
|
818
|
-
__metadata("design:type", Function),
|
819
|
-
__metadata("design:paramtypes", [String]),
|
820
|
-
__metadata("design:returntype", Promise)
|
821
|
-
], Conversation.prototype, "getParticipantByIdentity", null);
|
822
|
-
__decorate([
|
823
|
-
twilio_sdk_type_validator_1.validateTypesAsync([twilio_sdk_type_validator_1.nonEmptyString, participant_1.Participant]),
|
824
|
-
__metadata("design:type", Function),
|
825
|
-
__metadata("design:paramtypes", [Object]),
|
826
|
-
__metadata("design:returntype", Promise)
|
827
|
-
], Conversation.prototype, "removeParticipant", null);
|
828
|
-
__decorate([
|
829
|
-
twilio_sdk_type_validator_1.validateTypesAsync([
|
830
|
-
'string',
|
831
|
-
twilio_sdk_type_validator_1.literal(null),
|
832
|
-
// Wrapping it into a custom rule is necessary because the FormData class is not available on initialization.
|
833
|
-
twilio_sdk_type_validator_1.custom((value) => [value instanceof FormData, 'an instance of FormData']),
|
834
|
-
twilio_sdk_type_validator_1.objectSchema('media options', {
|
835
|
-
contentType: twilio_sdk_type_validator_1.nonEmptyString,
|
836
|
-
media: twilio_sdk_type_validator_1.custom((value) => {
|
837
|
-
let isValid = (typeof value === 'string' && value.length > 0) || value instanceof Uint8Array || value instanceof ArrayBuffer;
|
838
|
-
if (typeof Blob === 'function') {
|
839
|
-
isValid = isValid || value instanceof Blob;
|
840
|
-
}
|
841
|
-
return [
|
842
|
-
isValid,
|
843
|
-
'a non-empty string, an instance of Buffer or an instance of Blob'
|
844
|
-
];
|
845
|
-
})
|
846
|
-
})
|
847
|
-
], ['undefined', 'string', 'number', 'boolean', 'object', twilio_sdk_type_validator_1.literal(null)], ['undefined', twilio_sdk_type_validator_1.literal(null), twilio_sdk_type_validator_1.objectSchema('email attributes', {
|
848
|
-
subject: [twilio_sdk_type_validator_1.nonEmptyString, 'undefined']
|
849
|
-
})]),
|
850
|
-
__metadata("design:type", Function),
|
851
|
-
__metadata("design:paramtypes", [Object, Object, Object]),
|
852
|
-
__metadata("design:returntype", Promise)
|
853
|
-
], Conversation.prototype, "sendMessage", null);
|
854
|
-
__decorate([
|
855
|
-
twilio_sdk_type_validator_1.validateTypesAsync(twilio_sdk_type_validator_1.literal('default', 'muted')),
|
856
|
-
__metadata("design:type", Function),
|
857
|
-
__metadata("design:paramtypes", [String]),
|
858
|
-
__metadata("design:returntype", Promise)
|
859
|
-
], Conversation.prototype, "setUserNotificationLevel", null);
|
860
|
-
__decorate([
|
861
|
-
twilio_sdk_type_validator_1.validateTypesAsync(['string', 'number', 'boolean', 'object', twilio_sdk_type_validator_1.literal(null)]),
|
862
|
-
__metadata("design:type", Function),
|
863
|
-
__metadata("design:paramtypes", [Object]),
|
864
|
-
__metadata("design:returntype", Promise)
|
865
|
-
], Conversation.prototype, "updateAttributes", null);
|
866
|
-
__decorate([
|
867
|
-
twilio_sdk_type_validator_1.validateTypesAsync(['string', twilio_sdk_type_validator_1.literal(null)]),
|
868
|
-
__metadata("design:type", Function),
|
869
|
-
__metadata("design:paramtypes", [String]),
|
870
|
-
__metadata("design:returntype", Promise)
|
871
|
-
], Conversation.prototype, "updateFriendlyName", null);
|
872
|
-
__decorate([
|
873
|
-
twilio_sdk_type_validator_1.validateTypesAsync([twilio_sdk_type_validator_1.literal(null), twilio_sdk_type_validator_1.nonNegativeInteger]),
|
874
|
-
__metadata("design:type", Function),
|
875
|
-
__metadata("design:paramtypes", [Number]),
|
876
|
-
__metadata("design:returntype", Promise)
|
877
|
-
], Conversation.prototype, "updateLastReadMessageIndex", null);
|
878
|
-
__decorate([
|
879
|
-
twilio_sdk_type_validator_1.validateTypesAsync(['string', twilio_sdk_type_validator_1.literal(null)]),
|
880
|
-
__metadata("design:type", Function),
|
881
|
-
__metadata("design:paramtypes", [String]),
|
882
|
-
__metadata("design:returntype", Promise)
|
883
|
-
], Conversation.prototype, "updateUniqueName", null);
|
884
|
-
exports.Conversation = Conversation;
|
885
|
-
/**
|
886
|
-
* Fired when a Participant has joined the Conversation.
|
887
|
-
* @event Conversation#participantJoined
|
888
|
-
* @type {Participant}
|
889
|
-
*/
|
890
|
-
/**
|
891
|
-
* Fired when a Participant has left the Conversation.
|
892
|
-
* @event Conversation#participantLeft
|
893
|
-
* @type {Participant}
|
894
|
-
*/
|
895
|
-
/**
|
896
|
-
* Fired when a Participant's fields has been updated.
|
897
|
-
* @event Conversation#participantUpdated
|
898
|
-
* @type {Object}
|
899
|
-
* @property {Participant} participant - Updated Participant
|
900
|
-
* @property {Participant#UpdateReason[]} updateReasons - Array of Participant's updated event reasons
|
901
|
-
*/
|
902
|
-
/**
|
903
|
-
* Fired when a new Message has been added to the Conversation.
|
904
|
-
* @event Conversation#messageAdded
|
905
|
-
* @type {Message}
|
906
|
-
*/
|
907
|
-
/**
|
908
|
-
* Fired when Message is removed from Conversation's message list.
|
909
|
-
* @event Conversation#messageRemoved
|
910
|
-
* @type {Message}
|
911
|
-
*/
|
912
|
-
/**
|
913
|
-
* Fired when an existing Message's fields are updated with new values.
|
914
|
-
* @event Conversation#messageUpdated
|
915
|
-
* @type {Object}
|
916
|
-
* @property {Message} message - Updated Message
|
917
|
-
* @property {Message#UpdateReason[]} updateReasons - Array of Message's updated event reasons
|
918
|
-
*/
|
919
|
-
/**
|
920
|
-
* Fired when a Participant has stopped typing.
|
921
|
-
* @event Conversation#typingEnded
|
922
|
-
* @type {Participant}
|
923
|
-
*/
|
924
|
-
/**
|
925
|
-
* Fired when a Participant has started typing.
|
926
|
-
* @event Conversation#typingStarted
|
927
|
-
* @type {Participant}
|
928
|
-
*/
|
929
|
-
/**
|
930
|
-
* Fired when a Conversation's attributes or metadata have been updated.
|
931
|
-
* @event Conversation#updated
|
932
|
-
* @type {Object}
|
933
|
-
* @property {Conversation} conversation - Updated Conversation
|
934
|
-
* @property {Conversation#UpdateReason[]} updateReasons - Array of Conversation's updated event reasons
|
935
|
-
*/
|
936
|
-
/**
|
937
|
-
* Fired when the Conversation was destroyed or currently logged in User has left private Conversation
|
938
|
-
* @event Conversation#removed
|
939
|
-
* @type {Conversation}
|
940
|
-
*/
|