feat(client): bot commands related methods

This commit is contained in:
teidesu 2021-06-26 19:45:06 +03:00
parent 084eb35901
commit 42f6ed1357
8 changed files with 351 additions and 0 deletions

View file

@ -17,12 +17,16 @@ import { startTest } from './methods/auth/start-test'
import { start } from './methods/auth/start'
import { answerCallbackQuery } from './methods/bots/answer-callback-query'
import { answerInlineQuery } from './methods/bots/answer-inline-query'
import { deleteMyCommands } from './methods/bots/delete-my-commands'
import { getCallbackAnswer } from './methods/bots/get-callback-answer'
import {
getGameHighScores,
getInlineGameHighScores,
} from './methods/bots/get-game-high-scores'
import { getMyCommands } from './methods/bots/get-my-commands'
import { _normalizeCommandScope } from './methods/bots/normalize-command-scope'
import { setGameScore, setInlineGameScore } from './methods/bots/set-game-score'
import { setMyCommands } from './methods/bots/set-my-commands'
import { addChatMembers } from './methods/chats/add-chat-members'
import { archiveChats } from './methods/chats/archive-chats'
import { banChatMember } from './methods/chats/ban-chat-member'
@ -156,6 +160,7 @@ import { IMessageEntityParser } from './parser'
import { Readable } from 'stream'
import {
ArrayWithTotal,
BotCommands,
Chat,
ChatEvent,
ChatInviteLink,
@ -605,6 +610,27 @@ export interface TelegramClient extends BaseTelegramClient {
parseMode?: string | null
}
): Promise<void>
/**
* Delete commands for the current bot and the given scope.
*
* Does the same as passing `null` to {@link setMyCommands}
*
* Learn more about scopes in the [Bot API docs](https://core.telegram.org/bots/api#botcommandscope)
*
*/
deleteMyCommands(params?: {
/**
* Scope of the commands.
*
* Defaults to `BotScope.default_` (i.e. `botCommandScopeDefault`)
*/
scope?: tl.TypeBotCommandScope | BotCommands.IntermediateScope
/**
* User language applied to the scope.
*/
langCode?: string
}): Promise<void>
/**
* Request a callback answer from a bot,
* i.e. click an inline button that contains data.
@ -663,6 +689,26 @@ export interface TelegramClient extends BaseTelegramClient {
messageId: string | tl.TypeInputBotInlineMessageID,
userId?: InputPeerLike
): Promise<GameHighScore[]>
/**
* Get a list of current bot's commands for the given command scope
* and user language. If they are not set, empty set is returned.
*
* Learn more about scopes in the [Bot API docs](https://core.telegram.org/bots/api#botcommandscope)
*
*/
getMyCommands(params?: {
/**
* Scope of the commands.
*
* Defaults to `BotScope.default_` (i.e. `botCommandScopeDefault`)
*/
scope?: tl.TypeBotCommandScope | BotCommands.IntermediateScope
/**
* User language applied to the scope.
*/
langCode?: string
}): Promise<tl.RawBotCommand[]>
/**
* Set a score of a user in a game
*
@ -719,6 +765,32 @@ export interface TelegramClient extends BaseTelegramClient {
force?: boolean
}
): Promise<void>
/**
* Set or delete commands for the current bot and the given scope
*
* Learn more about scopes in the [Bot API docs](https://core.telegram.org/bots/api#botcommandscope)
*
*/
setMyCommands(params: {
/**
* New list of bot commands for the given scope.
*
* Pass empty array or `null` to delete them.
*/
commands: tl.RawBotCommand[] | null
/**
* Scope of the commands.
*
* Defaults to `BotScope.default_` (i.e. `botCommandScopeDefault`)
*/
scope?: tl.TypeBotCommandScope | BotCommands.IntermediateScope
/**
* User language applied to the scope.
*/
langCode?: string
}): Promise<void>
/**
* Add new members to a group, supergroup or channel.
*
@ -3133,11 +3205,15 @@ export class TelegramClient extends BaseTelegramClient {
start = start
answerCallbackQuery = answerCallbackQuery
answerInlineQuery = answerInlineQuery
deleteMyCommands = deleteMyCommands
getCallbackAnswer = getCallbackAnswer
getGameHighScores = getGameHighScores
getInlineGameHighScores = getInlineGameHighScores
getMyCommands = getMyCommands
protected _normalizeCommandScope = _normalizeCommandScope
setGameScore = setGameScore
setInlineGameScore = setInlineGameScore
setMyCommands = setMyCommands
addChatMembers = addChatMembers
archiveChats = archiveChats
banChatMember = banChatMember

View file

@ -39,6 +39,7 @@ import {
ChatsIndex,
GameHighScore,
ArrayWithTotal,
BotCommands
} from '../types'
// @copy

View file

@ -0,0 +1,41 @@
import { TelegramClient } from '../../client'
import { tl } from '@mtcute/tl'
import { BotCommands } from '../../types'
/**
* Delete commands for the current bot and the given scope.
*
* Does the same as passing `null` to {@link setMyCommands}
*
* Learn more about scopes in the [Bot API docs](https://core.telegram.org/bots/api#botcommandscope)
*
* @internal
*/
export async function deleteMyCommands(
this: TelegramClient,
params?: {
/**
* Scope of the commands.
*
* Defaults to `BotScope.default_` (i.e. `botCommandScopeDefault`)
*/
scope?: tl.TypeBotCommandScope | BotCommands.IntermediateScope
/**
* User language applied to the scope.
*/
langCode?: string
}
): Promise<void> {
const scope: tl.TypeBotCommandScope = params?.scope
? await this._normalizeCommandScope(params.scope)
: {
_: 'botCommandScopeDefault',
}
await this.call({
_: 'bots.resetBotCommands',
scope,
langCode: params?.langCode ?? '',
})
}

