feat(client): chat restrictions related methods

This commit is contained in:
teidesu 2021-05-12 22:07:00 +03:00
parent 30253c83c7
commit 79a8962284
6 changed files with 296 additions and 44 deletions

View file

@ -19,6 +19,7 @@ import { answerCallbackQuery } from './methods/bots/answer-callback-query'
import { answerInlineQuery } from './methods/bots/answer-inline-query' import { answerInlineQuery } from './methods/bots/answer-inline-query'
import { addChatMembers } from './methods/chats/add-chat-members' import { addChatMembers } from './methods/chats/add-chat-members'
import { archiveChats } from './methods/chats/archive-chats' import { archiveChats } from './methods/chats/archive-chats'
import { banChatMember } from './methods/chats/ban-chat-member'
import { createChannel } from './methods/chats/create-channel' import { createChannel } from './methods/chats/create-channel'
import { createGroup } from './methods/chats/create-group' import { createGroup } from './methods/chats/create-group'
import { createSupergroup } from './methods/chats/create-supergroup' import { createSupergroup } from './methods/chats/create-supergroup'
@ -36,7 +37,9 @@ import { getFullChat } from './methods/chats/get-full-chat'
import { getNearbyChats } from './methods/chats/get-nearby-chats' import { getNearbyChats } from './methods/chats/get-nearby-chats'
import { iterChatMembers } from './methods/chats/iter-chat-members' import { iterChatMembers } from './methods/chats/iter-chat-members'
import { joinChat } from './methods/chats/join-chat' import { joinChat } from './methods/chats/join-chat'
import { kickChatMember } from './methods/chats/kick-chat-member'
import { leaveChat } from './methods/chats/leave-chat' import { leaveChat } from './methods/chats/leave-chat'
import { restrictChatMember } from './methods/chats/restrict-chat-member'
import { saveDraft } from './methods/chats/save-draft' import { saveDraft } from './methods/chats/save-draft'
import { setChatDefaultPermissions } from './methods/chats/set-chat-default-permissions' import { setChatDefaultPermissions } from './methods/chats/set-chat-default-permissions'
import { setChatDescription } from './methods/chats/set-chat-description' import { setChatDescription } from './methods/chats/set-chat-description'
@ -45,6 +48,7 @@ import { setChatTitle } from './methods/chats/set-chat-title'
import { setChatUsername } from './methods/chats/set-chat-username' import { setChatUsername } from './methods/chats/set-chat-username'
import { setSlowMode } from './methods/chats/set-slow-mode' import { setSlowMode } from './methods/chats/set-slow-mode'
import { unarchiveChats } from './methods/chats/unarchive-chats' import { unarchiveChats } from './methods/chats/unarchive-chats'
import { unbanChatMember } from './methods/chats/unban-chat-member'
import { addContact } from './methods/contacts/add-contact' import { addContact } from './methods/contacts/add-contact'
import { deleteContacts } from './methods/contacts/delete-contacts' import { deleteContacts } from './methods/contacts/delete-contacts'
import { getContacts } from './methods/contacts/get-contacts' import { getContacts } from './methods/contacts/get-contacts'
@ -596,6 +600,19 @@ export interface TelegramClient extends BaseTelegramClient {
* @param chats Chat ID(s), username(s), phone number(s), `"me"` or `"self"` * @param chats Chat ID(s), username(s), phone number(s), `"me"` or `"self"`
*/ */
archiveChats(chats: MaybeArray<InputPeerLike>): Promise<void> archiveChats(chats: MaybeArray<InputPeerLike>): Promise<void>
/**
* Ban a user from a legacy group, a supergroup or a channel.
* They will not be able to re-join the group on their own,
* manual administrator's action is required.
*
* @param chatId Chat ID
* @param userId User ID
* @returns Service message about removed user, if one was generated.
*/
banChatMember(
chatId: InputPeerLike,
userId: InputPeerLike
): Promise<Message | null>
/** /**
* Create a new broadcast channel * Create a new broadcast channel
* *
@ -695,7 +712,6 @@ export interface TelegramClient extends BaseTelegramClient {
* *
* @param chatId Chat ID * @param chatId Chat ID
* @param params * @param params
*/ */
getChatEventLog( getChatEventLog(
chatId: InputPeerLike, chatId: InputPeerLike,
@ -881,6 +897,15 @@ export interface TelegramClient extends BaseTelegramClient {
* or ID of the linked supergroup or channel. * or ID of the linked supergroup or channel.
*/ */
joinChat(chatId: InputPeerLike): Promise<Chat> joinChat(chatId: InputPeerLike): Promise<Chat>
/**
* Kick a user from a chat.
*
* This effectively bans a user and immediately unbans them.
*
* @param chatId Chat ID
* @param userId User ID
*/
kickChatMember(chatId: InputPeerLike, userId: InputPeerLike): Promise<void>
/** /**
* Leave a group chat, supergroup or channel * Leave a group chat, supergroup or channel
* *
@ -888,6 +913,28 @@ export interface TelegramClient extends BaseTelegramClient {
* @param clear (default: `false`) Whether to clear history after leaving (only for legacy group chats) * @param clear (default: `false`) Whether to clear history after leaving (only for legacy group chats)
*/ */
leaveChat(chatId: InputPeerLike, clear?: boolean): Promise<void> leaveChat(chatId: InputPeerLike, clear?: boolean): Promise<void>
/**
* Restrict a user in a supergroup.
*
* @param chatId Chat ID
* @param userId User ID
* @param restrictions
* Restrictions for the user. Note that unlike Bot API, this object contains
* the restrictions, and not the permissions, i.e. to
* passing `sendMessages=true` will disallow the user to send messages,
* and passing `{}` (empty object) will lift any restrictions
* @param until
* Date when the user will be unrestricted.
* When `number` is passed, UNIX time in ms is expected.
* If this value is less than 30 seconds or more than 366 days in
* the future, user will be restricted forever. Defaults to `0` (forever)
*/
restrictChatMember(
chatId: InputPeerLike,
userId: InputPeerLike,
restrictions: Omit<tl.RawChatBannedRights, '_' | 'untilDate'>,
until?: number | Date
): Promise<void>
/** /**
* Save or delete a draft message associated with some chat * Save or delete a draft message associated with some chat
* *
@ -904,24 +951,15 @@ export interface TelegramClient extends BaseTelegramClient {
* You must be an administrator in the chat and have appropriate permissions. * You must be an administrator in the chat and have appropriate permissions.
* *
* @param chatId Chat ID or username * @param chatId Chat ID or username
* @param permissions New default chat permissions * @param restrictions
* @example * Restrictions for the chat. Note that unlike Bot API, this object contains
* ```typescript * the restrictions, and not the permissions, i.e. to
* // Completely restrict chat * passing `sendMessages=true` will disallow the users to send messages,
* await tg.setDefaultChatPermissions('somechat', {}) * and passing `{}` (empty object) will lift any restrictions
*
* // Chat members can only send text, media, stickers and GIFs
* await tg.setDefaultChatPermissions('somechat', {
* canSendMessages: true,
* canSendMedia: true,
* canSendStickers: true,
* canSendGifs: true,
* })
* ```
*/ */
setChatDefaultPermissions( setChatDefaultPermissions(
chatId: InputPeerLike, chatId: InputPeerLike,
permissions: InputChatPermissions restrictions: Omit<tl.RawChatBannedRights, '_' | 'untilDate'>
): Promise<Chat> ): Promise<Chat>
/** /**
* Change chat description * Change chat description
@ -991,6 +1029,35 @@ export interface TelegramClient extends BaseTelegramClient {
* @param chats Chat ID(s), username(s), phone number(s), `"me"` or `"self"` * @param chats Chat ID(s), username(s), phone number(s), `"me"` or `"self"`
*/ */
unarchiveChats(chats: MaybeArray<InputPeerLike>): Promise<void> unarchiveChats(chats: MaybeArray<InputPeerLike>): Promise<void>
/**
* Unban a user from a supergroup or a channel,
* or remove any restrictions that they have.
* Unbanning does not add the user back to the chat, this
* just allows the user to join the chat again, if they want.
*
* This method acts as a no-op in case a legacy group is passed.
*
* @param chatId Chat ID
* @param userId User ID
*/
unbanChatMember(chatId: InputPeerLike, userId: InputPeerLike): Promise<void>
/**
* Unban a user from a supergroup or a channel,
* or remove any restrictions that they have.
* Unbanning does not add the user back to the chat, this
* just allows the user to join the chat again, if they want.
*
* This method acts as a no-op in case a legacy group is passed.
*
* @param chatId Chat ID
* @param userId User ID
*/
unrestrictChatMember(
chatId: InputPeerLike,
userId: InputPeerLike
): Promise<void>
/** /**
* Add an existing Telegram user as a contact * Add an existing Telegram user as a contact
* *
@ -1109,7 +1176,6 @@ export interface TelegramClient extends BaseTelegramClient {
* is not considered when sorting. * is not considered when sorting.
* *
* @param params Fetch parameters * @param params Fetch parameters
*/ */
getDialogs(params?: { getDialogs(params?: {
/** /**
@ -2605,7 +2671,9 @@ export interface TelegramClient extends BaseTelegramClient {
getUsers(id: InputPeerLike): Promise<User> getUsers(id: InputPeerLike): Promise<User>
/** /**
* Get information about multiple users. * Get information about multiple users.
* You can retrieve up to 200 users at once * You can retrieve up to 200 users at once.
*
* Note that order is not guaranteed.
* *
* @param ids Users' identifiers. Can be ID, username, phone number, `"me"`, `"self"` or TL object * @param ids Users' identifiers. Can be ID, username, phone number, `"me"`, `"self"` or TL object
*/ */
@ -2791,6 +2859,7 @@ export class TelegramClient extends BaseTelegramClient {
answerInlineQuery = answerInlineQuery answerInlineQuery = answerInlineQuery
addChatMembers = addChatMembers addChatMembers = addChatMembers
archiveChats = archiveChats archiveChats = archiveChats
banChatMember = banChatMember
createChannel = createChannel createChannel = createChannel
createGroup = createGroup createGroup = createGroup
createSupergroup = createSupergroup createSupergroup = createSupergroup
@ -2809,7 +2878,9 @@ export class TelegramClient extends BaseTelegramClient {
getNearbyChats = getNearbyChats getNearbyChats = getNearbyChats
iterChatMembers = iterChatMembers iterChatMembers = iterChatMembers
joinChat = joinChat joinChat = joinChat
kickChatMember = kickChatMember
leaveChat = leaveChat leaveChat = leaveChat
restrictChatMember = restrictChatMember
saveDraft = saveDraft saveDraft = saveDraft
setChatDefaultPermissions = setChatDefaultPermissions setChatDefaultPermissions = setChatDefaultPermissions
setChatDescription = setChatDescription setChatDescription = setChatDescription
@ -2818,6 +2889,8 @@ export class TelegramClient extends BaseTelegramClient {
setChatUsername = setChatUsername setChatUsername = setChatUsername
setSlowMode = setSlowMode setSlowMode = setSlowMode
unarchiveChats = unarchiveChats unarchiveChats = unarchiveChats
unbanChatMember = unbanChatMember
unrestrictChatMember = unbanChatMember
addContact = addContact addContact = addContact
deleteContacts = deleteContacts deleteContacts = deleteContacts
getContacts = getContacts getContacts = getContacts

View file

@ -0,0 +1,71 @@
import { TelegramClient } from '../../client'
import {
InputPeerLike,
Message,
MtCuteInvalidPeerTypeError,
MtCuteTypeAssertionError,
} from '../../types'
import {
isInputPeerChannel,
isInputPeerChat,
normalizeToInputChannel,
normalizeToInputPeer,
normalizeToInputUser,
} from '../../utils/peer-utils'
/**
* Ban a user from a legacy group, a supergroup or a channel.
* They will not be able to re-join the group on their own,
* manual administrator's action is required.
*
* @param chatId Chat ID
* @param userId User ID
* @returns Service message about removed user, if one was generated.
* @internal
*/
export async function banChatMember(
this: TelegramClient,
chatId: InputPeerLike,
userId: InputPeerLike
): Promise<Message | null> {
const chat = normalizeToInputPeer(await this.resolvePeer(chatId))
const user = normalizeToInputPeer(await this.resolvePeer(userId))
let res
if (isInputPeerChannel(chat)) {
res = await this.call({
_: 'channels.editBanned',
channel: normalizeToInputChannel(chat),
participant: user,
bannedRights: {
_: 'chatBannedRights',
// bans can't be temporary.
untilDate: 0,
viewMessages: true,
},
})
} else if (isInputPeerChat(chat)) {
const normUser = normalizeToInputUser(user)
if (!normUser) throw new MtCuteInvalidPeerTypeError(userId, 'user')
res = await this.call({
_: 'messages.deleteChatUser',
chatId: chat.chatId,
userId: normUser,
})
} else throw new MtCuteInvalidPeerTypeError(chatId, 'chat or channel')
try {
return this._findMessageInUpdate(res)
} catch (e) {
if (
e instanceof MtCuteTypeAssertionError &&
e.context === '_findInUpdate (@ .updates[*])'
) {
// no service message
return null
}
throw e
}
}

View file

@ -0,0 +1,28 @@
import { TelegramClient } from '../../client'
import { InputPeerLike } from '../../types'
import { isInputPeerChannel, normalizeToInputPeer } from '../../utils/peer-utils'
/**
* Kick a user from a chat.
*
* This effectively bans a user and immediately unbans them.
*
* @param chatId Chat ID
* @param userId User ID
* @internal
*/
export async function kickChatMember(
this: TelegramClient,
chatId: InputPeerLike,
userId: InputPeerLike
): Promise<void> {
const chat = normalizeToInputPeer(await this.resolvePeer(chatId))
const user = normalizeToInputPeer(await this.resolvePeer(userId))
await this.banChatMember(chat, user)
// not needed in case this is a legacy group
if (isInputPeerChannel(chat)) {
await this.unbanChatMember(chat, user)
}
}

View file

@ -0,0 +1,52 @@
import { TelegramClient } from '../../client'
import { InputPeerLike, MtCuteInvalidPeerTypeError } from '../../types'
import {
isInputPeerChannel,
normalizeToInputChannel,
normalizeToInputPeer,
} from '../../utils/peer-utils'
import { tl } from '@mtcute/tl'
import { normalizeDate } from '../../utils/misc-utils'
/**
* Restrict a user in a supergroup.
*
* @param chatId Chat ID
* @param userId User ID
* @param restrictions
* Restrictions for the user. Note that unlike Bot API, this object contains
* the restrictions, and not the permissions, i.e. to
* passing `sendMessages=true` will disallow the user to send messages,
* and passing `{}` (empty object) will lift any restrictions
* @param until
* Date when the user will be unrestricted.
* When `number` is passed, UNIX time in ms is expected.
* If this value is less than 30 seconds or more than 366 days in
* the future, user will be restricted forever. Defaults to `0` (forever)
* @internal
*/
export async function restrictChatMember(
this: TelegramClient,
chatId: InputPeerLike,
userId: InputPeerLike,
restrictions: Omit<tl.RawChatBannedRights, '_' | 'untilDate'>,
until?: number | Date
): Promise<void> {
const chat = normalizeToInputPeer(await this.resolvePeer(chatId))
if (!isInputPeerChannel(chat))
throw new MtCuteInvalidPeerTypeError(chatId, 'channel')
const user = normalizeToInputPeer(await this.resolvePeer(userId))
const res = await this.call({
_: 'channels.editBanned',
channel: normalizeToInputChannel(chat),
participant: user,
bannedRights: {
_: 'chatBannedRights',
untilDate: normalizeDate(until) ?? 0,
...restrictions,
},
})
this._handleUpdate(res)
}

View file

@ -1,6 +1,7 @@
import { TelegramClient } from '../../client' import { TelegramClient } from '../../client'
import { Chat, InputChatPermissions, InputPeerLike, MtCuteTypeAssertionError } from '../../types' import { Chat, InputChatPermissions, InputPeerLike, MtCuteTypeAssertionError } from '../../types'
import { normalizeToInputPeer } from '../../utils/peer-utils' import { normalizeToInputPeer } from '../../utils/peer-utils'
import { tl } from '@mtcute/tl'
/** /**
* Change default chat permissions for all members. * Change default chat permissions for all members.
@ -8,26 +9,17 @@ import { normalizeToInputPeer } from '../../utils/peer-utils'
* You must be an administrator in the chat and have appropriate permissions. * You must be an administrator in the chat and have appropriate permissions.
* *
* @param chatId Chat ID or username * @param chatId Chat ID or username
* @param permissions New default chat permissions * @param restrictions
* @example * Restrictions for the chat. Note that unlike Bot API, this object contains
* ```typescript * the restrictions, and not the permissions, i.e. to
* // Completely restrict chat * passing `sendMessages=true` will disallow the users to send messages,
* await tg.setDefaultChatPermissions('somechat', {}) * and passing `{}` (empty object) will lift any restrictions
*
* // Chat members can only send text, media, stickers and GIFs
* await tg.setDefaultChatPermissions('somechat', {
* canSendMessages: true,
* canSendMedia: true,
* canSendStickers: true,
* canSendGifs: true,
* })
* ```
* @internal * @internal
*/ */
export async function setChatDefaultPermissions( export async function setChatDefaultPermissions(
this: TelegramClient, this: TelegramClient,
chatId: InputPeerLike, chatId: InputPeerLike,
permissions: InputChatPermissions restrictions: Omit<tl.RawChatBannedRights, '_' | 'untilDate'>
): Promise<Chat> { ): Promise<Chat> {
const peer = normalizeToInputPeer(await this.resolvePeer(chatId)) const peer = normalizeToInputPeer(await this.resolvePeer(chatId))
@ -37,17 +29,7 @@ export async function setChatDefaultPermissions(
bannedRights: { bannedRights: {
_: 'chatBannedRights', _: 'chatBannedRights',
untilDate: 0, untilDate: 0,
sendMessages: !permissions.canSendMessages, ...restrictions
sendMedia: !permissions.canSendMedia,
sendStickers: !permissions.canSendStickers,
sendGifs: !permissions.canSendGifs,
sendGames: !permissions.canSendGames,
sendInline: !permissions.canUseInline,
embedLinks: !permissions.canAddWebPreviews,
sendPolls: !permissions.canSendPolls,
changeInfo: !permissions.canChangeInfo,
inviteUsers: !permissions.canInviteUsers,
pinMessages: !permissions.canPinMessages,
} }
}) })

View file

@ -0,0 +1,46 @@
import { TelegramClient } from '../../client'
import { InputPeerLike, MtCuteInvalidPeerTypeError } from '../../types'
import {
isInputPeerChannel,
isInputPeerChat,
normalizeToInputChannel,
normalizeToInputPeer,
} from '../../utils/peer-utils'
// @alias=unrestrictChatMember
/**
* Unban a user from a supergroup or a channel,
* or remove any restrictions that they have.
* Unbanning does not add the user back to the chat, this
* just allows the user to join the chat again, if they want.
*
* This method acts as a no-op in case a legacy group is passed.
*
* @param chatId Chat ID
* @param userId User ID
* @internal
*/
export async function unbanChatMember(
this: TelegramClient,
chatId: InputPeerLike,
userId: InputPeerLike
): Promise<void> {
const chat = normalizeToInputPeer(await this.resolvePeer(chatId))
const user = normalizeToInputPeer(await this.resolvePeer(userId))
if (isInputPeerChannel(chat)) {
const res = await this.call({
_: 'channels.editBanned',
channel: normalizeToInputChannel(chat),
participant: user,
bannedRights: {
_: 'chatBannedRights',
untilDate: 0,
},
})
this._handleUpdate(res)
} else if (isInputPeerChat(chat)) {
// no-op //
} else throw new MtCuteInvalidPeerTypeError(chatId, 'chat or channel')
}