feat: Event messages (#3345)
* feat: add createCallLink function * feat: create Event class * feat: add functionality for sending Events * feat: add editEvent function * refactor: send event location prop as wa does * refactor: combine modules * feat: add sendResponseToEvent function * fix: createEventCallLink parameter * docs: add documentation * fix: eslint * refactor: change timestamp to Date for the user's convenience * refactor: rename 'Event' to 'ScheduledEvent' for more clarity * style: fix typo in inner function * refactor: remove unnecessary inner function * refactor: rename 'sendResponseToEvent' to 'sendResponseToScheduledEvent' for more clarity * fix: update the module name
This commit is contained in:
parent
ab321f3d7e
commit
f9db14d185
9 changed files with 261 additions and 4 deletions
74
index.d.ts
vendored
74
index.d.ts
vendored
|
|
@ -261,6 +261,16 @@ declare namespace WAWebJS {
|
||||||
/** Deletes the current user's profile picture */
|
/** Deletes the current user's profile picture */
|
||||||
deleteProfilePicture(): Promise<boolean>
|
deleteProfilePicture(): Promise<boolean>
|
||||||
|
|
||||||
|
/** Generates a WhatsApp call link (video call or voice call) */
|
||||||
|
createCallLink(startTime: Date, callType: string): Promise<string>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a response to the scheduled event message, indicating whether a user is going to attend the event or not
|
||||||
|
* @param response The response code to the event message. Valid values are: `0` for NONE response (removes a previous response) | `1` for GOING | `2` for NOT GOING | `3` for MAYBE going
|
||||||
|
* @param eventMessageId The event message ID
|
||||||
|
*/
|
||||||
|
sendResponseToScheduledEvent(response: number, eventMessageId: string): Promise<boolean>
|
||||||
|
|
||||||
/** Gets an array of membership requests */
|
/** Gets an array of membership requests */
|
||||||
getGroupMembershipRequests(groupId: string): Promise<Array<GroupMembershipRequest>>
|
getGroupMembershipRequests(groupId: string): Promise<Array<GroupMembershipRequest>>
|
||||||
|
|
||||||
|
|
@ -902,6 +912,7 @@ declare namespace WAWebJS {
|
||||||
REACTION = 'reaction',
|
REACTION = 'reaction',
|
||||||
TEMPLATE_BUTTON_REPLY = 'template_button_reply',
|
TEMPLATE_BUTTON_REPLY = 'template_button_reply',
|
||||||
POLL_CREATION = 'poll_creation',
|
POLL_CREATION = 'poll_creation',
|
||||||
|
SCHEDULED_EVENT_CREATION = 'scheduled_event_creation',
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Client status */
|
/** Client status */
|
||||||
|
|
@ -1071,6 +1082,24 @@ declare namespace WAWebJS {
|
||||||
pollOptions: string[],
|
pollOptions: string[],
|
||||||
/** False for a single choice poll, true for a multiple choice poll */
|
/** False for a single choice poll, true for a multiple choice poll */
|
||||||
allowMultipleAnswers: boolean,
|
allowMultipleAnswers: boolean,
|
||||||
|
/** The start time of the event in timestamp (10 digits) */
|
||||||
|
eventStartTime: number,
|
||||||
|
/** The end time of the event in timestamp (10 digits) */
|
||||||
|
eventEndTime?: number,
|
||||||
|
/** The event description */
|
||||||
|
eventDescription?: string,
|
||||||
|
/** The location of the event */
|
||||||
|
eventLocation?: {
|
||||||
|
degreesLatitude: number;
|
||||||
|
degreesLongitude: number;
|
||||||
|
name: string;
|
||||||
|
},
|
||||||
|
/** WhatsApp call link (video call or voice call) */
|
||||||
|
eventJoinLink?: string,
|
||||||
|
/** Indicates if an event should be sent as an already canceled */
|
||||||
|
isEventCaneled: boolean,
|
||||||
|
/** The custom message secret, can be used as an event ID */
|
||||||
|
messageSecret?: Array<number>,
|
||||||
/*
|
/*
|
||||||
* Reloads this Message object's data in-place with the latest values from WhatsApp Web.
|
* Reloads this Message object's data in-place with the latest values from WhatsApp Web.
|
||||||
* Note that the Message must still be in the web app cache for this to work, otherwise will return null.
|
* Note that the Message must still be in the web app cache for this to work, otherwise will return null.
|
||||||
|
|
@ -1128,6 +1157,11 @@ declare namespace WAWebJS {
|
||||||
getReactions: () => Promise<ReactionList[]>,
|
getReactions: () => Promise<ReactionList[]>,
|
||||||
/** Edits the current message */
|
/** Edits the current message */
|
||||||
edit: (content: MessageContent, options?: MessageEditOptions) => Promise<Message | null>,
|
edit: (content: MessageContent, options?: MessageEditOptions) => Promise<Message | null>,
|
||||||
|
/**
|
||||||
|
* Edits the current ScheduledEvent message.
|
||||||
|
* Once the event is canceled, it can not be edited.
|
||||||
|
*/
|
||||||
|
editScheduledEvent: (editedEventObject: Event) => Promise<Message | null>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/** ID that represents a message */
|
/** ID that represents a message */
|
||||||
|
|
@ -1183,6 +1217,44 @@ declare namespace WAWebJS {
|
||||||
constructor(pollName: string, pollOptions: Array<string>, options?: PollSendOptions)
|
constructor(pollName: string, pollOptions: Array<string>, options?: PollSendOptions)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** ScheduledEvent send options */
|
||||||
|
export interface ScheduledEventSendOptions {
|
||||||
|
/** The scheduled event description */
|
||||||
|
description?: string,
|
||||||
|
/** The end time of the event */
|
||||||
|
endTime?: Date,
|
||||||
|
/** The location of the event */
|
||||||
|
location?: string,
|
||||||
|
/** The type of a WhatsApp call link to generate, valid values are: `video` | `voice` */
|
||||||
|
callType?: string,
|
||||||
|
/**
|
||||||
|
* Indicates if a scheduled event should be sent as an already canceled
|
||||||
|
* @default false
|
||||||
|
*/
|
||||||
|
isEventCanceled?: boolean
|
||||||
|
/**
|
||||||
|
* The custom message secret, can be used as an event ID
|
||||||
|
* @note It has to be a unique vector with a length of 32
|
||||||
|
*/
|
||||||
|
messageSecret: Array<number>|undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Represents a ScheduledEvent on WhatsApp */
|
||||||
|
export class ScheduledEvent {
|
||||||
|
name: string
|
||||||
|
startTimeTs: number
|
||||||
|
eventSendOptions: {
|
||||||
|
description?: string;
|
||||||
|
endTimeTs?: number;
|
||||||
|
location?: string;
|
||||||
|
callType?: string;
|
||||||
|
isEventCanceled?: boolean;
|
||||||
|
messageSecret?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
constructor(name: string, startTime: Date, options?: EventSendOptions)
|
||||||
|
}
|
||||||
|
|
||||||
/** Represents a Poll Vote on WhatsApp */
|
/** Represents a Poll Vote on WhatsApp */
|
||||||
export interface PollVote {
|
export interface PollVote {
|
||||||
/** The person who voted */
|
/** The person who voted */
|
||||||
|
|
@ -1338,7 +1410,7 @@ declare namespace WAWebJS {
|
||||||
static fromUrl: (url: string, options?: MediaFromURLOptions) => Promise<MessageMedia>
|
static fromUrl: (url: string, options?: MediaFromURLOptions) => Promise<MessageMedia>
|
||||||
}
|
}
|
||||||
|
|
||||||
export type MessageContent = string | MessageMedia | Location | Poll | Contact | Contact[] | List | Buttons
|
export type MessageContent = string | MessageMedia | Location | Poll | Contact | Contact[] | List | Buttons | ScheduledEvent
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a Contact on WhatsApp
|
* Represents a Contact on WhatsApp
|
||||||
|
|
|
||||||
1
index.js
1
index.js
|
|
@ -20,6 +20,7 @@ module.exports = {
|
||||||
ClientInfo: require('./src/structures/ClientInfo'),
|
ClientInfo: require('./src/structures/ClientInfo'),
|
||||||
Location: require('./src/structures/Location'),
|
Location: require('./src/structures/Location'),
|
||||||
Poll: require('./src/structures/Poll'),
|
Poll: require('./src/structures/Poll'),
|
||||||
|
ScheduledEvent: require('./src/structures/ScheduledEvent'),
|
||||||
ProductMetadata: require('./src/structures/ProductMetadata'),
|
ProductMetadata: require('./src/structures/ProductMetadata'),
|
||||||
List: require('./src/structures/List'),
|
List: require('./src/structures/List'),
|
||||||
Buttons: require('./src/structures/Buttons'),
|
Buttons: require('./src/structures/Buttons'),
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ const { LoadUtils } = require('./util/Injected/Utils');
|
||||||
const ChatFactory = require('./factories/ChatFactory');
|
const ChatFactory = require('./factories/ChatFactory');
|
||||||
const ContactFactory = require('./factories/ContactFactory');
|
const ContactFactory = require('./factories/ContactFactory');
|
||||||
const WebCacheFactory = require('./webCache/WebCacheFactory');
|
const WebCacheFactory = require('./webCache/WebCacheFactory');
|
||||||
const { Broadcast, Buttons, Call, ClientInfo, Contact, GroupNotification, Label, List, Location, Message, MessageMedia, Poll, PollVote, Reaction } = require('./structures');
|
const { ClientInfo, Message, MessageMedia, Contact, Location, Poll, PollVote, GroupNotification, Label, Call, Buttons, List, Reaction, Broadcast, ScheduledEvent } = require('./structures');
|
||||||
const NoAuth = require('./authStrategies/NoAuth');
|
const NoAuth = require('./authStrategies/NoAuth');
|
||||||
const {exposeFunctionIfAbsent} = require('./util/Puppeteer');
|
const {exposeFunctionIfAbsent} = require('./util/Puppeteer');
|
||||||
|
|
||||||
|
|
@ -939,6 +939,9 @@ class Client extends EventEmitter {
|
||||||
} else if (content instanceof Poll) {
|
} else if (content instanceof Poll) {
|
||||||
internalOptions.poll = content;
|
internalOptions.poll = content;
|
||||||
content = '';
|
content = '';
|
||||||
|
} else if (content instanceof ScheduledEvent) {
|
||||||
|
internalOptions.event = content;
|
||||||
|
content = '';
|
||||||
} else if (content instanceof Contact) {
|
} else if (content instanceof Contact) {
|
||||||
internalOptions.contactCard = content.id._serialized;
|
internalOptions.contactCard = content.id._serialized;
|
||||||
content = '';
|
content = '';
|
||||||
|
|
@ -2196,6 +2199,45 @@ class Client extends EventEmitter {
|
||||||
}, chatId);
|
}, chatId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a WhatsApp call link (video call or voice call)
|
||||||
|
* @param {Date} startTime The start time of the call
|
||||||
|
* @param {string} callType The type of a WhatsApp call link to generate, valid values are: `video` | `voice`
|
||||||
|
* @returns {Promise<string>} The WhatsApp call link (https://call.whatsapp.com/video/XxXxXxXxXxXxXx) or an empty string if a generation failed.
|
||||||
|
*/
|
||||||
|
async createCallLink(startTime, callType) {
|
||||||
|
if (!['video', 'voice'].includes(callType)) {
|
||||||
|
throw new class CreateCallLinkError extends Error {
|
||||||
|
constructor(m) { super(m); }
|
||||||
|
}('Invalid \'callType\' parameter value is provided. Valid values are: \'voice\' | \'video\'.');
|
||||||
|
}
|
||||||
|
|
||||||
|
startTime = Math.floor(startTime.getTime() / 1000);
|
||||||
|
|
||||||
|
return await this.pupPage.evaluate(async (startTimeTs, callType) => {
|
||||||
|
const response = await window.Store.ScheduledEventMsgUtils.createEventCallLink(startTimeTs, callType);
|
||||||
|
return response ?? '';
|
||||||
|
}, startTime, callType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a response to the scheduled event message, indicating whether a user is going to attend the event or not
|
||||||
|
* @param {number} response The response code to the scheduled event message. Valid values are: `0` for NONE response (removes a previous response) | `1` for GOING | `2` for NOT GOING | `3` for MAYBE going
|
||||||
|
* @param {string} eventMessageId The scheduled event message ID
|
||||||
|
* @returns {Promise<boolean>}
|
||||||
|
*/
|
||||||
|
async sendResponseToScheduledEvent(response, eventMessageId) {
|
||||||
|
if (![0, 1, 2, 3].includes(response)) return false;
|
||||||
|
|
||||||
|
return await this.pupPage.evaluate(async (response, msgId) => {
|
||||||
|
const eventMsg = window.Store.Msg.get(msgId) || (await window.Store.Msg.getMessagesById([msgId]))?.messages?.[0];
|
||||||
|
if (!eventMsg) return false;
|
||||||
|
|
||||||
|
await window.Store.ScheduledEventMsgUtils.sendEventResponseMsg(response, eventMsg);
|
||||||
|
return true;
|
||||||
|
}, response, eventMessageId);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save new contact to user's addressbook or edit the existing one
|
* Save new contact to user's addressbook or edit the existing one
|
||||||
* @param {string} phoneNumber The contact's phone number in a format "17182222222", where "1" is a country code
|
* @param {string} phoneNumber The contact's phone number in a format "17182222222", where "1" is a country code
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ const Order = require('./Order');
|
||||||
const Payment = require('./Payment');
|
const Payment = require('./Payment');
|
||||||
const Reaction = require('./Reaction');
|
const Reaction = require('./Reaction');
|
||||||
const Contact = require('./Contact');
|
const Contact = require('./Contact');
|
||||||
|
const ScheduledEvent = require('./ScheduledEvent'); // eslint-disable-line no-unused-vars
|
||||||
const { MessageTypes } = require('../util/Constants');
|
const { MessageTypes } = require('../util/Constants');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -51,7 +52,7 @@ class Message extends Base {
|
||||||
* Message content
|
* Message content
|
||||||
* @type {string}
|
* @type {string}
|
||||||
*/
|
*/
|
||||||
this.body = this.hasMedia ? data.caption || '' : data.body || data.pollName || '';
|
this.body = this.hasMedia ? data.caption || '' : data.body || data.pollName || data.eventName || '';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Message type
|
* Message type
|
||||||
|
|
@ -699,6 +700,40 @@ class Message extends Base {
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Edits the current ScheduledEvent message.
|
||||||
|
* Once the scheduled event is canceled, it can not be edited.
|
||||||
|
* @param {ScheduledEvent} editedEventObject
|
||||||
|
* @returns {Promise<?Message>}
|
||||||
|
*/
|
||||||
|
async editScheduledEvent(editedEventObject) {
|
||||||
|
if (!this.fromMe) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const edittedEventMsg = await this.client.pupPage.evaluate(async (msgId, editedEventObject) => {
|
||||||
|
const msg = window.Store.Msg.get(msgId) || (await window.Store.Msg.getMessagesById([msgId]))?.messages?.[0];
|
||||||
|
if (!msg) return null;
|
||||||
|
|
||||||
|
const { name, startTimeTs, eventSendOptions } = editedEventObject;
|
||||||
|
const eventOptions = {
|
||||||
|
name: name,
|
||||||
|
description: eventSendOptions.description,
|
||||||
|
startTime: startTimeTs,
|
||||||
|
endTime: eventSendOptions.endTimeTs,
|
||||||
|
location: eventSendOptions.location,
|
||||||
|
callType: eventSendOptions.callType,
|
||||||
|
isEventCanceled: eventSendOptions.isEventCanceled,
|
||||||
|
};
|
||||||
|
|
||||||
|
await window.Store.ScheduledEventMsgUtils.sendEventEditMessage(eventOptions, msg);
|
||||||
|
const editedMsg = window.Store.Msg.get(msg.id._serialized);
|
||||||
|
return editedMsg?.serialize();
|
||||||
|
}, this.id._serialized, editedEventObject);
|
||||||
|
|
||||||
|
return edittedEventMsg && new Message(this.client, edittedEventMsg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = Message;
|
module.exports = Message;
|
||||||
|
|
|
||||||
71
src/structures/ScheduledEvent.js
Normal file
71
src/structures/ScheduledEvent.js
Normal file
|
|
@ -0,0 +1,71 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ScheduledEvent send options
|
||||||
|
* @typedef {Object} ScheduledEventSendOptions
|
||||||
|
* @property {?string} description The scheduled event description
|
||||||
|
* @property {?Date} endTime The end time of the event
|
||||||
|
* @property {?string} location The location of the event
|
||||||
|
* @property {?string} callType The type of a WhatsApp call link to generate, valid values are: `video` | `voice`
|
||||||
|
* @property {boolean} [isEventCanceled = false] Indicates if a scheduled event should be sent as an already canceled
|
||||||
|
* @property {?Array<number>} messageSecret The custom message secret, can be used as an event ID. NOTE: it has to be a unique vector with a length of 32
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** Represents a ScheduledEvent on WhatsApp */
|
||||||
|
class ScheduledEvent {
|
||||||
|
/**
|
||||||
|
* @param {string} name
|
||||||
|
* @param {Date} startTime
|
||||||
|
* @param {ScheduledEventSendOptions} options
|
||||||
|
*/
|
||||||
|
constructor(name, startTime, options = {}) {
|
||||||
|
/**
|
||||||
|
* The name of the event
|
||||||
|
* @type {string}
|
||||||
|
*/
|
||||||
|
this.name = this._validateInputs('name', name).trim();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The start time of the event
|
||||||
|
* @type {number}
|
||||||
|
*/
|
||||||
|
this.startTimeTs = Math.floor(startTime.getTime() / 1000);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The send options for the event
|
||||||
|
* @type {Object}
|
||||||
|
*/
|
||||||
|
this.eventSendOptions = {
|
||||||
|
description: options.description?.trim(),
|
||||||
|
endTimeTs: options.endTime ? Math.floor(options.endTime.getTime() / 1000) : null,
|
||||||
|
location: options.location?.trim(),
|
||||||
|
callType: this._validateInputs('callType', options.callType),
|
||||||
|
isEventCanceled: options.isEventCanceled ?? false,
|
||||||
|
messageSecret: options.messageSecret
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inner function to validate input values
|
||||||
|
* @param {string} propName The property name to validate the value of
|
||||||
|
* @param {string | number} propValue The property value to validate
|
||||||
|
* @returns {string | number} The property value if a validation succeeded
|
||||||
|
*/
|
||||||
|
_validateInputs(propName, propValue) {
|
||||||
|
if (propName === 'name' && !propValue) {
|
||||||
|
throw new class CreateScheduledEventError extends Error {
|
||||||
|
constructor(m) { super(m); }
|
||||||
|
}(`Empty '${propName}' parameter value is provided.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (propName === 'callType' && propValue && !['video', 'voice'].includes(propValue)) {
|
||||||
|
throw new class CreateScheduledEventError extends Error {
|
||||||
|
constructor(m) { super(m); }
|
||||||
|
}(`Invalid '${propName}' parameter value is provided. Valid values are: 'voice' | 'video'.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return propValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = ScheduledEvent;
|
||||||
|
|
@ -22,5 +22,6 @@ module.exports = {
|
||||||
Reaction: require('./Reaction'),
|
Reaction: require('./Reaction'),
|
||||||
Poll: require('./Poll'),
|
Poll: require('./Poll'),
|
||||||
PollVote: require('./PollVote'),
|
PollVote: require('./PollVote'),
|
||||||
Broadcast: require('./Broadcast')
|
Broadcast: require('./Broadcast'),
|
||||||
|
ScheduledEvent: require('./ScheduledEvent'),
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -111,6 +111,7 @@ exports.MessageTypes = {
|
||||||
REACTION: 'reaction',
|
REACTION: 'reaction',
|
||||||
TEMPLATE_BUTTON_REPLY: 'template_button_reply',
|
TEMPLATE_BUTTON_REPLY: 'template_button_reply',
|
||||||
POLL_CREATION: 'poll_creation',
|
POLL_CREATION: 'poll_creation',
|
||||||
|
SCHEDULED_EVENT_CREATION: 'scheduled_event_creation',
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -114,6 +114,11 @@ exports.ExposeStore = () => {
|
||||||
window.Store.ForwardUtils = {
|
window.Store.ForwardUtils = {
|
||||||
...window.require('WAWebChatForwardMessage')
|
...window.require('WAWebChatForwardMessage')
|
||||||
};
|
};
|
||||||
|
window.Store.ScheduledEventMsgUtils = {
|
||||||
|
...window.require('WAWebGenerateEventCallLink'),
|
||||||
|
...window.require('WAWebSendEventEditMsgAction'),
|
||||||
|
...window.require('WAWebSendEventResponseMsgAction')
|
||||||
|
};
|
||||||
window.Store.VCard = {
|
window.Store.VCard = {
|
||||||
...window.require('WAWebFrontendVcardUtils'),
|
...window.require('WAWebFrontendVcardUtils'),
|
||||||
...window.require('WAWebVcardParsingUtils'),
|
...window.require('WAWebVcardParsingUtils'),
|
||||||
|
|
|
||||||
|
|
@ -116,6 +116,34 @@ exports.LoadUtils = () => {
|
||||||
delete options.poll;
|
delete options.poll;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let eventOptions = {};
|
||||||
|
if (options.event) {
|
||||||
|
const { name, startTimeTs, eventSendOptions } = options.event;
|
||||||
|
const { messageSecret } = eventSendOptions;
|
||||||
|
eventOptions = {
|
||||||
|
type: 'event_creation',
|
||||||
|
eventName: name,
|
||||||
|
eventDescription: eventSendOptions.description,
|
||||||
|
eventStartTime: startTimeTs,
|
||||||
|
eventEndTime: eventSendOptions.endTimeTs,
|
||||||
|
eventLocation: eventSendOptions.location && {
|
||||||
|
degreesLatitude: 0,
|
||||||
|
degreesLongitude: 0,
|
||||||
|
name: eventSendOptions.location
|
||||||
|
},
|
||||||
|
eventJoinLink: await window.Store.ScheduledEventMsgUtils.createEventCallLink(
|
||||||
|
startTimeTs,
|
||||||
|
eventSendOptions.callType
|
||||||
|
),
|
||||||
|
isEventCanceled: eventSendOptions.isEventCanceled,
|
||||||
|
messageSecret:
|
||||||
|
Array.isArray(messageSecret) && messageSecret.length === 32
|
||||||
|
? new Uint8Array(messageSecret)
|
||||||
|
: window.crypto.getRandomValues(new Uint8Array(32)),
|
||||||
|
};
|
||||||
|
delete options.event;
|
||||||
|
}
|
||||||
|
|
||||||
let vcardOptions = {};
|
let vcardOptions = {};
|
||||||
if (options.contactCard) {
|
if (options.contactCard) {
|
||||||
let contact = window.Store.Contact.get(options.contactCard);
|
let contact = window.Store.Contact.get(options.contactCard);
|
||||||
|
|
@ -255,6 +283,7 @@ exports.LoadUtils = () => {
|
||||||
...quotedMsgOptions,
|
...quotedMsgOptions,
|
||||||
...locationOptions,
|
...locationOptions,
|
||||||
..._pollOptions,
|
..._pollOptions,
|
||||||
|
...eventOptions,
|
||||||
...vcardOptions,
|
...vcardOptions,
|
||||||
...buttonOptions,
|
...buttonOptions,
|
||||||
...listOptions,
|
...listOptions,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue