diff --git a/example.js b/example.js index 3f21a2e..3334e5b 100644 --- a/example.js +++ b/example.js @@ -465,6 +465,11 @@ client.on('message', async msg => { // const isSynced = await chat.syncHistory(); await msg.reply(isSynced ? 'Historical chat is syncing..' : 'There is no historical chat to sync.'); + } else if (msg.body === '!statuses') { + const statuses = await client.getBroadcasts(); + console.log(statuses); + const chat = await statuses[0]?.getChat(); // Get user chat of a first status + console.log(chat); } }); diff --git a/index.d.ts b/index.d.ts index eed78b5..bd75dbf 100644 --- a/index.d.ts +++ b/index.d.ts @@ -75,6 +75,9 @@ declare namespace WAWebJS { /** Get all current Labels */ getLabels(): Promise + /** Get all current Broadcasts */ + getBroadcasts(): Promise + /** Change labels in chats */ addOrRemoveLabels(labelIds: Array, chatIds: Array): Promise @@ -1089,6 +1092,28 @@ declare namespace WAWebJS { getChats: () => Promise } + export interface Broadcast { + /** Chat Object ID */ + id: { + server: string, + user: string, + _serialized: string + }, + /** Unix timestamp of last story */ + timestamp: number, + /** Number of available statuses */ + totalCount: number, + /** Number of not viewed */ + unreadCount: number, + /** Unix timestamp of last story */ + msgs: Message[], + + /** Returns the Chat of the owner of the story */ + getChat: () => Promise, + /** Returns the Contact of the owner of the story */ + getContact: () => Promise, + } + /** Options for sending a message */ export interface MessageSendOptions { /** Show links preview. Has no effect on multi-device accounts. */ diff --git a/index.js b/index.js index dd991f5..aebe6ce 100644 --- a/index.js +++ b/index.js @@ -22,6 +22,7 @@ module.exports = { ProductMetadata: require('./src/structures/ProductMetadata'), List: require('./src/structures/List'), Buttons: require('./src/structures/Buttons'), + Broadcast: require('./src/structures/Broadcast'), // Auth Strategies NoAuth: require('./src/authStrategies/NoAuth'), diff --git a/src/Client.js b/src/Client.js index f040362..c5a6c3b 100644 --- a/src/Client.js +++ b/src/Client.js @@ -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 { ClientInfo, Message, MessageMedia, Contact, Location, Poll, PollVote, GroupNotification, Label, Call, Buttons, List, Reaction } = require('./structures'); +const { ClientInfo, Message, MessageMedia, Contact, Location, Poll, PollVote, GroupNotification, Label, Call, Buttons, List, Reaction, Broadcast} = require('./structures'); const NoAuth = require('./authStrategies/NoAuth'); const {exposeFunctionIfAbsent} = require('./util/Puppeteer'); @@ -1472,6 +1472,17 @@ class Client extends EventEmitter { return labels.map(data => new Label(this, data)); } + + /** + * Get all current Broadcast + * @returns {Promise>} + */ + async getBroadcasts() { + const broadcasts = await this.pupPage.evaluate(async () => { + return window.WWebJS.getAllStatuses(); + }); + return broadcasts.map(data => new Broadcast(this, data)); + } /** * Get Label instance by ID diff --git a/src/structures/Broadcast.js b/src/structures/Broadcast.js new file mode 100644 index 0000000..eb7f977 --- /dev/null +++ b/src/structures/Broadcast.js @@ -0,0 +1,69 @@ +'use strict'; + +const Base = require('./Base'); +const Message = require('./Message'); + +/** + * Represents a Status/Story on WhatsApp + * @extends {Base} + */ +class Broadcast extends Base { + constructor(client, data) { + super(client); + + if (data) this._patch(data); + } + + _patch(data) { + /** + * ID that represents the chat + * @type {object} + */ + this.id = data.id; + + /** + * Unix timestamp of last status + * @type {number} + */ + this.timestamp = data.t; + + /** + * Number of available statuses + * @type {number} + */ + this.totalCount = data.totalCount; + + /** + * Number of not viewed + * @type {number} + */ + this.unreadCount = data.unreadCount; + + /** + * Messages statuses + * @type {Message[]} + */ + this.msgs = data.msgs.map(msg => new Message(this.client, msg)); + + return super._patch(data); + } + + /** + * Returns the Chat this message was sent in + * @returns {Promise} + */ + getChat() { + return this.client.getChatById(this.id._serialized); + } + + /** + * Returns the Contact this message was sent from + * @returns {Promise} + */ + getContact() { + return this.client.getContactById(this.id._serialized); + } + +} + +module.exports = Broadcast; diff --git a/src/structures/index.js b/src/structures/index.js index 5568a87..a3abc6f 100644 --- a/src/structures/index.js +++ b/src/structures/index.js @@ -20,5 +20,6 @@ module.exports = { Payment: require('./Payment'), Reaction: require('./Reaction'), Poll: require('./Poll'), - PollVote: require('./PollVote') + PollVote: require('./PollVote'), + Broadcast: require('./Broadcast') }; diff --git a/src/util/Injected/Utils.js b/src/util/Injected/Utils.js index f842c55..6052627 100644 --- a/src/util/Injected/Utils.js +++ b/src/util/Injected/Utils.js @@ -1013,5 +1013,16 @@ exports.LoadUtils = () => { const response = await window.Store.pinUnpinMsg(message, action, duration); return response.messageSendResult === 'OK'; }; + + window.WWebJS.getStatusModel = status => { + let res = status.serialize(); + delete res._msgs; + res.msgs = status._msgs.map(msg => window.WWebJS.getMessageModel(msg)); + return res; + }; + window.WWebJS.getAllStatuses = () => { + const statuses = window.Store.Status.getModelsArray(); + return statuses.map(status => window.WWebJS.getStatusModel(status)); + }; };