diff --git a/packages/client/src/client.ts b/packages/client/src/client.ts index 3ae63f95..199e7b73 100644 --- a/packages/client/src/client.ts +++ b/packages/client/src/client.ts @@ -75,6 +75,7 @@ import { setChatPhoto } from './methods/chats/set-chat-photo' import { setChatTitle } from './methods/chats/set-chat-title' import { setChatUsername } from './methods/chats/set-chat-username' import { setSlowMode } from './methods/chats/set-slow-mode' +import { toggleContentProtection } from './methods/chats/toggle-content-protection' import { toggleFragmentUsername } from './methods/chats/toggle-fragment-username' import { toggleJoinRequests } from './methods/chats/toggle-join-requests' import { toggleJoinToSend } from './methods/chats/toggle-join-to-send' @@ -1528,6 +1529,13 @@ export interface TelegramClient extends BaseTelegramClient { * Valid values are: `0 (off), 10, 30, 60 (1m), 300 (5m), 900 (15m) or 3600 (1h)` */ setSlowMode(chatId: InputPeerLike, seconds?: number): Promise + /** + * Set whether a chat has content protection (i.e. forwarding messages is disabled) + * + * @param chatId Chat ID or username + * @param enabled (default: `false`) Whether content protection should be enabled + */ + toggleContentProtection(chatId: InputPeerLike, enabled?: boolean): Promise /** * Toggle a collectible (Fragment) username * @@ -4442,6 +4450,7 @@ export class TelegramClient extends BaseTelegramClient { setChatTitle = setChatTitle setChatUsername = setChatUsername setSlowMode = setSlowMode + toggleContentProtection = toggleContentProtection toggleFragmentUsername = toggleFragmentUsername toggleJoinRequests = toggleJoinRequests toggleJoinToSend = toggleJoinToSend diff --git a/packages/client/src/methods/chats/toggle-content-protection.ts b/packages/client/src/methods/chats/toggle-content-protection.ts new file mode 100644 index 00000000..82570801 --- /dev/null +++ b/packages/client/src/methods/chats/toggle-content-protection.ts @@ -0,0 +1,22 @@ +import { TelegramClient } from '../../client' +import { InputPeerLike } from '../../types' + +/** + * Set whether a chat has content protection (i.e. forwarding messages is disabled) + * + * @param chatId Chat ID or username + * @param enabled Whether content protection should be enabled + * @internal + */ +export async function toggleContentProtection( + this: TelegramClient, + chatId: InputPeerLike, + enabled = false, +): Promise { + const res = await this.call({ + _: 'messages.toggleNoForwards', + peer: await this.resolvePeer(chatId), + enabled, + }) + this._handleUpdate(res) +} diff --git a/packages/client/src/types/messages/message.ts b/packages/client/src/types/messages/message.ts index 28500c5a..8ad03de5 100644 --- a/packages/client/src/types/messages/message.ts +++ b/packages/client/src/types/messages/message.ts @@ -146,6 +146,11 @@ export class Message { return this.raw._ === 'messageService' } + /** Whether this message has content protection (i.e. disabled forwards) */ + get isContentProtected(): boolean { + return this.raw._ === 'message' && this.raw.noforwards! + } + /** * Multiple media messages with the same grouped ID * indicate an album or media group diff --git a/packages/client/src/types/peers/chat-event/actions.ts b/packages/client/src/types/peers/chat-event/actions.ts index 58f8c4f0..b668e5da 100644 --- a/packages/client/src/types/peers/chat-event/actions.ts +++ b/packages/client/src/types/peers/chat-event/actions.ts @@ -10,12 +10,12 @@ import { ChatMember } from '../chat-member' import { ChatPermissions } from '../chat-permissions' import { User } from '../user' -/** A user has joined the group (in the case of big groups, info of the user that has joined isn't shown) */ +/** A user has joined the channel (in the case of big groups, info of the user that has joined isn't shown) */ export interface ChatActionUserJoined { type: 'user_joined' } -/** A user has joined the group using an invite link */ +/** A user has joined the channel using an invite link */ export interface ChatActionUserJoinedInvite { type: 'user_joined_invite' @@ -23,7 +23,7 @@ export interface ChatActionUserJoinedInvite { link: ChatInviteLink } -/** A user has joined the group using an invite link and was approved by an admin */ +/** A user has joined the channel using an invite link and was approved by an admin */ export interface ChatActionUserJoinedApproved { type: 'user_joined_approved' @@ -34,12 +34,12 @@ export interface ChatActionUserJoinedApproved { approvedBy: User } -/** A user has left the group (in the case of big groups, info of the user that has joined isn't shown) */ +/** A user has left the channel (in the case of big groups, info of the user that has joined isn't shown) */ export interface ChatActionUserLeft { type: 'user_left' } -/** A user was invited to the group */ +/** A user was invited to the channel */ export interface ChatActionUserInvited { type: 'user_invited' @@ -47,7 +47,7 @@ export interface ChatActionUserInvited { member: ChatMember } -/** Group title has been changed */ +/** Channel title has been changed */ export interface ChatActionTitleChanged { type: 'title_changed' @@ -58,7 +58,7 @@ export interface ChatActionTitleChanged { new: string } -/** Group description has been changed */ +/** Channel description has been changed */ export interface ChatActionDescriptionChanged { type: 'description_changed' @@ -69,7 +69,7 @@ export interface ChatActionDescriptionChanged { new: string } -/** Group username has been changed */ +/** Channel username has been changed */ export interface ChatActionUsernameChanged { type: 'username_changed' @@ -80,7 +80,18 @@ export interface ChatActionUsernameChanged { new: string } -/** Group photo has been changed */ +/** Channel username list has been changed */ +export interface ChatActionUsernamesChanged { + type: 'usernames_changed' + + /** Old username */ + old: string[] + + /** New username */ + new: string[] +} + +/** Channel photo has been changed */ export interface ChatActionPhotoChanged { type: 'photo_changed' @@ -298,6 +309,14 @@ export interface ChatActionTtlChanged { new: number } +/** Content protection has been toggled */ +export interface ChatActionNoForwardsToggled { + type: 'no_forwards_toggled' + + /** New status */ + enabled: boolean +} + /** Forum has been toggled */ export interface ChatActionForumToggled { type: 'forum_toggled' @@ -341,6 +360,7 @@ export type ChatAction = | ChatActionTitleChanged | ChatActionDescriptionChanged | ChatActionUsernameChanged + | ChatActionUsernamesChanged | ChatActionPhotoChanged | ChatActionInvitesToggled | ChatActionSignaturesToggled @@ -365,6 +385,7 @@ export type ChatAction = | ChatActionInviteLinkRevoked | ChatActionUserJoinedApproved | ChatActionTtlChanged + | ChatActionNoForwardsToggled | ChatActionForumToggled | ChatActionTopicCreated | ChatActionTopicEdited @@ -377,10 +398,6 @@ export function _actionFromTl( client: TelegramClient, peers: PeersIndex, ): ChatAction { - // todo - MTQ-84 - // channelAdminLogEventActionToggleNoForwards#cb2ac766 new_value:Bool = ChannelAdminLogEventAction; - // todo - MTQ-57 - // channelAdminLogEventActionChangeUsernames#f04fb3a9 prev_value:Vector new_value:Vector // todo - MTQ-72 // channelAdminLogEventActionSendMessage#278f2868 message:Message = ChannelAdminLogEventAction; // channelAdminLogEventActionChangeAvailableReactions#be4e0ef8 prev_value:ChatReactions new_value:ChatReactions @@ -407,6 +424,12 @@ export function _actionFromTl( old: e.prevValue, new: e.newValue, } + case 'channelAdminLogEventActionChangeUsernames': + return { + type: 'usernames_changed', + old: e.prevValue, + new: e.newValue, + } case 'channelAdminLogEventActionChangePhoto': return { type: 'photo_changed', @@ -585,6 +608,11 @@ export function _actionFromTl( type: 'topic_deleted', topic: new ForumTopic(client, e.topic, peers), } + case 'channelAdminLogEventActionToggleNoForwards': + return { + type: 'no_forwards_toggled', + enabled: e.newValue, + } // case 'channelAdminLogEventActionPinTopic' // ^ looks like it is not used, and pinned topics are not at all presented in the event log default: diff --git a/packages/client/src/types/peers/chat-event/filters.ts b/packages/client/src/types/peers/chat-event/filters.ts index 5ae8989d..06dcc94c 100644 --- a/packages/client/src/types/peers/chat-event/filters.ts +++ b/packages/client/src/types/peers/chat-event/filters.ts @@ -48,6 +48,7 @@ export function normalizeChatEventFilters(input: InputChatEventFilters): ChatEve case 'location_changed': case 'photo_changed': case 'username_changed': + case 'usernames_changed': case 'stickerset_changed': case 'slow_mode_changed': case 'ttl_changed': @@ -58,6 +59,7 @@ export function normalizeChatEventFilters(input: InputChatEventFilters): ChatEve case 'signatures_toggled': case 'def_perms_changed': case 'forum_toggled': + case 'no_forwards_toggled': serverFilter.settings = true break case 'msg_pinned': diff --git a/packages/client/src/types/peers/chat.ts b/packages/client/src/types/peers/chat.ts index 42fad580..60bdf2e5 100644 --- a/packages/client/src/types/peers/chat.ts +++ b/packages/client/src/types/peers/chat.ts @@ -212,6 +212,11 @@ export class Chat { return this.peer._ === 'channel' && this.peer.joinToSend! } + /** Whether this group has content protection (i.e. disabled forwards) */ + get hasContentProtection(): boolean { + return (this.peer._ === 'channel' || this.peer._ === 'chat') && this.peer.noforwards! + } + /** * Title, for supergroups, channels and groups */