feat: Channel (#2620)

* window.injectToFunction clarifications

* added createChannel method

* initial Channel class structure

* added getChannelById and getChannels methods

* added 4 methods to change channel metadata

* added deleteChannel method

* added subscribe to/unsubscribe from channel methods

* ecmaVersion updated to 2022

* added searchChannels method

* refactoring of: getChat, getChannel, getChatModel, getChannelModel

* removed Channel.canSend

* sendMessage updated to support channels [p1]

* createChannel: returns string if an error occupied

* added getSubscribers

* added mute/unmute methods

* searchChannels: minor update

* sendMessage updated to support channels [p2]

- added support to send image, sticker, gif and video

* [REFAC] refactored chat retrieving in getChatOrChannel

* [FEAT] added getChannelByInviteCode method

* [CHG] added check if channel creation enabled

* [FEAT] added sendChannelAdminInvitation method

* [WIP] preparations for sending polls [p1]

* [BUG] fixed some internal functions

* [BUG] fixed poll creation

* [COPY] renamed some internal functions

- window.WWebJS.getChatOrChannel renamed back to window.WWebJS.getChat
-window.WWebJS.getChatOrChannelModel renamed back to window.WWebJS.getChatModel

* fix: typo

* fix: send docs without caption

* fix: fixed some internal function

* fix: channel retrieving

* fix: fixed internal getChannelMetadata function

* fix: fixed channel admin can unsubscribe from channel

* feat: channel admin functionality

* feat: added fetchMessages method

Co-authored-by: tuke307 <58882912+tuke307@users.noreply.github.com>

* refactor: revert removing support for Buttons and Lists

Note: buttons and lists are deprecated

* refactor: revert parameter name from 'chatOrChannel' to 'chat'

* fix: support Node v12

* refactor: return 'undefined' in a case of falsy value

* refactor: use already created variable

* docs: fix 'countryCodes' property type

* fix: 'searchChannels' method fixed

* fix: add check in 'setReactionSetting' method

* sendNewsletterMessageJob requires a proper Msg Object in 2.24xx (#10)

Co-authored-by: Sven Neumann <s.neumann@websix.de>

* style: fix broken link in readme file

* fix: only directPath determines whether hasMedia or not

fixes #2952

* fix: get rid of unnecessary 'await'

* feat: add option to send polls in channels

* refactor: get channel instances with 'getChatById'

* chore: fix eslint

* fix: fatal error

* refactor: delete local models by default when unsubscribing

* fix: prevent TypeError if no channel models are returned

* fix: update 'searchChannels' function for WWeb > 2.3000.0

* fix: fix for 'getChannelByInviteCode' function

* fix: fix for 'sendChannelAdminInvite' function

* fix: update 'fetchMessages' for channels

* refactor: update 'setReactionSetting' function

* fix: update 'sendMessage' for channels

* feat: add 'transferChannelOwnership' function

* refactor: add 'deleteChannel' function to 'Client'

* style: fix project code style

* chore: eslint fix

* feat: add 'sendSeen' function

* fix: fix the function restoration after injection

* refactor: remove duplicate module

* fix: get isNewsletter properly

* fix: fix channels media - add mediaHandle

Co-authored-by: devlikepro <155617407+devlikepro@users.noreply.github.com>

---------

Co-authored-by: tuke307 <58882912+tuke307@users.noreply.github.com>
Co-authored-by: Sven <sven2neumann@gmail.com>
Co-authored-by: Sven Neumann <s.neumann@websix.de>
Co-authored-by: devlikepro <155617407+devlikepro@users.noreply.github.com>
This commit is contained in:
alechkos 2025-05-31 21:36:19 +03:00 • committed by GitHub
commit d0642b761c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 1241 additions and 234 deletions

190
index.d.ts vendored
View file

@ -24,6 +24,15 @@ declare namespace WAWebJS {
/**Accepts an invitation to join a group */
acceptInvite(inviteCode: string): Promise<string>
/** Accepts a channel admin invitation and promotes the current user to a channel admin */
acceptChannelAdminInvite(channelId: string): Promise<boolean>
/** Revokes a channel admin invitation sent to a user by a channel owner */
revokeChannelAdminInvite(channelId: string, userId: string): Promise<boolean>
/** Demotes a channel admin to a regular subscriber (can be used also for self-demotion) */
demoteChannelAdmin(channelId: string, userId: string): Promise<boolean>
/** Accepts a private invitation to join a group (v4 invite) */
acceptGroupV4Invite: (inviteV4: InviteV4Data) => Promise<{status: number}>
@ -42,6 +51,27 @@ declare namespace WAWebJS {
/** Creates a new group */
createGroup(title: string, participants?: string | Contact | Contact[] | string[], options?: CreateGroupOptions): Promise<CreateGroupResult|string>
/** Creates a new channel */
createChannel(title: string, options?: CreateChannelOptions): Promise<CreateChannelResult | string>
/** Deletes the channel you created */
deleteChannel(channelId: string): Promise<boolean>;
/** Subscribe to channel */
subscribeToChannel(channelId: string): Promise<boolean>
/** Unsubscribe from channel */
unsubscribeFromChannel(channelId: string, options?: UnsubscribeOptions): Promise<boolean>
/**
* Searches for channels based on search criteria, there are some notes:
* 1. The method finds only channels you are not subscribed to currently
* 2. If you have never been subscribed to a found channel
* or you have unsubscribed from it with {@link UnsubscribeOptions.deleteLocalModels} set to 'true',
* the lastMessage property of a found channel will be 'null'
*/
searchChannels(searchOptions: SearchChannelsOptions): Promise<Array<Channel> | []>
/** Closes the client */
destroy(): Promise<void>
@ -51,12 +81,18 @@ declare namespace WAWebJS {
/** Get all blocked contacts by host account */
getBlockedContacts(): Promise<Contact[]>
/** Get chat instance by ID */
/** Gets chat or channel instance by ID */
getChatById(chatId: string): Promise<Chat>
/** Gets a {@link Channel} instance by invite code */
getChannelByInviteCode(inviteCode: string): Promise<Channel>
/** Get all current chat instances */
getChats(): Promise<Chat[]>
/** Gets all cached {@link Channel} instances */
getChannels(): Promise<Channel[]>
/** Get contact instance by ID */
getContactById(contactId: string): Promise<Contact>
@ -131,6 +167,9 @@ declare namespace WAWebJS {
/** Send a message to a specific chatId */
sendMessage(chatId: string, content: MessageContent, options?: MessageSendOptions): Promise<Message>
/** Sends a channel admin invitation to a user, allowing them to become an admin of the channel */
sendChannelAdminInvite(chatId: string, channelId: string, options?: { comment?: string }): Promise<boolean>
/** Searches for messages */
searchMessages(query: string, options?: { chatId?: string, page?: number, limit?: number }): Promise<Message[]>
@ -217,13 +256,19 @@ declare namespace WAWebJS {
deleteProfilePicture(): Promise<boolean>
/** Gets an array of membership requests */
getGroupMembershipRequests: (groupId: string) => Promise<Array<GroupMembershipRequest>>
getGroupMembershipRequests(groupId: string): Promise<Array<GroupMembershipRequest>>
/** Approves membership requests if any */
approveGroupMembershipRequests: (groupId: string, options: MembershipRequestActionOptions) => Promise<Array<MembershipRequestActionResult>>;
approveGroupMembershipRequests(groupId: string, options: MembershipRequestActionOptions): Promise<Array<MembershipRequestActionResult>>;
/** Rejects membership requests if any */
rejectGroupMembershipRequests: (groupId: string, options: MembershipRequestActionOptions) => Promise<Array<MembershipRequestActionResult>>;
rejectGroupMembershipRequests(groupId: string, options: MembershipRequestActionOptions): Promise<Array<MembershipRequestActionResult>>;
/**
* Transfers a channel ownership to another user.
* Note: the user you are transferring the channel ownership to must be a channel admin.
*/
transferChannelOwnership(channelId: string, newOwnerId: string, options?: TransferChannelOwnershipOptions): Promise<boolean>;
/** Generic event */
on(event: string, listener: (...args: any) => void): this
@ -655,6 +700,46 @@ declare namespace WAWebJS {
};
}
/** An object that handles options for channel creation */
export interface CreateChannelOptions {
/** The channel description */
description?: string,
/** The channel profile picture */
picture?: MessageMedia
}
/** An object that handles the result for createGroup method */
export interface CreateChannelResult {
/** A channel title */
title: string,
/** An object that handles the newly created channel ID */
nid: ChatId,
/** The channel invite link, starts with 'https://whatsapp.com/channel/' */
inviteLink: string,
/** The timestamp the channel was created at */
createdAtTs: number
}
/** Options for unsubscribe from a channel */
export interface UnsubscribeOptions {
/**
* If true, after an unsubscription, it will completely remove a channel from the channel collection
* making it seem like the current user have never interacted with it.
* Otherwise it will only remove a channel from the list of channels the current user is subscribed to
* and will set the membership type for that channel to GUEST
*/
deleteLocalModels?: boolean
}
/** Options for searching for channels */
export interface SearchChannelsOptions {
searchText?: string;
countryCodes?: string[];
skipSubscribedNewsletters?: boolean;
view?: number;
limit?: number;
}
export interface GroupNotification {
/** ContactId for the user that produced the GroupNotification */
author: string,
@ -1471,8 +1556,8 @@ declare namespace WAWebJS {
mute: (unmuteDate?: Date) => Promise<{ isMuted: boolean, muteExpiration: number }>,
/** Send a message to this chat */
sendMessage: (content: MessageContent, options?: MessageSendOptions) => Promise<Message>,
/** Set the chat as seen */
sendSeen: () => Promise<void>,
/** Sets the chat as seen */
sendSeen: () => Promise<boolean>,
/** Simulate recording audio in chat. This will last for 25 seconds */
sendStateRecording: () => Promise<void>,
/** Simulate typing in chat. This will last for 25 seconds. */
@ -1493,6 +1578,99 @@ declare namespace WAWebJS {
syncHistory: () => Promise<boolean>
}
export interface Channel {
/** ID that represents the channel */
id: {
server: string;
user: string;
_serialized: string;
};
/** Title of the channel */
name: string;
/** The channel description */
description: string;
/** Indicates if it is a Channel */
isChannel: boolean;
/** Indicates if it is a Group */
isGroup: boolean;
/** Indicates if the channel is readonly */
isReadOnly: boolean;
/** Amount of messages unread */
unreadCount: number;
/** Unix timestamp for when the last activity occurred */
timestamp: number;
/** Indicates if the channel is muted or not */
isMuted: boolean;
/** Unix timestamp for when the mute expires */
muteExpiration: number;
/** Last message in the channel */
lastMessage: Message | undefined;
/** Gets the subscribers of the channel (only those who are in your contact list) */
getSubscribers(limit?: number): Promise<{contact: Contact, role: string}[]>;
/** Updates the channel subject */
setSubject(newSubject: string): Promise<boolean>;
/** Updates the channel description */
setDescription(newDescription: string): Promise<boolean>;
/** Updates the channel profile picture */
setProfilePicture(newProfilePicture: MessageMedia): Promise<boolean>;
/**
* Updates available reactions to use in the channel
*
* Valid values for passing to the method are:
* 0 for NONE reactions to be avaliable
* 1 for BASIC reactions to be available: 👍, ❤️, 😂, 😮, 😢, 🙏
* 2 for ALL reactions to be available
*/
setReactionSetting(reactionCode: number): Promise<boolean>;
/** Mutes the channel */
mute(): Promise<boolean>;
/** Unmutes the channel */
unmute(): Promise<boolean>;
/** Sends a message to this channel */
sendMessage(content: string|MessageMedia, options?: MessageSendChannelOptions): Promise<Message>;
/** Sets the channel as seen */
sendSeen(): Promise<boolean>;
/** Sends a channel admin invitation to a user, allowing them to become an admin of the channel */
sendChannelAdminInvite(chatId: string, options?: { comment?: string }): Promise<boolean>;
/** Accepts a channel admin invitation and promotes the current user to a channel admin */
acceptChannelAdminInvite(): Promise<boolean>;
/** Revokes a channel admin invitation sent to a user by a channel owner */
revokeChannelAdminInvite(userId: string): Promise<boolean>;
/** Demotes a channel admin to a regular subscriber (can be used also for self-demotion) */
demoteChannelAdmin(userId: string): Promise<boolean>;
/** Loads channel messages, sorted from earliest to latest */
fetchMessages: (searchOptions: MessageSearchOptions) => Promise<Message[]>;
/**
* Transfers a channel ownership to another user.
* Note: the user you are transferring the channel ownership to must be a channel admin.
*/
transferChannelOwnership(newOwnerId: string, options?: TransferChannelOwnershipOptions): Promise<boolean>;
/** Deletes the channel you created */
deleteChannel(): Promise<boolean>;
}
/** Options for transferring a channel ownership to another user */
export interface TransferChannelOwnershipOptions {
/**
* If true, after the channel ownership is being transferred to another user,
* the current user will be dismissed as a channel admin and will become to a channel subscriber.
*/
shouldDismissSelfAsAdmin?: boolean
}
/** Options for sending a message */
export interface MessageSendChannelOptions {
/** Image or videos caption */
caption?: string
/** User IDs of user that will be mentioned in the message */
mentions?: string[]
/** Image or video to be sent */
media?: MessageMedia
/** Extra options */
extra?: any
}
export interface MessageSearchOptions {
/**
* The amount of messages to return. If no limit is specified, the available messages will be returned.