feat: whatsapp stories implementation (#3994)

* support sending message from status broadcast

* add to index.d.ts

* add method to contact

* new modules

* Update Utils.js

* add for the examples

* add color assertion function

* finishing..

* added waveforms for audio messages and minor fixes

* fix eslint

* refactor

reorganize the store to include additional modules.

* adapt

* the last one.

---------

Co-authored-by: Rajeh Taher <rajeh@reforward.dev>
This commit is contained in:
RendyCraft047 2025-12-13 11:34:55 +07:00 • committed by GitHub
commit 6aa1bd85ab
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 152 additions and 12 deletions

View file

@ -948,9 +948,10 @@ class Client extends EventEmitter {
*/
async sendMessage(chatId, content, options = {}) {
const isChannel = /@\w*newsletter\b/.test(chatId);
const isStatus = /@\w*broadcast\b/.test(chatId);
if (isChannel && [
options.sendMediaAsDocument, options.quotedMessageId,
options.sendMediaAsDocument, options.quotedMessageId,
options.parseVCards, options.isViewOnce,
content instanceof Location, content instanceof Contact,
content instanceof Buttons, content instanceof List,
@ -958,6 +959,16 @@ class Client extends EventEmitter {
].includes(true)) {
console.warn('The message type is currently not supported for sending in channels,\nthe supported message types are: text, image, sticker, gif, video, voice and poll.');
return null;
} else if (isStatus && [
options.sendMediaAsDocument, options.quotedMessageId,
options.parseVCards, options.isViewOnce, options.sendMediaAsSticker,
content instanceof Location, content instanceof Contact,
content instanceof Poll, content instanceof Buttons, content instanceof List,
Array.isArray(content) && content.length > 0 && content[0] instanceof Contact
].includes(true)) {
console.warn('The message type is currently not supported for sending in status broadcast,\nthe supported message types are: text, image, gif, audio and video.');
return null;
}
if (options.mentions) {
@ -1193,7 +1204,12 @@ class Client extends EventEmitter {
return ContactFactory.create(this, contact);
}
/**
* Get message by ID
* @param {string} messageId
* @returns {Promise<Message>}
*/
async getMessageById(messageId) {
const msg = await this.pupPage.evaluate(async messageId => {
let msg = window.Store.Msg.get(messageId);
@ -1970,7 +1986,7 @@ class Client extends EventEmitter {
return labels.map(data => new Label(this, data));
}
/**
* Get all current Broadcast
* @returns {Promise<Array<Broadcast>>}
@ -1982,6 +1998,49 @@ class Client extends EventEmitter {
return broadcasts.map(data => new Broadcast(this, data));
}
/**
* Get broadcast instance by current user ID
* @param {string} contactId
* @returns {Promise<Broadcast>}
*/
async getBroadcastById(contactId) {
const broadcast = await this.pupPage.evaluate(async (userId) => {
let status;
try {
status = window.Store.Status.get(userId);
if (!status) {
status = await window.Store.Status.find(userId);
}
} catch {
status = null;
}
if (status) return window.WWebJS.getStatusModel(status);
}, contactId);
return new Broadcast(this, broadcast);
}
/**
* Revoke current own status messages
* @param {string} messageId
* @returns {Promise<void>}
*/
async revokeStatusMessage(messageId) {
return await this.pupPage.evaluate(async (msgId) => {
const status = window.Store.Status.getMyStatus();
if (!status) return;
const msg =
window.Store.Msg.get(msgId) || (await window.Store.Msg.getMessagesById([msgId]))?.messages?.[0];
if (!msg) return;
if (!msg.id.fromMe || !msg.id.remote.isStatus())
throw 'Invalid usage! Can only revoke the message its from own status broadcast';
return await window.Store.StatusUtils.sendStatusRevokeMsgAction(status, msg);
}, messageId);
}
/**
* Get Label instance by ID
* @param {string} labelId