feat: feature parity with botapi 6.9
well mostly, and assuming i didn't miss anything. closes MTQ-72
This commit is contained in:
parent
e7dc8f0ec7
commit
2bde1c4f3e
22 changed files with 569 additions and 96 deletions
|
@ -32,11 +32,13 @@ 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 { answerPreCheckoutQuery } from './methods/bots/answer-pre-checkout-query'
|
import { answerPreCheckoutQuery } from './methods/bots/answer-pre-checkout-query'
|
||||||
import { deleteMyCommands } from './methods/bots/delete-my-commands'
|
import { deleteMyCommands } from './methods/bots/delete-my-commands'
|
||||||
|
import { getBotInfo } from './methods/bots/get-bot-info'
|
||||||
import { getBotMenuButton } from './methods/bots/get-bot-menu-button'
|
import { getBotMenuButton } from './methods/bots/get-bot-menu-button'
|
||||||
import { getCallbackAnswer } from './methods/bots/get-callback-answer'
|
import { getCallbackAnswer } from './methods/bots/get-callback-answer'
|
||||||
import { getGameHighScores, getInlineGameHighScores } from './methods/bots/get-game-high-scores'
|
import { getGameHighScores, getInlineGameHighScores } from './methods/bots/get-game-high-scores'
|
||||||
import { getMyCommands } from './methods/bots/get-my-commands'
|
import { getMyCommands } from './methods/bots/get-my-commands'
|
||||||
import { _normalizeCommandScope } from './methods/bots/normalize-command-scope'
|
import { _normalizeCommandScope } from './methods/bots/normalize-command-scope'
|
||||||
|
import { setBotInfo } from './methods/bots/set-bot-info'
|
||||||
import { setBotMenuButton } from './methods/bots/set-bot-menu-button'
|
import { setBotMenuButton } from './methods/bots/set-bot-menu-button'
|
||||||
import { setGameScore, setInlineGameScore } from './methods/bots/set-game-score'
|
import { setGameScore, setInlineGameScore } from './methods/bots/set-game-score'
|
||||||
import { setMyCommands } from './methods/bots/set-my-commands'
|
import { setMyCommands } from './methods/bots/set-my-commands'
|
||||||
|
@ -183,6 +185,7 @@ import { getCustomEmojis } from './methods/stickers/get-custom-emojis'
|
||||||
import { getInstalledStickers } from './methods/stickers/get-installed-stickers'
|
import { getInstalledStickers } from './methods/stickers/get-installed-stickers'
|
||||||
import { getStickerSet } from './methods/stickers/get-sticker-set'
|
import { getStickerSet } from './methods/stickers/get-sticker-set'
|
||||||
import { moveStickerInSet } from './methods/stickers/move-sticker-in-set'
|
import { moveStickerInSet } from './methods/stickers/move-sticker-in-set'
|
||||||
|
import { setChatStickerSet } from './methods/stickers/set-chat-sticker-set'
|
||||||
import { setStickerSetThumb } from './methods/stickers/set-sticker-set-thumb'
|
import { setStickerSetThumb } from './methods/stickers/set-sticker-set-thumb'
|
||||||
import { applyBoost } from './methods/stories/apply-boost'
|
import { applyBoost } from './methods/stories/apply-boost'
|
||||||
import { canApplyBoost, CanApplyBoostResult } from './methods/stories/can-apply-boost'
|
import { canApplyBoost, CanApplyBoostResult } from './methods/stories/can-apply-boost'
|
||||||
|
@ -285,6 +288,7 @@ import {
|
||||||
InputPeerLike,
|
InputPeerLike,
|
||||||
InputPrivacyRule,
|
InputPrivacyRule,
|
||||||
InputReaction,
|
InputReaction,
|
||||||
|
InputStickerSet,
|
||||||
InputStickerSetItem,
|
InputStickerSetItem,
|
||||||
MaybeDynamic,
|
MaybeDynamic,
|
||||||
Message,
|
Message,
|
||||||
|
@ -916,6 +920,23 @@ export interface TelegramClient extends BaseTelegramClient {
|
||||||
*/
|
*/
|
||||||
langCode?: string
|
langCode?: string
|
||||||
}): Promise<void>
|
}): Promise<void>
|
||||||
|
/**
|
||||||
|
* Gets information about a bot the current uzer owns (or the current bot)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
getBotInfo(params: {
|
||||||
|
/**
|
||||||
|
* When called by a user, a bot the user owns must be specified.
|
||||||
|
* When called by a bot, must be empty
|
||||||
|
*/
|
||||||
|
bot?: InputPeerLike
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If passed, will retrieve the bot's description in the given language.
|
||||||
|
* If left empty, will retrieve the fallback description.
|
||||||
|
*/
|
||||||
|
langCode?: string
|
||||||
|
}): Promise<tl.bots.RawBotInfo>
|
||||||
/**
|
/**
|
||||||
* Fetches the menu button set for the given user.
|
* Fetches the menu button set for the given user.
|
||||||
*
|
*
|
||||||
|
@ -999,6 +1020,32 @@ export interface TelegramClient extends BaseTelegramClient {
|
||||||
_normalizeCommandScope(
|
_normalizeCommandScope(
|
||||||
scope: tl.TypeBotCommandScope | BotCommands.IntermediateScope,
|
scope: tl.TypeBotCommandScope | BotCommands.IntermediateScope,
|
||||||
): Promise<tl.TypeBotCommandScope>
|
): Promise<tl.TypeBotCommandScope>
|
||||||
|
/**
|
||||||
|
* Sets information about a bot the current uzer owns (or the current bot)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
setBotInfo(params: {
|
||||||
|
/**
|
||||||
|
* When called by a user, a bot the user owns must be specified.
|
||||||
|
* When called by a bot, must be empty
|
||||||
|
*/
|
||||||
|
bot?: InputPeerLike
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If passed, will update the bot's description in the given language.
|
||||||
|
* If left empty, will change the fallback description.
|
||||||
|
*/
|
||||||
|
langCode?: string
|
||||||
|
|
||||||
|
/** New bot name */
|
||||||
|
name?: string
|
||||||
|
|
||||||
|
/** New bio text (displayed in the profile) */
|
||||||
|
bio?: string
|
||||||
|
|
||||||
|
/** New description text (displayed when the chat is empty) */
|
||||||
|
description?: string
|
||||||
|
}): Promise<void>
|
||||||
/**
|
/**
|
||||||
* Sets a menu button for the given user.
|
* Sets a menu button for the given user.
|
||||||
*
|
*
|
||||||
|
@ -1107,15 +1154,18 @@ export interface TelegramClient extends BaseTelegramClient {
|
||||||
*/
|
*/
|
||||||
archiveChats(chats: MaybeArray<InputPeerLike>): Promise<void>
|
archiveChats(chats: MaybeArray<InputPeerLike>): Promise<void>
|
||||||
/**
|
/**
|
||||||
* Ban a user from a legacy group, a supergroup or a channel.
|
* Ban a user/channel from a legacy group, a supergroup or a channel.
|
||||||
* They will not be able to re-join the group on their own,
|
* They will not be able to re-join the group on their own,
|
||||||
* manual administrator's action is required.
|
* manual administrator's action will be required.
|
||||||
|
*
|
||||||
|
* When banning a channel, the user won't be able to use
|
||||||
|
* any of their channels to post until the ban is lifted.
|
||||||
*
|
*
|
||||||
* @param chatId Chat ID
|
* @param chatId Chat ID
|
||||||
* @param userId User ID
|
* @param peerId User/Channel ID
|
||||||
* @returns Service message about removed user, if one was generated.
|
* @returns Service message about removed user, if one was generated.
|
||||||
*/
|
*/
|
||||||
banChatMember(chatId: InputPeerLike, userId: InputPeerLike): Promise<Message | null>
|
banChatMember(chatId: InputPeerLike, peerId: InputPeerLike): Promise<Message | null>
|
||||||
/**
|
/**
|
||||||
* Create a new broadcast channel
|
* Create a new broadcast channel
|
||||||
*
|
*
|
||||||
|
@ -1666,7 +1716,7 @@ export interface TelegramClient extends BaseTelegramClient {
|
||||||
unarchiveChats(chats: MaybeArray<InputPeerLike>): Promise<void>
|
unarchiveChats(chats: MaybeArray<InputPeerLike>): Promise<void>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unban a user from a supergroup or a channel,
|
* Unban a user/channel from a supergroup or a channel,
|
||||||
* or remove any restrictions that they have.
|
* or remove any restrictions that they have.
|
||||||
* Unbanning does not add the user back to the chat, this
|
* Unbanning does not add the user back to the chat, this
|
||||||
* just allows the user to join the chat again, if they want.
|
* just allows the user to join the chat again, if they want.
|
||||||
|
@ -1674,12 +1724,12 @@ export interface TelegramClient extends BaseTelegramClient {
|
||||||
* This method acts as a no-op in case a legacy group is passed.
|
* This method acts as a no-op in case a legacy group is passed.
|
||||||
*
|
*
|
||||||
* @param chatId Chat ID
|
* @param chatId Chat ID
|
||||||
* @param userId User ID
|
* @param peerId User/channel ID
|
||||||
*/
|
*/
|
||||||
unbanChatMember(chatId: InputPeerLike, userId: InputPeerLike): Promise<void>
|
unbanChatMember(chatId: InputPeerLike, peerId: InputPeerLike): Promise<void>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unban a user from a supergroup or a channel,
|
* Unban a user/channel from a supergroup or a channel,
|
||||||
* or remove any restrictions that they have.
|
* or remove any restrictions that they have.
|
||||||
* Unbanning does not add the user back to the chat, this
|
* Unbanning does not add the user back to the chat, this
|
||||||
* just allows the user to join the chat again, if they want.
|
* just allows the user to join the chat again, if they want.
|
||||||
|
@ -1687,9 +1737,9 @@ export interface TelegramClient extends BaseTelegramClient {
|
||||||
* This method acts as a no-op in case a legacy group is passed.
|
* This method acts as a no-op in case a legacy group is passed.
|
||||||
*
|
*
|
||||||
* @param chatId Chat ID
|
* @param chatId Chat ID
|
||||||
* @param userId User ID
|
* @param peerId User/channel ID
|
||||||
*/
|
*/
|
||||||
unrestrictChatMember(chatId: InputPeerLike, userId: InputPeerLike): Promise<void>
|
unrestrictChatMember(chatId: InputPeerLike, peerId: InputPeerLike): Promise<void>
|
||||||
/**
|
/**
|
||||||
* Add an existing Telegram user as a contact
|
* Add an existing Telegram user as a contact
|
||||||
*
|
*
|
||||||
|
@ -3982,7 +4032,7 @@ export interface TelegramClient extends BaseTelegramClient {
|
||||||
* @returns Modfiied sticker set
|
* @returns Modfiied sticker set
|
||||||
*/
|
*/
|
||||||
addStickerToSet(
|
addStickerToSet(
|
||||||
id: string | tl.TypeInputStickerSet,
|
id: InputStickerSet,
|
||||||
sticker: InputStickerSetItem,
|
sticker: InputStickerSetItem,
|
||||||
params?: {
|
params?: {
|
||||||
/**
|
/**
|
||||||
|
@ -4102,7 +4152,7 @@ export interface TelegramClient extends BaseTelegramClient {
|
||||||
*
|
*
|
||||||
* @param id Sticker pack short name, dice emoji, `"emoji"` for animated emojis or input ID
|
* @param id Sticker pack short name, dice emoji, `"emoji"` for animated emojis or input ID
|
||||||
*/
|
*/
|
||||||
getStickerSet(id: string | { dice: string } | tl.TypeInputStickerSet): Promise<StickerSet>
|
getStickerSet(id: InputStickerSet): Promise<StickerSet>
|
||||||
/**
|
/**
|
||||||
* Move a sticker in a sticker set
|
* Move a sticker in a sticker set
|
||||||
* to another position
|
* to another position
|
||||||
|
@ -4120,6 +4170,15 @@ export interface TelegramClient extends BaseTelegramClient {
|
||||||
sticker: string | tdFileId.RawFullRemoteFileLocation | tl.TypeInputDocument,
|
sticker: string | tdFileId.RawFullRemoteFileLocation | tl.TypeInputDocument,
|
||||||
position: number,
|
position: number,
|
||||||
): Promise<StickerSet>
|
): Promise<StickerSet>
|
||||||
|
/**
|
||||||
|
* Set group sticker set for a supergroup
|
||||||
|
*
|
||||||
|
* @param id Sticker set short name or a TL object with input sticker set
|
||||||
|
* @param thumb Sticker set thumbnail
|
||||||
|
* @param params
|
||||||
|
* @returns Modified sticker set
|
||||||
|
*/
|
||||||
|
setChatStickerSet(chatId: InputPeerLike, id: InputStickerSet): Promise<void>
|
||||||
/**
|
/**
|
||||||
* Set sticker set thumbnail
|
* Set sticker set thumbnail
|
||||||
*
|
*
|
||||||
|
@ -4129,7 +4188,7 @@ export interface TelegramClient extends BaseTelegramClient {
|
||||||
* @returns Modified sticker set
|
* @returns Modified sticker set
|
||||||
*/
|
*/
|
||||||
setStickerSetThumb(
|
setStickerSetThumb(
|
||||||
id: string | tl.TypeInputStickerSet,
|
id: InputStickerSet,
|
||||||
thumb: InputFileLike | tl.TypeInputDocument,
|
thumb: InputFileLike | tl.TypeInputDocument,
|
||||||
params?: {
|
params?: {
|
||||||
/**
|
/**
|
||||||
|
@ -5056,12 +5115,14 @@ export class TelegramClient extends BaseTelegramClient {
|
||||||
answerInlineQuery = answerInlineQuery
|
answerInlineQuery = answerInlineQuery
|
||||||
answerPreCheckoutQuery = answerPreCheckoutQuery
|
answerPreCheckoutQuery = answerPreCheckoutQuery
|
||||||
deleteMyCommands = deleteMyCommands
|
deleteMyCommands = deleteMyCommands
|
||||||
|
getBotInfo = getBotInfo
|
||||||
getBotMenuButton = getBotMenuButton
|
getBotMenuButton = getBotMenuButton
|
||||||
getCallbackAnswer = getCallbackAnswer
|
getCallbackAnswer = getCallbackAnswer
|
||||||
getGameHighScores = getGameHighScores
|
getGameHighScores = getGameHighScores
|
||||||
getInlineGameHighScores = getInlineGameHighScores
|
getInlineGameHighScores = getInlineGameHighScores
|
||||||
getMyCommands = getMyCommands
|
getMyCommands = getMyCommands
|
||||||
_normalizeCommandScope = _normalizeCommandScope
|
_normalizeCommandScope = _normalizeCommandScope
|
||||||
|
setBotInfo = setBotInfo
|
||||||
setBotMenuButton = setBotMenuButton
|
setBotMenuButton = setBotMenuButton
|
||||||
setGameScore = setGameScore
|
setGameScore = setGameScore
|
||||||
setInlineGameScore = setInlineGameScore
|
setInlineGameScore = setInlineGameScore
|
||||||
|
@ -5213,6 +5274,7 @@ export class TelegramClient extends BaseTelegramClient {
|
||||||
getInstalledStickers = getInstalledStickers
|
getInstalledStickers = getInstalledStickers
|
||||||
getStickerSet = getStickerSet
|
getStickerSet = getStickerSet
|
||||||
moveStickerInSet = moveStickerInSet
|
moveStickerInSet = moveStickerInSet
|
||||||
|
setChatStickerSet = setChatStickerSet
|
||||||
setStickerSetThumb = setStickerSetThumb
|
setStickerSetThumb = setStickerSetThumb
|
||||||
applyBoost = applyBoost
|
applyBoost = applyBoost
|
||||||
canApplyBoost = canApplyBoost
|
canApplyBoost = canApplyBoost
|
||||||
|
|
|
@ -48,6 +48,7 @@ import {
|
||||||
InputPeerLike,
|
InputPeerLike,
|
||||||
InputPrivacyRule,
|
InputPrivacyRule,
|
||||||
InputReaction,
|
InputReaction,
|
||||||
|
InputStickerSet,
|
||||||
InputStickerSetItem,
|
InputStickerSetItem,
|
||||||
MaybeDynamic,
|
MaybeDynamic,
|
||||||
Message,
|
Message,
|
||||||
|
|
35
packages/client/src/methods/bots/get-bot-info.ts
Normal file
35
packages/client/src/methods/bots/get-bot-info.ts
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
import { tl } from '@mtcute/core'
|
||||||
|
|
||||||
|
import { TelegramClient } from '../../client'
|
||||||
|
import { InputPeerLike } from '../../types'
|
||||||
|
import { normalizeToInputUser } from '../../utils/peer-utils'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets information about a bot the current uzer owns (or the current bot)
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
export async function getBotInfo(
|
||||||
|
this: TelegramClient,
|
||||||
|
params: {
|
||||||
|
/**
|
||||||
|
* When called by a user, a bot the user owns must be specified.
|
||||||
|
* When called by a bot, must be empty
|
||||||
|
*/
|
||||||
|
bot?: InputPeerLike
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If passed, will retrieve the bot's description in the given language.
|
||||||
|
* If left empty, will retrieve the fallback description.
|
||||||
|
*/
|
||||||
|
langCode?: string
|
||||||
|
},
|
||||||
|
): Promise<tl.bots.RawBotInfo> {
|
||||||
|
const { bot, langCode = '' } = params
|
||||||
|
|
||||||
|
return this.call({
|
||||||
|
_: 'bots.getBotInfo',
|
||||||
|
bot: bot ? normalizeToInputUser(await this.resolvePeer(bot), bot) : undefined,
|
||||||
|
langCode: langCode,
|
||||||
|
})
|
||||||
|
}
|
45
packages/client/src/methods/bots/set-bot-info.ts
Normal file
45
packages/client/src/methods/bots/set-bot-info.ts
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
import { TelegramClient } from '../../client'
|
||||||
|
import { InputPeerLike } from '../../types'
|
||||||
|
import { normalizeToInputUser } from '../../utils/peer-utils'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets information about a bot the current uzer owns (or the current bot)
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
export async function setBotInfo(
|
||||||
|
this: TelegramClient,
|
||||||
|
params: {
|
||||||
|
/**
|
||||||
|
* When called by a user, a bot the user owns must be specified.
|
||||||
|
* When called by a bot, must be empty
|
||||||
|
*/
|
||||||
|
bot?: InputPeerLike
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If passed, will update the bot's description in the given language.
|
||||||
|
* If left empty, will change the fallback description.
|
||||||
|
*/
|
||||||
|
langCode?: string
|
||||||
|
|
||||||
|
/** New bot name */
|
||||||
|
name?: string
|
||||||
|
|
||||||
|
/** New bio text (displayed in the profile) */
|
||||||
|
bio?: string
|
||||||
|
|
||||||
|
/** New description text (displayed when the chat is empty) */
|
||||||
|
description?: string
|
||||||
|
},
|
||||||
|
): Promise<void> {
|
||||||
|
const { bot, langCode = '', name, bio, description } = params
|
||||||
|
|
||||||
|
await this.call({
|
||||||
|
_: 'bots.setBotInfo',
|
||||||
|
bot: bot ? normalizeToInputUser(await this.resolvePeer(bot), bot) : undefined,
|
||||||
|
langCode: langCode,
|
||||||
|
name,
|
||||||
|
about: bio,
|
||||||
|
description,
|
||||||
|
})
|
||||||
|
}
|
|
@ -10,29 +10,32 @@ import {
|
||||||
} from '../../utils/peer-utils'
|
} from '../../utils/peer-utils'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ban a user from a legacy group, a supergroup or a channel.
|
* Ban a user/channel from a legacy group, a supergroup or a channel.
|
||||||
* They will not be able to re-join the group on their own,
|
* They will not be able to re-join the group on their own,
|
||||||
* manual administrator's action is required.
|
* manual administrator's action will be required.
|
||||||
|
*
|
||||||
|
* When banning a channel, the user won't be able to use
|
||||||
|
* any of their channels to post until the ban is lifted.
|
||||||
*
|
*
|
||||||
* @param chatId Chat ID
|
* @param chatId Chat ID
|
||||||
* @param userId User ID
|
* @param peerId User/Channel ID
|
||||||
* @returns Service message about removed user, if one was generated.
|
* @returns Service message about removed user, if one was generated.
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
export async function banChatMember(
|
export async function banChatMember(
|
||||||
this: TelegramClient,
|
this: TelegramClient,
|
||||||
chatId: InputPeerLike,
|
chatId: InputPeerLike,
|
||||||
userId: InputPeerLike,
|
peerId: InputPeerLike,
|
||||||
): Promise<Message | null> {
|
): Promise<Message | null> {
|
||||||
const chat = await this.resolvePeer(chatId)
|
const chat = await this.resolvePeer(chatId)
|
||||||
const user = await this.resolvePeer(userId)
|
const peer = await this.resolvePeer(peerId)
|
||||||
|
|
||||||
let res
|
let res
|
||||||
if (isInputPeerChannel(chat)) {
|
if (isInputPeerChannel(chat)) {
|
||||||
res = await this.call({
|
res = await this.call({
|
||||||
_: 'channels.editBanned',
|
_: 'channels.editBanned',
|
||||||
channel: normalizeToInputChannel(chat),
|
channel: normalizeToInputChannel(chat),
|
||||||
participant: user,
|
participant: peer,
|
||||||
bannedRights: {
|
bannedRights: {
|
||||||
_: 'chatBannedRights',
|
_: 'chatBannedRights',
|
||||||
// bans can't be temporary.
|
// bans can't be temporary.
|
||||||
|
@ -44,7 +47,7 @@ export async function banChatMember(
|
||||||
res = await this.call({
|
res = await this.call({
|
||||||
_: 'messages.deleteChatUser',
|
_: 'messages.deleteChatUser',
|
||||||
chatId: chat.chatId,
|
chatId: chat.chatId,
|
||||||
userId: normalizeToInputUser(user),
|
userId: normalizeToInputUser(peer),
|
||||||
})
|
})
|
||||||
} else throw new MtInvalidPeerTypeError(chatId, 'chat or channel')
|
} else throw new MtInvalidPeerTypeError(chatId, 'chat or channel')
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { isInputPeerChannel, isInputPeerChat, normalizeToInputChannel } from '..
|
||||||
|
|
||||||
// @alias=unrestrictChatMember
|
// @alias=unrestrictChatMember
|
||||||
/**
|
/**
|
||||||
* Unban a user from a supergroup or a channel,
|
* Unban a user/channel from a supergroup or a channel,
|
||||||
* or remove any restrictions that they have.
|
* or remove any restrictions that they have.
|
||||||
* Unbanning does not add the user back to the chat, this
|
* Unbanning does not add the user back to the chat, this
|
||||||
* just allows the user to join the chat again, if they want.
|
* just allows the user to join the chat again, if they want.
|
||||||
|
@ -12,22 +12,22 @@ import { isInputPeerChannel, isInputPeerChat, normalizeToInputChannel } from '..
|
||||||
* This method acts as a no-op in case a legacy group is passed.
|
* This method acts as a no-op in case a legacy group is passed.
|
||||||
*
|
*
|
||||||
* @param chatId Chat ID
|
* @param chatId Chat ID
|
||||||
* @param userId User ID
|
* @param peerId User/channel ID
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
export async function unbanChatMember(
|
export async function unbanChatMember(
|
||||||
this: TelegramClient,
|
this: TelegramClient,
|
||||||
chatId: InputPeerLike,
|
chatId: InputPeerLike,
|
||||||
userId: InputPeerLike,
|
peerId: InputPeerLike,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const chat = await this.resolvePeer(chatId)
|
const chat = await this.resolvePeer(chatId)
|
||||||
const user = await this.resolvePeer(userId)
|
const peer = await this.resolvePeer(peerId)
|
||||||
|
|
||||||
if (isInputPeerChannel(chat)) {
|
if (isInputPeerChannel(chat)) {
|
||||||
const res = await this.call({
|
const res = await this.call({
|
||||||
_: 'channels.editBanned',
|
_: 'channels.editBanned',
|
||||||
channel: normalizeToInputChannel(chat),
|
channel: normalizeToInputChannel(chat),
|
||||||
participant: user,
|
participant: peer,
|
||||||
bannedRights: {
|
bannedRights: {
|
||||||
_: 'chatBannedRights',
|
_: 'chatBannedRights',
|
||||||
untilDate: 0,
|
untilDate: 0,
|
||||||
|
|
|
@ -248,6 +248,7 @@ export async function _normalizeInputMedia(
|
||||||
fileReference: res.photo.fileReference,
|
fileReference: res.photo.fileReference,
|
||||||
},
|
},
|
||||||
ttlSeconds: media.ttlSeconds,
|
ttlSeconds: media.ttlSeconds,
|
||||||
|
spoiler: media.type === 'video' && media.spoiler,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assertTypeIs('normalizeInputMedia (@ messages.uploadMedia)', res, 'messageMediaDocument')
|
assertTypeIs('normalizeInputMedia (@ messages.uploadMedia)', res, 'messageMediaDocument')
|
||||||
|
@ -262,6 +263,7 @@ export async function _normalizeInputMedia(
|
||||||
fileReference: res.document.fileReference,
|
fileReference: res.document.fileReference,
|
||||||
},
|
},
|
||||||
ttlSeconds: media.ttlSeconds,
|
ttlSeconds: media.ttlSeconds,
|
||||||
|
spoiler: media.type === 'video' && media.spoiler,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -323,6 +325,7 @@ export async function _normalizeInputMedia(
|
||||||
_: 'inputMediaUploadedPhoto',
|
_: 'inputMediaUploadedPhoto',
|
||||||
file: inputFile,
|
file: inputFile,
|
||||||
ttlSeconds: media.ttlSeconds,
|
ttlSeconds: media.ttlSeconds,
|
||||||
|
spoiler: media.spoiler,
|
||||||
},
|
},
|
||||||
true,
|
true,
|
||||||
)
|
)
|
||||||
|
@ -387,6 +390,7 @@ export async function _normalizeInputMedia(
|
||||||
mimeType: mime,
|
mimeType: mime,
|
||||||
attributes,
|
attributes,
|
||||||
ttlSeconds: media.ttlSeconds,
|
ttlSeconds: media.ttlSeconds,
|
||||||
|
spoiler: media.type === 'video' && media.spoiler,
|
||||||
},
|
},
|
||||||
false,
|
false,
|
||||||
)
|
)
|
||||||
|
|
|
@ -70,7 +70,7 @@ export async function uploadMedia(
|
||||||
assertTypeIs('uploadMedia', res, 'messageMediaPhoto')
|
assertTypeIs('uploadMedia', res, 'messageMediaPhoto')
|
||||||
assertTypeIs('uploadMedia', res.photo!, 'photo')
|
assertTypeIs('uploadMedia', res.photo!, 'photo')
|
||||||
|
|
||||||
return new Photo(this, res.photo)
|
return new Photo(this, res.photo, res)
|
||||||
case 'inputMediaUploadedDocument':
|
case 'inputMediaUploadedDocument':
|
||||||
case 'inputMediaDocument':
|
case 'inputMediaDocument':
|
||||||
case 'inputMediaDocumentExternal':
|
case 'inputMediaDocumentExternal':
|
||||||
|
@ -78,7 +78,7 @@ export async function uploadMedia(
|
||||||
assertTypeIs('uploadMedia', res.document!, 'document')
|
assertTypeIs('uploadMedia', res.document!, 'document')
|
||||||
|
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
return parseDocument(this, res.document) as any
|
return parseDocument(this, res.document, res) as any
|
||||||
case 'inputMediaStory':
|
case 'inputMediaStory':
|
||||||
throw new MtArgumentError("This media (story) can't be uploaded")
|
throw new MtArgumentError("This media (story) can't be uploaded")
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
import { tl } from '@mtcute/core'
|
|
||||||
|
|
||||||
import { TelegramClient } from '../../client'
|
import { TelegramClient } from '../../client'
|
||||||
import { InputStickerSetItem, StickerSet } from '../../types'
|
import { InputStickerSet, InputStickerSetItem, normalizeInputStickerSet, StickerSet } from '../../types'
|
||||||
|
|
||||||
const MASK_POS = {
|
const MASK_POS = {
|
||||||
forehead: 0,
|
forehead: 0,
|
||||||
|
@ -24,7 +22,7 @@ const MASK_POS = {
|
||||||
*/
|
*/
|
||||||
export async function addStickerToSet(
|
export async function addStickerToSet(
|
||||||
this: TelegramClient,
|
this: TelegramClient,
|
||||||
id: string | tl.TypeInputStickerSet,
|
id: InputStickerSet,
|
||||||
sticker: InputStickerSetItem,
|
sticker: InputStickerSetItem,
|
||||||
params?: {
|
params?: {
|
||||||
/**
|
/**
|
||||||
|
@ -36,16 +34,9 @@ export async function addStickerToSet(
|
||||||
progressCallback?: (uploaded: number, total: number) => void
|
progressCallback?: (uploaded: number, total: number) => void
|
||||||
},
|
},
|
||||||
): Promise<StickerSet> {
|
): Promise<StickerSet> {
|
||||||
if (typeof id === 'string') {
|
|
||||||
id = {
|
|
||||||
_: 'inputStickerSetShortName',
|
|
||||||
shortName: id,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const res = await this.call({
|
const res = await this.call({
|
||||||
_: 'stickers.addStickerToSet',
|
_: 'stickers.addStickerToSet',
|
||||||
stickerset: id,
|
stickerset: normalizeInputStickerSet(id),
|
||||||
sticker: {
|
sticker: {
|
||||||
_: 'inputStickerSetItem',
|
_: 'inputStickerSetItem',
|
||||||
document: await this._normalizeFileToDocument(sticker.file, params ?? {}),
|
document: await this._normalizeFileToDocument(sticker.file, params ?? {}),
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
import { tl } from '@mtcute/core'
|
|
||||||
|
|
||||||
import { TelegramClient } from '../../client'
|
import { TelegramClient } from '../../client'
|
||||||
import { StickerSet } from '../../types'
|
import { InputStickerSet, normalizeInputStickerSet, StickerSet } from '../../types'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a sticker pack and stickers inside of it.
|
* Get a sticker pack and stickers inside of it.
|
||||||
|
@ -9,34 +7,10 @@ import { StickerSet } from '../../types'
|
||||||
* @param id Sticker pack short name, dice emoji, `"emoji"` for animated emojis or input ID
|
* @param id Sticker pack short name, dice emoji, `"emoji"` for animated emojis or input ID
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
export async function getStickerSet(
|
export async function getStickerSet(this: TelegramClient, id: InputStickerSet): Promise<StickerSet> {
|
||||||
this: TelegramClient,
|
|
||||||
id: string | { dice: string } | tl.TypeInputStickerSet,
|
|
||||||
): Promise<StickerSet> {
|
|
||||||
let input: tl.TypeInputStickerSet
|
|
||||||
|
|
||||||
if (typeof id === 'string') {
|
|
||||||
input =
|
|
||||||
id === 'emoji' ?
|
|
||||||
{
|
|
||||||
_: 'inputStickerSetAnimatedEmoji',
|
|
||||||
} :
|
|
||||||
{
|
|
||||||
_: 'inputStickerSetShortName',
|
|
||||||
shortName: id,
|
|
||||||
}
|
|
||||||
} else if ('dice' in id) {
|
|
||||||
input = {
|
|
||||||
_: 'inputStickerSetDice',
|
|
||||||
emoticon: id.dice,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
input = id
|
|
||||||
}
|
|
||||||
|
|
||||||
const res = await this.call({
|
const res = await this.call({
|
||||||
_: 'messages.getStickerSet',
|
_: 'messages.getStickerSet',
|
||||||
stickerset: input,
|
stickerset: normalizeInputStickerSet(id),
|
||||||
hash: 0,
|
hash: 0,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
24
packages/client/src/methods/stickers/set-chat-sticker-set.ts
Normal file
24
packages/client/src/methods/stickers/set-chat-sticker-set.ts
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
import { TelegramClient } from '../../client'
|
||||||
|
import { InputPeerLike, InputStickerSet, normalizeInputStickerSet } from '../../types'
|
||||||
|
import { normalizeToInputChannel } from '../../utils'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set group sticker set for a supergroup
|
||||||
|
*
|
||||||
|
* @param id Sticker set short name or a TL object with input sticker set
|
||||||
|
* @param thumb Sticker set thumbnail
|
||||||
|
* @param params
|
||||||
|
* @returns Modified sticker set
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
export async function setChatStickerSet(
|
||||||
|
this: TelegramClient,
|
||||||
|
chatId: InputPeerLike,
|
||||||
|
id: InputStickerSet,
|
||||||
|
): Promise<void> {
|
||||||
|
await this.call({
|
||||||
|
_: 'channels.setStickers',
|
||||||
|
channel: normalizeToInputChannel(await this.resolvePeer(chatId), chatId),
|
||||||
|
stickerset: normalizeInputStickerSet(id),
|
||||||
|
})
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
import { tl } from '@mtcute/core'
|
import { tl } from '@mtcute/core'
|
||||||
|
|
||||||
import { TelegramClient } from '../../client'
|
import { TelegramClient } from '../../client'
|
||||||
import { InputFileLike, StickerSet } from '../../types'
|
import { InputFileLike, InputStickerSet, normalizeInputStickerSet, StickerSet } from '../../types'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set sticker set thumbnail
|
* Set sticker set thumbnail
|
||||||
|
@ -14,7 +14,7 @@ import { InputFileLike, StickerSet } from '../../types'
|
||||||
*/
|
*/
|
||||||
export async function setStickerSetThumb(
|
export async function setStickerSetThumb(
|
||||||
this: TelegramClient,
|
this: TelegramClient,
|
||||||
id: string | tl.TypeInputStickerSet,
|
id: InputStickerSet,
|
||||||
thumb: InputFileLike | tl.TypeInputDocument,
|
thumb: InputFileLike | tl.TypeInputDocument,
|
||||||
params?: {
|
params?: {
|
||||||
/**
|
/**
|
||||||
|
@ -26,16 +26,9 @@ export async function setStickerSetThumb(
|
||||||
progressCallback?: (uploaded: number, total: number) => void
|
progressCallback?: (uploaded: number, total: number) => void
|
||||||
},
|
},
|
||||||
): Promise<StickerSet> {
|
): Promise<StickerSet> {
|
||||||
if (typeof id === 'string') {
|
|
||||||
id = {
|
|
||||||
_: 'inputStickerSetShortName',
|
|
||||||
shortName: id,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const res = await this.call({
|
const res = await this.call({
|
||||||
_: 'stickers.setStickerSetThumb',
|
_: 'stickers.setStickerSetThumb',
|
||||||
stickerset: id,
|
stickerset: normalizeInputStickerSet(id),
|
||||||
thumb: await this._normalizeFileToDocument(thumb, params ?? {}),
|
thumb: await this._normalizeFileToDocument(thumb, params ?? {}),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -347,6 +347,26 @@ export namespace BotKeyboard {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Button to request a peer from the user
|
||||||
|
*
|
||||||
|
* @param text Text of the button
|
||||||
|
* @param buttonId ID of the button that will later be passed to the service message
|
||||||
|
* @param peerType Peer type, along with filters
|
||||||
|
*/
|
||||||
|
export function requestPeer(
|
||||||
|
text: string,
|
||||||
|
buttonId: number,
|
||||||
|
peerType: tl.TypeRequestPeerType,
|
||||||
|
): tl.RawKeyboardButtonRequestPeer {
|
||||||
|
return {
|
||||||
|
_: 'keyboardButtonRequestPeer',
|
||||||
|
text,
|
||||||
|
buttonId,
|
||||||
|
peerType,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find a button in the keyboard by its text or by predicate
|
* Find a button in the keyboard by its text or by predicate
|
||||||
*
|
*
|
||||||
|
|
|
@ -10,7 +10,11 @@ import { Voice } from './voice'
|
||||||
export type ParsedDocument = Sticker | Voice | Audio | Video | Document
|
export type ParsedDocument = Sticker | Voice | Audio | Video | Document
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
export function parseDocument(client: TelegramClient, doc: tl.RawDocument): ParsedDocument {
|
export function parseDocument(
|
||||||
|
client: TelegramClient,
|
||||||
|
doc: tl.RawDocument,
|
||||||
|
media?: tl.RawMessageMediaDocument,
|
||||||
|
): ParsedDocument {
|
||||||
const stickerAttr = doc.attributes.find(
|
const stickerAttr = doc.attributes.find(
|
||||||
(a) => a._ === 'documentAttributeSticker' || a._ === 'documentAttributeCustomEmoji',
|
(a) => a._ === 'documentAttributeSticker' || a._ === 'documentAttributeCustomEmoji',
|
||||||
)
|
)
|
||||||
|
@ -38,12 +42,12 @@ export function parseDocument(client: TelegramClient, doc: tl.RawDocument): Pars
|
||||||
return new Audio(client, doc, attr)
|
return new Audio(client, doc, attr)
|
||||||
|
|
||||||
case 'documentAttributeVideo':
|
case 'documentAttributeVideo':
|
||||||
return new Video(client, doc, attr)
|
return new Video(client, doc, attr, media)
|
||||||
|
|
||||||
case 'documentAttributeImageSize':
|
case 'documentAttributeImageSize':
|
||||||
// legacy gif
|
// legacy gif
|
||||||
if (doc.mimeType === 'image/gif') {
|
if (doc.mimeType === 'image/gif') {
|
||||||
return new Video(client, doc, attr)
|
return new Video(client, doc, attr, media)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -151,6 +151,11 @@ export interface InputMediaDocument extends FileMixin, CaptionMixin {
|
||||||
*/
|
*/
|
||||||
export interface InputMediaPhoto extends FileMixin, CaptionMixin {
|
export interface InputMediaPhoto extends FileMixin, CaptionMixin {
|
||||||
type: 'photo'
|
type: 'photo'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether this photo should be hidden with a spoiler
|
||||||
|
*/
|
||||||
|
spoiler?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -238,6 +243,11 @@ export interface InputMediaVideo extends FileMixin, CaptionMixin {
|
||||||
* Only applicable to newly uploaded files.
|
* Only applicable to newly uploaded files.
|
||||||
*/
|
*/
|
||||||
isRound?: boolean
|
isRound?: boolean
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether this video should be hidden with a spoiler
|
||||||
|
*/
|
||||||
|
spoiler?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -11,9 +11,6 @@ import { Thumbnail } from './thumbnail'
|
||||||
export class Photo extends FileLocation {
|
export class Photo extends FileLocation {
|
||||||
readonly type: 'photo'
|
readonly type: 'photo'
|
||||||
|
|
||||||
/** Raw TL object */
|
|
||||||
readonly raw: tl.RawPhoto
|
|
||||||
|
|
||||||
/** Biggest available photo width */
|
/** Biggest available photo width */
|
||||||
readonly width: number
|
readonly width: number
|
||||||
|
|
||||||
|
@ -22,7 +19,7 @@ export class Photo extends FileLocation {
|
||||||
|
|
||||||
private _bestSize?: tl.RawPhotoSize | tl.RawPhotoSizeProgressive
|
private _bestSize?: tl.RawPhotoSize | tl.RawPhotoSizeProgressive
|
||||||
|
|
||||||
constructor(client: TelegramClient, raw: tl.RawPhoto) {
|
constructor(client: TelegramClient, readonly raw: tl.RawPhoto, readonly media?: tl.RawMessageMediaPhoto) {
|
||||||
const location = {
|
const location = {
|
||||||
_: 'inputPhotoFileLocation',
|
_: 'inputPhotoFileLocation',
|
||||||
id: raw.id,
|
id: raw.id,
|
||||||
|
@ -71,7 +68,6 @@ export class Photo extends FileLocation {
|
||||||
|
|
||||||
super(client, location, size, raw.dcId)
|
super(client, location, size, raw.dcId)
|
||||||
this._bestSize = bestSize
|
this._bestSize = bestSize
|
||||||
this.raw = raw
|
|
||||||
this.width = width
|
this.width = width
|
||||||
this.height = height
|
this.height = height
|
||||||
this.type = 'photo'
|
this.type = 'photo'
|
||||||
|
@ -105,6 +101,16 @@ export class Photo extends FileLocation {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Whether this photo is hidden with a spoiler */
|
||||||
|
get hasSpoiler(): boolean {
|
||||||
|
return this.media?.spoiler ?? false
|
||||||
|
}
|
||||||
|
|
||||||
|
/** For self-destructing photos, TTL in seconds */
|
||||||
|
get ttlSeconds(): number | null {
|
||||||
|
return this.media?.ttlSeconds ?? null
|
||||||
|
}
|
||||||
|
|
||||||
private _thumbnails?: Thumbnail[]
|
private _thumbnails?: Thumbnail[]
|
||||||
/**
|
/**
|
||||||
* Available thumbnails.
|
* Available thumbnails.
|
||||||
|
|
|
@ -24,6 +24,7 @@ export class Video extends RawDocument {
|
||||||
client: TelegramClient,
|
client: TelegramClient,
|
||||||
doc: tl.RawDocument,
|
doc: tl.RawDocument,
|
||||||
readonly attr: tl.RawDocumentAttributeVideo | tl.RawDocumentAttributeImageSize,
|
readonly attr: tl.RawDocumentAttributeVideo | tl.RawDocumentAttributeImageSize,
|
||||||
|
readonly media?: tl.RawMessageMediaDocument,
|
||||||
) {
|
) {
|
||||||
super(client, doc)
|
super(client, doc)
|
||||||
}
|
}
|
||||||
|
@ -75,6 +76,16 @@ export class Video extends RawDocument {
|
||||||
get isLegacyGif(): boolean {
|
get isLegacyGif(): boolean {
|
||||||
return this.attr._ === 'documentAttributeImageSize'
|
return this.attr._ === 'documentAttributeImageSize'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Whether this video is hidden with a spoiler */
|
||||||
|
get hasSpoiler(): boolean {
|
||||||
|
return this.media?.spoiler ?? false
|
||||||
|
}
|
||||||
|
|
||||||
|
/** For self-destructing videos, TTL in seconds */
|
||||||
|
get ttlSeconds(): number | null {
|
||||||
|
return this.media?.ttlSeconds ?? null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
makeInspectable(Video, ['fileSize', 'dcId'], ['inputMedia', 'inputDocument'])
|
makeInspectable(Video, ['fileSize', 'dcId'], ['inputMedia', 'inputDocument'])
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { tl } from '@mtcute/core'
|
import { getMarkedPeerId, tl } from '@mtcute/core'
|
||||||
|
|
||||||
import { _callDiscardReasonFromTl, CallDiscardReason } from '../calls'
|
import { _callDiscardReasonFromTl, CallDiscardReason } from '../calls'
|
||||||
import { Photo } from '../media'
|
import { Photo } from '../media'
|
||||||
|
@ -122,6 +122,14 @@ export interface ActionUserJoinedLink {
|
||||||
readonly inviter: number
|
readonly inviter: number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User has joined the group via an invite link
|
||||||
|
* and was approved by an administrator
|
||||||
|
*/
|
||||||
|
export interface ActionUserJoinedApproved {
|
||||||
|
readonly type: 'user_joined_approved'
|
||||||
|
}
|
||||||
|
|
||||||
/** A payment was received from a user (bot) */
|
/** A payment was received from a user (bot) */
|
||||||
export interface ActionPaymentReceived {
|
export interface ActionPaymentReceived {
|
||||||
readonly type: 'payment_received'
|
readonly type: 'payment_received'
|
||||||
|
@ -230,6 +238,17 @@ export interface ActionGroupCallEnded {
|
||||||
readonly duration: number
|
readonly duration: number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Group call has been scheduled */
|
||||||
|
export interface ActionGroupCallScheduled {
|
||||||
|
readonly type: 'group_call_scheduled'
|
||||||
|
|
||||||
|
/** TL object representing the call */
|
||||||
|
readonly call: tl.TypeInputGroupCall
|
||||||
|
|
||||||
|
/** Date when the call will start */
|
||||||
|
readonly date: Date
|
||||||
|
}
|
||||||
|
|
||||||
/** Group call has ended */
|
/** Group call has ended */
|
||||||
export interface ActionGroupInvite {
|
export interface ActionGroupInvite {
|
||||||
readonly type: 'group_call_invite'
|
readonly type: 'group_call_invite'
|
||||||
|
@ -242,8 +261,8 @@ export interface ActionGroupInvite {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Messages TTL changed */
|
/** Messages TTL changed */
|
||||||
export interface ActionSetTtl {
|
export interface ActionTtlChanged {
|
||||||
readonly type: 'set_ttl'
|
readonly type: 'ttl_changed'
|
||||||
|
|
||||||
/** New TTL period */
|
/** New TTL period */
|
||||||
readonly period: number
|
readonly period: number
|
||||||
|
@ -280,6 +299,106 @@ export interface ActionTopicEdited {
|
||||||
hidden?: boolean
|
hidden?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** A non-standard action has happened in the chat */
|
||||||
|
export interface ActionCustom {
|
||||||
|
readonly type: 'custom'
|
||||||
|
|
||||||
|
/** Text to be shown in the interface */
|
||||||
|
action: string
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Chat theme was changed */
|
||||||
|
export interface ActionThemeChanged {
|
||||||
|
readonly type: 'theme_changed'
|
||||||
|
|
||||||
|
/** Emoji representing the new theme */
|
||||||
|
emoji: string
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Data was sent from a WebView (user-side action) */
|
||||||
|
export interface ActionWebviewDataSent {
|
||||||
|
readonly type: 'webview_sent'
|
||||||
|
|
||||||
|
/** Text of the button that was pressed to open the WebView */
|
||||||
|
text: string
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Data was received from a WebView (bot-side action) */
|
||||||
|
export interface ActionWebviewDataReceived {
|
||||||
|
readonly type: 'webview_received'
|
||||||
|
|
||||||
|
/** Text of the button that was pressed to open the WebView */
|
||||||
|
text: string
|
||||||
|
|
||||||
|
/** Data received from the WebView */
|
||||||
|
data: string
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Premium subscription was gifted */
|
||||||
|
export interface ActionPremiumGifted {
|
||||||
|
readonly type: 'premium_gifted'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Currency in which it was paid for.
|
||||||
|
* Three-letter ISO 4217 currency code)
|
||||||
|
*/
|
||||||
|
currency: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Price of the product in the smallest units of the currency
|
||||||
|
* (integer, not float/double). For example, for a price of
|
||||||
|
* `US$ 1.45`, `amount = 145`
|
||||||
|
*/
|
||||||
|
amount: number
|
||||||
|
|
||||||
|
/** Duration of the gifted subscription in months */
|
||||||
|
months: number
|
||||||
|
|
||||||
|
/** If the subscription was bought with crypto, information about it */
|
||||||
|
crypto?: {
|
||||||
|
/** Crypto currency name */
|
||||||
|
currency: string
|
||||||
|
/** Price in the smallest units */
|
||||||
|
amount: number
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A photo has been suggested as a profile photo */
|
||||||
|
export interface ActionPhotoSuggested {
|
||||||
|
readonly type: 'photo_suggested'
|
||||||
|
|
||||||
|
/** Photo that was suggested */
|
||||||
|
photo: Photo
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A peer was chosen by the user after clicking on a RequestPeer button */
|
||||||
|
export interface ActionPeerChosen {
|
||||||
|
readonly type: 'peer_chosen'
|
||||||
|
|
||||||
|
/** ID of the button passed earlier by the bot */
|
||||||
|
buttonId: number
|
||||||
|
|
||||||
|
/** Marked ID of the chosen peer */
|
||||||
|
peerId: number
|
||||||
|
|
||||||
|
/** Input peer of the chosen peer */
|
||||||
|
inputPeer?: tl.TypeInputPeer
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A wallpaper of the chathas been changed */
|
||||||
|
export interface ActionWallpaperChanged {
|
||||||
|
readonly type: 'wallpaper_changed'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the user has applied the same wallpaper
|
||||||
|
* as the other party previously set in the chat
|
||||||
|
*/
|
||||||
|
same: boolean
|
||||||
|
|
||||||
|
/** TL object representing the new wallpaper */
|
||||||
|
wallpaper: tl.TypeWallPaper
|
||||||
|
}
|
||||||
|
|
||||||
export type MessageAction =
|
export type MessageAction =
|
||||||
| ActionChatCreated
|
| ActionChatCreated
|
||||||
| ActionChannelCreated
|
| ActionChannelCreated
|
||||||
|
@ -304,14 +423,28 @@ export type MessageAction =
|
||||||
| ActionGeoProximity
|
| ActionGeoProximity
|
||||||
| ActionGroupCallStarted
|
| ActionGroupCallStarted
|
||||||
| ActionGroupCallEnded
|
| ActionGroupCallEnded
|
||||||
|
| ActionGroupCallScheduled
|
||||||
| ActionGroupInvite
|
| ActionGroupInvite
|
||||||
| ActionSetTtl
|
| ActionTtlChanged
|
||||||
| ActionTopicCreated
|
| ActionTopicCreated
|
||||||
| ActionTopicEdited
|
| ActionTopicEdited
|
||||||
|
| ActionCustom
|
||||||
|
| ActionThemeChanged
|
||||||
|
| ActionUserJoinedApproved
|
||||||
|
| ActionWebviewDataSent
|
||||||
|
| ActionWebviewDataReceived
|
||||||
|
| ActionPremiumGifted
|
||||||
|
| ActionPhotoSuggested
|
||||||
|
| ActionPeerChosen
|
||||||
|
| ActionWallpaperChanged
|
||||||
| null
|
| null
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
export function _messageActionFromTl(this: Message, act: tl.TypeMessageAction): MessageAction {
|
export function _messageActionFromTl(this: Message, act: tl.TypeMessageAction): MessageAction {
|
||||||
|
// todo - passport
|
||||||
|
// messageActionSecureValuesSentMe#1b287353 values:Vector<SecureValue> credentials:SecureCredentialsEncrypted
|
||||||
|
// messageActionSecureValuesSent#d95c6154 types:Vector<SecureValueType>
|
||||||
|
|
||||||
switch (act._) {
|
switch (act._) {
|
||||||
case 'messageActionChatCreate':
|
case 'messageActionChatCreate':
|
||||||
return {
|
return {
|
||||||
|
@ -447,7 +580,12 @@ export function _messageActionFromTl(this: Message, act: tl.TypeMessageAction):
|
||||||
type: 'group_call_started',
|
type: 'group_call_started',
|
||||||
call: act.call,
|
call: act.call,
|
||||||
}
|
}
|
||||||
|
case 'messageActionGroupCallScheduled':
|
||||||
|
return {
|
||||||
|
type: 'group_call_scheduled',
|
||||||
|
call: act.call,
|
||||||
|
date: new Date(act.scheduleDate * 1000),
|
||||||
|
}
|
||||||
case 'messageActionInviteToGroupCall':
|
case 'messageActionInviteToGroupCall':
|
||||||
return {
|
return {
|
||||||
type: 'group_call_invite',
|
type: 'group_call_invite',
|
||||||
|
@ -456,7 +594,7 @@ export function _messageActionFromTl(this: Message, act: tl.TypeMessageAction):
|
||||||
}
|
}
|
||||||
case 'messageActionSetMessagesTTL':
|
case 'messageActionSetMessagesTTL':
|
||||||
return {
|
return {
|
||||||
type: 'set_ttl',
|
type: 'ttl_changed',
|
||||||
period: act.period,
|
period: act.period,
|
||||||
}
|
}
|
||||||
case 'messageActionTopicCreate':
|
case 'messageActionTopicCreate':
|
||||||
|
@ -474,6 +612,63 @@ export function _messageActionFromTl(this: Message, act: tl.TypeMessageAction):
|
||||||
closed: act.closed,
|
closed: act.closed,
|
||||||
hidden: act.hidden,
|
hidden: act.hidden,
|
||||||
}
|
}
|
||||||
|
case 'messageActionCustomAction':
|
||||||
|
return {
|
||||||
|
type: 'custom',
|
||||||
|
action: act.message,
|
||||||
|
}
|
||||||
|
case 'messageActionSetChatTheme':
|
||||||
|
return {
|
||||||
|
type: 'theme_changed',
|
||||||
|
emoji: act.emoticon,
|
||||||
|
}
|
||||||
|
case 'messageActionChatJoinedByRequest':
|
||||||
|
return {
|
||||||
|
type: 'user_joined_approved',
|
||||||
|
}
|
||||||
|
case 'messageActionWebViewDataSent':
|
||||||
|
return {
|
||||||
|
type: 'webview_sent',
|
||||||
|
text: act.text,
|
||||||
|
}
|
||||||
|
case 'messageActionWebViewDataSentMe':
|
||||||
|
return {
|
||||||
|
type: 'webview_received',
|
||||||
|
text: act.text,
|
||||||
|
data: act.data,
|
||||||
|
}
|
||||||
|
case 'messageActionGiftPremium':
|
||||||
|
return {
|
||||||
|
type: 'premium_gifted',
|
||||||
|
currency: act.currency,
|
||||||
|
amount: act.amount.toNumber(),
|
||||||
|
months: act.months,
|
||||||
|
crypto: act.cryptoAmount ?
|
||||||
|
{
|
||||||
|
currency: act.cryptoCurrency!,
|
||||||
|
amount: act.cryptoAmount.toNumber(),
|
||||||
|
} :
|
||||||
|
undefined,
|
||||||
|
}
|
||||||
|
case 'messageActionSuggestProfilePhoto':
|
||||||
|
return {
|
||||||
|
type: 'photo_suggested',
|
||||||
|
photo: new Photo(this.client, act.photo as tl.RawPhoto),
|
||||||
|
}
|
||||||
|
case 'messageActionRequestedPeer':
|
||||||
|
return {
|
||||||
|
type: 'peer_chosen',
|
||||||
|
buttonId: act.buttonId,
|
||||||
|
peerId: getMarkedPeerId(act.peer),
|
||||||
|
// todo - pass the peer itself?
|
||||||
|
}
|
||||||
|
case 'messageActionSetChatWallPaper':
|
||||||
|
case 'messageActionSetSameChatWallPaper':
|
||||||
|
return {
|
||||||
|
type: 'wallpaper_changed',
|
||||||
|
same: act._ === 'messageActionSetSameChatWallPaper',
|
||||||
|
wallpaper: act.wallpaper,
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,7 +53,7 @@ export function _messageMediaFromTl(
|
||||||
case 'messageMediaPhoto':
|
case 'messageMediaPhoto':
|
||||||
if (!(m.photo?._ === 'photo')) return null
|
if (!(m.photo?._ === 'photo')) return null
|
||||||
|
|
||||||
return new Photo(client, m.photo)
|
return new Photo(client, m.photo, m)
|
||||||
case 'messageMediaDice':
|
case 'messageMediaDice':
|
||||||
return new Dice(m)
|
return new Dice(m)
|
||||||
case 'messageMediaContact':
|
case 'messageMediaContact':
|
||||||
|
@ -61,7 +61,7 @@ export function _messageMediaFromTl(
|
||||||
case 'messageMediaDocument':
|
case 'messageMediaDocument':
|
||||||
if (!(m.document?._ === 'document')) return null
|
if (!(m.document?._ === 'document')) return null
|
||||||
|
|
||||||
return parseDocument(client, m.document) as MessageMedia
|
return parseDocument(client, m.document, m) as MessageMedia
|
||||||
case 'messageMediaGeo':
|
case 'messageMediaGeo':
|
||||||
if (!(m.geo._ === 'geoPoint')) return null
|
if (!(m.geo._ === 'geoPoint')) return null
|
||||||
|
|
||||||
|
|
|
@ -269,6 +269,23 @@ export class Message {
|
||||||
return this._forward
|
return this._forward
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the message is a channel post that was
|
||||||
|
* automatically forwarded to the connected discussion group
|
||||||
|
*/
|
||||||
|
get isAutomaticForward(): boolean {
|
||||||
|
if (this.raw._ === 'messageService' || !this.raw.fwdFrom) return false
|
||||||
|
|
||||||
|
const fwd = this.raw.fwdFrom
|
||||||
|
|
||||||
|
return Boolean(
|
||||||
|
this.chat.chatType === 'supergroup' &&
|
||||||
|
fwd.channelPost &&
|
||||||
|
fwd.savedFromMsgId &&
|
||||||
|
fwd.savedFromPeer?._ === 'peerChannel',
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private _replies?: MessageRepliesInfo | MessageCommentsInfo
|
private _replies?: MessageRepliesInfo | MessageCommentsInfo
|
||||||
/**
|
/**
|
||||||
* Information about comments (for channels) or replies (for groups)
|
* Information about comments (for channels) or replies (for groups)
|
||||||
|
@ -309,8 +326,8 @@ export class Message {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For replies, ID of the thread (i.e. ID of the top message
|
* For replies, ID of the thread/topic
|
||||||
* in the thread)
|
* (i.e. ID of the top message in the thread/topic)
|
||||||
*/
|
*/
|
||||||
get replyToThreadId(): number | null {
|
get replyToThreadId(): number | null {
|
||||||
if (this.raw.replyTo?._ !== 'messageReplyHeader') return null
|
if (this.raw.replyTo?._ !== 'messageReplyHeader') return null
|
||||||
|
@ -327,6 +344,13 @@ export class Message {
|
||||||
return this.raw.replyTo
|
return this.raw.replyTo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Whether this message is in a forum topic */
|
||||||
|
get isTopicMessage(): boolean {
|
||||||
|
if (this.raw.replyTo?._ !== 'messageReplyHeader') return false
|
||||||
|
|
||||||
|
return this.raw.replyTo.forumTopic!
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether this message contains mention of the current user
|
* Whether this message contains mention of the current user
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -8,6 +8,68 @@ import { InputFileLike } from '../files'
|
||||||
import { MaskPosition, Sticker, StickerSourceType, StickerType, Thumbnail } from '../media'
|
import { MaskPosition, Sticker, StickerSourceType, StickerType, Thumbnail } from '../media'
|
||||||
import { parseDocument } from '../media/document-utils'
|
import { parseDocument } from '../media/document-utils'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Input sticker set.
|
||||||
|
* Can be one of:
|
||||||
|
* - Raw TL object
|
||||||
|
* - Sticker set short name
|
||||||
|
* - `{ dice: "<emoji>" }` (e.g. `{ dice: "🎲" }`) - Used for fetching animated dice stickers
|
||||||
|
* - `{ system: string }` - for system stickersets:
|
||||||
|
* - `"animated"` - Animated emojis stickerset
|
||||||
|
* - `"animated_animations"` - Animated emoji reaction stickerset
|
||||||
|
* (contains animations to play when a user clicks on a given animated emoji)
|
||||||
|
* - `"premium_gifts"` - Stickers to show when receiving a gifted Telegram Premium subscription,
|
||||||
|
* - `"generic_animations"` - Generic animation stickerset containing animations to play
|
||||||
|
* when reacting to messages using a normal emoji without a custom animation
|
||||||
|
* - `"default_statuses"` - Default custom emoji status stickerset
|
||||||
|
* - `"default_topic_icons"` - Default custom emoji stickerset for forum topic icons
|
||||||
|
*/
|
||||||
|
export type InputStickerSet =
|
||||||
|
| tl.TypeInputStickerSet
|
||||||
|
| { dice: string }
|
||||||
|
| {
|
||||||
|
system:
|
||||||
|
| 'animated'
|
||||||
|
| 'animated_animations'
|
||||||
|
| 'premium_gifts'
|
||||||
|
| 'generic_animations'
|
||||||
|
| 'default_statuses'
|
||||||
|
| 'default_topic_icons'
|
||||||
|
}
|
||||||
|
| string
|
||||||
|
|
||||||
|
export function normalizeInputStickerSet(input: InputStickerSet): tl.TypeInputStickerSet {
|
||||||
|
if (typeof input === 'string') {
|
||||||
|
return {
|
||||||
|
_: 'inputStickerSetShortName',
|
||||||
|
shortName: input,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ('_' in input) return input
|
||||||
|
|
||||||
|
if ('dice' in input) {
|
||||||
|
return {
|
||||||
|
_: 'inputStickerSetDice',
|
||||||
|
emoticon: input.dice,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (input.system) {
|
||||||
|
case 'animated':
|
||||||
|
return { _: 'inputStickerSetAnimatedEmoji' }
|
||||||
|
case 'animated_animations':
|
||||||
|
return { _: 'inputStickerSetAnimatedEmojiAnimations' }
|
||||||
|
case 'premium_gifts':
|
||||||
|
return { _: 'inputStickerSetPremiumGifts' }
|
||||||
|
case 'generic_animations':
|
||||||
|
return { _: 'inputStickerSetEmojiGenericAnimations' }
|
||||||
|
case 'default_statuses':
|
||||||
|
return { _: 'inputStickerSetEmojiDefaultStatuses' }
|
||||||
|
case 'default_topic_icons':
|
||||||
|
return { _: 'inputStickerSetEmojiDefaultTopicIcons' }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Information about one sticker inside the set
|
* Information about one sticker inside the set
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -231,6 +231,15 @@ export class Chat {
|
||||||
return (this.peer._ === 'channel' || this.peer._ === 'chat') && this.peer.noforwards!
|
return (this.peer._ === 'channel' || this.peer._ === 'chat') && this.peer.noforwards!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether this chat (user) has restricted sending them voice/video messages.
|
||||||
|
*
|
||||||
|
* Returned only in {@link TelegramClient.getFullChat}
|
||||||
|
*/
|
||||||
|
get hasBlockedVoices(): boolean {
|
||||||
|
return this.fullPeer?._ === 'userFull' && this.fullPeer.voiceMessagesForbidden!
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Title, for supergroups, channels and groups
|
* Title, for supergroups, channels and groups
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in a new issue