@webex/internal-plugin-presence 2.59.2 → 2.59.3-next.1

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/src/presence.js CHANGED
@@ -1,262 +1,262 @@
1
- /*!
2
- * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
3
- */
4
-
5
- import '@webex/internal-plugin-device';
6
-
7
- import {WebexPlugin} from '@webex/webex-core';
8
-
9
- import PresenceBatcher from './presence-batcher';
10
- import PresenceWorker from './presence-worker';
11
-
12
- const defaultSubscriptionTtl = 600;
13
- const USER = 'user';
14
- const USER_PRESENCE_ENABLED = 'user-presence-enabled';
15
-
16
- /**
17
- * @class
18
- * @extends WebexPlugin
19
- */
20
- const Presence = WebexPlugin.extend({
21
- namespace: 'Presence',
22
-
23
- children: {
24
- batcher: PresenceBatcher,
25
- },
26
-
27
- session: {
28
- worker: {
29
- default() {
30
- return new PresenceWorker();
31
- },
32
- type: 'any',
33
- },
34
- },
35
-
36
- /**
37
- * Initialize the presence worker for client
38
- * @returns {undefined}
39
- */
40
- initialize() {
41
- this.webex.once('ready', () => {
42
- if (this.config.initializeWorker) {
43
- this.worker.initialize(this.webex);
44
- }
45
- });
46
- },
47
-
48
- /**
49
- * Trigger an event.
50
- * @param {string} event
51
- * @param {string} payload
52
- * @returns {undefined}
53
- */
54
- emitEvent(event, payload) {
55
- if (payload.type && payload.payload) {
56
- this.trigger(event, payload);
57
- }
58
- },
59
-
60
- /**
61
- * Enables presence feature
62
- * @returns {Promise<boolean>} resolves with true, if successful
63
- */
64
- enable() {
65
- return this.webex.internal.feature
66
- .setFeature(USER, USER_PRESENCE_ENABLED, true)
67
- .then((response) => response.value);
68
- },
69
-
70
- /**
71
- * Disables presence feature
72
- * @returns {Promise<boolean>} resolves with false, if successful
73
- */
74
- disable() {
75
- return this.webex.internal.feature
76
- .setFeature(USER, USER_PRESENCE_ENABLED, false)
77
- .then((response) => response.value);
78
- },
79
-
80
- /**
81
- * Returns true if presence is enabled, false otherwise
82
- * @returns {Promise<boolean>} resolves with true if presence is enabled
83
- */
84
- isEnabled() {
85
- return this.webex.internal.feature.getFeature(USER, USER_PRESENCE_ENABLED);
86
- },
87
-
88
- /**
89
- * The status object
90
- * @typedef {Object} PresenceStatusObject
91
- * @property {string} url: Public resource identifier for presence
92
- * @property {string} subject: User ID for the user the returned composed presence represents
93
- * @property {string} status: Current composed presence state
94
- * @property {string} statusTime: DateTime in RFC3339 format that the current status began
95
- * @property {string} lastActive: DateTime in RFC3339 format that the service last saw activity from the user.
96
- * @property {string} expires: DEPRECATED - DateTime in RFC3339 format that represents when the current
97
- * status will expire. Will not exist if expiresTTL is -1.
98
- * @property {Number} expiresTTL: TTL in seconds until the status will expire. If TTL is -1 the current
99
- * status has no known expiration.
100
- * @property {string} expiresTime: DateTime in RFC3339 format that the current status will expire. Missing
101
- * field means no known expiration.
102
- * @property {Object} vectorCounters: Used for packet ordering and tracking.
103
- * @property {Boolean} suppressNotifications: Indicates if notification suppression is recommended for this status.
104
- * @property {string} lastSeenDeviceUrl: Resource Identifier of the last device to post presence activity for
105
- * this user.
106
- */
107
-
108
- /**
109
- * Gets the current presence status of a given person id
110
- * @param {string} personId
111
- * @returns {Promise<PresenceStatusObject>} resolves with status object of person
112
- */
113
- get(personId) {
114
- if (!personId) {
115
- return Promise.reject(new Error('A person id is required'));
116
- }
117
-
118
- return this.webex
119
- .request({
120
- method: 'GET',
121
- service: 'apheleia',
122
- resource: `compositions?userId=${personId}`,
123
- })
124
- .then((response) => response.body);
125
- },
126
-
127
- /**
128
- * @typedef {Object} PresenceStatusesObject
129
- * @property {Array.<PresenceStatusObject>} statusList
130
- */
131
- /**
132
- * Gets the current presence statuses of an array of people ids
133
- * @param {Array} personIds
134
- * @returns {Promise<PresenceStatusesObject>} resolves with an object with key of `statusList` array
135
- */
136
- list(personIds) {
137
- if (!personIds || !Array.isArray(personIds)) {
138
- return Promise.reject(new Error('An array of person ids is required'));
139
- }
140
-
141
- return Promise.all(personIds.map((id) => this.batcher.request(id))).then((presences) => ({
142
- statusList: presences,
143
- }));
144
- },
145
-
146
- /**
147
- * Subscribes to a person's presence status updates
148
- * Updates are sent via mercury events `apheleia.subscription_update`
149
- * @param {string | Array} personIds
150
- * @param {number} subscriptionTtl - Requested length of subscriptions in seconds.
151
- * @returns {Promise}
152
- */
153
- subscribe(personIds, subscriptionTtl = defaultSubscriptionTtl) {
154
- let subjects;
155
- const batches = [];
156
- const batchLimit = 50;
157
-
158
- if (!personIds) {
159
- return Promise.reject(new Error('A person id is required'));
160
- }
161
- if (Array.isArray(personIds)) {
162
- subjects = personIds;
163
- } else {
164
- subjects = [personIds];
165
- }
166
- // Limit batches to 50 ids per request
167
- for (let i = 0; i < subjects.length; i += batchLimit) {
168
- batches.push(subjects.slice(i, i + batchLimit));
169
- }
170
-
171
- return Promise.all(
172
- batches.map((ids) =>
173
- this.webex
174
- .request({
175
- method: 'POST',
176
- api: 'apheleia',
177
- resource: 'subscriptions',
178
- body: {
179
- subjects: ids,
180
- subscriptionTtl,
181
- includeStatus: true,
182
- },
183
- })
184
- .then((response) => response.body.responses)
185
- )
186
- ).then((idBatches) => ({responses: [].concat(...idBatches)}));
187
- },
188
-
189
- /**
190
- * Unsubscribes from a person or group of people's presence subscription
191
- * @param {string | Array} personIds
192
- * @returns {Promise}
193
- */
194
- unsubscribe(personIds) {
195
- let subjects;
196
-
197
- if (!personIds) {
198
- return Promise.reject(new Error('A person id is required'));
199
- }
200
- if (Array.isArray(personIds)) {
201
- subjects = personIds;
202
- } else {
203
- subjects = [personIds];
204
- }
205
-
206
- return this.webex.request({
207
- method: 'POST',
208
- api: 'apheleia',
209
- resource: 'subscriptions',
210
- body: {
211
- subjects,
212
- subscriptionTtl: 0,
213
- includeStatus: true,
214
- },
215
- });
216
- },
217
-
218
- /**
219
- * Sets the status of the current user
220
- * @param {string} status - active | inactive | ooo | dnd
221
- * @param {number} ttl - Time To Live for the event in seconds.
222
- * @returns {Promise}
223
- */
224
- setStatus(status, ttl) {
225
- if (!status) {
226
- return Promise.reject(new Error('A status is required'));
227
- }
228
-
229
- return this.webex
230
- .request({
231
- method: 'POST',
232
- api: 'apheleia',
233
- resource: 'events',
234
- body: {
235
- subject: this.webex.internal.device.userId,
236
- eventType: status,
237
- ttl,
238
- },
239
- })
240
- .then((response) => response.body);
241
- },
242
-
243
- /**
244
- * Retrieves and subscribes to a user's presence.
245
- * @param {string} id
246
- * @returns {undefined}
247
- */
248
- enqueue(id) {
249
- return this.worker.enqueue(id);
250
- },
251
-
252
- /**
253
- * Retract from subscribing to a user's presence.
254
- * @param {string} id
255
- * @returns {undefined}
256
- */
257
- dequeue(id) {
258
- return this.worker.dequeue(id);
259
- },
260
- });
261
-
262
- export default Presence;
1
+ /*!
2
+ * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
3
+ */
4
+
5
+ import '@webex/internal-plugin-device';
6
+
7
+ import {WebexPlugin} from '@webex/webex-core';
8
+
9
+ import PresenceBatcher from './presence-batcher';
10
+ import PresenceWorker from './presence-worker';
11
+
12
+ const defaultSubscriptionTtl = 600;
13
+ const USER = 'user';
14
+ const USER_PRESENCE_ENABLED = 'user-presence-enabled';
15
+
16
+ /**
17
+ * @class
18
+ * @extends WebexPlugin
19
+ */
20
+ const Presence = WebexPlugin.extend({
21
+ namespace: 'Presence',
22
+
23
+ children: {
24
+ batcher: PresenceBatcher,
25
+ },
26
+
27
+ session: {
28
+ worker: {
29
+ default() {
30
+ return new PresenceWorker();
31
+ },
32
+ type: 'any',
33
+ },
34
+ },
35
+
36
+ /**
37
+ * Initialize the presence worker for client
38
+ * @returns {undefined}
39
+ */
40
+ initialize() {
41
+ this.webex.once('ready', () => {
42
+ if (this.config.initializeWorker) {
43
+ this.worker.initialize(this.webex);
44
+ }
45
+ });
46
+ },
47
+
48
+ /**
49
+ * Trigger an event.
50
+ * @param {string} event
51
+ * @param {string} payload
52
+ * @returns {undefined}
53
+ */
54
+ emitEvent(event, payload) {
55
+ if (payload.type && payload.payload) {
56
+ this.trigger(event, payload);
57
+ }
58
+ },
59
+
60
+ /**
61
+ * Enables presence feature
62
+ * @returns {Promise<boolean>} resolves with true, if successful
63
+ */
64
+ enable() {
65
+ return this.webex.internal.feature
66
+ .setFeature(USER, USER_PRESENCE_ENABLED, true)
67
+ .then((response) => response.value);
68
+ },
69
+
70
+ /**
71
+ * Disables presence feature
72
+ * @returns {Promise<boolean>} resolves with false, if successful
73
+ */
74
+ disable() {
75
+ return this.webex.internal.feature
76
+ .setFeature(USER, USER_PRESENCE_ENABLED, false)
77
+ .then((response) => response.value);
78
+ },
79
+
80
+ /**
81
+ * Returns true if presence is enabled, false otherwise
82
+ * @returns {Promise<boolean>} resolves with true if presence is enabled
83
+ */
84
+ isEnabled() {
85
+ return this.webex.internal.feature.getFeature(USER, USER_PRESENCE_ENABLED);
86
+ },
87
+
88
+ /**
89
+ * The status object
90
+ * @typedef {Object} PresenceStatusObject
91
+ * @property {string} url: Public resource identifier for presence
92
+ * @property {string} subject: User ID for the user the returned composed presence represents
93
+ * @property {string} status: Current composed presence state
94
+ * @property {string} statusTime: DateTime in RFC3339 format that the current status began
95
+ * @property {string} lastActive: DateTime in RFC3339 format that the service last saw activity from the user.
96
+ * @property {string} expires: DEPRECATED - DateTime in RFC3339 format that represents when the current
97
+ * status will expire. Will not exist if expiresTTL is -1.
98
+ * @property {Number} expiresTTL: TTL in seconds until the status will expire. If TTL is -1 the current
99
+ * status has no known expiration.
100
+ * @property {string} expiresTime: DateTime in RFC3339 format that the current status will expire. Missing
101
+ * field means no known expiration.
102
+ * @property {Object} vectorCounters: Used for packet ordering and tracking.
103
+ * @property {Boolean} suppressNotifications: Indicates if notification suppression is recommended for this status.
104
+ * @property {string} lastSeenDeviceUrl: Resource Identifier of the last device to post presence activity for
105
+ * this user.
106
+ */
107
+
108
+ /**
109
+ * Gets the current presence status of a given person id
110
+ * @param {string} personId
111
+ * @returns {Promise<PresenceStatusObject>} resolves with status object of person
112
+ */
113
+ get(personId) {
114
+ if (!personId) {
115
+ return Promise.reject(new Error('A person id is required'));
116
+ }
117
+
118
+ return this.webex
119
+ .request({
120
+ method: 'GET',
121
+ service: 'apheleia',
122
+ resource: `compositions?userId=${personId}`,
123
+ })
124
+ .then((response) => response.body);
125
+ },
126
+
127
+ /**
128
+ * @typedef {Object} PresenceStatusesObject
129
+ * @property {Array.<PresenceStatusObject>} statusList
130
+ */
131
+ /**
132
+ * Gets the current presence statuses of an array of people ids
133
+ * @param {Array} personIds
134
+ * @returns {Promise<PresenceStatusesObject>} resolves with an object with key of `statusList` array
135
+ */
136
+ list(personIds) {
137
+ if (!personIds || !Array.isArray(personIds)) {
138
+ return Promise.reject(new Error('An array of person ids is required'));
139
+ }
140
+
141
+ return Promise.all(personIds.map((id) => this.batcher.request(id))).then((presences) => ({
142
+ statusList: presences,
143
+ }));
144
+ },
145
+
146
+ /**
147
+ * Subscribes to a person's presence status updates
148
+ * Updates are sent via mercury events `apheleia.subscription_update`
149
+ * @param {string | Array} personIds
150
+ * @param {number} subscriptionTtl - Requested length of subscriptions in seconds.
151
+ * @returns {Promise}
152
+ */
153
+ subscribe(personIds, subscriptionTtl = defaultSubscriptionTtl) {
154
+ let subjects;
155
+ const batches = [];
156
+ const batchLimit = 50;
157
+
158
+ if (!personIds) {
159
+ return Promise.reject(new Error('A person id is required'));
160
+ }
161
+ if (Array.isArray(personIds)) {
162
+ subjects = personIds;
163
+ } else {
164
+ subjects = [personIds];
165
+ }
166
+ // Limit batches to 50 ids per request
167
+ for (let i = 0; i < subjects.length; i += batchLimit) {
168
+ batches.push(subjects.slice(i, i + batchLimit));
169
+ }
170
+
171
+ return Promise.all(
172
+ batches.map((ids) =>
173
+ this.webex
174
+ .request({
175
+ method: 'POST',
176
+ api: 'apheleia',
177
+ resource: 'subscriptions',
178
+ body: {
179
+ subjects: ids,
180
+ subscriptionTtl,
181
+ includeStatus: true,
182
+ },
183
+ })
184
+ .then((response) => response.body.responses)
185
+ )
186
+ ).then((idBatches) => ({responses: [].concat(...idBatches)}));
187
+ },
188
+
189
+ /**
190
+ * Unsubscribes from a person or group of people's presence subscription
191
+ * @param {string | Array} personIds
192
+ * @returns {Promise}
193
+ */
194
+ unsubscribe(personIds) {
195
+ let subjects;
196
+
197
+ if (!personIds) {
198
+ return Promise.reject(new Error('A person id is required'));
199
+ }
200
+ if (Array.isArray(personIds)) {
201
+ subjects = personIds;
202
+ } else {
203
+ subjects = [personIds];
204
+ }
205
+
206
+ return this.webex.request({
207
+ method: 'POST',
208
+ api: 'apheleia',
209
+ resource: 'subscriptions',
210
+ body: {
211
+ subjects,
212
+ subscriptionTtl: 0,
213
+ includeStatus: true,
214
+ },
215
+ });
216
+ },
217
+
218
+ /**
219
+ * Sets the status of the current user
220
+ * @param {string} status - active | inactive | ooo | dnd
221
+ * @param {number} ttl - Time To Live for the event in seconds.
222
+ * @returns {Promise}
223
+ */
224
+ setStatus(status, ttl) {
225
+ if (!status) {
226
+ return Promise.reject(new Error('A status is required'));
227
+ }
228
+
229
+ return this.webex
230
+ .request({
231
+ method: 'POST',
232
+ api: 'apheleia',
233
+ resource: 'events',
234
+ body: {
235
+ subject: this.webex.internal.device.userId,
236
+ eventType: status,
237
+ ttl,
238
+ },
239
+ })
240
+ .then((response) => response.body);
241
+ },
242
+
243
+ /**
244
+ * Retrieves and subscribes to a user's presence.
245
+ * @param {string} id
246
+ * @returns {undefined}
247
+ */
248
+ enqueue(id) {
249
+ return this.worker.enqueue(id);
250
+ },
251
+
252
+ /**
253
+ * Retract from subscribing to a user's presence.
254
+ * @param {string} id
255
+ * @returns {undefined}
256
+ */
257
+ dequeue(id) {
258
+ return this.worker.dequeue(id);
259
+ },
260
+ });
261
+
262
+ export default Presence;