@wireapp/core 17.20.0 → 17.21.0

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 CHANGED
@@ -3,6 +3,41 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [17.21.0](https://github.com/wireapp/wire-web-packages/tree/main/packages/core/compare/@wireapp/core@17.20.3...@wireapp/core@17.21.0) (2021-10-28)
7
+
8
+
9
+ ### Features
10
+
11
+ * **core:** Allow the consumer to give a list of clients when sending a message ([#4163](https://github.com/wireapp/wire-web-packages/tree/main/packages/core/issues/4163)) ([b437acc](https://github.com/wireapp/wire-web-packages/tree/main/packages/core/commit/b437accfc7151518a780734efeecd0dcbbde8c7e))
12
+
13
+
14
+
15
+
16
+
17
+ ## [17.20.3](https://github.com/wireapp/wire-web-packages/tree/main/packages/core/compare/@wireapp/core@17.20.2...@wireapp/core@17.20.3) (2021-10-21)
18
+
19
+ **Note:** Version bump only for package @wireapp/core
20
+
21
+
22
+
23
+
24
+
25
+ ## [17.20.2](https://github.com/wireapp/wire-web-packages/tree/main/packages/core/compare/@wireapp/core@17.20.1...@wireapp/core@17.20.2) (2021-10-19)
26
+
27
+ **Note:** Version bump only for package @wireapp/core
28
+
29
+
30
+
31
+
32
+
33
+ ## [17.20.1](https://github.com/wireapp/wire-web-packages/tree/main/packages/core/compare/@wireapp/core@17.20.0...@wireapp/core@17.20.1) (2021-10-19)
34
+
35
+ **Note:** Version bump only for package @wireapp/core
36
+
37
+
38
+
39
+
40
+
6
41
  # [17.20.0](https://github.com/wireapp/wire-web-packages/tree/main/packages/core/compare/@wireapp/core@17.19.2...@wireapp/core@17.20.0) (2021-10-19)
7
42
 
8
43
 
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "dependencies": {
6
6
  "@types/long": "4.0.1",
7
7
  "@types/node": "~14",
8
- "@wireapp/api-client": "15.2.0",
8
+ "@wireapp/api-client": "15.3.0",
9
9
  "@wireapp/cryptobox": "12.7.1",
10
10
  "bazinga64": "5.9.7",
11
11
  "hash.js": "1.1.7",
@@ -69,6 +69,6 @@
69
69
  "test:project": "yarn dist && yarn test",
70
70
  "test:node": "nyc jasmine --config=jasmine.json"
71
71
  },
72
- "version": "17.20.0",
73
- "gitHead": "af77fd3daa9b5279b16065eccce626d7936c1a49"
72
+ "version": "17.21.0",
73
+ "gitHead": "f4c18025a50cd71587620069cf7a8be47470175f"
74
74
  }
@@ -8,7 +8,7 @@ import { AssetService, MessageTimer } from '../conversation/';
8
8
  import type { RemoteData } from '../conversation/content/';
9
9
  import type { CryptographyService } from '../cryptography/';
10
10
  import { MessageBuilder } from './message/MessageBuilder';
11
- import type { ButtonActionConfirmationMessage, ButtonActionMessage, CallMessage, ClearConversationMessage, CompositeMessage, ConfirmationMessage, DeleteMessage, EditedTextMessage, FileAssetAbortMessage, FileAssetMessage, FileAssetMetaDataMessage, HideMessage, ImageAssetMessage, LocationMessage, OtrMessage, PingMessage, ReactionMessage, ResetSessionMessage, TextMessage } from './message/OtrMessage';
11
+ import type { ClearConversationMessage, DeleteMessage, HideMessage, OtrMessage } from './message/OtrMessage';
12
12
  export interface MessageSendingCallbacks {
13
13
  onStart?: (message: GenericMessage) => void;
14
14
  onSuccess?: (message: GenericMessage, sentTime?: string) => void;
@@ -26,23 +26,35 @@ export declare class ConversationService {
26
26
  getPreKeyBundleMap(conversationId: string, userIds?: string[] | UserClients): Promise<UserPreKeyBundleMap>;
27
27
  private getSelfConversation;
28
28
  private sendExternalGenericMessage;
29
+ /**
30
+ * Sends a message to a federated environment.
31
+ *
32
+ * @param sendingClientId - The clientId from which the message is sent
33
+ * @param conversationId - The conversation in which to send the message
34
+ * @param conversationDomain - The domain where the conversation lives
35
+ * @param genericMessage - The payload of the message to send
36
+ * @param userIds? - can be either a QualifiedId[] or QualfiedUserClients. The type has some effect on the behavior of the method.
37
+ * When given a QualifiedId[] the method will fetch the freshest list of devices for those users (since they are not given by the consumer). As a consequence no ClientMismatch error will trigger and we will ignore missing clients when sending
38
+ * When given a QualifiedUserClients the method will only send to the clients listed in the userIds. This could lead to ClientMismatch (since the given list of devices might not be the freshest one and new clients could have been created)
39
+ * @return Resolves with the message sending status from backend
40
+ */
29
41
  private sendFederatedGenericMessage;
30
42
  private sendGenericMessage;
31
- private sendButtonAction;
32
- private sendButtonActionConfirmation;
33
- private sendComposite;
34
- private sendConfirmation;
35
- private sendEditedText;
36
- private sendFileData;
37
- private sendFileMetaData;
38
- private sendFileAbort;
39
- private sendImage;
40
- private sendLocation;
41
- private sendKnock;
42
- private sendReaction;
43
- private sendSessionReset;
44
- private sendCall;
45
- private sendText;
43
+ private generateButtonActionGenericMessage;
44
+ private generateButtonActionConfirmationGenericMessage;
45
+ private generateCompositeGenericMessage;
46
+ private generateConfirmationGenericMessage;
47
+ private generateEditedTextGenericMessage;
48
+ private generateFileDataGenericMessage;
49
+ private generateFileMetaDataGenericMessage;
50
+ private generateFileAbortGenericMessage;
51
+ private generateImageGenericMessage;
52
+ private generateLocationGenericMessage;
53
+ private generatePingGenericMessage;
54
+ private generateReactionGenericMessage;
55
+ private generateSessionResetGenericMessage;
56
+ private generateCallGenericMessage;
57
+ private generateTextGenericMessage;
46
58
  clearConversation(conversationId: string, timestamp?: number | Date, messageId?: string, sendAsProtobuf?: boolean, conversationDomain?: string): Promise<ClearConversationMessage>;
47
59
  deleteMessageLocal(conversationId: string, messageIdToHide: string, sendAsProtobuf?: boolean, conversationDomain?: string): Promise<HideMessage>;
48
60
  deleteMessageEveryone(conversationId: string, messageIdToDelete: string, userIds?: string[] | QualifiedId[] | UserClients | QualifiedUserClients, sendAsProtobuf?: boolean, conversationDomain?: string, callbacks?: MessageSendingCallbacks): Promise<DeleteMessage>;
@@ -57,18 +69,26 @@ export declare class ConversationService {
57
69
  addUser<T extends string | string[] | QualifiedId | QualifiedId[]>(conversationId: string, userIds: T): Promise<T>;
58
70
  removeUser(conversationId: string, userId: string): Promise<string>;
59
71
  /**
60
- * @param payloadBundle Outgoing message
61
- * @param userIds Only send message to specified user IDs or to certain clients of specified user IDs
62
- * @param [callbacks] Optional callbacks that will be called when the message starts being sent and when it has been succesfully sent. Currently only used for `sendText`.
63
- * @returns Sent message
72
+ * Sends a message to a conversation
73
+ *
74
+ * @param params.payloadBundle The message to send to the conversation
75
+ * @param params.userIds? Can be either a QualifiedId[], string[], UserClients or QualfiedUserClients. The type has some effect on the behavior of the method.
76
+ * When given a QualifiedId[] or string[] the method will fetch the freshest list of devices for those users (since they are not given by the consumer). As a consequence no ClientMismatch error will trigger and we will ignore missing clients when sending
77
+ * When given a QualifiedUserClients or UserClients the method will only send to the clients listed in the userIds. This could lead to ClientMismatch (since the given list of devices might not be the freshest one and new clients could have been created)
78
+ * When given a QualifiedId[] or QualifiedUserClients the method will send the message through the federated API endpoint
79
+ * When given a string[] or UserClients the method will send the message through the old API endpoint
80
+ * @param params.sendAsProtobuf?
81
+ * @param params.conversationDomain? The domain the conversation lives on (if given with QualifiedId[] or QualfiedUserClients in the userIds params, will send the message to the federated endpoint)
82
+ * @param params.callbacks? Optional callbacks that will be called when the message starts being sent and when it has been succesfully sent.
83
+ * @return resolves with the sent message
64
84
  */
65
- send({ payloadBundle, userIds, sendAsProtobuf, conversationDomain, callbacks, }: {
66
- payloadBundle: OtrMessage;
85
+ send<T extends OtrMessage = OtrMessage>({ payloadBundle, userIds, sendAsProtobuf, conversationDomain, callbacks, }: {
86
+ payloadBundle: T;
67
87
  userIds?: string[] | QualifiedId[] | UserClients | QualifiedUserClients;
68
88
  sendAsProtobuf?: boolean;
69
89
  conversationDomain?: string;
70
90
  callbacks?: MessageSendingCallbacks;
71
- }): Promise<ButtonActionMessage | ButtonActionConfirmationMessage | CallMessage | CompositeMessage | ConfirmationMessage | EditedTextMessage | FileAssetAbortMessage | FileAssetMessage | FileAssetMetaDataMessage | ImageAssetMessage | LocationMessage | PingMessage | ReactionMessage | ResetSessionMessage | TextMessage>;
91
+ }): Promise<T>;
72
92
  sendTypingStart(conversationId: string): Promise<void>;
73
93
  sendTypingStop(conversationId: string): Promise<void>;
74
94
  setConversationMutedStatus(conversationId: string, status: MutedStatus, muteTimestamp: number | Date): Promise<void>;
@@ -164,11 +164,25 @@ class ConversationService {
164
164
  }
165
165
  return undefined;
166
166
  }
167
+ /**
168
+ * Sends a message to a federated environment.
169
+ *
170
+ * @param sendingClientId - The clientId from which the message is sent
171
+ * @param conversationId - The conversation in which to send the message
172
+ * @param conversationDomain - The domain where the conversation lives
173
+ * @param genericMessage - The payload of the message to send
174
+ * @param userIds? - can be either a QualifiedId[] or QualfiedUserClients. The type has some effect on the behavior of the method.
175
+ * When given a QualifiedId[] the method will fetch the freshest list of devices for those users (since they are not given by the consumer). As a consequence no ClientMismatch error will trigger and we will ignore missing clients when sending
176
+ * When given a QualifiedUserClients the method will only send to the clients listed in the userIds. This could lead to ClientMismatch (since the given list of devices might not be the freshest one and new clients could have been created)
177
+ * @return Resolves with the message sending status from backend
178
+ */
167
179
  async sendFederatedGenericMessage(sendingClientId, conversationId, conversationDomain, genericMessage, userIds) {
168
180
  const plainTextArray = protocol_messaging_1.GenericMessage.encode(genericMessage).finish();
169
- const preKeyBundles = await this.getQualifiedPreKeyBundle(conversationId, conversationDomain, userIds);
181
+ const preKeyBundles = (0, TypePredicateUtil_1.isQualifiedUserClients)(userIds)
182
+ ? userIds
183
+ : await this.getQualifiedPreKeyBundle(conversationId, conversationDomain, userIds);
170
184
  const recipients = await this.cryptographyService.encryptQualified(plainTextArray, preKeyBundles);
171
- return this.messageService.sendFederatedOTRMessage(sendingClientId, conversationId, conversationDomain, recipients, plainTextArray);
185
+ return this.messageService.sendFederatedOTRMessage(sendingClientId, conversationId, conversationDomain, recipients, plainTextArray, undefined, (0, TypePredicateUtil_1.isQualifiedUserClients)(userIds));
172
186
  }
173
187
  async sendGenericMessage(sendingClientId, conversationId, genericMessage, userIds, sendAsProtobuf, conversationDomain) {
174
188
  if (conversationDomain) {
@@ -191,58 +205,42 @@ class ConversationService {
191
205
  ? this.messageService.sendOTRProtobufMessage(sendingClientId, recipients, conversationId, plainTextArray)
192
206
  : this.messageService.sendOTRMessage(sendingClientId, recipients, conversationId, plainTextArray);
193
207
  }
194
- async sendButtonAction(payloadBundle, userIds, sendAsProtobuf, conversationDomain) {
195
- const genericMessage = protocol_messaging_1.GenericMessage.create({
208
+ generateButtonActionGenericMessage(payloadBundle) {
209
+ return protocol_messaging_1.GenericMessage.create({
196
210
  [conversation_2.GenericMessageType.BUTTON_ACTION]: protocol_messaging_1.ButtonAction.create(payloadBundle.content),
197
211
  messageId: payloadBundle.id,
198
212
  });
199
- await this.sendGenericMessage(this.apiClient.validatedClientId, payloadBundle.conversation, genericMessage, userIds, sendAsProtobuf, conversationDomain);
200
- return Object.assign(Object.assign({}, payloadBundle), { messageTimer: 0, state: conversation_2.PayloadBundleState.OUTGOING_SENT });
201
213
  }
202
- async sendButtonActionConfirmation(payloadBundle, userIds, sendAsProtobuf, conversationDomain) {
203
- const genericMessage = protocol_messaging_1.GenericMessage.create({
214
+ generateButtonActionConfirmationGenericMessage(payloadBundle) {
215
+ return protocol_messaging_1.GenericMessage.create({
204
216
  [conversation_2.GenericMessageType.BUTTON_ACTION_CONFIRMATION]: protocol_messaging_1.ButtonActionConfirmation.create(payloadBundle.content),
205
217
  messageId: payloadBundle.id,
206
218
  });
207
- await this.sendGenericMessage(this.apiClient.validatedClientId, payloadBundle.conversation, genericMessage, userIds, sendAsProtobuf, conversationDomain);
208
- return Object.assign(Object.assign({}, payloadBundle), { messageTimer: 0, state: conversation_2.PayloadBundleState.OUTGOING_SENT });
209
219
  }
210
- async sendComposite(payloadBundle, userIds, sendAsProtobuf, conversationDomain) {
211
- const genericMessage = protocol_messaging_1.GenericMessage.create({
220
+ generateCompositeGenericMessage(payloadBundle) {
221
+ return protocol_messaging_1.GenericMessage.create({
212
222
  [conversation_2.GenericMessageType.COMPOSITE]: protocol_messaging_1.Composite.create(payloadBundle.content),
213
223
  messageId: payloadBundle.id,
214
224
  });
215
- await this.sendGenericMessage(this.apiClient.validatedClientId, payloadBundle.conversation, genericMessage, userIds, sendAsProtobuf, conversationDomain);
216
- return Object.assign(Object.assign({}, payloadBundle), { messageTimer: 0, state: conversation_2.PayloadBundleState.OUTGOING_SENT });
217
225
  }
218
- async sendConfirmation(payloadBundle, userIds, sendAsProtobuf, conversationDomain, callbacks) {
219
- var _a, _b;
226
+ generateConfirmationGenericMessage(payloadBundle) {
220
227
  const content = protocol_messaging_1.Confirmation.create(payloadBundle.content);
221
- const genericMessage = protocol_messaging_1.GenericMessage.create({
228
+ return protocol_messaging_1.GenericMessage.create({
222
229
  [conversation_2.GenericMessageType.CONFIRMATION]: content,
223
230
  messageId: payloadBundle.id,
224
231
  });
225
- (_a = callbacks === null || callbacks === void 0 ? void 0 : callbacks.onStart) === null || _a === void 0 ? void 0 : _a.call(callbacks, genericMessage);
226
- const response = await this.sendGenericMessage(this.apiClient.validatedClientId, payloadBundle.conversation, genericMessage, userIds, sendAsProtobuf, conversationDomain);
227
- (_b = callbacks === null || callbacks === void 0 ? void 0 : callbacks.onSuccess) === null || _b === void 0 ? void 0 : _b.call(callbacks, genericMessage, response === null || response === void 0 ? void 0 : response.time);
228
- return Object.assign(Object.assign({}, payloadBundle), { messageTimer: 0, state: conversation_2.PayloadBundleState.OUTGOING_SENT });
229
232
  }
230
- async sendEditedText(payloadBundle, userIds, sendAsProtobuf, conversationDomain, callbacks) {
231
- var _a, _b;
233
+ generateEditedTextGenericMessage(payloadBundle) {
232
234
  const editedMessage = protocol_messaging_1.MessageEdit.create({
233
235
  replacingMessageId: payloadBundle.content.originalMessageId,
234
236
  text: MessageToProtoMapper_1.MessageToProtoMapper.mapText(payloadBundle),
235
237
  });
236
- const genericMessage = protocol_messaging_1.GenericMessage.create({
238
+ return protocol_messaging_1.GenericMessage.create({
237
239
  [conversation_2.GenericMessageType.EDITED]: editedMessage,
238
240
  messageId: payloadBundle.id,
239
241
  });
240
- (_a = callbacks === null || callbacks === void 0 ? void 0 : callbacks.onStart) === null || _a === void 0 ? void 0 : _a.call(callbacks, genericMessage);
241
- const response = await this.sendGenericMessage(this.apiClient.validatedClientId, payloadBundle.conversation, genericMessage, userIds, sendAsProtobuf, conversationDomain);
242
- (_b = callbacks === null || callbacks === void 0 ? void 0 : callbacks.onSuccess) === null || _b === void 0 ? void 0 : _b.call(callbacks, genericMessage, response === null || response === void 0 ? void 0 : response.time);
243
- return Object.assign(Object.assign({}, payloadBundle), { messageTimer: 0, state: conversation_2.PayloadBundleState.OUTGOING_SENT });
244
242
  }
245
- async sendFileData(payloadBundle, userIds, sendAsProtobuf, conversationDomain) {
243
+ generateFileDataGenericMessage(payloadBundle) {
246
244
  if (!payloadBundle.content) {
247
245
  throw new Error('No content for sendFileData provided.');
248
246
  }
@@ -259,18 +257,14 @@ class ConversationService {
259
257
  uploaded: remoteData,
260
258
  });
261
259
  assetMessage.status = conversation_2.AssetTransferState.UPLOADED;
262
- let genericMessage = protocol_messaging_1.GenericMessage.create({
260
+ const genericMessage = protocol_messaging_1.GenericMessage.create({
263
261
  [conversation_2.GenericMessageType.ASSET]: assetMessage,
264
262
  messageId: payloadBundle.id,
265
263
  });
266
264
  const expireAfterMillis = this.messageTimer.getMessageTimer(payloadBundle.conversation);
267
- if (expireAfterMillis > 0) {
268
- genericMessage = this.createEphemeral(genericMessage, expireAfterMillis);
269
- }
270
- await this.sendGenericMessage(this.apiClient.validatedClientId, payloadBundle.conversation, genericMessage, userIds, sendAsProtobuf, conversationDomain);
271
- return Object.assign(Object.assign({}, payloadBundle), { messageTimer: this.messageTimer.getMessageTimer(payloadBundle.conversation), state: conversation_2.PayloadBundleState.OUTGOING_SENT });
265
+ return expireAfterMillis > 0 ? this.createEphemeral(genericMessage, expireAfterMillis) : genericMessage;
272
266
  }
273
- async sendFileMetaData(payloadBundle, userIds, sendAsProtobuf, conversationDomain) {
267
+ generateFileMetaDataGenericMessage(payloadBundle) {
274
268
  if (!payloadBundle.content) {
275
269
  throw new Error('No content for sendFileMetaData provided.');
276
270
  }
@@ -287,18 +281,14 @@ class ConversationService {
287
281
  legalHoldStatus,
288
282
  original,
289
283
  });
290
- let genericMessage = protocol_messaging_1.GenericMessage.create({
284
+ const genericMessage = protocol_messaging_1.GenericMessage.create({
291
285
  [conversation_2.GenericMessageType.ASSET]: assetMessage,
292
286
  messageId: payloadBundle.id,
293
287
  });
294
288
  const expireAfterMillis = this.messageTimer.getMessageTimer(payloadBundle.conversation);
295
- if (expireAfterMillis > 0) {
296
- genericMessage = this.createEphemeral(genericMessage, expireAfterMillis);
297
- }
298
- await this.sendGenericMessage(this.apiClient.validatedClientId, payloadBundle.conversation, genericMessage, userIds, sendAsProtobuf, conversationDomain);
299
- return Object.assign(Object.assign({}, payloadBundle), { messageTimer: this.messageTimer.getMessageTimer(payloadBundle.conversation), state: conversation_2.PayloadBundleState.OUTGOING_SENT });
289
+ return expireAfterMillis > 0 ? this.createEphemeral(genericMessage, expireAfterMillis) : genericMessage;
300
290
  }
301
- async sendFileAbort(payloadBundle, userIds, sendAsProtobuf, conversationDomain) {
291
+ generateFileAbortGenericMessage(payloadBundle) {
302
292
  if (!payloadBundle.content) {
303
293
  throw new Error('No content for sendFileAbort provided.');
304
294
  }
@@ -309,18 +299,14 @@ class ConversationService {
309
299
  notUploaded: reason,
310
300
  });
311
301
  assetMessage.status = conversation_2.AssetTransferState.NOT_UPLOADED;
312
- let genericMessage = protocol_messaging_1.GenericMessage.create({
302
+ const genericMessage = protocol_messaging_1.GenericMessage.create({
313
303
  [conversation_2.GenericMessageType.ASSET]: assetMessage,
314
304
  messageId: payloadBundle.id,
315
305
  });
316
306
  const expireAfterMillis = this.messageTimer.getMessageTimer(payloadBundle.conversation);
317
- if (expireAfterMillis > 0) {
318
- genericMessage = this.createEphemeral(genericMessage, expireAfterMillis);
319
- }
320
- await this.sendGenericMessage(this.apiClient.validatedClientId, payloadBundle.conversation, genericMessage, userIds, sendAsProtobuf, conversationDomain);
321
- return Object.assign(Object.assign({}, payloadBundle), { messageTimer: this.messageTimer.getMessageTimer(payloadBundle.conversation), state: conversation_2.PayloadBundleState.OUTGOING_SENT });
307
+ return expireAfterMillis > 0 ? this.createEphemeral(genericMessage, expireAfterMillis) : genericMessage;
322
308
  }
323
- async sendImage(payloadBundle, userIds, sendAsProtobuf, conversationDomain) {
309
+ generateImageGenericMessage(payloadBundle) {
324
310
  if (!payloadBundle.content) {
325
311
  throw new Error('No content for sendImage provided.');
326
312
  }
@@ -353,13 +339,12 @@ class ConversationService {
353
339
  messageId: payloadBundle.id,
354
340
  });
355
341
  const expireAfterMillis = this.messageTimer.getMessageTimer(payloadBundle.conversation);
356
- if (expireAfterMillis > 0) {
342
+ if (expireAfterMillis) {
357
343
  genericMessage = this.createEphemeral(genericMessage, expireAfterMillis);
358
344
  }
359
- await this.sendGenericMessage(this.apiClient.validatedClientId, payloadBundle.conversation, genericMessage, userIds, sendAsProtobuf, conversationDomain);
360
- return Object.assign(Object.assign({}, payloadBundle), { content: assetMessage, messageTimer: this.messageTimer.getMessageTimer(payloadBundle.conversation), state: conversation_2.PayloadBundleState.OUTGOING_SENT });
345
+ return { content: assetMessage, genericMessage };
361
346
  }
362
- async sendLocation(payloadBundle, userIds, sendAsProtobuf, conversationDomain) {
347
+ generateLocationGenericMessage(payloadBundle) {
363
348
  const { expectsReadConfirmation, latitude, legalHoldStatus, longitude, name, zoom } = payloadBundle.content;
364
349
  const locationMessage = protocol_messaging_1.Location.create({
365
350
  expectsReadConfirmation,
@@ -369,34 +354,23 @@ class ConversationService {
369
354
  name,
370
355
  zoom,
371
356
  });
372
- let genericMessage = protocol_messaging_1.GenericMessage.create({
357
+ const genericMessage = protocol_messaging_1.GenericMessage.create({
373
358
  [conversation_2.GenericMessageType.LOCATION]: locationMessage,
374
359
  messageId: payloadBundle.id,
375
360
  });
376
361
  const expireAfterMillis = this.messageTimer.getMessageTimer(payloadBundle.conversation);
377
- if (expireAfterMillis > 0) {
378
- genericMessage = this.createEphemeral(genericMessage, expireAfterMillis);
379
- }
380
- await this.sendGenericMessage(this.apiClient.validatedClientId, payloadBundle.conversation, genericMessage, userIds, sendAsProtobuf, conversationDomain);
381
- return Object.assign(Object.assign({}, payloadBundle), { messageTimer: this.messageTimer.getMessageTimer(payloadBundle.conversation), state: conversation_2.PayloadBundleState.OUTGOING_SENT });
362
+ return expireAfterMillis > 0 ? this.createEphemeral(genericMessage, expireAfterMillis) : genericMessage;
382
363
  }
383
- async sendKnock(payloadBundle, userIds, sendAsProtobuf, conversationDomain, callbacks) {
384
- var _a, _b;
364
+ generatePingGenericMessage(payloadBundle) {
385
365
  const content = protocol_messaging_1.Knock.create(payloadBundle.content);
386
- let genericMessage = protocol_messaging_1.GenericMessage.create({
366
+ const genericMessage = protocol_messaging_1.GenericMessage.create({
387
367
  [conversation_2.GenericMessageType.KNOCK]: content,
388
368
  messageId: payloadBundle.id,
389
369
  });
390
- (_a = callbacks === null || callbacks === void 0 ? void 0 : callbacks.onStart) === null || _a === void 0 ? void 0 : _a.call(callbacks, genericMessage);
391
370
  const expireAfterMillis = this.messageTimer.getMessageTimer(payloadBundle.conversation);
392
- if (expireAfterMillis > 0) {
393
- genericMessage = this.createEphemeral(genericMessage, expireAfterMillis);
394
- }
395
- const response = await this.sendGenericMessage(this.apiClient.validatedClientId, payloadBundle.conversation, genericMessage, userIds, sendAsProtobuf, conversationDomain);
396
- (_b = callbacks === null || callbacks === void 0 ? void 0 : callbacks.onSuccess) === null || _b === void 0 ? void 0 : _b.call(callbacks, genericMessage, response === null || response === void 0 ? void 0 : response.time);
397
- return Object.assign(Object.assign({}, payloadBundle), { conversation: payloadBundle.conversation, messageTimer: this.messageTimer.getMessageTimer(payloadBundle.conversation), state: conversation_2.PayloadBundleState.OUTGOING_SENT });
371
+ return expireAfterMillis > 0 ? this.createEphemeral(genericMessage, expireAfterMillis) : genericMessage;
398
372
  }
399
- async sendReaction(payloadBundle, userIds, sendAsProtobuf, conversationDomain) {
373
+ generateReactionGenericMessage(payloadBundle) {
400
374
  const { legalHoldStatus, originalMessageId, type } = payloadBundle.content;
401
375
  const reaction = protocol_messaging_1.Reaction.create({
402
376
  emoji: type,
@@ -407,42 +381,30 @@ class ConversationService {
407
381
  [conversation_2.GenericMessageType.REACTION]: reaction,
408
382
  messageId: payloadBundle.id,
409
383
  });
410
- await this.sendGenericMessage(this.apiClient.validatedClientId, payloadBundle.conversation, genericMessage, userIds, sendAsProtobuf, conversationDomain);
411
- return Object.assign(Object.assign({}, payloadBundle), { messageTimer: 0, state: conversation_2.PayloadBundleState.OUTGOING_SENT });
384
+ return genericMessage;
412
385
  }
413
- async sendSessionReset(payloadBundle, userIds, sendAsProtobuf, conversationDomain) {
414
- const genericMessage = protocol_messaging_1.GenericMessage.create({
386
+ generateSessionResetGenericMessage(payloadBundle) {
387
+ return protocol_messaging_1.GenericMessage.create({
415
388
  [conversation_2.GenericMessageType.CLIENT_ACTION]: protocol_messaging_1.ClientAction.RESET_SESSION,
416
389
  messageId: payloadBundle.id,
417
390
  });
418
- await this.sendGenericMessage(this.apiClient.validatedClientId, payloadBundle.conversation, genericMessage, userIds, sendAsProtobuf, conversationDomain);
419
- return Object.assign(Object.assign({}, payloadBundle), { messageTimer: this.messageTimer.getMessageTimer(payloadBundle.conversation), state: conversation_2.PayloadBundleState.OUTGOING_SENT });
420
391
  }
421
- async sendCall(payloadBundle, userIds, sendAsProtobuf, conversationDomain) {
392
+ generateCallGenericMessage(payloadBundle) {
422
393
  const callMessage = protocol_messaging_1.Calling.create({
423
394
  content: payloadBundle.content,
424
395
  });
425
- const genericMessage = protocol_messaging_1.GenericMessage.create({
396
+ return protocol_messaging_1.GenericMessage.create({
426
397
  [conversation_2.GenericMessageType.CALLING]: callMessage,
427
398
  messageId: payloadBundle.id,
428
399
  });
429
- await this.sendGenericMessage(this.apiClient.validatedClientId, payloadBundle.conversation, genericMessage, userIds, sendAsProtobuf, conversationDomain);
430
- return Object.assign(Object.assign({}, payloadBundle), { messageTimer: 0, state: conversation_2.PayloadBundleState.OUTGOING_SENT });
431
400
  }
432
- async sendText(payloadBundle, userIds, sendAsProtobuf, conversationDomain, callbacks) {
433
- var _a, _b;
434
- let genericMessage = protocol_messaging_1.GenericMessage.create({
401
+ generateTextGenericMessage(payloadBundle) {
402
+ const genericMessage = protocol_messaging_1.GenericMessage.create({
435
403
  messageId: payloadBundle.id,
436
404
  [conversation_2.GenericMessageType.TEXT]: MessageToProtoMapper_1.MessageToProtoMapper.mapText(payloadBundle),
437
405
  });
438
406
  const expireAfterMillis = this.messageTimer.getMessageTimer(payloadBundle.conversation);
439
- if (expireAfterMillis > 0) {
440
- genericMessage = this.createEphemeral(genericMessage, expireAfterMillis);
441
- }
442
- (_a = callbacks === null || callbacks === void 0 ? void 0 : callbacks.onStart) === null || _a === void 0 ? void 0 : _a.call(callbacks, genericMessage);
443
- const response = await this.sendGenericMessage(this.apiClient.validatedClientId, payloadBundle.conversation, genericMessage, userIds, sendAsProtobuf, conversationDomain);
444
- (_b = callbacks === null || callbacks === void 0 ? void 0 : callbacks.onSuccess) === null || _b === void 0 ? void 0 : _b.call(callbacks, genericMessage, response === null || response === void 0 ? void 0 : response.time);
445
- return Object.assign(Object.assign({}, payloadBundle), { messageTimer: this.messageTimer.getMessageTimer(payloadBundle.conversation), state: conversation_2.PayloadBundleState.OUTGOING_SENT });
407
+ return expireAfterMillis > 0 ? this.createEphemeral(genericMessage, expireAfterMillis) : genericMessage;
446
408
  }
447
409
  async clearConversation(conversationId, timestamp = new Date(), messageId = MessageBuilder_1.MessageBuilder.createId(), sendAsProtobuf, conversationDomain) {
448
410
  if (timestamp instanceof Date) {
@@ -588,50 +550,82 @@ class ConversationService {
588
550
  return userId;
589
551
  }
590
552
  /**
591
- * @param payloadBundle Outgoing message
592
- * @param userIds Only send message to specified user IDs or to certain clients of specified user IDs
593
- * @param [callbacks] Optional callbacks that will be called when the message starts being sent and when it has been succesfully sent. Currently only used for `sendText`.
594
- * @returns Sent message
553
+ * Sends a message to a conversation
554
+ *
555
+ * @param params.payloadBundle The message to send to the conversation
556
+ * @param params.userIds? Can be either a QualifiedId[], string[], UserClients or QualfiedUserClients. The type has some effect on the behavior of the method.
557
+ * When given a QualifiedId[] or string[] the method will fetch the freshest list of devices for those users (since they are not given by the consumer). As a consequence no ClientMismatch error will trigger and we will ignore missing clients when sending
558
+ * When given a QualifiedUserClients or UserClients the method will only send to the clients listed in the userIds. This could lead to ClientMismatch (since the given list of devices might not be the freshest one and new clients could have been created)
559
+ * When given a QualifiedId[] or QualifiedUserClients the method will send the message through the federated API endpoint
560
+ * When given a string[] or UserClients the method will send the message through the old API endpoint
561
+ * @param params.sendAsProtobuf?
562
+ * @param params.conversationDomain? The domain the conversation lives on (if given with QualifiedId[] or QualfiedUserClients in the userIds params, will send the message to the federated endpoint)
563
+ * @param params.callbacks? Optional callbacks that will be called when the message starts being sent and when it has been succesfully sent.
564
+ * @return resolves with the sent message
595
565
  */
596
566
  async send({ payloadBundle, userIds, sendAsProtobuf, conversationDomain, callbacks, }) {
567
+ var _a, _b, _c;
568
+ let genericMessage;
569
+ let processedContent = undefined;
597
570
  switch (payloadBundle.type) {
598
571
  case conversation_2.PayloadBundleType.ASSET:
599
- return this.sendFileData(payloadBundle, userIds, sendAsProtobuf, conversationDomain);
572
+ genericMessage = this.generateFileDataGenericMessage(payloadBundle);
573
+ break;
600
574
  case conversation_2.PayloadBundleType.ASSET_ABORT:
601
- return this.sendFileAbort(payloadBundle, userIds, sendAsProtobuf, conversationDomain);
575
+ genericMessage = this.generateFileAbortGenericMessage(payloadBundle);
576
+ break;
602
577
  case conversation_2.PayloadBundleType.ASSET_META:
603
- return this.sendFileMetaData(payloadBundle, userIds, sendAsProtobuf, conversationDomain);
578
+ genericMessage = this.generateFileMetaDataGenericMessage(payloadBundle);
579
+ break;
604
580
  case conversation_2.PayloadBundleType.ASSET_IMAGE:
605
- return this.sendImage(payloadBundle, userIds, sendAsProtobuf, conversationDomain);
581
+ const res = this.generateImageGenericMessage(payloadBundle);
582
+ genericMessage = res.genericMessage;
583
+ processedContent = res.content;
584
+ break;
606
585
  case conversation_2.PayloadBundleType.BUTTON_ACTION:
607
- return this.sendButtonAction(payloadBundle, userIds, sendAsProtobuf, conversationDomain);
586
+ genericMessage = this.generateButtonActionGenericMessage(payloadBundle);
587
+ break;
608
588
  case conversation_2.PayloadBundleType.BUTTON_ACTION_CONFIRMATION:
609
- return this.sendButtonActionConfirmation(payloadBundle, userIds, sendAsProtobuf, conversationDomain);
589
+ genericMessage = this.generateButtonActionConfirmationGenericMessage(payloadBundle);
590
+ break;
610
591
  case conversation_2.PayloadBundleType.CALL:
611
- return this.sendCall(payloadBundle, userIds, sendAsProtobuf, conversationDomain);
592
+ genericMessage = this.generateCallGenericMessage(payloadBundle);
593
+ break;
612
594
  case conversation_2.PayloadBundleType.CLIENT_ACTION: {
613
- if (payloadBundle.content.clientAction === protocol_messaging_1.ClientAction.RESET_SESSION) {
614
- return this.sendSessionReset(payloadBundle, userIds, sendAsProtobuf, conversationDomain);
595
+ if (payloadBundle.content.clientAction !== protocol_messaging_1.ClientAction.RESET_SESSION) {
596
+ throw new Error(`No send method implemented for "${payloadBundle.type}" and ClientAction "${payloadBundle.content}".`);
615
597
  }
616
- throw new Error(`No send method implemented for "${payloadBundle.type}" and ClientAction "${payloadBundle.content}".`);
598
+ genericMessage = this.generateSessionResetGenericMessage(payloadBundle);
599
+ break;
617
600
  }
618
601
  case conversation_2.PayloadBundleType.COMPOSITE:
619
- return this.sendComposite(payloadBundle, userIds, sendAsProtobuf, conversationDomain);
602
+ genericMessage = this.generateCompositeGenericMessage(payloadBundle);
603
+ break;
620
604
  case conversation_2.PayloadBundleType.CONFIRMATION:
621
- return this.sendConfirmation(payloadBundle, userIds, sendAsProtobuf, conversationDomain, callbacks);
605
+ genericMessage = this.generateConfirmationGenericMessage(payloadBundle);
606
+ break;
622
607
  case conversation_2.PayloadBundleType.LOCATION:
623
- return this.sendLocation(payloadBundle, userIds, sendAsProtobuf, conversationDomain);
608
+ genericMessage = this.generateLocationGenericMessage(payloadBundle);
609
+ break;
624
610
  case conversation_2.PayloadBundleType.MESSAGE_EDIT:
625
- return this.sendEditedText(payloadBundle, userIds, sendAsProtobuf, conversationDomain, callbacks);
611
+ genericMessage = this.generateEditedTextGenericMessage(payloadBundle);
612
+ break;
626
613
  case conversation_2.PayloadBundleType.PING:
627
- return this.sendKnock(payloadBundle, userIds, sendAsProtobuf, conversationDomain, callbacks);
614
+ genericMessage = this.generatePingGenericMessage(payloadBundle);
615
+ break;
628
616
  case conversation_2.PayloadBundleType.REACTION:
629
- return this.sendReaction(payloadBundle, userIds, sendAsProtobuf, conversationDomain);
617
+ genericMessage = this.generateReactionGenericMessage(payloadBundle);
618
+ break;
630
619
  case conversation_2.PayloadBundleType.TEXT:
631
- return this.sendText(payloadBundle, userIds, sendAsProtobuf, conversationDomain, callbacks);
620
+ genericMessage = this.generateTextGenericMessage(payloadBundle);
621
+ break;
632
622
  default:
633
623
  throw new Error(`No send method implemented for "${payloadBundle['type']}".`);
634
624
  }
625
+ (_a = callbacks === null || callbacks === void 0 ? void 0 : callbacks.onStart) === null || _a === void 0 ? void 0 : _a.call(callbacks, genericMessage);
626
+ const response = await this.sendGenericMessage(this.apiClient.validatedClientId, payloadBundle.conversation, genericMessage, userIds, sendAsProtobuf, conversationDomain);
627
+ (_b = callbacks === null || callbacks === void 0 ? void 0 : callbacks.onSuccess) === null || _b === void 0 ? void 0 : _b.call(callbacks, genericMessage, response === null || response === void 0 ? void 0 : response.time);
628
+ return Object.assign(Object.assign({}, payloadBundle), { content: processedContent || payloadBundle.content, messageTimer: ((_c = genericMessage.ephemeral) === null || _c === void 0 ? void 0 : _c.expireAfterMillis) || 0, state: conversation_2.PayloadBundleState.OUTGOING_SENT });
635
629
  }
636
630
  sendTypingStart(conversationId) {
637
631
  return this.apiClient.conversation.api.postTyping(conversationId, { status: data_1.CONVERSATION_TYPING.STARTED });