feat: accept high-level objects as inputs to methods
This commit is contained in:
parent
a03d73503a
commit
e01c876690
45 changed files with 734 additions and 1233 deletions
File diff suppressed because it is too large
Load diff
|
@ -42,6 +42,7 @@ import {
|
||||||
InputFileLike,
|
InputFileLike,
|
||||||
InputInlineResult,
|
InputInlineResult,
|
||||||
InputMediaLike,
|
InputMediaLike,
|
||||||
|
InputMessageId,
|
||||||
InputPeerLike,
|
InputPeerLike,
|
||||||
InputPrivacyRule,
|
InputPrivacyRule,
|
||||||
InputReaction,
|
InputReaction,
|
||||||
|
|
|
@ -1,14 +1,16 @@
|
||||||
import { BaseTelegramClient, Long } from '@mtcute/core'
|
import { BaseTelegramClient, Long } from '@mtcute/core'
|
||||||
|
|
||||||
|
import { CallbackQuery } from '../../types/bots/callback-query'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send an answer to a callback query.
|
* Send an answer to a callback query.
|
||||||
*
|
*
|
||||||
* @param queryId ID of the callback query
|
* @param queryId ID of the callback query, or the query itself
|
||||||
* @param params Parameters of the answer
|
* @param params Parameters of the answer
|
||||||
*/
|
*/
|
||||||
export async function answerCallbackQuery(
|
export async function answerCallbackQuery(
|
||||||
client: BaseTelegramClient,
|
client: BaseTelegramClient,
|
||||||
queryId: Long,
|
queryId: Long | CallbackQuery,
|
||||||
params?: {
|
params?: {
|
||||||
/**
|
/**
|
||||||
* Maximum amount of time in seconds for which
|
* Maximum amount of time in seconds for which
|
||||||
|
@ -49,7 +51,7 @@ export async function answerCallbackQuery(
|
||||||
|
|
||||||
await client.call({
|
await client.call({
|
||||||
_: 'messages.setBotCallbackAnswer',
|
_: 'messages.setBotCallbackAnswer',
|
||||||
queryId,
|
queryId: Long.isLong(queryId) ? queryId : queryId.id,
|
||||||
cacheTime,
|
cacheTime,
|
||||||
alert,
|
alert,
|
||||||
message: text,
|
message: text,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { BaseTelegramClient, tl } from '@mtcute/core'
|
import { BaseTelegramClient, Long, tl } from '@mtcute/core'
|
||||||
|
|
||||||
import { BotInline, InputInlineResult } from '../../types'
|
import { BotInline, InlineQuery, InputInlineResult } from '../../types/bots'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Answer an inline query.
|
* Answer an inline query.
|
||||||
|
@ -11,7 +11,7 @@ import { BotInline, InputInlineResult } from '../../types'
|
||||||
*/
|
*/
|
||||||
export async function answerInlineQuery(
|
export async function answerInlineQuery(
|
||||||
client: BaseTelegramClient,
|
client: BaseTelegramClient,
|
||||||
queryId: tl.Long,
|
queryId: tl.Long | InlineQuery,
|
||||||
results: InputInlineResult[],
|
results: InputInlineResult[],
|
||||||
params?: {
|
params?: {
|
||||||
/**
|
/**
|
||||||
|
@ -99,7 +99,7 @@ export async function answerInlineQuery(
|
||||||
|
|
||||||
await client.call({
|
await client.call({
|
||||||
_: 'messages.setInlineBotResults',
|
_: 'messages.setInlineBotResults',
|
||||||
queryId,
|
queryId: Long.isLong(queryId) ? queryId : queryId.id,
|
||||||
results: tlResults,
|
results: tlResults,
|
||||||
cacheTime,
|
cacheTime,
|
||||||
gallery: gallery ?? defaultGallery,
|
gallery: gallery ?? defaultGallery,
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
import { BaseTelegramClient, tl } from '@mtcute/core'
|
import { BaseTelegramClient, Long, tl } from '@mtcute/core'
|
||||||
|
|
||||||
|
import { PreCheckoutQuery } from '../../types/updates'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Answer a pre-checkout query.
|
* Answer a pre-checkout query.
|
||||||
|
@ -7,7 +9,7 @@ import { BaseTelegramClient, tl } from '@mtcute/core'
|
||||||
*/
|
*/
|
||||||
export async function answerPreCheckoutQuery(
|
export async function answerPreCheckoutQuery(
|
||||||
client: BaseTelegramClient,
|
client: BaseTelegramClient,
|
||||||
queryId: tl.Long,
|
queryId: tl.Long | PreCheckoutQuery,
|
||||||
params?: {
|
params?: {
|
||||||
/** If pre-checkout is rejected, error message to show to the user */
|
/** If pre-checkout is rejected, error message to show to the user */
|
||||||
error?: string
|
error?: string
|
||||||
|
@ -17,7 +19,7 @@ export async function answerPreCheckoutQuery(
|
||||||
|
|
||||||
await client.call({
|
await client.call({
|
||||||
_: 'messages.setBotPrecheckoutResults',
|
_: 'messages.setBotPrecheckoutResults',
|
||||||
queryId,
|
queryId: Long.isLong(queryId) ? queryId : queryId.queryId,
|
||||||
success: !error,
|
success: !error,
|
||||||
error,
|
error,
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { BaseTelegramClient, tl } from '@mtcute/core'
|
import { BaseTelegramClient, tl } from '@mtcute/core'
|
||||||
|
|
||||||
import { GameHighScore, InputPeerLike, PeersIndex } from '../../types'
|
import { GameHighScore, InputMessageId, InputPeerLike, normalizeInputMessageId, PeersIndex } from '../../types'
|
||||||
import { normalizeInlineId } from '../../utils/inline-utils'
|
import { normalizeInlineId } from '../../utils/inline-utils'
|
||||||
import { normalizeToInputUser } from '../../utils/peer-utils'
|
import { normalizeToInputUser } from '../../utils/peer-utils'
|
||||||
import { resolvePeer } from '../users/resolve-peer'
|
import { resolvePeer } from '../users/resolve-peer'
|
||||||
|
@ -10,18 +10,13 @@ import { resolvePeer } from '../users/resolve-peer'
|
||||||
*/
|
*/
|
||||||
export async function getGameHighScores(
|
export async function getGameHighScores(
|
||||||
client: BaseTelegramClient,
|
client: BaseTelegramClient,
|
||||||
params: {
|
params: InputMessageId & {
|
||||||
/** ID of the chat where the game was found */
|
|
||||||
chatId: InputPeerLike
|
|
||||||
|
|
||||||
/** ID of the message containing the game */
|
|
||||||
message: number
|
|
||||||
|
|
||||||
/** ID of the user to find high scores for */
|
/** ID of the user to find high scores for */
|
||||||
userId?: InputPeerLike
|
userId?: InputPeerLike
|
||||||
},
|
},
|
||||||
): Promise<GameHighScore[]> {
|
): Promise<GameHighScore[]> {
|
||||||
const { chatId, message, userId } = params
|
const { userId } = params
|
||||||
|
const { chatId, message } = normalizeInputMessageId(params)
|
||||||
|
|
||||||
const chat = await resolvePeer(client, chatId)
|
const chat = await resolvePeer(client, chatId)
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { BaseTelegramClient, tl } from '@mtcute/core'
|
import { BaseTelegramClient, tl } from '@mtcute/core'
|
||||||
|
|
||||||
import { InputPeerLike, Message } from '../../types'
|
import { InputMessageId, InputPeerLike, Message, normalizeInputMessageId } from '../../types'
|
||||||
import { normalizeInlineId } from '../../utils/inline-utils'
|
import { normalizeInlineId } from '../../utils/inline-utils'
|
||||||
import { normalizeToInputUser } from '../../utils/peer-utils'
|
import { normalizeToInputUser } from '../../utils/peer-utils'
|
||||||
import { _findMessageInUpdate } from '../messages/find-in-update'
|
import { _findMessageInUpdate } from '../messages/find-in-update'
|
||||||
|
@ -14,13 +14,7 @@ import { resolvePeer } from '../users/resolve-peer'
|
||||||
*/
|
*/
|
||||||
export async function setGameScore(
|
export async function setGameScore(
|
||||||
client: BaseTelegramClient,
|
client: BaseTelegramClient,
|
||||||
params: {
|
params: InputMessageId & {
|
||||||
/** Chat where the game was found */
|
|
||||||
chatId: InputPeerLike
|
|
||||||
|
|
||||||
/** ID of the message where the game was found */
|
|
||||||
message: number
|
|
||||||
|
|
||||||
/** ID of the user who has scored */
|
/** ID of the user who has scored */
|
||||||
userId: InputPeerLike
|
userId: InputPeerLike
|
||||||
|
|
||||||
|
@ -40,7 +34,8 @@ export async function setGameScore(
|
||||||
force?: boolean
|
force?: boolean
|
||||||
},
|
},
|
||||||
): Promise<Message> {
|
): Promise<Message> {
|
||||||
const { chatId, message, userId, score, noEdit, force } = params
|
const { userId, score, noEdit, force } = params
|
||||||
|
const { chatId, message } = normalizeInputMessageId(params)
|
||||||
|
|
||||||
const user = normalizeToInputUser(await resolvePeer(client, userId), userId)
|
const user = normalizeToInputUser(await resolvePeer(client, userId), userId)
|
||||||
const chat = await resolvePeer(client, chatId)
|
const chat = await resolvePeer(client, chatId)
|
||||||
|
|
|
@ -11,6 +11,7 @@ import {
|
||||||
} from '../../utils/peer-utils'
|
} from '../../utils/peer-utils'
|
||||||
import { resolvePeer } from '../users/resolve-peer'
|
import { resolvePeer } from '../users/resolve-peer'
|
||||||
|
|
||||||
|
// @available=both
|
||||||
/**
|
/**
|
||||||
* Get basic information about a chat.
|
* Get basic information about a chat.
|
||||||
*
|
*
|
||||||
|
|
|
@ -11,6 +11,7 @@ import {
|
||||||
} from '../../utils/peer-utils'
|
} from '../../utils/peer-utils'
|
||||||
import { resolvePeer } from '../users/resolve-peer'
|
import { resolvePeer } from '../users/resolve-peer'
|
||||||
|
|
||||||
|
// @available=both
|
||||||
/**
|
/**
|
||||||
* Get full information about a chat.
|
* Get full information about a chat.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { BaseTelegramClient } from '@mtcute/core'
|
import { BaseTelegramClient } from '@mtcute/core'
|
||||||
import { assertTypeIsNot } from '@mtcute/core/utils'
|
import { assertTypeIsNot } from '@mtcute/core/utils'
|
||||||
|
|
||||||
import { InputPeerLike } from '../../types'
|
import type { ForumTopic, InputPeerLike } from '../../types'
|
||||||
import { normalizeToInputChannel } from '../../utils/peer-utils'
|
import { normalizeToInputChannel } from '../../utils/peer-utils'
|
||||||
import { createDummyUpdate } from '../../utils/updates-utils'
|
import { createDummyUpdate } from '../../utils/updates-utils'
|
||||||
import { resolvePeer } from '../users/resolve-peer'
|
import { resolvePeer } from '../users/resolve-peer'
|
||||||
|
@ -15,7 +15,7 @@ import { resolvePeer } from '../users/resolve-peer'
|
||||||
export async function deleteForumTopicHistory(
|
export async function deleteForumTopicHistory(
|
||||||
client: BaseTelegramClient,
|
client: BaseTelegramClient,
|
||||||
chat: InputPeerLike,
|
chat: InputPeerLike,
|
||||||
topicId: number,
|
topicId: number | ForumTopic,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const channel = normalizeToInputChannel(await resolvePeer(client, chat), chat)
|
const channel = normalizeToInputChannel(await resolvePeer(client, chat), chat)
|
||||||
assertTypeIsNot('deleteForumTopicHistory', channel, 'inputChannelEmpty')
|
assertTypeIsNot('deleteForumTopicHistory', channel, 'inputChannelEmpty')
|
||||||
|
@ -23,7 +23,7 @@ export async function deleteForumTopicHistory(
|
||||||
const res = await client.call({
|
const res = await client.call({
|
||||||
_: 'channels.deleteTopicHistory',
|
_: 'channels.deleteTopicHistory',
|
||||||
channel,
|
channel,
|
||||||
topMsgId: topicId,
|
topMsgId: typeof topicId === 'number' ? topicId : topicId.id,
|
||||||
})
|
})
|
||||||
|
|
||||||
client.network.handleUpdate(createDummyUpdate(res.pts, res.ptsCount, channel.channelId))
|
client.network.handleUpdate(createDummyUpdate(res.pts, res.ptsCount, channel.channelId))
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { BaseTelegramClient, Long, tl } from '@mtcute/core'
|
import { BaseTelegramClient, Long, tl } from '@mtcute/core'
|
||||||
|
|
||||||
import { InputPeerLike, Message } from '../../types'
|
import type { ForumTopic, InputPeerLike, Message } from '../../types'
|
||||||
import { normalizeToInputChannel } from '../../utils/peer-utils'
|
import { normalizeToInputChannel } from '../../utils/peer-utils'
|
||||||
import { _findMessageInUpdate } from '../messages/find-in-update'
|
import { _findMessageInUpdate } from '../messages/find-in-update'
|
||||||
import { resolvePeer } from '../users/resolve-peer'
|
import { resolvePeer } from '../users/resolve-peer'
|
||||||
|
@ -19,9 +19,10 @@ export async function editForumTopic(
|
||||||
params: {
|
params: {
|
||||||
/** Chat ID or username */
|
/** Chat ID or username */
|
||||||
chatId: InputPeerLike
|
chatId: InputPeerLike
|
||||||
/** ID of the topic (i.e. its top message ID) */
|
|
||||||
|
|
||||||
topicId: number
|
/** ID of the topic (i.e. its top message ID) */
|
||||||
|
topicId: number | ForumTopic
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* New topic title
|
* New topic title
|
||||||
*/
|
*/
|
||||||
|
@ -41,7 +42,7 @@ export async function editForumTopic(
|
||||||
const res = await client.call({
|
const res = await client.call({
|
||||||
_: 'channels.editForumTopic',
|
_: 'channels.editForumTopic',
|
||||||
channel: normalizeToInputChannel(await resolvePeer(client, chatId), chatId),
|
channel: normalizeToInputChannel(await resolvePeer(client, chatId), chatId),
|
||||||
topicId,
|
topicId: typeof topicId === 'number' ? topicId : topicId.id,
|
||||||
title,
|
title,
|
||||||
iconEmojiId: icon ? icon ?? Long.ZERO : undefined,
|
iconEmojiId: icon ? icon ?? Long.ZERO : undefined,
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { BaseTelegramClient } from '@mtcute/core'
|
import { BaseTelegramClient } from '@mtcute/core'
|
||||||
|
|
||||||
import { InputPeerLike } from '../../types'
|
import type { ForumTopic, InputPeerLike } from '../../types'
|
||||||
import { normalizeToInputChannel } from '../../utils/peer-utils'
|
import { normalizeToInputChannel } from '../../utils/peer-utils'
|
||||||
import { resolvePeer } from '../users/resolve-peer'
|
import { resolvePeer } from '../users/resolve-peer'
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ export async function reorderPinnedForumTopics(
|
||||||
/**
|
/**
|
||||||
* Order of the pinned topics
|
* Order of the pinned topics
|
||||||
*/
|
*/
|
||||||
order: number[]
|
order: (number | ForumTopic)[]
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether to un-pin topics not present in the order
|
* Whether to un-pin topics not present in the order
|
||||||
|
@ -30,7 +30,7 @@ export async function reorderPinnedForumTopics(
|
||||||
await client.call({
|
await client.call({
|
||||||
_: 'channels.reorderPinnedForumTopics',
|
_: 'channels.reorderPinnedForumTopics',
|
||||||
channel: normalizeToInputChannel(await resolvePeer(client, chatId), chatId),
|
channel: normalizeToInputChannel(await resolvePeer(client, chatId), chatId),
|
||||||
order,
|
order: order.map((it) => (typeof it === 'number' ? it : it.id)),
|
||||||
force,
|
force,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { BaseTelegramClient } from '@mtcute/core'
|
import { BaseTelegramClient } from '@mtcute/core'
|
||||||
|
|
||||||
import { InputPeerLike, Message } from '../../types'
|
import type { ForumTopic, InputPeerLike, Message } from '../../types'
|
||||||
import { normalizeToInputChannel } from '../../utils/peer-utils'
|
import { normalizeToInputChannel } from '../../utils/peer-utils'
|
||||||
import { _findMessageInUpdate } from '../messages/find-in-update'
|
import { _findMessageInUpdate } from '../messages/find-in-update'
|
||||||
import { resolvePeer } from '../users/resolve-peer'
|
import { resolvePeer } from '../users/resolve-peer'
|
||||||
|
@ -19,7 +19,7 @@ export async function toggleForumTopicClosed(
|
||||||
chatId: InputPeerLike
|
chatId: InputPeerLike
|
||||||
|
|
||||||
/** ID of the topic (i.e. its top message ID) */
|
/** ID of the topic (i.e. its top message ID) */
|
||||||
topicId: number
|
topicId: number | ForumTopic
|
||||||
|
|
||||||
/** Whether the topic should be closed */
|
/** Whether the topic should be closed */
|
||||||
closed: boolean
|
closed: boolean
|
||||||
|
@ -30,7 +30,7 @@ export async function toggleForumTopicClosed(
|
||||||
const res = await client.call({
|
const res = await client.call({
|
||||||
_: 'channels.editForumTopic',
|
_: 'channels.editForumTopic',
|
||||||
channel: normalizeToInputChannel(await resolvePeer(client, chatId), chatId),
|
channel: normalizeToInputChannel(await resolvePeer(client, chatId), chatId),
|
||||||
topicId,
|
topicId: typeof topicId === 'number' ? topicId : topicId.id,
|
||||||
closed,
|
closed,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { BaseTelegramClient } from '@mtcute/core'
|
import { BaseTelegramClient } from '@mtcute/core'
|
||||||
|
|
||||||
import { InputPeerLike } from '../../types'
|
import { ForumTopic, InputPeerLike } from '../../types'
|
||||||
import { normalizeToInputChannel } from '../../utils/peer-utils'
|
import { normalizeToInputChannel } from '../../utils/peer-utils'
|
||||||
import { resolvePeer } from '../users/resolve-peer'
|
import { resolvePeer } from '../users/resolve-peer'
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ export async function toggleForumTopicPinned(
|
||||||
/** Chat ID or username */
|
/** Chat ID or username */
|
||||||
chatId: InputPeerLike
|
chatId: InputPeerLike
|
||||||
/** ID of the topic (i.e. its top message ID) */
|
/** ID of the topic (i.e. its top message ID) */
|
||||||
topicId: number
|
topicId: number | ForumTopic
|
||||||
/** Whether the topic should be pinned */
|
/** Whether the topic should be pinned */
|
||||||
pinned: boolean
|
pinned: boolean
|
||||||
},
|
},
|
||||||
|
@ -25,7 +25,7 @@ export async function toggleForumTopicPinned(
|
||||||
await client.call({
|
await client.call({
|
||||||
_: 'channels.updatePinnedForumTopic',
|
_: 'channels.updatePinnedForumTopic',
|
||||||
channel: normalizeToInputChannel(await resolvePeer(client, chatId), chatId),
|
channel: normalizeToInputChannel(await resolvePeer(client, chatId), chatId),
|
||||||
topicId,
|
topicId: typeof topicId === 'number' ? topicId : topicId.id,
|
||||||
pinned,
|
pinned,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ export async function editInviteLink(
|
||||||
/** Chat ID */
|
/** Chat ID */
|
||||||
chatId: InputPeerLike
|
chatId: InputPeerLike
|
||||||
/** Invite link to edit */
|
/** Invite link to edit */
|
||||||
link: string
|
link: string | ChatInviteLink
|
||||||
/**
|
/**
|
||||||
* Date when this link will expire.
|
* Date when this link will expire.
|
||||||
* If `number` is passed, UNIX time in ms is expected.
|
* If `number` is passed, UNIX time in ms is expected.
|
||||||
|
@ -48,7 +48,7 @@ export async function editInviteLink(
|
||||||
const res = await client.call({
|
const res = await client.call({
|
||||||
_: 'messages.editExportedChatInvite',
|
_: 'messages.editExportedChatInvite',
|
||||||
peer: await resolvePeer(client, chatId),
|
peer: await resolvePeer(client, chatId),
|
||||||
link,
|
link: typeof link === 'string' ? link : link.link,
|
||||||
expireDate: normalizeDate(expires),
|
expireDate: normalizeDate(expires),
|
||||||
usageLimit,
|
usageLimit,
|
||||||
requestNeeded: withApproval,
|
requestNeeded: withApproval,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { BaseTelegramClient, tl } from '@mtcute/core'
|
import { BaseTelegramClient, tl } from '@mtcute/core'
|
||||||
|
|
||||||
import { ArrayPaginated, ChatInviteLinkMember, InputPeerLike, PeersIndex } from '../../types'
|
import { ArrayPaginated, ChatInviteLink, ChatInviteLinkMember, InputPeerLike, PeersIndex } from '../../types'
|
||||||
import { makeArrayPaginated, normalizeDate, normalizeToInputUser } from '../../utils'
|
import { makeArrayPaginated, normalizeDate, normalizeToInputUser } from '../../utils'
|
||||||
import { resolvePeer } from '../users/resolve-peer'
|
import { resolvePeer } from '../users/resolve-peer'
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ export async function getInviteLinkMembers(
|
||||||
/**
|
/**
|
||||||
* Invite link for which to get members
|
* Invite link for which to get members
|
||||||
*/
|
*/
|
||||||
link?: string
|
link?: string | ChatInviteLink
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maximum number of users to return
|
* Maximum number of users to return
|
||||||
|
@ -65,7 +65,7 @@ export async function getInviteLinkMembers(
|
||||||
_: 'messages.getChatInviteImporters',
|
_: 'messages.getChatInviteImporters',
|
||||||
limit,
|
limit,
|
||||||
peer,
|
peer,
|
||||||
link,
|
link: typeof link === 'string' ? link : link?.link,
|
||||||
requested,
|
requested,
|
||||||
q: requestedSearch,
|
q: requestedSearch,
|
||||||
offsetDate,
|
offsetDate,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { BaseTelegramClient } from '@mtcute/core'
|
import { BaseTelegramClient } from '@mtcute/core'
|
||||||
|
|
||||||
import { InputPeerLike } from '../../types'
|
import type { ChatInviteLink, InputPeerLike } from '../../types'
|
||||||
import { resolvePeer } from '../users/resolve-peer'
|
import { resolvePeer } from '../users/resolve-peer'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -16,7 +16,7 @@ export async function hideAllJoinRequests(
|
||||||
action: 'approve' | 'deny'
|
action: 'approve' | 'deny'
|
||||||
|
|
||||||
/** Invite link to target */
|
/** Invite link to target */
|
||||||
link?: string
|
link?: string | ChatInviteLink
|
||||||
},
|
},
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const { chatId, action, link } = params
|
const { chatId, action, link } = params
|
||||||
|
@ -25,6 +25,6 @@ export async function hideAllJoinRequests(
|
||||||
_: 'messages.hideAllChatJoinRequests',
|
_: 'messages.hideAllChatJoinRequests',
|
||||||
approved: action === 'approve',
|
approved: action === 'approve',
|
||||||
peer: await resolvePeer(client, chatId),
|
peer: await resolvePeer(client, chatId),
|
||||||
link,
|
link: typeof link === 'string' ? link : link?.link,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,12 +16,12 @@ import { resolvePeer } from '../users/resolve-peer'
|
||||||
export async function revokeInviteLink(
|
export async function revokeInviteLink(
|
||||||
client: BaseTelegramClient,
|
client: BaseTelegramClient,
|
||||||
chatId: InputPeerLike,
|
chatId: InputPeerLike,
|
||||||
link: string,
|
link: string | ChatInviteLink,
|
||||||
): Promise<ChatInviteLink> {
|
): Promise<ChatInviteLink> {
|
||||||
const res = await client.call({
|
const res = await client.call({
|
||||||
_: 'messages.editExportedChatInvite',
|
_: 'messages.editExportedChatInvite',
|
||||||
peer: await resolvePeer(client, chatId),
|
peer: await resolvePeer(client, chatId),
|
||||||
link,
|
link: typeof link === 'string' ? link : link.link,
|
||||||
revoked: true,
|
revoked: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { BaseTelegramClient, Long, MtTypeAssertionError } from '@mtcute/core'
|
import { BaseTelegramClient, Long, MtTypeAssertionError } from '@mtcute/core'
|
||||||
import { assertTypeIs } from '@mtcute/core/utils'
|
import { assertTypeIs } from '@mtcute/core/utils'
|
||||||
|
|
||||||
import { InputPeerLike, PeersIndex, Poll } from '../../types'
|
import { InputMessageId, normalizeInputMessageId, PeersIndex, Poll } from '../../types'
|
||||||
import { assertIsUpdatesGroup } from '../../utils/updates-utils'
|
import { assertIsUpdatesGroup } from '../../utils/updates-utils'
|
||||||
import { resolvePeer } from '../users/resolve-peer'
|
import { resolvePeer } from '../users/resolve-peer'
|
||||||
|
|
||||||
|
@ -11,16 +11,8 @@ import { resolvePeer } from '../users/resolve-peer'
|
||||||
* Once closed, poll can't be re-opened, and nobody
|
* Once closed, poll can't be re-opened, and nobody
|
||||||
* will be able to vote in it
|
* will be able to vote in it
|
||||||
*/
|
*/
|
||||||
export async function closePoll(
|
export async function closePoll(client: BaseTelegramClient, params: InputMessageId): Promise<Poll> {
|
||||||
client: BaseTelegramClient,
|
const { chatId, message } = normalizeInputMessageId(params)
|
||||||
params: {
|
|
||||||
/** Chat ID where this poll was found */
|
|
||||||
chatId: InputPeerLike
|
|
||||||
/** Message ID where this poll was found */
|
|
||||||
message: number
|
|
||||||
},
|
|
||||||
): Promise<Poll> {
|
|
||||||
const { chatId, message } = params
|
|
||||||
|
|
||||||
const res = await client.call({
|
const res = await client.call({
|
||||||
_: 'messages.editMessage',
|
_: 'messages.editMessage',
|
||||||
|
|
|
@ -1,34 +1,36 @@
|
||||||
import { BaseTelegramClient, MaybeArray } from '@mtcute/core'
|
import { BaseTelegramClient, tl } from '@mtcute/core'
|
||||||
|
|
||||||
import { InputPeerLike } from '../../types'
|
import { InputPeerLike, Message } from '../../types'
|
||||||
import { isInputPeerChannel, normalizeToInputChannel } from '../../utils/peer-utils'
|
import { isInputPeerChannel, normalizeToInputChannel } from '../../utils/peer-utils'
|
||||||
import { createDummyUpdate } from '../../utils/updates-utils'
|
import { createDummyUpdate } from '../../utils/updates-utils'
|
||||||
import { resolvePeer } from '../users/resolve-peer'
|
import { resolvePeer } from '../users/resolve-peer'
|
||||||
|
import { deleteScheduledMessages } from './delete-scheduled-messages'
|
||||||
|
|
||||||
|
// @exported
|
||||||
|
export interface DeleteMessagesParams {
|
||||||
|
/**
|
||||||
|
* Whether to "revoke" (i.e. delete for both sides).
|
||||||
|
* Only used for chats and private chats.
|
||||||
|
*
|
||||||
|
* @default true
|
||||||
|
*/
|
||||||
|
revoke?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete messages, including service messages.
|
* Delete messages by their IDs
|
||||||
*
|
*
|
||||||
* @param chatId Chat's marked ID, its username, phone or `"me"` or `"self"`.
|
* @param chatId Chat's marked ID, its username, phone or `"me"` or `"self"`.
|
||||||
* @param ids Message(s) ID(s) to delete.
|
* @param ids Message(s) ID(s) to delete.
|
||||||
*/
|
*/
|
||||||
export async function deleteMessages(
|
export async function deleteMessagesById(
|
||||||
client: BaseTelegramClient,
|
client: BaseTelegramClient,
|
||||||
chatId: InputPeerLike,
|
chatId: InputPeerLike,
|
||||||
ids: MaybeArray<number>,
|
ids: number[],
|
||||||
params?: {
|
params?: DeleteMessagesParams,
|
||||||
/**
|
|
||||||
* Whether to "revoke" (i.e. delete for both sides).
|
|
||||||
* Only used for chats and private chats.
|
|
||||||
*
|
|
||||||
* @default true
|
|
||||||
*/
|
|
||||||
revoke?: boolean
|
|
||||||
},
|
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const { revoke = true } = params ?? {}
|
const { revoke = true } = params ?? {}
|
||||||
|
|
||||||
if (!Array.isArray(ids)) ids = [ids]
|
|
||||||
|
|
||||||
const peer = await resolvePeer(client, chatId)
|
const peer = await resolvePeer(client, chatId)
|
||||||
|
|
||||||
let upd
|
let upd
|
||||||
|
@ -52,3 +54,38 @@ export async function deleteMessages(
|
||||||
|
|
||||||
client.network.handleUpdate(upd)
|
client.network.handleUpdate(upd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete one or more {@link Message}
|
||||||
|
*
|
||||||
|
* @param messages Message(s) to delete
|
||||||
|
*/
|
||||||
|
export async function deleteMessages(
|
||||||
|
client: BaseTelegramClient,
|
||||||
|
messages: Message[],
|
||||||
|
params?: DeleteMessagesParams,
|
||||||
|
): Promise<void> {
|
||||||
|
if (messages.length === 1) {
|
||||||
|
return deleteMessagesById(client, messages[0].chat.inputPeer, [messages[0].id], params)
|
||||||
|
}
|
||||||
|
|
||||||
|
const byChat = new Map<number, [tl.TypeInputPeer, number[]]>()
|
||||||
|
const byChatScheduled = new Map<number, [tl.TypeInputPeer, number[]]>()
|
||||||
|
|
||||||
|
for (const msg of messages) {
|
||||||
|
const map = msg.isScheduled ? byChatScheduled : byChat
|
||||||
|
|
||||||
|
if (!map.has(msg.chat.id)) {
|
||||||
|
map.set(msg.chat.id, [msg.chat.inputPeer, []])
|
||||||
|
}
|
||||||
|
map.get(msg.chat.id)![1].push(msg.id)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const [peer, ids] of byChat.values()) {
|
||||||
|
await deleteMessagesById(client, peer, ids, params)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const [peer, ids] of byChatScheduled.values()) {
|
||||||
|
await deleteScheduledMessages(client, peer, ids)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import { BaseTelegramClient, MaybeArray } from '@mtcute/core'
|
import { BaseTelegramClient } from '@mtcute/core'
|
||||||
|
|
||||||
import { InputPeerLike } from '../../types'
|
import { InputPeerLike } from '../../types'
|
||||||
import { resolvePeer } from '../users/resolve-peer'
|
import { resolvePeer } from '../users/resolve-peer'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete scheduled messages.
|
* Delete scheduled messages by their IDs.
|
||||||
*
|
*
|
||||||
* @param chatId Chat's marked ID, its username, phone or `"me"` or `"self"`.
|
* @param chatId Chat's marked ID, its username, phone or `"me"` or `"self"`.
|
||||||
* @param ids Message(s) ID(s) to delete.
|
* @param ids Message(s) ID(s) to delete.
|
||||||
|
@ -12,10 +12,8 @@ import { resolvePeer } from '../users/resolve-peer'
|
||||||
export async function deleteScheduledMessages(
|
export async function deleteScheduledMessages(
|
||||||
client: BaseTelegramClient,
|
client: BaseTelegramClient,
|
||||||
chatId: InputPeerLike,
|
chatId: InputPeerLike,
|
||||||
ids: MaybeArray<number>,
|
ids: number[],
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
if (!Array.isArray(ids)) ids = [ids]
|
|
||||||
|
|
||||||
const peer = await resolvePeer(client, chatId)
|
const peer = await resolvePeer(client, chatId)
|
||||||
|
|
||||||
const res = await client.call({
|
const res = await client.call({
|
||||||
|
|
|
@ -1,6 +1,14 @@
|
||||||
import { BaseTelegramClient, tl } from '@mtcute/core'
|
import { BaseTelegramClient, tl } from '@mtcute/core'
|
||||||
|
|
||||||
import { BotKeyboard, FormattedString, InputMediaLike, InputPeerLike, Message, ReplyMarkup } from '../../types'
|
import {
|
||||||
|
BotKeyboard,
|
||||||
|
FormattedString,
|
||||||
|
InputMediaLike,
|
||||||
|
InputMessageId,
|
||||||
|
Message,
|
||||||
|
normalizeInputMessageId,
|
||||||
|
ReplyMarkup,
|
||||||
|
} from '../../types'
|
||||||
import { _normalizeInputMedia } from '../files/normalize-input-media'
|
import { _normalizeInputMedia } from '../files/normalize-input-media'
|
||||||
import { resolvePeer } from '../users/resolve-peer'
|
import { resolvePeer } from '../users/resolve-peer'
|
||||||
import { _findMessageInUpdate } from './find-in-update'
|
import { _findMessageInUpdate } from './find-in-update'
|
||||||
|
@ -15,12 +23,7 @@ import { _parseEntities } from './parse-entities'
|
||||||
*/
|
*/
|
||||||
export async function editMessage(
|
export async function editMessage(
|
||||||
client: BaseTelegramClient,
|
client: BaseTelegramClient,
|
||||||
params: {
|
params: InputMessageId & {
|
||||||
/** Chat ID */
|
|
||||||
chatId: InputPeerLike
|
|
||||||
/** Message to edit */
|
|
||||||
message: number | Message
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* New message text
|
* New message text
|
||||||
*
|
*
|
||||||
|
@ -77,7 +80,7 @@ export async function editMessage(
|
||||||
progressCallback?: (uploaded: number, total: number) => void
|
progressCallback?: (uploaded: number, total: number) => void
|
||||||
},
|
},
|
||||||
): Promise<Message> {
|
): Promise<Message> {
|
||||||
const { chatId, message } = params
|
const { chatId, message } = normalizeInputMessageId(params)
|
||||||
let content: string | undefined = undefined
|
let content: string | undefined = undefined
|
||||||
let entities: tl.TypeMessageEntity[] | undefined
|
let entities: tl.TypeMessageEntity[] | undefined
|
||||||
let media: tl.TypeInputMedia | undefined = undefined
|
let media: tl.TypeInputMedia | undefined = undefined
|
||||||
|
@ -103,7 +106,7 @@ export async function editMessage(
|
||||||
|
|
||||||
const res = await client.call({
|
const res = await client.call({
|
||||||
_: 'messages.editMessage',
|
_: 'messages.editMessage',
|
||||||
id: typeof message === 'number' ? message : message.id,
|
id: message,
|
||||||
peer: await resolvePeer(client, chatId),
|
peer: await resolvePeer(client, chatId),
|
||||||
noWebpage: params.disableWebPreview,
|
noWebpage: params.disableWebPreview,
|
||||||
replyMarkup: BotKeyboard._convertToTl(params.replyMarkup),
|
replyMarkup: BotKeyboard._convertToTl(params.replyMarkup),
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { BaseTelegramClient, MaybeArray, MtArgumentError, tl } from '@mtcute/core'
|
import { BaseTelegramClient, MtArgumentError, tl } from '@mtcute/core'
|
||||||
import { randomLong } from '@mtcute/core/utils'
|
import { randomLong } from '@mtcute/core/utils'
|
||||||
|
|
||||||
import { FormattedString, InputMediaLike, InputPeerLike, Message, PeersIndex } from '../../types'
|
import { FormattedString, InputMediaLike, InputPeerLike, Message, PeersIndex } from '../../types'
|
||||||
|
@ -6,103 +6,93 @@ import { normalizeDate } from '../../utils/misc-utils'
|
||||||
import { assertIsUpdatesGroup } from '../../utils/updates-utils'
|
import { assertIsUpdatesGroup } from '../../utils/updates-utils'
|
||||||
import { resolvePeer } from '../users/resolve-peer'
|
import { resolvePeer } from '../users/resolve-peer'
|
||||||
|
|
||||||
/**
|
// @exported
|
||||||
* Forward a single message.
|
export interface ForwardMessageOptions {
|
||||||
*
|
/** Destination chat ID, username, phone, `"me"` or `"self"` */
|
||||||
* To forward with a caption, use another overload that takes an array of IDs.
|
toChatId: InputPeerLike
|
||||||
*
|
|
||||||
* @param message Message ID
|
|
||||||
* @param params Additional sending parameters
|
|
||||||
* @returns Newly sent, forwarded messages in the destination chat
|
|
||||||
*/
|
|
||||||
export async function forwardMessages(
|
|
||||||
client: BaseTelegramClient,
|
|
||||||
params: {
|
|
||||||
/** Source chat ID, username, phone, `"me"` or `"self"` */
|
|
||||||
fromChatId: InputPeerLike
|
|
||||||
/** Destination chat ID, username, phone, `"me"` or `"self"` */
|
|
||||||
toChatId: InputPeerLike
|
|
||||||
/** Message ID */
|
|
||||||
messages: number
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Optionally, a caption for your forwarded message(s).
|
* Optionally, a caption for your forwarded message(s).
|
||||||
* It will be sent as a separate message before the forwarded messages.
|
* It will be sent as a separate message before the forwarded messages.
|
||||||
*
|
*
|
||||||
* You can either pass `caption` or `captionMedia`, passing both will
|
* You can either pass `caption` or `captionMedia`, passing both will
|
||||||
* result in an error
|
* result in an error
|
||||||
*/
|
*/
|
||||||
caption?: string | FormattedString<string>
|
caption?: string | FormattedString<string>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Optionally, a media caption for your forwarded message(s).
|
* Optionally, a media caption for your forwarded message(s).
|
||||||
* It will be sent as a separate message before the forwarded messages.
|
* It will be sent as a separate message before the forwarded messages.
|
||||||
*
|
*
|
||||||
* You can either pass `caption` or `captionMedia`, passing both will
|
* You can either pass `caption` or `captionMedia`, passing both will
|
||||||
* result in an error
|
* result in an error
|
||||||
*/
|
*/
|
||||||
captionMedia?: InputMediaLike
|
captionMedia?: InputMediaLike
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse mode to use to parse entities in caption.
|
* Parse mode to use to parse entities in caption.
|
||||||
* Defaults to current default parse mode (if any).
|
* Defaults to current default parse mode (if any).
|
||||||
*
|
*
|
||||||
* Passing `null` will explicitly disable formatting.
|
* Passing `null` will explicitly disable formatting.
|
||||||
*/
|
*/
|
||||||
parseMode?: string | null
|
parseMode?: string | null
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of formatting entities in caption to use instead
|
* List of formatting entities in caption to use instead
|
||||||
* of parsing via a parse mode.
|
* of parsing via a parse mode.
|
||||||
*
|
*
|
||||||
* **Note:** Passing this makes the method ignore {@link parseMode}
|
* **Note:** Passing this makes the method ignore {@link parseMode}
|
||||||
*/
|
*/
|
||||||
entities?: tl.TypeMessageEntity[]
|
entities?: tl.TypeMessageEntity[]
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether to forward silently (also applies to caption message).
|
* Whether to forward silently (also applies to caption message).
|
||||||
*/
|
*/
|
||||||
silent?: boolean
|
silent?: boolean
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If set, the forwarding will be scheduled to this date
|
* If set, the forwarding will be scheduled to this date
|
||||||
* (also applies to caption message).
|
* (also applies to caption message).
|
||||||
* When passing a number, a UNIX time in ms is expected.
|
* When passing a number, a UNIX time in ms is expected.
|
||||||
*
|
*
|
||||||
* You can also pass `0x7FFFFFFE`, this will send the message
|
* You can also pass `0x7FFFFFFE`, this will send the message
|
||||||
* once the peer is online
|
* once the peer is online
|
||||||
*/
|
*/
|
||||||
schedule?: Date | number
|
schedule?: Date | number
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether to clear draft after sending this message (only used for caption)
|
* Whether to clear draft after sending this message (only used for caption)
|
||||||
*
|
*
|
||||||
* Defaults to `false`
|
* Defaults to `false`
|
||||||
*/
|
*/
|
||||||
clearDraft?: boolean
|
clearDraft?: boolean
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether to forward without author
|
* Whether to forward without author
|
||||||
*/
|
*/
|
||||||
noAuthor?: boolean
|
noAuthor?: boolean
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether to forward without caption (implies {@link noAuthor})
|
* Whether to forward without caption (implies {@link noAuthor})
|
||||||
*/
|
*/
|
||||||
noCaption?: boolean
|
noCaption?: boolean
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether to disallow further forwards of this message.
|
* Whether to disallow further forwards of this message.
|
||||||
*
|
*
|
||||||
* Only for bots, works even if the target chat does not
|
* Only for bots, works even if the target chat does not
|
||||||
* have content protection.
|
* have content protection.
|
||||||
*/
|
*/
|
||||||
forbidForwards?: boolean
|
forbidForwards?: boolean
|
||||||
},
|
|
||||||
): Promise<Message>
|
/**
|
||||||
|
* Peer to use when sending the message.
|
||||||
|
*/
|
||||||
|
sendAs?: InputPeerLike
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Forward one or more messages, optionally including a caption message.
|
* Forward one or more messages by their IDs.
|
||||||
* You can forward no more than 100 messages at once.
|
* You can forward no more than 100 messages at once.
|
||||||
*
|
*
|
||||||
* If a caption message was sent, it will be the first message in the resulting array.
|
* If a caption message was sent, it will be the first message in the resulting array.
|
||||||
|
@ -111,123 +101,18 @@ export async function forwardMessages(
|
||||||
* @param fromChatId Source chat ID, username, phone, `"me"` or `"self"`
|
* @param fromChatId Source chat ID, username, phone, `"me"` or `"self"`
|
||||||
* @param messages Message IDs
|
* @param messages Message IDs
|
||||||
* @param params Additional sending parameters
|
* @param params Additional sending parameters
|
||||||
* @returns
|
* @returns Newly sent, forwarded messages in the destination chat.
|
||||||
* Newly sent, forwarded messages in the destination chat.
|
|
||||||
* If a caption message was provided, it will be the first message in the array.
|
|
||||||
*/
|
*/
|
||||||
export async function forwardMessages(
|
export async function forwardMessagesById(
|
||||||
client: BaseTelegramClient,
|
client: BaseTelegramClient,
|
||||||
params: {
|
params: ForwardMessageOptions & {
|
||||||
/** Source chat ID, username, phone, `"me"` or `"self"` */
|
/** Source chat ID, username, phone, `"me"` or `"self"` */
|
||||||
fromChatId: InputPeerLike
|
fromChatId: InputPeerLike
|
||||||
/** Destination chat ID, username, phone, `"me"` or `"self"` */
|
/** Message IDs to forward */
|
||||||
toChatId: InputPeerLike
|
|
||||||
/** Message IDs */
|
|
||||||
messages: number[]
|
messages: number[]
|
||||||
|
|
||||||
/**
|
|
||||||
* Optionally, a caption for your forwarded message(s).
|
|
||||||
* It will be sent as a separate message before the forwarded messages.
|
|
||||||
*
|
|
||||||
* You can either pass `caption` or `captionMedia`, passing both will
|
|
||||||
* result in an error
|
|
||||||
*/
|
|
||||||
caption?: string | FormattedString<string>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Optionally, a media caption for your forwarded message(s).
|
|
||||||
* It will be sent as a separate message before the forwarded messages.
|
|
||||||
*
|
|
||||||
* You can either pass `caption` or `captionMedia`, passing both will
|
|
||||||
* result in an error
|
|
||||||
*/
|
|
||||||
captionMedia?: InputMediaLike
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse mode to use to parse entities in caption.
|
|
||||||
* Defaults to current default parse mode (if any).
|
|
||||||
*
|
|
||||||
* Passing `null` will explicitly disable formatting.
|
|
||||||
*/
|
|
||||||
parseMode?: string | null
|
|
||||||
|
|
||||||
/**
|
|
||||||
* List of formatting entities in caption to use instead
|
|
||||||
* of parsing via a parse mode.
|
|
||||||
*
|
|
||||||
* **Note:** Passing this makes the method ignore {@link parseMode}
|
|
||||||
*/
|
|
||||||
entities?: tl.TypeMessageEntity[]
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether to forward silently (also applies to caption message).
|
|
||||||
*/
|
|
||||||
silent?: boolean
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If set, the forwarding will be scheduled to this date
|
|
||||||
* (also applies to caption message).
|
|
||||||
* When passing a number, a UNIX time in ms is expected.
|
|
||||||
*
|
|
||||||
* You can also pass `0x7FFFFFFE`, this will send the message
|
|
||||||
* once the peer is online
|
|
||||||
*/
|
|
||||||
schedule?: Date | number
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether to clear draft after sending this message (only used for caption)
|
|
||||||
*
|
|
||||||
* Defaults to `false`
|
|
||||||
*/
|
|
||||||
clearDraft?: boolean
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether to forward without author
|
|
||||||
*/
|
|
||||||
noAuthor?: boolean
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether to forward without caption (implies {@link noAuthor})
|
|
||||||
*/
|
|
||||||
noCaption?: boolean
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether to disallow further forwards of this message.
|
|
||||||
*
|
|
||||||
* Only for bots, works even if the target chat does not
|
|
||||||
* have content protection.
|
|
||||||
*/
|
|
||||||
forbidForwards?: boolean
|
|
||||||
},
|
},
|
||||||
): Promise<MaybeArray<Message>>
|
): Promise<Message[]> {
|
||||||
|
const { messages, toChatId, fromChatId, silent, schedule, forbidForwards, sendAs, noAuthor, noCaption } = params
|
||||||
/** @internal */
|
|
||||||
export async function forwardMessages(
|
|
||||||
client: BaseTelegramClient,
|
|
||||||
params: {
|
|
||||||
toChatId: InputPeerLike
|
|
||||||
fromChatId: InputPeerLike
|
|
||||||
messages: MaybeArray<number>
|
|
||||||
parseMode?: string | null
|
|
||||||
entities?: tl.TypeMessageEntity[]
|
|
||||||
silent?: boolean
|
|
||||||
schedule?: Date | number
|
|
||||||
clearDraft?: boolean
|
|
||||||
noAuthor?: boolean
|
|
||||||
noCaption?: boolean
|
|
||||||
forbidForwards?: boolean
|
|
||||||
sendAs?: InputPeerLike
|
|
||||||
},
|
|
||||||
): Promise<MaybeArray<Message>> {
|
|
||||||
const { toChatId, fromChatId, silent, schedule, forbidForwards, sendAs, noAuthor, noCaption } = params
|
|
||||||
let { messages } = params
|
|
||||||
|
|
||||||
let isSingle = false
|
|
||||||
|
|
||||||
if (!Array.isArray(messages)) {
|
|
||||||
isSingle = true
|
|
||||||
messages = [messages]
|
|
||||||
}
|
|
||||||
|
|
||||||
// sending more than 100 will not result in a server-sent
|
// sending more than 100 will not result in a server-sent
|
||||||
// error, instead only first 100 IDs will be forwarded,
|
// error, instead only first 100 IDs will be forwarded,
|
||||||
|
@ -269,7 +154,25 @@ export async function forwardMessages(
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
if (isSingle) return forwarded[0]
|
|
||||||
|
|
||||||
return forwarded
|
return forwarded
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forward one or more {@link Message}s to another chat.
|
||||||
|
*
|
||||||
|
* > **Note**: all messages must be from the same chat.
|
||||||
|
*/
|
||||||
|
export async function forwardMessages(
|
||||||
|
client: BaseTelegramClient,
|
||||||
|
params: ForwardMessageOptions & {
|
||||||
|
messages: Message[]
|
||||||
|
},
|
||||||
|
): Promise<Message[]> {
|
||||||
|
const { messages, ...rest } = params
|
||||||
|
|
||||||
|
return forwardMessagesById(client, {
|
||||||
|
...rest,
|
||||||
|
fromChatId: messages[0].chat.inputPeer,
|
||||||
|
messages: messages.map((it) => it.id),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { BaseTelegramClient, tl } from '@mtcute/core'
|
import { BaseTelegramClient, tl } from '@mtcute/core'
|
||||||
|
|
||||||
import { Message } from '../../types/messages'
|
import { InputMessageId, Message, normalizeInputMessageId } from '../../types/messages'
|
||||||
import { InputPeerLike, PeersIndex } from '../../types/peers'
|
import { InputPeerLike, PeersIndex } from '../../types/peers'
|
||||||
import { resolvePeer } from '../users/resolve-peer'
|
import { resolvePeer } from '../users/resolve-peer'
|
||||||
|
|
||||||
|
@ -54,10 +54,11 @@ export async function _getDiscussionMessage(
|
||||||
*/
|
*/
|
||||||
export async function getDiscussionMessage(
|
export async function getDiscussionMessage(
|
||||||
client: BaseTelegramClient,
|
client: BaseTelegramClient,
|
||||||
peer: InputPeerLike,
|
params: InputMessageId,
|
||||||
message: number,
|
|
||||||
): Promise<Message | null> {
|
): Promise<Message | null> {
|
||||||
const inputPeer = await resolvePeer(client, peer)
|
const { chatId, message } = normalizeInputMessageId(params)
|
||||||
|
|
||||||
|
const inputPeer = await resolvePeer(client, chatId)
|
||||||
|
|
||||||
const res = await client.call({
|
const res = await client.call({
|
||||||
_: 'messages.getDiscussionMessage',
|
_: 'messages.getDiscussionMessage',
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { BaseTelegramClient, MtArgumentError } from '@mtcute/core'
|
import { BaseTelegramClient, MtArgumentError } from '@mtcute/core'
|
||||||
import { isPresent } from '@mtcute/core/utils'
|
import { isPresent } from '@mtcute/core/utils'
|
||||||
|
|
||||||
import { InputPeerLike, Message } from '../../types'
|
import { InputMessageId, Message, normalizeInputMessageId } from '../../types'
|
||||||
import { isInputPeerChannel } from '../../utils/peer-utils'
|
import { isInputPeerChannel } from '../../utils/peer-utils'
|
||||||
import { resolvePeer } from '../users/resolve-peer'
|
import { resolvePeer } from '../users/resolve-peer'
|
||||||
import { getMessages } from './get-messages'
|
import { getMessages } from './get-messages'
|
||||||
|
@ -12,11 +12,9 @@ import { getMessages } from './get-messages'
|
||||||
* @param chatId Chat ID
|
* @param chatId Chat ID
|
||||||
* @param message ID of one of the messages in the group
|
* @param message ID of one of the messages in the group
|
||||||
*/
|
*/
|
||||||
export async function getMessageGroup(
|
export async function getMessageGroup(client: BaseTelegramClient, params: InputMessageId): Promise<Message[]> {
|
||||||
client: BaseTelegramClient,
|
const { chatId, message } = normalizeInputMessageId(params)
|
||||||
chatId: InputPeerLike,
|
|
||||||
message: number,
|
|
||||||
): Promise<Message[]> {
|
|
||||||
// awesome hack stolen from pyrogram
|
// awesome hack stolen from pyrogram
|
||||||
// groups have no more than 10 items
|
// groups have no more than 10 items
|
||||||
// however, since for non-channels message ids are shared,
|
// however, since for non-channels message ids are shared,
|
||||||
|
|
|
@ -1,29 +1,12 @@
|
||||||
import { BaseTelegramClient, getMarkedPeerId, MaybeArray } from '@mtcute/core'
|
import { BaseTelegramClient, getMarkedPeerId } from '@mtcute/core'
|
||||||
import { assertTypeIs } from '@mtcute/core/utils'
|
import { assertTypeIs } from '@mtcute/core/utils'
|
||||||
|
|
||||||
import { InputPeerLike, MessageReactions, PeersIndex } from '../../types'
|
import { InputPeerLike, Message, MessageReactions, PeersIndex } from '../../types'
|
||||||
import { assertIsUpdatesGroup } from '../../utils/updates-utils'
|
import { assertIsUpdatesGroup } from '../../utils/updates-utils'
|
||||||
import { resolvePeer } from '../users/resolve-peer'
|
import { resolvePeer } from '../users/resolve-peer'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get reactions to a message.
|
* Get reactions to messages by their IDs.
|
||||||
*
|
|
||||||
* > Apps should short-poll reactions for visible messages
|
|
||||||
* > (that weren't sent by the user) once every 15-30 seconds,
|
|
||||||
* > but only if `message.reactions` is set
|
|
||||||
*
|
|
||||||
* @param chatId ID of the chat with the message
|
|
||||||
* @param messages Message ID
|
|
||||||
* @returns Reactions to the corresponding message, or `null` if there are none
|
|
||||||
*/
|
|
||||||
export async function getMessageReactions(
|
|
||||||
client: BaseTelegramClient,
|
|
||||||
chatId: InputPeerLike,
|
|
||||||
messages: number,
|
|
||||||
): Promise<MessageReactions | null>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get reactions to messages.
|
|
||||||
*
|
*
|
||||||
* > Apps should short-poll reactions for visible messages
|
* > Apps should short-poll reactions for visible messages
|
||||||
* > (that weren't sent by the user) once every 15-30 seconds,
|
* > (that weren't sent by the user) once every 15-30 seconds,
|
||||||
|
@ -33,26 +16,11 @@ export async function getMessageReactions(
|
||||||
* @param messages Message IDs
|
* @param messages Message IDs
|
||||||
* @returns Reactions to corresponding messages, or `null` if there are none
|
* @returns Reactions to corresponding messages, or `null` if there are none
|
||||||
*/
|
*/
|
||||||
export async function getMessageReactions(
|
export async function getMessageReactionsById(
|
||||||
client: BaseTelegramClient,
|
client: BaseTelegramClient,
|
||||||
chatId: InputPeerLike,
|
chatId: InputPeerLike,
|
||||||
messages: number[],
|
messages: number[],
|
||||||
): Promise<(MessageReactions | null)[]>
|
): Promise<(MessageReactions | null)[]> {
|
||||||
|
|
||||||
/**
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
export async function getMessageReactions(
|
|
||||||
client: BaseTelegramClient,
|
|
||||||
chatId: InputPeerLike,
|
|
||||||
messages: MaybeArray<number>,
|
|
||||||
): Promise<MaybeArray<MessageReactions | null>> {
|
|
||||||
const single = !Array.isArray(messages)
|
|
||||||
|
|
||||||
if (!Array.isArray(messages)) {
|
|
||||||
messages = [messages]
|
|
||||||
}
|
|
||||||
|
|
||||||
const res = await client.call({
|
const res = await client.call({
|
||||||
_: 'messages.getMessagesReactions',
|
_: 'messages.getMessagesReactions',
|
||||||
peer: await resolvePeer(client, chatId),
|
peer: await resolvePeer(client, chatId),
|
||||||
|
@ -77,9 +45,29 @@ export async function getMessageReactions(
|
||||||
index[update.msgId] = new MessageReactions(update.msgId, getMarkedPeerId(update.peer), update.reactions, peers)
|
index[update.msgId] = new MessageReactions(update.msgId, getMarkedPeerId(update.peer), update.reactions, peers)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (single) {
|
|
||||||
return index[messages[0]] ?? null
|
|
||||||
}
|
|
||||||
|
|
||||||
return messages.map((messageId) => index[messageId] ?? null)
|
return messages.map((messageId) => index[messageId] ?? null)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get reactions to {@link Message}s.
|
||||||
|
*
|
||||||
|
* > **Note**: messages must all be from the same chat.
|
||||||
|
*
|
||||||
|
* > Apps should short-poll reactions for visible messages
|
||||||
|
* > (that weren't sent by the user) once every 15-30 seconds,
|
||||||
|
* > but only if `message.reactions` is set
|
||||||
|
*
|
||||||
|
* @param chatId ID of the chat with messages
|
||||||
|
* @param messages Message IDs
|
||||||
|
* @returns Reactions to corresponding messages, or `null` if there are none
|
||||||
|
*/
|
||||||
|
export async function getMessageReactions(
|
||||||
|
client: BaseTelegramClient,
|
||||||
|
messages: Message[],
|
||||||
|
): Promise<(MessageReactions | null)[]> {
|
||||||
|
return getMessageReactionsById(
|
||||||
|
client,
|
||||||
|
messages[0].chat.inputPeer,
|
||||||
|
messages.map((it) => it.id),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
@ -3,23 +3,6 @@ import { assertTypeIsNot } from '@mtcute/core/utils'
|
||||||
|
|
||||||
import { Message, PeersIndex } from '../../types'
|
import { Message, PeersIndex } from '../../types'
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a single message from PM or legacy group by its ID.
|
|
||||||
* For channels, use {@link getMessages}.
|
|
||||||
*
|
|
||||||
* Unlike {@link getMessages}, this method does not
|
|
||||||
* check if the message belongs to some chat.
|
|
||||||
*
|
|
||||||
* @param messageId Messages ID
|
|
||||||
* @param [fromReply=false]
|
|
||||||
* Whether the reply to a given message should be fetched
|
|
||||||
* (i.e. `getMessages(msg.chat.id, msg.id, true).id === msg.replyToMessageId`)
|
|
||||||
*/
|
|
||||||
export async function getMessagesUnsafe(
|
|
||||||
client: BaseTelegramClient,
|
|
||||||
messageId: number,
|
|
||||||
fromReply?: boolean,
|
|
||||||
): Promise<Message | null>
|
|
||||||
/**
|
/**
|
||||||
* Get messages from PM or legacy group by their IDs.
|
* Get messages from PM or legacy group by their IDs.
|
||||||
* For channels, use {@link getMessages}.
|
* For channels, use {@link getMessages}.
|
||||||
|
@ -35,23 +18,15 @@ export async function getMessagesUnsafe(
|
||||||
* Whether the reply to a given message should be fetched
|
* Whether the reply to a given message should be fetched
|
||||||
* (i.e. `getMessages(msg.chat.id, msg.id, true).id === msg.replyToMessageId`)
|
* (i.e. `getMessages(msg.chat.id, msg.id, true).id === msg.replyToMessageId`)
|
||||||
*/
|
*/
|
||||||
export async function getMessagesUnsafe(
|
|
||||||
client: BaseTelegramClient,
|
|
||||||
messageIds: number[],
|
|
||||||
fromReply?: boolean,
|
|
||||||
): Promise<(Message | null)[]>
|
|
||||||
|
|
||||||
/** @internal */
|
|
||||||
export async function getMessagesUnsafe(
|
export async function getMessagesUnsafe(
|
||||||
client: BaseTelegramClient,
|
client: BaseTelegramClient,
|
||||||
messageIds: MaybeArray<number>,
|
messageIds: MaybeArray<number>,
|
||||||
fromReply = false,
|
fromReply = false,
|
||||||
): Promise<MaybeArray<Message | null>> {
|
): Promise<(Message | null)[]> {
|
||||||
const isSingle = !Array.isArray(messageIds)
|
if (!Array.isArray(messageIds)) messageIds = [messageIds]
|
||||||
if (isSingle) messageIds = [messageIds as number]
|
|
||||||
|
|
||||||
const type = fromReply ? 'inputMessageReplyTo' : 'inputMessageID'
|
const type = fromReply ? 'inputMessageReplyTo' : 'inputMessageID'
|
||||||
const ids: tl.TypeInputMessage[] = (messageIds as number[]).map((it) => ({
|
const ids: tl.TypeInputMessage[] = messageIds.map((it) => ({
|
||||||
_: type,
|
_: type,
|
||||||
id: it,
|
id: it,
|
||||||
}))
|
}))
|
||||||
|
@ -65,11 +40,9 @@ export async function getMessagesUnsafe(
|
||||||
|
|
||||||
const peers = PeersIndex.from(res)
|
const peers = PeersIndex.from(res)
|
||||||
|
|
||||||
const ret = res.messages.map((msg) => {
|
return res.messages.map((msg) => {
|
||||||
if (msg._ === 'messageEmpty') return null
|
if (msg._ === 'messageEmpty') return null
|
||||||
|
|
||||||
return new Message(msg, peers)
|
return new Message(msg, peers)
|
||||||
})
|
})
|
||||||
|
|
||||||
return isSingle ? ret[0] : ret
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,21 +7,7 @@ import { isInputPeerChannel, normalizeToInputChannel } from '../../utils/peer-ut
|
||||||
import { getAuthState } from '../auth/_state'
|
import { getAuthState } from '../auth/_state'
|
||||||
import { resolvePeer } from '../users/resolve-peer'
|
import { resolvePeer } from '../users/resolve-peer'
|
||||||
|
|
||||||
/**
|
// @available=both
|
||||||
* Get a single message in chat by its ID
|
|
||||||
*
|
|
||||||
* @param chatId Chat's marked ID, its username, phone or `"me"` or `"self"`
|
|
||||||
* @param messageId Messages ID
|
|
||||||
* @param [fromReply=false]
|
|
||||||
* Whether the reply to a given message should be fetched
|
|
||||||
* (i.e. `getMessages(msg.chat.id, msg.id, true).id === msg.replyToMessageId`)
|
|
||||||
*/
|
|
||||||
export async function getMessages(
|
|
||||||
client: BaseTelegramClient,
|
|
||||||
chatId: InputPeerLike,
|
|
||||||
messageId: number,
|
|
||||||
fromReply?: boolean,
|
|
||||||
): Promise<Message | null>
|
|
||||||
/**
|
/**
|
||||||
* Get messages in chat by their IDs
|
* Get messages in chat by their IDs
|
||||||
*
|
*
|
||||||
|
@ -34,28 +20,17 @@ export async function getMessages(
|
||||||
* Whether the reply to a given message should be fetched
|
* Whether the reply to a given message should be fetched
|
||||||
* (i.e. `getMessages(msg.chat.id, msg.id, true).id === msg.replyToMessageId`)
|
* (i.e. `getMessages(msg.chat.id, msg.id, true).id === msg.replyToMessageId`)
|
||||||
*/
|
*/
|
||||||
export async function getMessages(
|
|
||||||
client: BaseTelegramClient,
|
|
||||||
chatId: InputPeerLike,
|
|
||||||
messageIds: number[],
|
|
||||||
fromReply?: boolean,
|
|
||||||
): Promise<(Message | null)[]>
|
|
||||||
|
|
||||||
// @available=both
|
|
||||||
/** @internal */
|
|
||||||
export async function getMessages(
|
export async function getMessages(
|
||||||
client: BaseTelegramClient,
|
client: BaseTelegramClient,
|
||||||
chatId: InputPeerLike,
|
chatId: InputPeerLike,
|
||||||
messageIds: MaybeArray<number>,
|
messageIds: MaybeArray<number>,
|
||||||
fromReply = false,
|
fromReply = false,
|
||||||
): Promise<MaybeArray<Message | null>> {
|
): Promise<(Message | null)[]> {
|
||||||
const peer = await resolvePeer(client, chatId)
|
const peer = await resolvePeer(client, chatId)
|
||||||
|
if (!Array.isArray(messageIds)) messageIds = [messageIds]
|
||||||
const isSingle = !Array.isArray(messageIds)
|
|
||||||
if (isSingle) messageIds = [messageIds as number]
|
|
||||||
|
|
||||||
const type = fromReply ? 'inputMessageReplyTo' : 'inputMessageID'
|
const type = fromReply ? 'inputMessageReplyTo' : 'inputMessageID'
|
||||||
const ids: tl.TypeInputMessage[] = (messageIds as number[]).map((it) => ({
|
const ids: tl.TypeInputMessage[] = messageIds.map((it) => ({
|
||||||
_: type,
|
_: type,
|
||||||
id: it,
|
id: it,
|
||||||
}))
|
}))
|
||||||
|
@ -80,7 +55,8 @@ export async function getMessages(
|
||||||
const peers = PeersIndex.from(res)
|
const peers = PeersIndex.from(res)
|
||||||
|
|
||||||
let selfId: number | null | undefined = undefined
|
let selfId: number | null | undefined = undefined
|
||||||
const ret = res.messages.map((msg) => {
|
|
||||||
|
return res.messages.map((msg) => {
|
||||||
if (msg._ === 'messageEmpty') return null
|
if (msg._ === 'messageEmpty') return null
|
||||||
|
|
||||||
if (!isChannel) {
|
if (!isChannel) {
|
||||||
|
@ -110,6 +86,4 @@ export async function getMessages(
|
||||||
|
|
||||||
return new Message(msg, peers)
|
return new Message(msg, peers)
|
||||||
})
|
})
|
||||||
|
|
||||||
return isSingle ? ret[0] : ret
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,9 @@ import { BaseTelegramClient } from '@mtcute/core'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ArrayPaginated,
|
ArrayPaginated,
|
||||||
InputPeerLike,
|
InputMessageId,
|
||||||
InputReaction,
|
InputReaction,
|
||||||
|
normalizeInputMessageId,
|
||||||
normalizeInputReaction,
|
normalizeInputReaction,
|
||||||
PeerReaction,
|
PeerReaction,
|
||||||
PeersIndex,
|
PeersIndex,
|
||||||
|
@ -17,15 +18,11 @@ export type GetReactionUsersOffset = string
|
||||||
/**
|
/**
|
||||||
* Get users who have reacted to the message.
|
* Get users who have reacted to the message.
|
||||||
*
|
*
|
||||||
* @param chatId Chat ID
|
|
||||||
* @param messageId Message ID
|
|
||||||
* @param params
|
* @param params
|
||||||
*/
|
*/
|
||||||
export async function getReactionUsers(
|
export async function getReactionUsers(
|
||||||
client: BaseTelegramClient,
|
client: BaseTelegramClient,
|
||||||
chatId: InputPeerLike,
|
params: InputMessageId & {
|
||||||
messageId: number,
|
|
||||||
params?: {
|
|
||||||
/**
|
/**
|
||||||
* Get only reactions with the specified emoji
|
* Get only reactions with the specified emoji
|
||||||
*/
|
*/
|
||||||
|
@ -44,9 +41,8 @@ export async function getReactionUsers(
|
||||||
offset?: GetReactionUsersOffset
|
offset?: GetReactionUsersOffset
|
||||||
},
|
},
|
||||||
): Promise<ArrayPaginated<PeerReaction, GetReactionUsersOffset>> {
|
): Promise<ArrayPaginated<PeerReaction, GetReactionUsersOffset>> {
|
||||||
if (!params) params = {}
|
|
||||||
|
|
||||||
const { limit = 100, offset, emoji } = params
|
const { limit = 100, offset, emoji } = params
|
||||||
|
const { chatId, message } = normalizeInputMessageId(params)
|
||||||
|
|
||||||
const peer = await resolvePeer(client, chatId)
|
const peer = await resolvePeer(client, chatId)
|
||||||
|
|
||||||
|
@ -55,7 +51,7 @@ export async function getReactionUsers(
|
||||||
const res = await client.call({
|
const res = await client.call({
|
||||||
_: 'messages.getMessageReactionsList',
|
_: 'messages.getMessageReactionsList',
|
||||||
peer,
|
peer,
|
||||||
id: messageId,
|
id: message,
|
||||||
reaction,
|
reaction,
|
||||||
limit,
|
limit,
|
||||||
offset,
|
offset,
|
||||||
|
|
|
@ -4,17 +4,6 @@ import { assertTypeIsNot } from '@mtcute/core/utils'
|
||||||
import { InputPeerLike, Message, PeersIndex } from '../../types'
|
import { InputPeerLike, Message, PeersIndex } from '../../types'
|
||||||
import { resolvePeer } from '../users/resolve-peer'
|
import { resolvePeer } from '../users/resolve-peer'
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a single scheduled message in chat by its ID
|
|
||||||
*
|
|
||||||
* @param chatId Chat's marked ID, its username, phone or `"me"` or `"self"`
|
|
||||||
* @param messageId Scheduled message ID
|
|
||||||
*/
|
|
||||||
export async function getScheduledMessages(
|
|
||||||
client: BaseTelegramClient,
|
|
||||||
chatId: InputPeerLike,
|
|
||||||
messageId: number,
|
|
||||||
): Promise<Message | null>
|
|
||||||
/**
|
/**
|
||||||
* Get scheduled messages in chat by their IDs
|
* Get scheduled messages in chat by their IDs
|
||||||
*
|
*
|
||||||
|
@ -24,27 +13,18 @@ export async function getScheduledMessages(
|
||||||
* @param chatId Chat's marked ID, its username, phone or `"me"` or `"self"`
|
* @param chatId Chat's marked ID, its username, phone or `"me"` or `"self"`
|
||||||
* @param messageIds Scheduled messages IDs
|
* @param messageIds Scheduled messages IDs
|
||||||
*/
|
*/
|
||||||
export async function getScheduledMessages(
|
|
||||||
client: BaseTelegramClient,
|
|
||||||
chatId: InputPeerLike,
|
|
||||||
messageIds: number[],
|
|
||||||
): Promise<(Message | null)[]>
|
|
||||||
|
|
||||||
/** @internal */
|
|
||||||
export async function getScheduledMessages(
|
export async function getScheduledMessages(
|
||||||
client: BaseTelegramClient,
|
client: BaseTelegramClient,
|
||||||
chatId: InputPeerLike,
|
chatId: InputPeerLike,
|
||||||
messageIds: MaybeArray<number>,
|
messageIds: MaybeArray<number>,
|
||||||
): Promise<MaybeArray<Message | null>> {
|
): Promise<(Message | null)[]> {
|
||||||
const peer = await resolvePeer(client, chatId)
|
const peer = await resolvePeer(client, chatId)
|
||||||
|
if (!Array.isArray(messageIds)) messageIds = [messageIds]
|
||||||
const isSingle = !Array.isArray(messageIds)
|
|
||||||
if (isSingle) messageIds = [messageIds as number]
|
|
||||||
|
|
||||||
const res = await client.call({
|
const res = await client.call({
|
||||||
_: 'messages.getScheduledMessages',
|
_: 'messages.getScheduledMessages',
|
||||||
peer,
|
peer,
|
||||||
id: messageIds as number[],
|
id: messageIds,
|
||||||
})
|
})
|
||||||
|
|
||||||
assertTypeIsNot('getScheduledMessages', res, 'messages.messagesNotModified')
|
assertTypeIsNot('getScheduledMessages', res, 'messages.messagesNotModified')
|
||||||
|
@ -57,5 +37,5 @@ export async function getScheduledMessages(
|
||||||
return new Message(msg, peers, true)
|
return new Message(msg, peers, true)
|
||||||
})
|
})
|
||||||
|
|
||||||
return isSingle ? ret[0] : ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { BaseTelegramClient } from '@mtcute/core'
|
import { BaseTelegramClient } from '@mtcute/core'
|
||||||
|
|
||||||
import { InputPeerLike, normalizeInputReaction, PeerReaction } from '../../types'
|
import { normalizeInputMessageId, normalizeInputReaction, PeerReaction } from '../../types'
|
||||||
import { resolvePeer } from '../users/resolve-peer'
|
import { resolvePeer } from '../users/resolve-peer'
|
||||||
import { getReactionUsers } from './get-reaction-users'
|
import { getReactionUsers } from './get-reaction-users'
|
||||||
|
|
||||||
|
@ -15,9 +15,7 @@ import { getReactionUsers } from './get-reaction-users'
|
||||||
*/
|
*/
|
||||||
export async function* iterReactionUsers(
|
export async function* iterReactionUsers(
|
||||||
client: BaseTelegramClient,
|
client: BaseTelegramClient,
|
||||||
chatId: InputPeerLike,
|
params: Parameters<typeof getReactionUsers>[1] & {
|
||||||
messageId: number,
|
|
||||||
params?: Parameters<typeof getReactionUsers>[3] & {
|
|
||||||
/**
|
/**
|
||||||
* Limit the number of events returned.
|
* Limit the number of events returned.
|
||||||
*
|
*
|
||||||
|
@ -33,8 +31,7 @@ export async function* iterReactionUsers(
|
||||||
chunkSize?: number
|
chunkSize?: number
|
||||||
},
|
},
|
||||||
): AsyncIterableIterator<PeerReaction> {
|
): AsyncIterableIterator<PeerReaction> {
|
||||||
if (!params) params = {}
|
const { chatId, message } = normalizeInputMessageId(params)
|
||||||
|
|
||||||
const peer = await resolvePeer(client, chatId)
|
const peer = await resolvePeer(client, chatId)
|
||||||
|
|
||||||
const { limit = Infinity, chunkSize = 100 } = params
|
const { limit = Infinity, chunkSize = 100 } = params
|
||||||
|
@ -45,7 +42,9 @@ export async function* iterReactionUsers(
|
||||||
const reaction = normalizeInputReaction(params.emoji)
|
const reaction = normalizeInputReaction(params.emoji)
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
const res = await getReactionUsers(client, peer, messageId, {
|
const res = await getReactionUsers(client, {
|
||||||
|
chatId: peer,
|
||||||
|
message,
|
||||||
emoji: reaction,
|
emoji: reaction,
|
||||||
limit: Math.min(chunkSize, limit - current),
|
limit: Math.min(chunkSize, limit - current),
|
||||||
offset,
|
offset,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { BaseTelegramClient } from '@mtcute/core'
|
import { BaseTelegramClient } from '@mtcute/core'
|
||||||
|
|
||||||
import { InputPeerLike } from '../../types'
|
import { InputMessageId, normalizeInputMessageId } from '../../types'
|
||||||
import { resolvePeer } from '../users/resolve-peer'
|
import { resolvePeer } from '../users/resolve-peer'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -8,15 +8,10 @@ import { resolvePeer } from '../users/resolve-peer'
|
||||||
*
|
*
|
||||||
* For supergroups/channels, you must have appropriate permissions,
|
* For supergroups/channels, you must have appropriate permissions,
|
||||||
* either as an admin, or as default permissions
|
* either as an admin, or as default permissions
|
||||||
*
|
|
||||||
* @param chatId Chat ID, username, phone number, `"self"` or `"me"`
|
|
||||||
* @param messageId Message ID
|
|
||||||
*/
|
*/
|
||||||
export async function pinMessage(
|
export async function pinMessage(
|
||||||
client: BaseTelegramClient,
|
client: BaseTelegramClient,
|
||||||
chatId: InputPeerLike,
|
params: InputMessageId & {
|
||||||
messageId: number,
|
|
||||||
params?: {
|
|
||||||
/** Whether to send a notification (only for legacy groups and supergroups) */
|
/** Whether to send a notification (only for legacy groups and supergroups) */
|
||||||
notify?: boolean
|
notify?: boolean
|
||||||
/** Whether to pin for both sides (only for private chats) */
|
/** Whether to pin for both sides (only for private chats) */
|
||||||
|
@ -24,11 +19,12 @@ export async function pinMessage(
|
||||||
},
|
},
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const { notify, bothSides } = params ?? {}
|
const { notify, bothSides } = params ?? {}
|
||||||
|
const { chatId, message } = normalizeInputMessageId(params)
|
||||||
|
|
||||||
const res = await client.call({
|
const res = await client.call({
|
||||||
_: 'messages.updatePinnedMessage',
|
_: 'messages.updatePinnedMessage',
|
||||||
peer: await resolvePeer(client, chatId),
|
peer: await resolvePeer(client, chatId),
|
||||||
id: messageId,
|
id: message,
|
||||||
silent: !notify,
|
silent: !notify,
|
||||||
pmOneside: !bothSides,
|
pmOneside: !bothSides,
|
||||||
})
|
})
|
||||||
|
|
|
@ -6,9 +6,82 @@ import { getMessages } from './get-messages'
|
||||||
import { sendMedia } from './send-media'
|
import { sendMedia } from './send-media'
|
||||||
import { sendText } from './send-text'
|
import { sendText } from './send-text'
|
||||||
|
|
||||||
|
// @exported
|
||||||
|
export interface SendCopyParams {
|
||||||
|
/** Target chat ID */
|
||||||
|
toChatId: InputPeerLike
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether to send this message silently.
|
||||||
|
*/
|
||||||
|
silent?: boolean
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If set, the message will be scheduled to this date.
|
||||||
|
* When passing a number, a UNIX time in ms is expected.
|
||||||
|
*
|
||||||
|
* You can also pass `0x7FFFFFFE`, this will send the message
|
||||||
|
* once the peer is online
|
||||||
|
*/
|
||||||
|
schedule?: Date | number
|
||||||
|
|
||||||
|
/**
|
||||||
|
* New message caption (only used for media)
|
||||||
|
*/
|
||||||
|
caption?: string | FormattedString<string>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse mode to use to parse `text` entities before sending
|
||||||
|
* the message. Defaults to current default parse mode (if any).
|
||||||
|
*
|
||||||
|
* Passing `null` will explicitly disable formatting.
|
||||||
|
*/
|
||||||
|
parseMode?: string | null
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Message to reply to. Either a message object or message ID.
|
||||||
|
*
|
||||||
|
* For forums - can also be an ID of the topic (i.e. its top message ID)
|
||||||
|
*/
|
||||||
|
replyTo?: number | Message
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether to throw an error if {@link replyTo}
|
||||||
|
* message does not exist.
|
||||||
|
*
|
||||||
|
* If that message was not found, `NotFoundError` is thrown,
|
||||||
|
* with `text` set to `MESSAGE_NOT_FOUND`.
|
||||||
|
*
|
||||||
|
* Incurs an additional request, so only use when really needed.
|
||||||
|
*
|
||||||
|
* Defaults to `false`
|
||||||
|
*/
|
||||||
|
mustReply?: boolean
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of formatting entities to use instead of parsing via a
|
||||||
|
* parse mode.
|
||||||
|
*
|
||||||
|
* **Note:** Passing this makes the method ignore {@link parseMode}
|
||||||
|
*/
|
||||||
|
entities?: tl.TypeMessageEntity[]
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For bots: inline or reply markup or an instruction
|
||||||
|
* to hide a reply keyboard or to force a reply.
|
||||||
|
*/
|
||||||
|
replyMarkup?: ReplyMarkup
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether to clear draft after sending this message.
|
||||||
|
*
|
||||||
|
* Defaults to `false`
|
||||||
|
*/
|
||||||
|
clearDraft?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copy a message (i.e. send the same message,
|
* Copy a message (i.e. send the same message, but do not forward it).
|
||||||
* but do not forward it).
|
|
||||||
*
|
*
|
||||||
* Note that if the message contains a webpage,
|
* Note that if the message contains a webpage,
|
||||||
* it will be copied simply as a text message,
|
* it will be copied simply as a text message,
|
||||||
|
@ -19,90 +92,31 @@ import { sendText } from './send-text'
|
||||||
*/
|
*/
|
||||||
export async function sendCopy(
|
export async function sendCopy(
|
||||||
client: BaseTelegramClient,
|
client: BaseTelegramClient,
|
||||||
params: {
|
params: SendCopyParams &
|
||||||
/** Source chat ID */
|
(
|
||||||
fromChatId: InputPeerLike
|
| {
|
||||||
/** Target chat ID */
|
/** Source chat ID */
|
||||||
toChatId: InputPeerLike
|
fromChatId: InputPeerLike
|
||||||
/** Message ID to forward */
|
/** Message ID to forward */
|
||||||
message: number
|
message: number
|
||||||
/**
|
}
|
||||||
* Whether to send this message silently.
|
| { message: Message }
|
||||||
*/
|
),
|
||||||
silent?: boolean
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If set, the message will be scheduled to this date.
|
|
||||||
* When passing a number, a UNIX time in ms is expected.
|
|
||||||
*
|
|
||||||
* You can also pass `0x7FFFFFFE`, this will send the message
|
|
||||||
* once the peer is online
|
|
||||||
*/
|
|
||||||
schedule?: Date | number
|
|
||||||
|
|
||||||
/**
|
|
||||||
* New message caption (only used for media)
|
|
||||||
*/
|
|
||||||
caption?: string | FormattedString<string>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse mode to use to parse `text` entities before sending
|
|
||||||
* the message. Defaults to current default parse mode (if any).
|
|
||||||
*
|
|
||||||
* Passing `null` will explicitly disable formatting.
|
|
||||||
*/
|
|
||||||
parseMode?: string | null
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Message to reply to. Either a message object or message ID.
|
|
||||||
*
|
|
||||||
* For forums - can also be an ID of the topic (i.e. its top message ID)
|
|
||||||
*/
|
|
||||||
replyTo?: number | Message
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether to throw an error if {@link replyTo}
|
|
||||||
* message does not exist.
|
|
||||||
*
|
|
||||||
* If that message was not found, `NotFoundError` is thrown,
|
|
||||||
* with `text` set to `MESSAGE_NOT_FOUND`.
|
|
||||||
*
|
|
||||||
* Incurs an additional request, so only use when really needed.
|
|
||||||
*
|
|
||||||
* Defaults to `false`
|
|
||||||
*/
|
|
||||||
mustReply?: boolean
|
|
||||||
|
|
||||||
/**
|
|
||||||
* List of formatting entities to use instead of parsing via a
|
|
||||||
* parse mode.
|
|
||||||
*
|
|
||||||
* **Note:** Passing this makes the method ignore {@link parseMode}
|
|
||||||
*/
|
|
||||||
entities?: tl.TypeMessageEntity[]
|
|
||||||
|
|
||||||
/**
|
|
||||||
* For bots: inline or reply markup or an instruction
|
|
||||||
* to hide a reply keyboard or to force a reply.
|
|
||||||
*/
|
|
||||||
replyMarkup?: ReplyMarkup
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether to clear draft after sending this message.
|
|
||||||
*
|
|
||||||
* Defaults to `false`
|
|
||||||
*/
|
|
||||||
clearDraft?: boolean
|
|
||||||
},
|
|
||||||
): Promise<Message> {
|
): Promise<Message> {
|
||||||
const { fromChatId, toChatId, message, ...rest } = params
|
const { toChatId, ...rest } = params
|
||||||
|
|
||||||
const fromPeer = await resolvePeer(client, fromChatId)
|
let msg
|
||||||
|
|
||||||
const msg = await getMessages(client, fromPeer, message)
|
if ('fromChatId' in params) {
|
||||||
|
const fromPeer = await resolvePeer(client, params.fromChatId)
|
||||||
|
|
||||||
if (!msg) {
|
;[msg] = await getMessages(client, fromPeer, params.message)
|
||||||
throw new MtMessageNotFoundError(getMarkedPeerId(fromPeer), message, 'to copy')
|
|
||||||
|
if (!msg) {
|
||||||
|
throw new MtMessageNotFoundError(getMarkedPeerId(fromPeer), params.message, 'to copy')
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
msg = params.message
|
||||||
}
|
}
|
||||||
|
|
||||||
if (msg.raw._ === 'messageService') {
|
if (msg.raw._ === 'messageService') {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { BaseTelegramClient } from '@mtcute/core'
|
import { BaseTelegramClient } from '@mtcute/core'
|
||||||
|
|
||||||
import { InputPeerLike, InputReaction, Message, normalizeInputReaction } from '../../types'
|
import { InputMessageId, InputReaction, Message, normalizeInputMessageId, normalizeInputReaction } from '../../types'
|
||||||
import { assertIsUpdatesGroup } from '../../utils/updates-utils'
|
import { assertIsUpdatesGroup } from '../../utils/updates-utils'
|
||||||
import { resolvePeer } from '../users/resolve-peer'
|
import { resolvePeer } from '../users/resolve-peer'
|
||||||
import { _findMessageInUpdate } from './find-in-update'
|
import { _findMessageInUpdate } from './find-in-update'
|
||||||
|
@ -12,18 +12,15 @@ import { _findMessageInUpdate } from './find-in-update'
|
||||||
*/
|
*/
|
||||||
export async function sendReaction(
|
export async function sendReaction(
|
||||||
client: BaseTelegramClient,
|
client: BaseTelegramClient,
|
||||||
params: {
|
params: InputMessageId & {
|
||||||
/** Chat ID with the message to react to */
|
|
||||||
chatId: InputPeerLike
|
|
||||||
/** Message ID to react to */
|
|
||||||
message: number
|
|
||||||
/** Reaction emoji (or `null` to remove reaction) */
|
/** Reaction emoji (or `null` to remove reaction) */
|
||||||
emoji?: InputReaction | null
|
emoji?: InputReaction | null
|
||||||
/** Whether to use a big reaction */
|
/** Whether to use a big reaction */
|
||||||
big?: boolean
|
big?: boolean
|
||||||
},
|
},
|
||||||
): Promise<Message> {
|
): Promise<Message> {
|
||||||
const { chatId, message, emoji, big } = params
|
const { emoji, big } = params
|
||||||
|
const { chatId, message } = normalizeInputMessageId(params)
|
||||||
|
|
||||||
const reaction = normalizeInputReaction(emoji)
|
const reaction = normalizeInputReaction(emoji)
|
||||||
|
|
||||||
|
|
|
@ -4,18 +4,6 @@ import { InputPeerLike, Message, PeersIndex } from '../../types'
|
||||||
import { assertIsUpdatesGroup } from '../../utils/updates-utils'
|
import { assertIsUpdatesGroup } from '../../utils/updates-utils'
|
||||||
import { resolvePeer } from '../users/resolve-peer'
|
import { resolvePeer } from '../users/resolve-peer'
|
||||||
|
|
||||||
/**
|
|
||||||
* Send s previously scheduled message.
|
|
||||||
*
|
|
||||||
* Note that if the message belongs to a media group,
|
|
||||||
* the entire group will be sent, but only
|
|
||||||
* the first message will be returned (in this overload).
|
|
||||||
*
|
|
||||||
* @param peer Chat where the messages were scheduled
|
|
||||||
* @param id ID of the message
|
|
||||||
*/
|
|
||||||
export async function sendScheduled(client: BaseTelegramClient, peer: InputPeerLike, id: number): Promise<Message>
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send previously scheduled message(s)
|
* Send previously scheduled message(s)
|
||||||
*
|
*
|
||||||
|
@ -26,21 +14,17 @@ export async function sendScheduled(client: BaseTelegramClient, peer: InputPeerL
|
||||||
* @param peer Chat where the messages were scheduled
|
* @param peer Chat where the messages were scheduled
|
||||||
* @param ids ID(s) of the messages
|
* @param ids ID(s) of the messages
|
||||||
*/
|
*/
|
||||||
export async function sendScheduled(client: BaseTelegramClient, peer: InputPeerLike, ids: number[]): Promise<Message[]>
|
|
||||||
|
|
||||||
/** @internal */
|
|
||||||
export async function sendScheduled(
|
export async function sendScheduled(
|
||||||
client: BaseTelegramClient,
|
client: BaseTelegramClient,
|
||||||
peer: InputPeerLike,
|
peer: InputPeerLike,
|
||||||
ids: MaybeArray<number>,
|
ids: MaybeArray<number>,
|
||||||
): Promise<MaybeArray<Message>> {
|
): Promise<Message[]> {
|
||||||
const isSingle = !Array.isArray(ids)
|
if (!Array.isArray(ids)) ids = [ids]
|
||||||
if (isSingle) ids = [ids as number]
|
|
||||||
|
|
||||||
const res = await client.call({
|
const res = await client.call({
|
||||||
_: 'messages.sendScheduledMessages',
|
_: 'messages.sendScheduledMessages',
|
||||||
peer: await resolvePeer(client, peer),
|
peer: await resolvePeer(client, peer),
|
||||||
id: ids as number[],
|
id: ids,
|
||||||
})
|
})
|
||||||
|
|
||||||
assertIsUpdatesGroup('sendScheduled', res)
|
assertIsUpdatesGroup('sendScheduled', res)
|
||||||
|
@ -55,5 +39,5 @@ export async function sendScheduled(
|
||||||
)
|
)
|
||||||
.map((u) => new Message(u.message, peers))
|
.map((u) => new Message(u.message, peers))
|
||||||
|
|
||||||
return isSingle ? msgs[0] : msgs
|
return msgs
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { BaseTelegramClient, getMarkedPeerId, MaybeArray, MtArgumentError, MtTypeAssertionError } from '@mtcute/core'
|
import { BaseTelegramClient, getMarkedPeerId, MaybeArray, MtArgumentError, MtTypeAssertionError } from '@mtcute/core'
|
||||||
import { assertTypeIs } from '@mtcute/core/utils'
|
import { assertTypeIs } from '@mtcute/core/utils'
|
||||||
|
|
||||||
import { InputPeerLike, MtMessageNotFoundError, PeersIndex, Poll } from '../../types'
|
import { InputMessageId, MtMessageNotFoundError, normalizeInputMessageId, PeersIndex, Poll } from '../../types'
|
||||||
import { assertIsUpdatesGroup } from '../../utils/updates-utils'
|
import { assertIsUpdatesGroup } from '../../utils/updates-utils'
|
||||||
import { resolvePeer } from '../users/resolve-peer'
|
import { resolvePeer } from '../users/resolve-peer'
|
||||||
import { getMessages } from './get-messages'
|
import { getMessages } from './get-messages'
|
||||||
|
@ -11,11 +11,7 @@ import { getMessages } from './get-messages'
|
||||||
*/
|
*/
|
||||||
export async function sendVote(
|
export async function sendVote(
|
||||||
client: BaseTelegramClient,
|
client: BaseTelegramClient,
|
||||||
params: {
|
params: InputMessageId & {
|
||||||
/** Chat ID where this poll was found */
|
|
||||||
chatId: InputPeerLike
|
|
||||||
/** Message ID where this poll was found */
|
|
||||||
message: number
|
|
||||||
/**
|
/**
|
||||||
* Selected options, or `null` to retract.
|
* Selected options, or `null` to retract.
|
||||||
* You can pass indexes of the answers or the `Buffer`s
|
* You can pass indexes of the answers or the `Buffer`s
|
||||||
|
@ -25,7 +21,7 @@ export async function sendVote(
|
||||||
options: null | MaybeArray<number | Buffer>
|
options: null | MaybeArray<number | Buffer>
|
||||||
},
|
},
|
||||||
): Promise<Poll> {
|
): Promise<Poll> {
|
||||||
const { chatId, message } = params
|
const { chatId, message } = normalizeInputMessageId(params)
|
||||||
let { options } = params
|
let { options } = params
|
||||||
|
|
||||||
if (options === null) options = []
|
if (options === null) options = []
|
||||||
|
@ -36,7 +32,7 @@ export async function sendVote(
|
||||||
let poll: Poll | undefined = undefined
|
let poll: Poll | undefined = undefined
|
||||||
|
|
||||||
if (options.some((it) => typeof it === 'number')) {
|
if (options.some((it) => typeof it === 'number')) {
|
||||||
const msg = await getMessages(client, peer, message)
|
const [msg] = await getMessages(client, peer, message)
|
||||||
|
|
||||||
if (!msg) {
|
if (!msg) {
|
||||||
throw new MtMessageNotFoundError(getMarkedPeerId(peer), message, 'to vote in')
|
throw new MtMessageNotFoundError(getMarkedPeerId(peer), message, 'to vote in')
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { BaseTelegramClient } from '@mtcute/core'
|
import { BaseTelegramClient } from '@mtcute/core'
|
||||||
|
|
||||||
import { InputPeerLike, MessageEntity } from '../../types'
|
import { InputMessageId, MessageEntity, normalizeInputMessageId } from '../../types'
|
||||||
import { resolvePeer } from '../users/resolve-peer'
|
import { resolvePeer } from '../users/resolve-peer'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -10,21 +10,18 @@ import { resolvePeer } from '../users/resolve-peer'
|
||||||
*/
|
*/
|
||||||
export async function translateMessage(
|
export async function translateMessage(
|
||||||
client: BaseTelegramClient,
|
client: BaseTelegramClient,
|
||||||
params: {
|
params: InputMessageId & {
|
||||||
/** Chat or user ID */
|
|
||||||
chatId: InputPeerLike
|
|
||||||
/** Identifier of the message to translate */
|
|
||||||
messageId: number
|
|
||||||
/** Target language (two-letter ISO 639-1 language code) */
|
/** Target language (two-letter ISO 639-1 language code) */
|
||||||
toLanguage: string
|
toLanguage: string
|
||||||
},
|
},
|
||||||
): Promise<[string, MessageEntity[]] | null> {
|
): Promise<[string, MessageEntity[]] | null> {
|
||||||
const { chatId, messageId, toLanguage } = params
|
const { toLanguage } = params
|
||||||
|
const { chatId, message } = normalizeInputMessageId(params)
|
||||||
|
|
||||||
const res = await client.call({
|
const res = await client.call({
|
||||||
_: 'messages.translateText',
|
_: 'messages.translateText',
|
||||||
peer: await resolvePeer(client, chatId),
|
peer: await resolvePeer(client, chatId),
|
||||||
id: [messageId],
|
id: [message],
|
||||||
toLang: toLanguage,
|
toLang: toLanguage,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { BaseTelegramClient } from '@mtcute/core'
|
import { BaseTelegramClient } from '@mtcute/core'
|
||||||
|
|
||||||
import { InputPeerLike } from '../../types'
|
import { InputMessageId, normalizeInputMessageId } from '../../types'
|
||||||
import { resolvePeer } from '../users/resolve-peer'
|
import { resolvePeer } from '../users/resolve-peer'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -12,15 +12,13 @@ import { resolvePeer } from '../users/resolve-peer'
|
||||||
* @param chatId Chat ID, username, phone number, `"self"` or `"me"`
|
* @param chatId Chat ID, username, phone number, `"self"` or `"me"`
|
||||||
* @param messageId Message ID
|
* @param messageId Message ID
|
||||||
*/
|
*/
|
||||||
export async function unpinMessage(
|
export async function unpinMessage(client: BaseTelegramClient, params: InputMessageId): Promise<void> {
|
||||||
client: BaseTelegramClient,
|
const { chatId, message } = normalizeInputMessageId(params)
|
||||||
chatId: InputPeerLike,
|
|
||||||
messageId: number,
|
|
||||||
): Promise<void> {
|
|
||||||
const res = await client.call({
|
const res = await client.call({
|
||||||
_: 'messages.updatePinnedMessage',
|
_: 'messages.updatePinnedMessage',
|
||||||
peer: await resolvePeer(client, chatId),
|
peer: await resolvePeer(client, chatId),
|
||||||
id: messageId,
|
id: message,
|
||||||
unpin: true,
|
unpin: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -5,40 +5,22 @@ import { InputPeerLike, PeersIndex, Story } from '../../types'
|
||||||
import { resolvePeer } from '../users/resolve-peer'
|
import { resolvePeer } from '../users/resolve-peer'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a single story by its ID
|
* Get one or more stories by their IDs
|
||||||
*
|
|
||||||
* @param peerId Peer ID whose stories to fetch
|
|
||||||
* @param storyId Story ID
|
|
||||||
*/
|
|
||||||
export async function getStoriesById(client: BaseTelegramClient, peerId: InputPeerLike, storyId: number): Promise<Story>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get multiple stories by their IDs
|
|
||||||
*
|
*
|
||||||
* @param peerId Peer ID whose stories to fetch
|
* @param peerId Peer ID whose stories to fetch
|
||||||
* @param storyIds Story IDs
|
* @param storyIds Story IDs
|
||||||
*/
|
*/
|
||||||
export async function getStoriesById(
|
|
||||||
client: BaseTelegramClient,
|
|
||||||
peerId: InputPeerLike,
|
|
||||||
storyIds: number[],
|
|
||||||
): Promise<Story[]>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
export async function getStoriesById(
|
export async function getStoriesById(
|
||||||
client: BaseTelegramClient,
|
client: BaseTelegramClient,
|
||||||
peerId: InputPeerLike,
|
peerId: InputPeerLike,
|
||||||
storyIds: MaybeArray<number>,
|
storyIds: MaybeArray<number>,
|
||||||
): Promise<MaybeArray<Story>> {
|
): Promise<Story[]> {
|
||||||
const single = !Array.isArray(storyIds)
|
if (!Array.isArray(storyIds)) storyIds = [storyIds]
|
||||||
if (single) storyIds = [storyIds as number]
|
|
||||||
|
|
||||||
const res = await client.call({
|
const res = await client.call({
|
||||||
_: 'stories.getStoriesByID',
|
_: 'stories.getStoriesByID',
|
||||||
peer: await resolvePeer(client, peerId),
|
peer: await resolvePeer(client, peerId),
|
||||||
id: storyIds as number[],
|
id: storyIds,
|
||||||
})
|
})
|
||||||
|
|
||||||
const peers = PeersIndex.from(res)
|
const peers = PeersIndex.from(res)
|
||||||
|
@ -49,5 +31,5 @@ export async function getStoriesById(
|
||||||
return new Story(it, peers)
|
return new Story(it, peers)
|
||||||
})
|
})
|
||||||
|
|
||||||
return single ? stories[0] : stories
|
return stories
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,46 +3,27 @@ import { BaseTelegramClient, MaybeArray } from '@mtcute/core'
|
||||||
import { InputPeerLike, PeersIndex, StoryInteractions } from '../../types'
|
import { InputPeerLike, PeersIndex, StoryInteractions } from '../../types'
|
||||||
import { resolvePeer } from '../users/resolve-peer'
|
import { resolvePeer } from '../users/resolve-peer'
|
||||||
|
|
||||||
/**
|
|
||||||
* Get brief information about story interactions.
|
|
||||||
*/
|
|
||||||
export async function getStoriesInteractions(
|
|
||||||
client: BaseTelegramClient,
|
|
||||||
peerId: InputPeerLike,
|
|
||||||
storyId: number,
|
|
||||||
): Promise<StoryInteractions>
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get brief information about stories interactions.
|
* Get brief information about stories interactions.
|
||||||
*
|
*
|
||||||
* The result will be in the same order as the input IDs
|
* The result will be in the same order as the input IDs
|
||||||
*/
|
*/
|
||||||
export async function getStoriesInteractions(
|
|
||||||
client: BaseTelegramClient,
|
|
||||||
peerId: InputPeerLike,
|
|
||||||
storyIds: number[],
|
|
||||||
): Promise<StoryInteractions[]>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
export async function getStoriesInteractions(
|
export async function getStoriesInteractions(
|
||||||
client: BaseTelegramClient,
|
client: BaseTelegramClient,
|
||||||
peerId: InputPeerLike,
|
peerId: InputPeerLike,
|
||||||
storyIds: MaybeArray<number>,
|
storyIds: MaybeArray<number>,
|
||||||
): Promise<MaybeArray<StoryInteractions>> {
|
): Promise<StoryInteractions[]> {
|
||||||
const isSingle = !Array.isArray(storyIds)
|
if (!Array.isArray(storyIds)) storyIds = [storyIds]
|
||||||
if (isSingle) storyIds = [storyIds as number]
|
|
||||||
|
|
||||||
const res = await client.call({
|
const res = await client.call({
|
||||||
_: 'stories.getStoriesViews',
|
_: 'stories.getStoriesViews',
|
||||||
peer: await resolvePeer(client, peerId),
|
peer: await resolvePeer(client, peerId),
|
||||||
id: storyIds as number[],
|
id: storyIds,
|
||||||
})
|
})
|
||||||
|
|
||||||
const peers = PeersIndex.from(res)
|
const peers = PeersIndex.from(res)
|
||||||
|
|
||||||
const infos = res.views.map((it) => new StoryInteractions(it, peers))
|
const infos = res.views.map((it) => new StoryInteractions(it, peers))
|
||||||
|
|
||||||
return isSingle ? infos[0] : infos
|
return infos
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@ import {
|
||||||
tl,
|
tl,
|
||||||
toggleChannelIdMark,
|
toggleChannelIdMark,
|
||||||
} from '@mtcute/core'
|
} from '@mtcute/core'
|
||||||
import { assertTypeIs } from '@mtcute/core/utils'
|
|
||||||
|
|
||||||
import { MtPeerNotFoundError } from '../../types/errors'
|
import { MtPeerNotFoundError } from '../../types/errors'
|
||||||
import { InputPeerLike } from '../../types/peers'
|
import { InputPeerLike } from '../../types/peers'
|
||||||
|
@ -26,10 +25,13 @@ export async function resolvePeer(
|
||||||
peerId: InputPeerLike,
|
peerId: InputPeerLike,
|
||||||
force = false,
|
force = false,
|
||||||
): Promise<tl.TypeInputPeer> {
|
): Promise<tl.TypeInputPeer> {
|
||||||
// for convenience we also accept tl objects directly
|
// for convenience we also accept tl and User/Chat objects directly
|
||||||
if (typeof peerId === 'object') {
|
if (typeof peerId === 'object') {
|
||||||
if (tl.isAnyPeer(peerId)) {
|
if (tl.isAnyPeer(peerId)) {
|
||||||
peerId = getMarkedPeerId(peerId)
|
peerId = getMarkedPeerId(peerId)
|
||||||
|
} else if ('type' in peerId) {
|
||||||
|
// User | Chat
|
||||||
|
return peerId.inputPeer
|
||||||
} else {
|
} else {
|
||||||
return normalizeToInputPeer(peerId)
|
return normalizeToInputPeer(peerId)
|
||||||
}
|
}
|
||||||
|
@ -45,29 +47,17 @@ export async function resolvePeer(
|
||||||
|
|
||||||
peerId = peerId.replace(/[@+\s()]/g, '')
|
peerId = peerId.replace(/[@+\s()]/g, '')
|
||||||
|
|
||||||
|
let res
|
||||||
|
|
||||||
if (peerId.match(/^\d+$/)) {
|
if (peerId.match(/^\d+$/)) {
|
||||||
// phone number
|
// phone number
|
||||||
const fromStorage = await client.storage.getPeerByPhone(peerId)
|
const fromStorage = await client.storage.getPeerByPhone(peerId)
|
||||||
if (fromStorage) return fromStorage
|
if (fromStorage) return fromStorage
|
||||||
|
|
||||||
const res = await client.call({
|
res = await client.call({
|
||||||
_: 'contacts.getContacts',
|
_: 'contacts.resolvePhone',
|
||||||
hash: Long.ZERO,
|
phone: peerId,
|
||||||
})
|
})
|
||||||
|
|
||||||
assertTypeIs('contacts.getContacts', res, 'contacts.contacts')
|
|
||||||
|
|
||||||
const found = res.users.find((it) => (it as tl.RawUser).phone === peerId)
|
|
||||||
|
|
||||||
if (found && found._ === 'user') {
|
|
||||||
return {
|
|
||||||
_: 'inputPeerUser',
|
|
||||||
userId: found.id,
|
|
||||||
accessHash: found.accessHash!,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new MtPeerNotFoundError(`Could not find a peer by phone ${peerId}`)
|
|
||||||
} else {
|
} else {
|
||||||
// username
|
// username
|
||||||
if (!force) {
|
if (!force) {
|
||||||
|
@ -75,64 +65,62 @@ export async function resolvePeer(
|
||||||
if (fromStorage) return fromStorage
|
if (fromStorage) return fromStorage
|
||||||
}
|
}
|
||||||
|
|
||||||
const res = await client.call({
|
res = await client.call({
|
||||||
_: 'contacts.resolveUsername',
|
_: 'contacts.resolveUsername',
|
||||||
username: peerId,
|
username: peerId,
|
||||||
})
|
})
|
||||||
|
|
||||||
if (res.peer._ === 'peerUser') {
|
|
||||||
const id = res.peer.userId
|
|
||||||
|
|
||||||
const found = res.users.find((it) => it.id === id)
|
|
||||||
|
|
||||||
if (found && found._ === 'user') {
|
|
||||||
if (!found.accessHash) {
|
|
||||||
// no access hash, we can't use it
|
|
||||||
// this may happen when bot resolves a username
|
|
||||||
// of a user who hasn't started a conversation with it
|
|
||||||
throw new MtPeerNotFoundError(
|
|
||||||
`Peer (user) with username ${peerId} was found, but it has no access hash`,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
_: 'inputPeerUser',
|
|
||||||
userId: found.id,
|
|
||||||
accessHash: found.accessHash,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (res.peer._ === 'peerChannel') {
|
|
||||||
const id = res.peer.channelId
|
|
||||||
const found = res.chats.find((it) => it.id === id)
|
|
||||||
|
|
||||||
if (found) {
|
|
||||||
if (!(found._ === 'channel' || found._ === 'channelForbidden')) {
|
|
||||||
// chats can't have usernames
|
|
||||||
// furthermore, our id is a channel id, so it must be a channel
|
|
||||||
// this should never happen, unless Telegram goes crazy
|
|
||||||
throw new MtTypeAssertionError('contacts.resolveUsername#chats', 'channel', found._)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!found.accessHash) {
|
|
||||||
// shouldn't happen? but just in case
|
|
||||||
throw new MtPeerNotFoundError(
|
|
||||||
`Peer (channel) with username ${peerId} was found, but it has no access hash`,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
_: 'inputPeerChannel',
|
|
||||||
channelId: found.id,
|
|
||||||
accessHash: found.accessHash,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// chats can't have usernames
|
|
||||||
throw new MtTypeAssertionError('contacts.resolveUsername', 'user or channel', res.peer._)
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new MtPeerNotFoundError(`Could not find a peer by username ${peerId}`)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (res.peer._ === 'peerUser') {
|
||||||
|
const id = res.peer.userId
|
||||||
|
|
||||||
|
const found = res.users.find((it) => it.id === id)
|
||||||
|
|
||||||
|
if (found && found._ === 'user') {
|
||||||
|
if (!found.accessHash) {
|
||||||
|
// no access hash, we can't use it
|
||||||
|
// this may happen when bot resolves a username
|
||||||
|
// of a user who hasn't started a conversation with it
|
||||||
|
throw new MtPeerNotFoundError(
|
||||||
|
`Peer (user) with username ${peerId} was found, but it has no access hash`,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
_: 'inputPeerUser',
|
||||||
|
userId: found.id,
|
||||||
|
accessHash: found.accessHash,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (res.peer._ === 'peerChannel') {
|
||||||
|
const id = res.peer.channelId
|
||||||
|
const found = res.chats.find((it) => it.id === id)
|
||||||
|
|
||||||
|
if (found) {
|
||||||
|
if (!(found._ === 'channel' || found._ === 'channelForbidden')) {
|
||||||
|
// chats can't have usernames
|
||||||
|
// furthermore, our id is a channel id, so it must be a channel
|
||||||
|
// this should never happen, unless Telegram goes crazy
|
||||||
|
throw new MtTypeAssertionError('contacts.resolveUsername#chats', 'channel', found._)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found.accessHash) {
|
||||||
|
// shouldn't happen? but just in case
|
||||||
|
throw new MtPeerNotFoundError(`Peer (channel) with ${peerId} was found, but it has no access hash`)
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
_: 'inputPeerChannel',
|
||||||
|
channelId: found.id,
|
||||||
|
accessHash: found.accessHash,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// chats can't have usernames
|
||||||
|
throw new MtTypeAssertionError('contacts.resolveUsername', 'user or channel', res.peer._)
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new MtPeerNotFoundError(`Could not find a peer by ${peerId}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
const peerType = getBasicPeerType(peerId)
|
const peerType = getBasicPeerType(peerId)
|
||||||
|
@ -171,25 +159,10 @@ export async function resolvePeer(
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case 'chat': {
|
case 'chat': {
|
||||||
// do we really need to make a call?
|
|
||||||
// const id = -peerId
|
|
||||||
// const res = await client.call({
|
|
||||||
// _: 'messages.getChats',
|
|
||||||
// id: [id],
|
|
||||||
// })
|
|
||||||
//
|
|
||||||
// const found = res.chats.find((it) => it.id === id)
|
|
||||||
// if (found && (found._ === 'chat' || found._ === 'chatForbidden'))
|
|
||||||
// return {
|
|
||||||
// _: 'inputPeerChat',
|
|
||||||
// chatId: found.id
|
|
||||||
// }
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
_: 'inputPeerChat',
|
_: 'inputPeerChat',
|
||||||
chatId: -peerId,
|
chatId: -peerId,
|
||||||
}
|
}
|
||||||
// break
|
|
||||||
}
|
}
|
||||||
case 'channel': {
|
case 'channel': {
|
||||||
const id = toggleChannelIdMark(peerId)
|
const id = toggleChannelIdMark(peerId)
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
export * from './dialog'
|
export * from './dialog'
|
||||||
export * from './draft-message'
|
export * from './draft-message'
|
||||||
|
export * from './input-message-id'
|
||||||
export * from './message'
|
export * from './message'
|
||||||
export * from './message-action'
|
export * from './message-action'
|
||||||
export * from './message-entity'
|
export * from './message-entity'
|
||||||
|
|
16
packages/client/src/types/messages/input-message-id.ts
Normal file
16
packages/client/src/types/messages/input-message-id.ts
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
import type { InputPeerLike } from '../peers'
|
||||||
|
import type { Message } from './message'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parameters for methods that accept a message
|
||||||
|
*
|
||||||
|
* Either a message object (in `message` field), or a chat ID and a message ID
|
||||||
|
*/
|
||||||
|
export type InputMessageId = { chatId: InputPeerLike; message: number } | { message: Message }
|
||||||
|
|
||||||
|
/** @internal */
|
||||||
|
export function normalizeInputMessageId(id: InputMessageId) {
|
||||||
|
if ('chatId' in id) return id
|
||||||
|
|
||||||
|
return { chatId: id.message.chat.inputPeer, message: id.message.id }
|
||||||
|
}
|
|
@ -12,6 +12,7 @@ import { parseDocument } from '../media/document-utils'
|
||||||
* Can be one of:
|
* Can be one of:
|
||||||
* - Raw TL object
|
* - Raw TL object
|
||||||
* - Sticker set short name
|
* - Sticker set short name
|
||||||
|
* - {@link StickerSet} object
|
||||||
* - `{ dice: "<emoji>" }` (e.g. `{ dice: "🎲" }`) - Used for fetching animated dice stickers
|
* - `{ dice: "<emoji>" }` (e.g. `{ dice: "🎲" }`) - Used for fetching animated dice stickers
|
||||||
* - `{ system: string }` - for system stickersets:
|
* - `{ system: string }` - for system stickersets:
|
||||||
* - `"animated"` - Animated emojis stickerset
|
* - `"animated"` - Animated emojis stickerset
|
||||||
|
@ -35,6 +36,7 @@ export type InputStickerSet =
|
||||||
| 'default_statuses'
|
| 'default_statuses'
|
||||||
| 'default_topic_icons'
|
| 'default_topic_icons'
|
||||||
}
|
}
|
||||||
|
| StickerSet
|
||||||
| string
|
| string
|
||||||
|
|
||||||
export function normalizeInputStickerSet(input: InputStickerSet): tl.TypeInputStickerSet {
|
export function normalizeInputStickerSet(input: InputStickerSet): tl.TypeInputStickerSet {
|
||||||
|
@ -45,6 +47,7 @@ export function normalizeInputStickerSet(input: InputStickerSet): tl.TypeInputSt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ('_' in input) return input
|
if ('_' in input) return input
|
||||||
|
if (input instanceof StickerSet) return input.inputStickerSet
|
||||||
|
|
||||||
if ('dice' in input) {
|
if ('dice' in input) {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
import { tl } from '@mtcute/core'
|
import { tl } from '@mtcute/core'
|
||||||
|
|
||||||
|
import { Chat } from './chat'
|
||||||
|
import { User } from './user'
|
||||||
|
|
||||||
export * from './chat'
|
export * from './chat'
|
||||||
export * from './chat-event'
|
export * from './chat-event'
|
||||||
export * from './chat-invite-link'
|
export * from './chat-invite-link'
|
||||||
|
@ -21,15 +24,23 @@ export * from './user'
|
||||||
export type PeerType = 'user' | 'bot' | 'group' | 'channel' | 'supergroup'
|
export type PeerType = 'user' | 'bot' | 'group' | 'channel' | 'supergroup'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Type that can be used as an input peer
|
* Type that can be used as an input peer to most of the high-level methods. Can be:
|
||||||
* to most of the high-level methods. Can be:
|
|
||||||
* - `number`, representing peer's marked ID*
|
* - `number`, representing peer's marked ID*
|
||||||
* - `string`, representing peer's username (w/out preceding `@`)
|
* - `string`, representing peer's username (without preceding `@`)
|
||||||
* - `string`, representing user's phone number (only for contacts)
|
* - `string`, representing user's phone number
|
||||||
* - `"me"` and `"self"` which will be replaced with the current user/bot
|
* - `"me"` and `"self"` which will be replaced with the current user/bot
|
||||||
|
* - `Chat` or `User` object
|
||||||
* - Raw TL object
|
* - Raw TL object
|
||||||
*
|
*
|
||||||
* > Telegram has moved to int64 IDs. Though, Levin [has confirmed](https://t.me/tdlibchat/25075)
|
* > * Telegram has moved to int64 IDs. Though, Levin [has confirmed](https://t.me/tdlibchat/25071)
|
||||||
* > that new IDs *will* still fit into int53, meaning JS integers are fine.
|
* > that new IDs *will* still fit into int53, meaning JS integers are fine.
|
||||||
*/
|
*/
|
||||||
export type InputPeerLike = string | number | tl.TypePeer | tl.TypeInputPeer | tl.TypeInputUser | tl.TypeInputChannel
|
export type InputPeerLike =
|
||||||
|
| string
|
||||||
|
| number
|
||||||
|
| tl.TypePeer
|
||||||
|
| tl.TypeInputPeer
|
||||||
|
| tl.TypeInputUser
|
||||||
|
| tl.TypeInputChannel
|
||||||
|
| Chat
|
||||||
|
| User
|
||||||
|
|
Loading…
Reference in a new issue