View file

@ -0,0 +1,38 @@
import { TelegramClient } from '../../client'
import { tl } from '@mtcute/tl'
import { BotCommands } from '../../types'
/**
* Get a list of current bot's commands for the given command scope
* and user language. If they are not set, empty set is returned.
*
* Learn more about scopes in the [Bot API docs](https://core.telegram.org/bots/api#botcommandscope)
*
* @internal
*/
export async function getMyCommands(
this: TelegramClient,
params?: {
/**
* Scope of the commands.
*
* Defaults to `BotScope.default_` (i.e. `botCommandScopeDefault`)
*/
scope?: tl.TypeBotCommandScope | BotCommands.IntermediateScope
/**
* User language applied to the scope.
*/
langCode?: string
}
): Promise<tl.RawBotCommand[]> {
return this.call({
_: 'bots.getBotCommands',
scope: params?.scope
? await this._normalizeCommandScope(params.scope)
: {
_: 'botCommandScopeDefault',
},
langCode: params?.langCode ?? '',
})
}

View file

@ -0,0 +1,37 @@
import { tl } from '@mtcute/tl'
import { BotCommands, MtCuteInvalidPeerTypeError } from '../../types'
import { TelegramClient } from '../../client'
import { normalizeToInputUser } from '../../utils/peer-utils'
/** @internal */
export async function _normalizeCommandScope(
this: TelegramClient,
scope: tl.TypeBotCommandScope | BotCommands.IntermediateScope
): Promise<tl.TypeBotCommandScope> {
if (tl.isAnyBotCommandScope(scope)) return scope
switch (scope.type) {
case 'peer':
case 'peer_admins': {
const peer = await this.resolvePeer(scope.peer)
return {
_: scope.type === 'peer' ? 'botCommandScopePeer' : 'botCommandScopePeerAdmins',
peer
}
}
case 'member': {
const chat = await this.resolvePeer(scope.chat)
const user = normalizeToInputUser(await this.resolvePeer(scope.user))
if (!user)
throw new MtCuteInvalidPeerTypeError(scope.user, 'user')
return {
_: 'botCommandScopePeerUser',
peer: chat,
userId: user
}
}
}
}

