2023-01-03 19:55:46 +00:00
|
|
|
// Copyright 2020 Signal Messenger, LLC
|
2021-07-09 19:36:10 +00:00
|
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
/* eslint-disable max-classes-per-file */
|
|
|
|
|
2022-03-24 21:47:21 +00:00
|
|
|
import type { PublicKey } from '@signalapp/libsignal-client';
|
2021-07-23 17:44:21 +00:00
|
|
|
|
2021-10-26 19:15:33 +00:00
|
|
|
import type { SignalService as Proto } from '../protobuf';
|
2023-08-10 16:43:33 +00:00
|
|
|
import type { ServiceIdString, AciString } from '../types/ServiceId';
|
|
|
|
import type { StoryDistributionIdString } from '../types/StoryDistributionId';
|
2021-10-26 19:15:33 +00:00
|
|
|
import type {
|
2021-08-05 23:34:49 +00:00
|
|
|
ProcessedEnvelope,
|
|
|
|
ProcessedDataMessage,
|
|
|
|
ProcessedSent,
|
|
|
|
} from './Types.d';
|
2023-07-26 17:49:27 +00:00
|
|
|
import type { ModifiedContactDetails } from './ContactsParser';
|
2023-08-09 00:53:06 +00:00
|
|
|
import type { CallEventDetails, CallLogEvent } from '../types/CallDisposition';
|
2021-07-09 19:36:10 +00:00
|
|
|
|
|
|
|
export class EmptyEvent extends Event {
|
|
|
|
constructor() {
|
|
|
|
super('empty');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export class ProgressEvent extends Event {
|
|
|
|
public readonly count: number;
|
|
|
|
|
|
|
|
constructor({ count }: { count: number }) {
|
|
|
|
super('progress');
|
|
|
|
|
|
|
|
this.count = count;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export type TypingEventData = Readonly<{
|
|
|
|
typingMessage: Proto.ITypingMessage;
|
|
|
|
timestamp: number;
|
|
|
|
started: boolean;
|
|
|
|
stopped: boolean;
|
|
|
|
groupId?: string;
|
|
|
|
groupV2Id?: string;
|
|
|
|
}>;
|
|
|
|
|
|
|
|
export type TypingEventConfig = {
|
|
|
|
sender?: string;
|
2023-08-10 16:43:33 +00:00
|
|
|
senderAci?: AciString;
|
2021-07-09 19:36:10 +00:00
|
|
|
senderDevice: number;
|
|
|
|
typing: TypingEventData;
|
|
|
|
};
|
|
|
|
|
|
|
|
export class TypingEvent extends Event {
|
|
|
|
public readonly sender?: string;
|
|
|
|
|
2023-08-10 16:43:33 +00:00
|
|
|
public readonly senderAci?: AciString;
|
2021-07-09 19:36:10 +00:00
|
|
|
|
|
|
|
public readonly senderDevice: number;
|
|
|
|
|
|
|
|
public readonly typing: TypingEventData;
|
|
|
|
|
2023-08-10 16:43:33 +00:00
|
|
|
constructor({ sender, senderAci, senderDevice, typing }: TypingEventConfig) {
|
2021-07-09 19:36:10 +00:00
|
|
|
super('typing');
|
|
|
|
|
|
|
|
this.sender = sender;
|
2023-08-10 16:43:33 +00:00
|
|
|
this.senderAci = senderAci;
|
2021-07-09 19:36:10 +00:00
|
|
|
this.senderDevice = senderDevice;
|
|
|
|
this.typing = typing;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export class ErrorEvent extends Event {
|
|
|
|
constructor(public readonly error: Error) {
|
|
|
|
super('error');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-25 05:04:42 +00:00
|
|
|
export class ContactSyncEvent extends Event {
|
2022-06-20 22:43:16 +00:00
|
|
|
constructor(
|
2022-08-25 05:04:42 +00:00
|
|
|
public readonly contacts: ReadonlyArray<ModifiedContactDetails>,
|
2022-08-26 22:26:38 +00:00
|
|
|
public readonly complete: boolean,
|
2022-09-13 00:52:55 +00:00
|
|
|
public readonly receivedAtCounter: number,
|
|
|
|
public readonly sentAt: number
|
2022-06-20 22:43:16 +00:00
|
|
|
) {
|
2021-07-09 19:36:10 +00:00
|
|
|
super('contactSync');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-07-05 23:16:17 +00:00
|
|
|
// Emitted right before we do full decrypt on a message, but after Sealed Sender unseal
|
|
|
|
export class EnvelopeUnsealedEvent extends Event {
|
2021-08-05 23:34:49 +00:00
|
|
|
constructor(public readonly envelope: ProcessedEnvelope) {
|
2023-07-05 23:16:17 +00:00
|
|
|
super('envelopeUnsealed');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Emitted when we queue previously-decrypted events from the cache
|
|
|
|
export class EnvelopeQueuedEvent extends Event {
|
|
|
|
constructor(public readonly envelope: ProcessedEnvelope) {
|
|
|
|
super('envelopeQueued');
|
2021-08-05 23:34:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-09 19:36:10 +00:00
|
|
|
//
|
|
|
|
// Confirmable events below
|
|
|
|
//
|
|
|
|
|
|
|
|
export type ConfirmCallback = () => void;
|
|
|
|
|
|
|
|
export class ConfirmableEvent extends Event {
|
|
|
|
constructor(type: string, public readonly confirm: ConfirmCallback) {
|
|
|
|
super(type);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export type DeliveryEventData = Readonly<{
|
2023-08-21 20:08:27 +00:00
|
|
|
envelopeId: string;
|
2021-07-09 19:36:10 +00:00
|
|
|
timestamp: number;
|
2022-01-06 20:12:53 +00:00
|
|
|
envelopeTimestamp: number;
|
2021-07-09 19:36:10 +00:00
|
|
|
source?: string;
|
2023-08-10 16:43:33 +00:00
|
|
|
sourceServiceId?: ServiceIdString;
|
2021-07-09 19:36:10 +00:00
|
|
|
sourceDevice?: number;
|
2022-08-15 21:53:33 +00:00
|
|
|
wasSentEncrypted: boolean;
|
2021-07-09 19:36:10 +00:00
|
|
|
}>;
|
|
|
|
|
|
|
|
export class DeliveryEvent extends ConfirmableEvent {
|
|
|
|
constructor(
|
|
|
|
public readonly deliveryReceipt: DeliveryEventData,
|
|
|
|
confirm: ConfirmCallback
|
|
|
|
) {
|
|
|
|
super('delivery', confirm);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-20 21:50:00 +00:00
|
|
|
export type DecryptionErrorEventData = Readonly<{
|
|
|
|
cipherTextBytes?: Uint8Array;
|
|
|
|
cipherTextType?: number;
|
|
|
|
contentHint?: number;
|
|
|
|
groupId?: string;
|
|
|
|
receivedAtCounter: number;
|
|
|
|
receivedAtDate: number;
|
|
|
|
senderDevice: number;
|
2023-08-10 16:43:33 +00:00
|
|
|
senderAci: AciString;
|
2021-10-20 21:50:00 +00:00
|
|
|
timestamp: number;
|
|
|
|
}>;
|
|
|
|
|
|
|
|
export class DecryptionErrorEvent extends ConfirmableEvent {
|
|
|
|
constructor(
|
|
|
|
public readonly decryptionError: DecryptionErrorEventData,
|
|
|
|
confirm: ConfirmCallback
|
|
|
|
) {
|
|
|
|
super('decryption-error', confirm);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-05-03 20:53:28 +00:00
|
|
|
export type InvalidPlaintextEventData = Readonly<{
|
|
|
|
senderDevice: number;
|
2023-08-10 16:43:33 +00:00
|
|
|
senderAci: AciString;
|
2023-05-03 20:53:28 +00:00
|
|
|
timestamp: number;
|
|
|
|
}>;
|
|
|
|
|
|
|
|
export class InvalidPlaintextEvent extends Event {
|
|
|
|
constructor(public readonly data: InvalidPlaintextEventData) {
|
|
|
|
super('invalid-plaintext');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-20 21:50:00 +00:00
|
|
|
export type RetryRequestEventData = Readonly<{
|
|
|
|
groupId?: string;
|
|
|
|
ratchetKey?: PublicKey;
|
2023-08-10 16:43:33 +00:00
|
|
|
requesterAci: AciString;
|
2021-10-20 21:50:00 +00:00
|
|
|
requesterDevice: number;
|
|
|
|
senderDevice: number;
|
|
|
|
sentAt: number;
|
|
|
|
}>;
|
|
|
|
|
|
|
|
export class RetryRequestEvent extends ConfirmableEvent {
|
|
|
|
constructor(
|
|
|
|
public readonly retryRequest: RetryRequestEventData,
|
|
|
|
confirm: ConfirmCallback
|
|
|
|
) {
|
|
|
|
super('retry-request', confirm);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-09 19:36:10 +00:00
|
|
|
export type SentEventData = Readonly<{
|
2023-08-07 16:36:37 +00:00
|
|
|
envelopeId: string;
|
2021-07-09 19:36:10 +00:00
|
|
|
destination?: string;
|
2023-08-10 16:43:33 +00:00
|
|
|
destinationServiceId?: ServiceIdString;
|
2021-07-09 19:36:10 +00:00
|
|
|
timestamp?: number;
|
|
|
|
serverTimestamp?: number;
|
2022-11-23 20:52:36 +00:00
|
|
|
device: number | undefined;
|
2021-07-09 19:36:10 +00:00
|
|
|
unidentifiedStatus: ProcessedSent['unidentifiedStatus'];
|
|
|
|
message: ProcessedDataMessage;
|
|
|
|
isRecipientUpdate: boolean;
|
|
|
|
receivedAtCounter: number;
|
|
|
|
receivedAtDate: number;
|
|
|
|
expirationStartTimestamp?: number;
|
2023-08-10 16:43:33 +00:00
|
|
|
storyDistributionListId?: StoryDistributionIdString;
|
2021-07-09 19:36:10 +00:00
|
|
|
}>;
|
|
|
|
|
|
|
|
export class SentEvent extends ConfirmableEvent {
|
|
|
|
constructor(public readonly data: SentEventData, confirm: ConfirmCallback) {
|
|
|
|
super('sent', confirm);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export type ProfileKeyUpdateData = Readonly<{
|
|
|
|
source?: string;
|
2023-08-10 16:43:33 +00:00
|
|
|
sourceAci?: AciString;
|
2021-07-09 19:36:10 +00:00
|
|
|
profileKey: string;
|
|
|
|
}>;
|
|
|
|
|
|
|
|
export class ProfileKeyUpdateEvent extends ConfirmableEvent {
|
|
|
|
constructor(
|
|
|
|
public readonly data: ProfileKeyUpdateData,
|
|
|
|
confirm: ConfirmCallback
|
|
|
|
) {
|
|
|
|
super('profileKeyUpdate', confirm);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export type MessageEventData = Readonly<{
|
2023-08-07 16:36:37 +00:00
|
|
|
envelopeId: string;
|
2021-07-09 19:36:10 +00:00
|
|
|
source?: string;
|
2023-08-10 16:43:33 +00:00
|
|
|
sourceAci: AciString;
|
2021-07-09 19:36:10 +00:00
|
|
|
sourceDevice?: number;
|
2023-08-10 16:43:33 +00:00
|
|
|
destinationServiceId: ServiceIdString;
|
2021-07-09 19:36:10 +00:00
|
|
|
timestamp: number;
|
|
|
|
serverGuid?: string;
|
|
|
|
serverTimestamp?: number;
|
|
|
|
unidentifiedDeliveryReceived: boolean;
|
|
|
|
message: ProcessedDataMessage;
|
|
|
|
receivedAtCounter: number;
|
|
|
|
receivedAtDate: number;
|
|
|
|
}>;
|
|
|
|
|
|
|
|
export class MessageEvent extends ConfirmableEvent {
|
|
|
|
constructor(
|
|
|
|
public readonly data: MessageEventData,
|
|
|
|
confirm: ConfirmCallback
|
|
|
|
) {
|
|
|
|
super('message', confirm);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-27 15:42:25 +00:00
|
|
|
export type ReadOrViewEventData = Readonly<{
|
2023-08-21 20:08:27 +00:00
|
|
|
envelopeId: string;
|
2021-07-09 19:36:10 +00:00
|
|
|
timestamp: number;
|
|
|
|
envelopeTimestamp: number;
|
|
|
|
source?: string;
|
2023-08-10 16:43:33 +00:00
|
|
|
sourceServiceId?: ServiceIdString;
|
2021-07-15 23:48:09 +00:00
|
|
|
sourceDevice?: number;
|
2022-08-15 21:53:33 +00:00
|
|
|
wasSentEncrypted: true;
|
2021-07-09 19:36:10 +00:00
|
|
|
}>;
|
|
|
|
|
|
|
|
export class ReadEvent extends ConfirmableEvent {
|
2021-07-27 15:42:25 +00:00
|
|
|
constructor(
|
|
|
|
public readonly receipt: ReadOrViewEventData,
|
|
|
|
confirm: ConfirmCallback
|
|
|
|
) {
|
2021-07-09 19:36:10 +00:00
|
|
|
super('read', confirm);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-27 15:42:25 +00:00
|
|
|
export class ViewEvent extends ConfirmableEvent {
|
|
|
|
constructor(
|
|
|
|
public readonly receipt: ReadOrViewEventData,
|
|
|
|
confirm: ConfirmCallback
|
|
|
|
) {
|
|
|
|
super('view', confirm);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-09 19:36:10 +00:00
|
|
|
export class ConfigurationEvent extends ConfirmableEvent {
|
|
|
|
constructor(
|
|
|
|
public readonly configuration: Proto.SyncMessage.IConfiguration,
|
|
|
|
confirm: ConfirmCallback
|
|
|
|
) {
|
|
|
|
super('configuration', confirm);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-22 17:07:53 +00:00
|
|
|
export type ViewOnceOpenSyncOptions = {
|
2021-07-09 19:36:10 +00:00
|
|
|
source?: string;
|
2023-08-10 16:43:33 +00:00
|
|
|
sourceAci?: AciString;
|
2021-07-09 19:36:10 +00:00
|
|
|
timestamp?: number;
|
|
|
|
};
|
|
|
|
|
2021-07-22 17:07:53 +00:00
|
|
|
export class ViewOnceOpenSyncEvent extends ConfirmableEvent {
|
2021-07-09 19:36:10 +00:00
|
|
|
public readonly source?: string;
|
|
|
|
|
2023-08-10 16:43:33 +00:00
|
|
|
public readonly sourceAci?: AciString;
|
2021-07-09 19:36:10 +00:00
|
|
|
|
|
|
|
public readonly timestamp?: number;
|
|
|
|
|
|
|
|
constructor(
|
2023-08-10 16:43:33 +00:00
|
|
|
{ source, sourceAci, timestamp }: ViewOnceOpenSyncOptions,
|
2021-07-09 19:36:10 +00:00
|
|
|
confirm: ConfirmCallback
|
|
|
|
) {
|
2021-07-22 17:07:53 +00:00
|
|
|
super('viewOnceOpenSync', confirm);
|
2021-07-09 19:36:10 +00:00
|
|
|
|
|
|
|
this.source = source;
|
2023-08-10 16:43:33 +00:00
|
|
|
this.sourceAci = sourceAci;
|
2021-07-09 19:36:10 +00:00
|
|
|
this.timestamp = timestamp;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export type MessageRequestResponseOptions = {
|
2023-08-21 20:08:27 +00:00
|
|
|
envelopeId: string;
|
2021-07-09 19:36:10 +00:00
|
|
|
threadE164?: string;
|
2023-08-10 16:43:33 +00:00
|
|
|
threadAci?: AciString;
|
2021-07-09 19:36:10 +00:00
|
|
|
messageRequestResponseType: Proto.SyncMessage.IMessageRequestResponse['type'];
|
|
|
|
groupId?: string;
|
|
|
|
groupV2Id?: string;
|
|
|
|
};
|
|
|
|
|
|
|
|
export class MessageRequestResponseEvent extends ConfirmableEvent {
|
|
|
|
public readonly threadE164?: string;
|
|
|
|
|
2023-08-10 16:43:33 +00:00
|
|
|
public readonly threadAci?: AciString;
|
2021-07-09 19:36:10 +00:00
|
|
|
|
|
|
|
public readonly messageRequestResponseType?: MessageRequestResponseOptions['messageRequestResponseType'];
|
|
|
|
|
|
|
|
public readonly groupId?: string;
|
|
|
|
|
|
|
|
public readonly groupV2Id?: string;
|
|
|
|
|
2023-08-21 20:08:27 +00:00
|
|
|
public readonly envelopeId?: string;
|
|
|
|
|
2021-07-09 19:36:10 +00:00
|
|
|
constructor(
|
|
|
|
{
|
2023-08-21 20:08:27 +00:00
|
|
|
envelopeId,
|
2021-07-09 19:36:10 +00:00
|
|
|
threadE164,
|
2023-08-10 16:43:33 +00:00
|
|
|
threadAci,
|
2021-07-09 19:36:10 +00:00
|
|
|
messageRequestResponseType,
|
|
|
|
groupId,
|
|
|
|
groupV2Id,
|
|
|
|
}: MessageRequestResponseOptions,
|
|
|
|
confirm: ConfirmCallback
|
|
|
|
) {
|
|
|
|
super('messageRequestResponse', confirm);
|
|
|
|
|
2023-08-21 20:08:27 +00:00
|
|
|
this.envelopeId = envelopeId;
|
2021-07-09 19:36:10 +00:00
|
|
|
this.threadE164 = threadE164;
|
2023-08-10 16:43:33 +00:00
|
|
|
this.threadAci = threadAci;
|
2021-07-09 19:36:10 +00:00
|
|
|
this.messageRequestResponseType = messageRequestResponseType;
|
|
|
|
this.groupId = groupId;
|
|
|
|
this.groupV2Id = groupV2Id;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export class FetchLatestEvent extends ConfirmableEvent {
|
|
|
|
constructor(
|
|
|
|
public readonly eventType: Proto.SyncMessage.IFetchLatest['type'],
|
|
|
|
confirm: ConfirmCallback
|
|
|
|
) {
|
|
|
|
super('fetchLatest', confirm);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export class KeysEvent extends ConfirmableEvent {
|
|
|
|
constructor(
|
2021-09-24 00:49:05 +00:00
|
|
|
public readonly storageServiceKey: Uint8Array,
|
2021-07-09 19:36:10 +00:00
|
|
|
confirm: ConfirmCallback
|
|
|
|
) {
|
|
|
|
super('keys', confirm);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export type StickerPackEventData = Readonly<{
|
|
|
|
id?: string;
|
|
|
|
key?: string;
|
|
|
|
isInstall: boolean;
|
|
|
|
isRemove: boolean;
|
|
|
|
}>;
|
|
|
|
|
|
|
|
export class StickerPackEvent extends ConfirmableEvent {
|
|
|
|
constructor(
|
|
|
|
public readonly stickerPacks: ReadonlyArray<StickerPackEventData>,
|
|
|
|
confirm: ConfirmCallback
|
|
|
|
) {
|
|
|
|
super('sticker-pack', confirm);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export type ReadSyncEventData = Readonly<{
|
2023-08-21 20:08:27 +00:00
|
|
|
envelopeId: string;
|
2021-07-09 19:36:10 +00:00
|
|
|
timestamp?: number;
|
|
|
|
envelopeTimestamp: number;
|
|
|
|
sender?: string;
|
2023-08-10 16:43:33 +00:00
|
|
|
senderAci?: AciString;
|
2021-07-09 19:36:10 +00:00
|
|
|
}>;
|
|
|
|
|
|
|
|
export class ReadSyncEvent extends ConfirmableEvent {
|
|
|
|
constructor(
|
|
|
|
public readonly read: ReadSyncEventData,
|
|
|
|
confirm: ConfirmCallback
|
|
|
|
) {
|
|
|
|
super('readSync', confirm);
|
|
|
|
}
|
|
|
|
}
|
2021-08-12 18:15:55 +00:00
|
|
|
|
|
|
|
export type ViewSyncEventData = Readonly<{
|
2023-08-21 20:08:27 +00:00
|
|
|
envelopeId: string;
|
2021-08-12 18:15:55 +00:00
|
|
|
timestamp?: number;
|
|
|
|
envelopeTimestamp: number;
|
|
|
|
senderE164?: string;
|
2023-08-10 16:43:33 +00:00
|
|
|
senderAci?: AciString;
|
2021-08-12 18:15:55 +00:00
|
|
|
}>;
|
|
|
|
|
|
|
|
export class ViewSyncEvent extends ConfirmableEvent {
|
|
|
|
constructor(
|
|
|
|
public readonly view: ViewSyncEventData,
|
|
|
|
confirm: ConfirmCallback
|
|
|
|
) {
|
|
|
|
super('viewSync', confirm);
|
|
|
|
}
|
|
|
|
}
|
2022-07-13 23:09:18 +00:00
|
|
|
|
2023-01-10 00:52:01 +00:00
|
|
|
export type CallEventSyncEventData = Readonly<{
|
2023-08-09 00:53:06 +00:00
|
|
|
callEventDetails: CallEventDetails;
|
2023-01-10 00:52:01 +00:00
|
|
|
receivedAtCounter: number;
|
|
|
|
}>;
|
|
|
|
|
|
|
|
export class CallEventSyncEvent extends ConfirmableEvent {
|
|
|
|
constructor(
|
|
|
|
public readonly callEvent: CallEventSyncEventData,
|
|
|
|
confirm: ConfirmCallback
|
|
|
|
) {
|
|
|
|
super('callEventSync', confirm);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-08-09 00:53:06 +00:00
|
|
|
export type CallLogEventSyncEventData = Readonly<{
|
|
|
|
event: CallLogEvent;
|
|
|
|
timestamp: number;
|
|
|
|
receivedAtCounter: number;
|
|
|
|
}>;
|
|
|
|
|
|
|
|
export class CallLogEventSyncEvent extends ConfirmableEvent {
|
|
|
|
constructor(
|
|
|
|
public readonly callLogEvent: CallLogEventSyncEventData,
|
|
|
|
confirm: ConfirmCallback
|
|
|
|
) {
|
|
|
|
super('callLogEventSync', confirm);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-13 23:09:18 +00:00
|
|
|
export type StoryRecipientUpdateData = Readonly<{
|
2023-08-10 16:43:33 +00:00
|
|
|
destinationServiceId: ServiceIdString;
|
2022-07-13 23:09:18 +00:00
|
|
|
storyMessageRecipients: Array<Proto.SyncMessage.Sent.IStoryMessageRecipient>;
|
|
|
|
timestamp: number;
|
|
|
|
}>;
|
|
|
|
|
|
|
|
export class StoryRecipientUpdateEvent extends ConfirmableEvent {
|
|
|
|
constructor(
|
|
|
|
public readonly data: StoryRecipientUpdateData,
|
|
|
|
confirm: ConfirmCallback
|
|
|
|
) {
|
|
|
|
super('storyRecipientUpdate', confirm);
|
|
|
|
}
|
|
|
|
}
|