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:
alechkos 2025-08-09 00:36:27 +03:00 • committed by GitHub
commit f9db14d185
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 261 additions and 4 deletions

View file

@ -15,7 +15,7 @@ const { LoadUtils } = require('./util/Injected/Utils');
const ChatFactory = require('./factories/ChatFactory');
const ContactFactory = require('./factories/ContactFactory');
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 {exposeFunctionIfAbsent} = require('./util/Puppeteer');
@ -939,6 +939,9 @@ class Client extends EventEmitter {
} else if (content instanceof Poll) {
internalOptions.poll = content;
content = '';
} else if (content instanceof ScheduledEvent) {
internalOptions.event = content;
content = '';
} else if (content instanceof Contact) {
internalOptions.contactCard = content.id._serialized;
content = '';
@ -2196,6 +2199,45 @@ class Client extends EventEmitter {
}, 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
* @param {string} phoneNumber The contact's phone number in a format "17182222222", where "1" is a country code