View file

@ -0,0 +1,55 @@
import { TelegramClient } from '../../client'
import { tl } from '@mtcute/tl'
import { BotCommands } from '../../types'
/**
* Set or delete commands for the current bot and the given scope
*
* Learn more about scopes in the [Bot API docs](https://core.telegram.org/bots/api#botcommandscope)
*
* @internal
*/
export async function setMyCommands(
this: TelegramClient,
params: {
/**
* New list of bot commands for the given scope.
*
* Pass empty array or `null` to delete them.
*/
commands: tl.RawBotCommand[] | null
/**
* Scope of the commands.
*
* Defaults to `BotScope.default_` (i.e. `botCommandScopeDefault`)
*/
scope?: tl.TypeBotCommandScope | BotCommands.IntermediateScope
/**
* User language applied to the scope.
*/
langCode?: string
}
): Promise<void> {
const scope: tl.TypeBotCommandScope = params.scope
? await this._normalizeCommandScope(params.scope)
: {
_: 'botCommandScopeDefault',
}
if (params.commands?.length) {
await this.call({
_: 'bots.setBotCommands',
commands: params.commands,
scope,
langCode: params.langCode ?? '',
})
} else {
await this.call({
_: 'bots.resetBotCommands',
scope,
langCode: params.langCode ?? '',
})
}
}

View file

@ -0,0 +1,102 @@
import { tl } from '@mtcute/tl'
import { InputPeerLike } from '../peers'
/**
* Helper constants and builder functions for methods
* related to bot commands.
*
* You can learn more about bot command scopes in
* [Bot API docs](https://core.telegram.org/bots/api#botcommandscope)
*/
export namespace BotCommands {
/**
* Intermediate bot scope, that is converted to
* TL type `BotCommandScope` by the respective functions.
*
* Used to avoid manually resolving peers.
*/
export type IntermediateScope = {
type: 'peer' | 'peer_admins'
peer: InputPeerLike
} | {
type: 'member'
chat: InputPeerLike
user: InputPeerLike
}
/**
* Default commands scope.
*
* Used if no commands with a narrower scope are available.
*/
export const default_: tl.RawBotCommandScopeDefault = {
_: 'botCommandScopeDefault'
} as const
/**
* Scope that covers all private chats
*/
export const allPrivate: tl.RawBotCommandScopeUsers = {
_: 'botCommandScopeUsers'
} as const
/**
* Scope that covers all group chats (both legacy and supergroups)
*/
export const allGroups: tl.RawBotCommandScopeChats = {
_: 'botCommandScopeChats'
} as const
/**
* Scope that covers all group chat administrators (both legacy and supergroups)
*/
export const allGroupAdmins: tl.RawBotCommandScopeChatAdmins = {
_: 'botCommandScopeChatAdmins'
} as const
/**
* Scope that covers a specific peer (a single user in PMs,
* or all users of a legacy group or a supergroup)
*/
export function peer(peer: InputPeerLike): IntermediateScope {
return {
type: 'peer',
peer
}
}
/**
* Scope that covers admins in a specific group
*/
export function groupAdmins(peer: InputPeerLike): IntermediateScope {
return {
type: 'peer_admins',
peer
}
}
/**
* Scope that covers a specific user in a specific group
*/
export function groupMember(chat: InputPeerLike, user: InputPeerLike): IntermediateScope {
return {
type: 'member',
chat,
user
}
}
/**
* Helper function to create a bot command object
*
* @param command Bot command (without slash)
* @param description Command description
*/
export function cmd(command: string, description: string): tl.RawBotCommand {
return {
_: 'botCommand',
command,
description
}
}
}

View file

@ -4,3 +4,4 @@ export * from './keyboards'
export * from './inline-query'
export * from './callback-query'
export * from './game-high-score'
export * from './command-scope'