feat: support business connections
This commit is contained in:
parent
c021f64ed0
commit
2a399532a3
36 changed files with 857 additions and 49 deletions
|
@ -21,3 +21,8 @@ story: StoryUpdate = StoryUpdate
|
||||||
delete_story = DeleteStoryUpdate
|
delete_story = DeleteStoryUpdate
|
||||||
bot_reaction: BotReactionUpdate = BotReactionUpdate
|
bot_reaction: BotReactionUpdate = BotReactionUpdate
|
||||||
bot_reaction_count: BotReactionCountUpdate = BotReactionCountUpdate
|
bot_reaction_count: BotReactionCountUpdate = BotReactionCountUpdate
|
||||||
|
business_connection: BusinessConnectionUpdate = BusinessConnection
|
||||||
|
new_business_message = BusinessMessage + State in BusinessMessageContext
|
||||||
|
edit_business_message = BusinessMessage + State in BusinessMessageContext
|
||||||
|
business_message_group = BusinessMessage[] + State in BusinessMessageContext
|
||||||
|
delete_business_message = DeleteBusinessMessageUpdate
|
|
@ -183,6 +183,7 @@ import { deleteBusinessChatLink, editBusinessChatLink } from './methods/premium/
|
||||||
import { getBoostStats } from './methods/premium/get-boost-stats.js'
|
import { getBoostStats } from './methods/premium/get-boost-stats.js'
|
||||||
import { getBoosts } from './methods/premium/get-boosts.js'
|
import { getBoosts } from './methods/premium/get-boosts.js'
|
||||||
import { getBusinessChatLinks } from './methods/premium/get-business-chat-links.js'
|
import { getBusinessChatLinks } from './methods/premium/get-business-chat-links.js'
|
||||||
|
import { getBusinessConnection } from './methods/premium/get-business-connection.js'
|
||||||
import { getMyBoostSlots } from './methods/premium/get-my-boost-slots.js'
|
import { getMyBoostSlots } from './methods/premium/get-my-boost-slots.js'
|
||||||
import { iterBoosters } from './methods/premium/iter-boosters.js'
|
import { iterBoosters } from './methods/premium/iter-boosters.js'
|
||||||
import { setBusinessIntro } from './methods/premium/set-business-intro.js'
|
import { setBusinessIntro } from './methods/premium/set-business-intro.js'
|
||||||
|
@ -255,6 +256,8 @@ import {
|
||||||
BotReactionUpdate,
|
BotReactionUpdate,
|
||||||
BotStoppedUpdate,
|
BotStoppedUpdate,
|
||||||
BusinessChatLink,
|
BusinessChatLink,
|
||||||
|
BusinessConnection,
|
||||||
|
BusinessMessage,
|
||||||
BusinessWorkHoursDay,
|
BusinessWorkHoursDay,
|
||||||
CallbackQuery,
|
CallbackQuery,
|
||||||
Chat,
|
Chat,
|
||||||
|
@ -267,6 +270,7 @@ import {
|
||||||
ChatPreview,
|
ChatPreview,
|
||||||
ChosenInlineResult,
|
ChosenInlineResult,
|
||||||
CollectibleInfo,
|
CollectibleInfo,
|
||||||
|
DeleteBusinessMessageUpdate,
|
||||||
DeleteMessageUpdate,
|
DeleteMessageUpdate,
|
||||||
DeleteStoryUpdate,
|
DeleteStoryUpdate,
|
||||||
Dialog,
|
Dialog,
|
||||||
|
@ -524,6 +528,41 @@ export interface TelegramClient extends ITelegramClient {
|
||||||
* @param handler Bot reaction count update handler
|
* @param handler Bot reaction count update handler
|
||||||
*/
|
*/
|
||||||
on(name: 'bot_reaction_count', handler: (upd: BotReactionCountUpdate) => void): this
|
on(name: 'bot_reaction_count', handler: (upd: BotReactionCountUpdate) => void): this
|
||||||
|
/**
|
||||||
|
* Register a business connection update handler
|
||||||
|
*
|
||||||
|
* @param name Event name
|
||||||
|
* @param handler Business connection update handler
|
||||||
|
*/
|
||||||
|
on(name: 'business_connection', handler: (upd: BusinessConnection) => void): this
|
||||||
|
/**
|
||||||
|
* Register a new business message handler
|
||||||
|
*
|
||||||
|
* @param name Event name
|
||||||
|
* @param handler New business message handler
|
||||||
|
*/
|
||||||
|
on(name: 'new_business_message', handler: (upd: BusinessMessage) => void): this
|
||||||
|
/**
|
||||||
|
* Register an edit business message handler
|
||||||
|
*
|
||||||
|
* @param name Event name
|
||||||
|
* @param handler Edit business message handler
|
||||||
|
*/
|
||||||
|
on(name: 'edit_business_message', handler: (upd: BusinessMessage) => void): this
|
||||||
|
/**
|
||||||
|
* Register a business message group handler
|
||||||
|
*
|
||||||
|
* @param name Event name
|
||||||
|
* @param handler Business message group handler
|
||||||
|
*/
|
||||||
|
on(name: 'business_message_group', handler: (upd: BusinessMessage[]) => void): this
|
||||||
|
/**
|
||||||
|
* Register a delete business message handler
|
||||||
|
*
|
||||||
|
* @param name Event name
|
||||||
|
* @param handler Delete business message handler
|
||||||
|
*/
|
||||||
|
on(name: 'delete_business_message', handler: (upd: DeleteBusinessMessageUpdate) => void): this
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
on(name: string, handler: (...args: any[]) => void): this
|
on(name: string, handler: (...args: any[]) => void): this
|
||||||
|
@ -2338,6 +2377,7 @@ export interface TelegramClient extends ITelegramClient {
|
||||||
params?: {
|
params?: {
|
||||||
progressCallback?: (uploaded: number, total: number) => void
|
progressCallback?: (uploaded: number, total: number) => void
|
||||||
uploadPeer?: tl.TypeInputPeer
|
uploadPeer?: tl.TypeInputPeer
|
||||||
|
businessConnectionId?: string
|
||||||
},
|
},
|
||||||
uploadMedia?: boolean,
|
uploadMedia?: boolean,
|
||||||
): Promise<tl.TypeInputMedia>
|
): Promise<tl.TypeInputMedia>
|
||||||
|
@ -3123,6 +3163,8 @@ export interface TelegramClient extends ITelegramClient {
|
||||||
* client render the preview above the caption and not below.
|
* client render the preview above the caption and not below.
|
||||||
*/
|
*/
|
||||||
invertMedia?: boolean
|
invertMedia?: boolean
|
||||||
|
|
||||||
|
businessConnectionId?: string
|
||||||
},
|
},
|
||||||
): Promise<Message>
|
): Promise<Message>
|
||||||
/**
|
/**
|
||||||
|
@ -4009,6 +4051,11 @@ export interface TelegramClient extends ITelegramClient {
|
||||||
*/
|
*/
|
||||||
progress?: number
|
progress?: number
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unique identifier of the business connection on behalf of which the action will be sent
|
||||||
|
*/
|
||||||
|
businessConnectionId?: string
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For comment threads, ID of the thread (i.e. top message)
|
* For comment threads, ID of the thread (i.e. top message)
|
||||||
*/
|
*/
|
||||||
|
@ -4263,6 +4310,15 @@ export interface TelegramClient extends ITelegramClient {
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
getBusinessChatLinks(): Promise<BusinessChatLink[]>
|
getBusinessChatLinks(): Promise<BusinessChatLink[]>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get information about the connection of the bot with a business account
|
||||||
|
*
|
||||||
|
* **Available**: 🤖 bots only
|
||||||
|
*
|
||||||
|
* @param connectionId ID of the business connection
|
||||||
|
*/
|
||||||
|
getBusinessConnection(connectionId: string): Promise<BusinessConnection>
|
||||||
/**
|
/**
|
||||||
* Get boost slots information of the current user.
|
* Get boost slots information of the current user.
|
||||||
*
|
*
|
||||||
|
@ -5935,6 +5991,9 @@ TelegramClient.prototype.getBoosts = function (...args) {
|
||||||
TelegramClient.prototype.getBusinessChatLinks = function (...args) {
|
TelegramClient.prototype.getBusinessChatLinks = function (...args) {
|
||||||
return getBusinessChatLinks(this._client, ...args)
|
return getBusinessChatLinks(this._client, ...args)
|
||||||
}
|
}
|
||||||
|
TelegramClient.prototype.getBusinessConnection = function (...args) {
|
||||||
|
return getBusinessConnection(this._client, ...args)
|
||||||
|
}
|
||||||
TelegramClient.prototype.getMyBoostSlots = function (...args) {
|
TelegramClient.prototype.getMyBoostSlots = function (...args) {
|
||||||
return getMyBoostSlots(this._client, ...args)
|
return getMyBoostSlots(this._client, ...args)
|
||||||
}
|
}
|
||||||
|
|
|
@ -199,6 +199,7 @@ export { deleteBusinessChatLink } from './methods/premium/edit-business-chat-lin
|
||||||
export { getBoostStats } from './methods/premium/get-boost-stats.js'
|
export { getBoostStats } from './methods/premium/get-boost-stats.js'
|
||||||
export { getBoosts } from './methods/premium/get-boosts.js'
|
export { getBoosts } from './methods/premium/get-boosts.js'
|
||||||
export { getBusinessChatLinks } from './methods/premium/get-business-chat-links.js'
|
export { getBusinessChatLinks } from './methods/premium/get-business-chat-links.js'
|
||||||
|
export { getBusinessConnection } from './methods/premium/get-business-connection.js'
|
||||||
export { getMyBoostSlots } from './methods/premium/get-my-boost-slots.js'
|
export { getMyBoostSlots } from './methods/premium/get-my-boost-slots.js'
|
||||||
export { iterBoosters } from './methods/premium/iter-boosters.js'
|
export { iterBoosters } from './methods/premium/iter-boosters.js'
|
||||||
export { setBusinessIntro } from './methods/premium/set-business-intro.js'
|
export { setBusinessIntro } from './methods/premium/set-business-intro.js'
|
||||||
|
|
|
@ -27,6 +27,8 @@ import {
|
||||||
BotReactionUpdate,
|
BotReactionUpdate,
|
||||||
BotStoppedUpdate,
|
BotStoppedUpdate,
|
||||||
BusinessChatLink,
|
BusinessChatLink,
|
||||||
|
BusinessConnection,
|
||||||
|
BusinessMessage,
|
||||||
BusinessWorkHoursDay,
|
BusinessWorkHoursDay,
|
||||||
CallbackQuery,
|
CallbackQuery,
|
||||||
Chat,
|
Chat,
|
||||||
|
@ -39,6 +41,7 @@ import {
|
||||||
ChatPreview,
|
ChatPreview,
|
||||||
ChosenInlineResult,
|
ChosenInlineResult,
|
||||||
CollectibleInfo,
|
CollectibleInfo,
|
||||||
|
DeleteBusinessMessageUpdate,
|
||||||
DeleteMessageUpdate,
|
DeleteMessageUpdate,
|
||||||
DeleteStoryUpdate,
|
DeleteStoryUpdate,
|
||||||
Dialog,
|
Dialog,
|
||||||
|
|
|
@ -28,6 +28,7 @@ export async function _normalizeInputMedia(
|
||||||
params: {
|
params: {
|
||||||
progressCallback?: (uploaded: number, total: number) => void
|
progressCallback?: (uploaded: number, total: number) => void
|
||||||
uploadPeer?: tl.TypeInputPeer
|
uploadPeer?: tl.TypeInputPeer
|
||||||
|
businessConnectionId?: string
|
||||||
} = {},
|
} = {},
|
||||||
uploadMedia = false,
|
uploadMedia = false,
|
||||||
): Promise<tl.TypeInputMedia> {
|
): Promise<tl.TypeInputMedia> {
|
||||||
|
@ -254,6 +255,7 @@ export async function _normalizeInputMedia(
|
||||||
_: 'messages.uploadMedia',
|
_: 'messages.uploadMedia',
|
||||||
peer: uploadPeer,
|
peer: uploadPeer,
|
||||||
media: inputMedia,
|
media: inputMedia,
|
||||||
|
businessConnectionId: params.businessConnectionId,
|
||||||
})
|
})
|
||||||
|
|
||||||
if (photo) {
|
if (photo) {
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
import { tl } from '@mtcute/tl'
|
||||||
|
|
||||||
|
import { RpcCallOptions } from '../../../network/network-manager.js'
|
||||||
|
import { LruMap } from '../../../utils/lru-map.js'
|
||||||
|
import { ITelegramClient } from '../../client.types.js'
|
||||||
|
import { getBusinessConnection } from '../premium/get-business-connection.js'
|
||||||
|
|
||||||
|
// temporary solution
|
||||||
|
// todo – rework once we have either a more generic caching solution
|
||||||
|
const DC_MAP_SYMBOL = Symbol('dcMap')
|
||||||
|
|
||||||
|
const getDcMap = (client: ITelegramClient): LruMap<string, number> => {
|
||||||
|
const client_ = client as typeof client & { [DC_MAP_SYMBOL]?: LruMap<string, number> }
|
||||||
|
|
||||||
|
if (!client_[DC_MAP_SYMBOL]) {
|
||||||
|
client_[DC_MAP_SYMBOL] = new LruMap(50)
|
||||||
|
}
|
||||||
|
|
||||||
|
return client_[DC_MAP_SYMBOL]
|
||||||
|
}
|
||||||
|
|
||||||
|
// @available=both
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
export async function _maybeInvokeWithBusinessConnection<T extends tl.RpcMethod>(
|
||||||
|
client: ITelegramClient,
|
||||||
|
businessConnectionId: string | undefined,
|
||||||
|
request: T,
|
||||||
|
params?: RpcCallOptions,
|
||||||
|
): Promise<tl.RpcCallReturn[T['_']]> {
|
||||||
|
if (!businessConnectionId) {
|
||||||
|
return client.call(request, params)
|
||||||
|
}
|
||||||
|
|
||||||
|
const dcMap = getDcMap(client)
|
||||||
|
|
||||||
|
if (!dcMap.has(businessConnectionId)) {
|
||||||
|
const res = await getBusinessConnection(client, businessConnectionId)
|
||||||
|
|
||||||
|
dcMap.set(businessConnectionId, res.dcId)
|
||||||
|
}
|
||||||
|
|
||||||
|
const dcId = dcMap.get(businessConnectionId)!
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
||||||
|
return client.call(
|
||||||
|
{
|
||||||
|
_: 'invokeWithBusinessConnection',
|
||||||
|
connectionId: businessConnectionId,
|
||||||
|
query: request,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
...params,
|
||||||
|
localMigrate: true, // just in case
|
||||||
|
dcId,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
|
@ -13,6 +13,7 @@ import {
|
||||||
import { _normalizeInputMedia } from '../files/normalize-input-media.js'
|
import { _normalizeInputMedia } from '../files/normalize-input-media.js'
|
||||||
import { _normalizeInputText } from '../misc/normalize-text.js'
|
import { _normalizeInputText } from '../misc/normalize-text.js'
|
||||||
import { resolvePeer } from '../users/resolve-peer.js'
|
import { resolvePeer } from '../users/resolve-peer.js'
|
||||||
|
import { _maybeInvokeWithBusinessConnection } from './_business-connection.js'
|
||||||
import { _findMessageInUpdate } from './find-in-update.js'
|
import { _findMessageInUpdate } from './find-in-update.js'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -75,6 +76,8 @@ export async function editMessage(
|
||||||
* client render the preview above the caption and not below.
|
* client render the preview above the caption and not below.
|
||||||
*/
|
*/
|
||||||
invertMedia?: boolean
|
invertMedia?: boolean
|
||||||
|
|
||||||
|
businessConnectionId?: string
|
||||||
},
|
},
|
||||||
): Promise<Message> {
|
): Promise<Message> {
|
||||||
const { chatId, message } = normalizeInputMessageId(params)
|
const { chatId, message } = normalizeInputMessageId(params)
|
||||||
|
@ -96,7 +99,7 @@ export async function editMessage(
|
||||||
[content, entities] = await _normalizeInputText(client, params.text)
|
[content, entities] = await _normalizeInputText(client, params.text)
|
||||||
}
|
}
|
||||||
|
|
||||||
const res = await client.call({
|
const res = await _maybeInvokeWithBusinessConnection(client, params.businessConnectionId, {
|
||||||
_: 'messages.editMessage',
|
_: 'messages.editMessage',
|
||||||
id: message,
|
id: message,
|
||||||
peer: await resolvePeer(client, chatId),
|
peer: await resolvePeer(client, chatId),
|
||||||
|
|
|
@ -57,14 +57,23 @@ export function _findMessageInUpdate(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isEdit) {
|
if (isEdit) {
|
||||||
if (!(u._ === 'updateEditMessage' || u._ === 'updateEditChannelMessage')) continue
|
if (
|
||||||
|
!(
|
||||||
|
u._ === 'updateEditMessage' ||
|
||||||
|
u._ === 'updateEditChannelMessage' ||
|
||||||
|
u._ === 'updateBotEditBusinessMessage'
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (
|
if (
|
||||||
!(
|
!(
|
||||||
u._ === 'updateNewMessage' ||
|
u._ === 'updateNewMessage' ||
|
||||||
u._ === 'updateNewChannelMessage' ||
|
u._ === 'updateNewChannelMessage' ||
|
||||||
u._ === 'updateNewScheduledMessage' ||
|
u._ === 'updateNewScheduledMessage' ||
|
||||||
u._ === 'updateQuickReplyMessage'
|
u._ === 'updateQuickReplyMessage' ||
|
||||||
|
u._ === 'updateBotNewBusinessMessage'
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
continue
|
continue
|
||||||
|
|
|
@ -111,6 +111,12 @@ export interface CommonSendParams {
|
||||||
* to the client's update handler.
|
* to the client's update handler.
|
||||||
*/
|
*/
|
||||||
shouldDispatch?: true
|
shouldDispatch?: true
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unique identifier of the business connection on behalf of which
|
||||||
|
* the message will be sent
|
||||||
|
*/
|
||||||
|
businessConnectionId?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -9,6 +9,7 @@ import { assertIsUpdatesGroup } from '../../updates/utils.js'
|
||||||
import { _normalizeInputMedia } from '../files/normalize-input-media.js'
|
import { _normalizeInputMedia } from '../files/normalize-input-media.js'
|
||||||
import { _normalizeInputText } from '../misc/normalize-text.js'
|
import { _normalizeInputText } from '../misc/normalize-text.js'
|
||||||
import { resolvePeer } from '../users/resolve-peer.js'
|
import { resolvePeer } from '../users/resolve-peer.js'
|
||||||
|
import { _maybeInvokeWithBusinessConnection } from './_business-connection.js'
|
||||||
import { _getDiscussionMessage } from './get-discussion-message.js'
|
import { _getDiscussionMessage } from './get-discussion-message.js'
|
||||||
import { _processCommonSendParameters, CommonSendParams } from './send-common.js'
|
import { _processCommonSendParameters, CommonSendParams } from './send-common.js'
|
||||||
|
|
||||||
|
@ -77,6 +78,7 @@ export async function sendMediaGroup(
|
||||||
// but otherwise Telegram throws MEDIA_INVALID
|
// but otherwise Telegram throws MEDIA_INVALID
|
||||||
// fuck my life
|
// fuck my life
|
||||||
uploadPeer: peer,
|
uploadPeer: peer,
|
||||||
|
businessConnectionId: params.businessConnectionId,
|
||||||
},
|
},
|
||||||
true,
|
true,
|
||||||
)
|
)
|
||||||
|
@ -97,7 +99,9 @@ export async function sendMediaGroup(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const res = await client.call(
|
const res = await _maybeInvokeWithBusinessConnection(
|
||||||
|
client,
|
||||||
|
params.businessConnectionId,
|
||||||
{
|
{
|
||||||
_: 'messages.sendMultiMedia',
|
_: 'messages.sendMultiMedia',
|
||||||
peer,
|
peer,
|
||||||
|
|
|
@ -8,6 +8,7 @@ import { InputPeerLike } from '../../types/peers/index.js'
|
||||||
import { _normalizeInputMedia } from '../files/normalize-input-media.js'
|
import { _normalizeInputMedia } from '../files/normalize-input-media.js'
|
||||||
import { _normalizeInputText } from '../misc/normalize-text.js'
|
import { _normalizeInputText } from '../misc/normalize-text.js'
|
||||||
import { resolvePeer } from '../users/resolve-peer.js'
|
import { resolvePeer } from '../users/resolve-peer.js'
|
||||||
|
import { _maybeInvokeWithBusinessConnection } from './_business-connection.js'
|
||||||
import { _findMessageInUpdate } from './find-in-update.js'
|
import { _findMessageInUpdate } from './find-in-update.js'
|
||||||
import { _getDiscussionMessage } from './get-discussion-message.js'
|
import { _getDiscussionMessage } from './get-discussion-message.js'
|
||||||
import { _processCommonSendParameters, CommonSendParams } from './send-common.js'
|
import { _processCommonSendParameters, CommonSendParams } from './send-common.js'
|
||||||
|
@ -87,7 +88,9 @@ export async function sendMedia(
|
||||||
)
|
)
|
||||||
|
|
||||||
const randomId = randomLong()
|
const randomId = randomLong()
|
||||||
const res = await client.call(
|
const res = await _maybeInvokeWithBusinessConnection(
|
||||||
|
client,
|
||||||
|
params.businessConnectionId,
|
||||||
{
|
{
|
||||||
_: 'messages.sendMedia',
|
_: 'messages.sendMedia',
|
||||||
peer,
|
peer,
|
||||||
|
|
|
@ -13,6 +13,7 @@ import { inputPeerToPeer } from '../../utils/peer-utils.js'
|
||||||
import { _getRawPeerBatched } from '../chats/batched-queries.js'
|
import { _getRawPeerBatched } from '../chats/batched-queries.js'
|
||||||
import { _normalizeInputText } from '../misc/normalize-text.js'
|
import { _normalizeInputText } from '../misc/normalize-text.js'
|
||||||
import { resolvePeer } from '../users/resolve-peer.js'
|
import { resolvePeer } from '../users/resolve-peer.js'
|
||||||
|
import { _maybeInvokeWithBusinessConnection } from './_business-connection.js'
|
||||||
import { _findMessageInUpdate } from './find-in-update.js'
|
import { _findMessageInUpdate } from './find-in-update.js'
|
||||||
import { _getDiscussionMessage } from './get-discussion-message.js'
|
import { _getDiscussionMessage } from './get-discussion-message.js'
|
||||||
import { _processCommonSendParameters, CommonSendParams } from './send-common.js'
|
import { _processCommonSendParameters, CommonSendParams } from './send-common.js'
|
||||||
|
@ -61,7 +62,9 @@ export async function sendText(
|
||||||
)
|
)
|
||||||
|
|
||||||
const randomId = randomLong()
|
const randomId = randomLong()
|
||||||
const res = await client.call(
|
const res = await _maybeInvokeWithBusinessConnection(
|
||||||
|
client,
|
||||||
|
params.businessConnectionId,
|
||||||
{
|
{
|
||||||
_: 'messages.sendMessage',
|
_: 'messages.sendMessage',
|
||||||
peer,
|
peer,
|
||||||
|
|
|
@ -5,6 +5,7 @@ import { assertTrue } from '../../../utils/type-assertions.js'
|
||||||
import { ITelegramClient } from '../../client.types.js'
|
import { ITelegramClient } from '../../client.types.js'
|
||||||
import { InputPeerLike, TypingStatus } from '../../types/index.js'
|
import { InputPeerLike, TypingStatus } from '../../types/index.js'
|
||||||
import { resolvePeer } from '../users/resolve-peer.js'
|
import { resolvePeer } from '../users/resolve-peer.js'
|
||||||
|
import { _maybeInvokeWithBusinessConnection } from './_business-connection.js'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends a current user/bot typing event
|
* Sends a current user/bot typing event
|
||||||
|
@ -28,6 +29,11 @@ export async function sendTyping(
|
||||||
*/
|
*/
|
||||||
progress?: number
|
progress?: number
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unique identifier of the business connection on behalf of which the action will be sent
|
||||||
|
*/
|
||||||
|
businessConnectionId?: string
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For comment threads, ID of the thread (i.e. top message)
|
* For comment threads, ID of the thread (i.e. top message)
|
||||||
*/
|
*/
|
||||||
|
@ -91,7 +97,7 @@ export async function sendTyping(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const r = await client.call({
|
const r = await _maybeInvokeWithBusinessConnection(client, params?.businessConnectionId, {
|
||||||
_: 'messages.setTyping',
|
_: 'messages.setTyping',
|
||||||
peer: await resolvePeer(client, chatId),
|
peer: await resolvePeer(client, chatId),
|
||||||
action: status,
|
action: status,
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
import { assertTypeIs } from '../../../utils/type-assertions.js'
|
||||||
|
import { ITelegramClient } from '../../client.types.js'
|
||||||
|
import { PeersIndex } from '../../types/peers/peers-index.js'
|
||||||
|
import { BusinessConnection } from '../../types/premium/business-connection.js'
|
||||||
|
import { assertIsUpdatesGroup } from '../../updates/utils.js'
|
||||||
|
|
||||||
|
// @available=bot
|
||||||
|
/**
|
||||||
|
* Get information about the connection of the bot with a business account
|
||||||
|
*
|
||||||
|
* @param connectionId ID of the business connection
|
||||||
|
*/
|
||||||
|
export async function getBusinessConnection(
|
||||||
|
client: ITelegramClient,
|
||||||
|
connectionId: string,
|
||||||
|
): Promise<BusinessConnection> {
|
||||||
|
const res = await client.call({
|
||||||
|
_: 'account.getBotBusinessConnection',
|
||||||
|
connectionId,
|
||||||
|
})
|
||||||
|
|
||||||
|
assertIsUpdatesGroup('account.getBotBusinessConnection', res)
|
||||||
|
assertTypeIs('account.getBotBusinessConnection', res.updates[0], 'updateBotBusinessConnect')
|
||||||
|
|
||||||
|
const peers = PeersIndex.from(res)
|
||||||
|
|
||||||
|
return new BusinessConnection(res.updates[0].connection, peers)
|
||||||
|
}
|
|
@ -194,21 +194,7 @@ export class Dialog {
|
||||||
* Chat that this dialog represents
|
* Chat that this dialog represents
|
||||||
*/
|
*/
|
||||||
get chat(): Chat {
|
get chat(): Chat {
|
||||||
const peer = this.raw.peer
|
return Chat._parseFromPeer(this.raw.peer, this._peers)
|
||||||
|
|
||||||
let chat
|
|
||||||
|
|
||||||
switch (peer._) {
|
|
||||||
case 'peerChannel':
|
|
||||||
case 'peerChat':
|
|
||||||
chat = this._peers.chat(peer._ === 'peerChannel' ? peer.channelId : peer.chatId)
|
|
||||||
break
|
|
||||||
default:
|
|
||||||
chat = this._peers.user(peer.userId)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Chat(chat)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -253,6 +253,20 @@ export class Message {
|
||||||
return new User(this._peers.user(this.raw.viaBotId))
|
return new User(this._peers.user(this.raw.viaBotId))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If this message was sent by a business bot on behalf of {@link sender},
|
||||||
|
* information about the business bot.
|
||||||
|
*
|
||||||
|
* **Note**: only available to the business account and the bot itself.
|
||||||
|
*/
|
||||||
|
get viaBusinessBot(): User | null {
|
||||||
|
if (this.raw._ === 'messageService' || !this.raw.viaBusinessBotId) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return new User(this._peers.user(this.raw.viaBusinessBotId))
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Message text or media caption.
|
* Message text or media caption.
|
||||||
*
|
*
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
import { tl } from '@mtcute/tl'
|
||||||
|
|
||||||
|
import { makeInspectable } from '../../utils/inspectable.js'
|
||||||
|
import { memoizeGetters } from '../../utils/memoize.js'
|
||||||
|
import { PeersIndex } from '../peers/peers-index.js'
|
||||||
|
import { User } from '../peers/user.js'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Describes the connection of the bot with a business account.
|
||||||
|
*/
|
||||||
|
export class BusinessConnection {
|
||||||
|
constructor(
|
||||||
|
readonly raw: tl.TypeBotBusinessConnection,
|
||||||
|
readonly _peers: PeersIndex,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
/** Whether the connection was removed by the user */
|
||||||
|
get isRemoved(): boolean {
|
||||||
|
return this.raw.disabled!
|
||||||
|
}
|
||||||
|
|
||||||
|
/** ID of the connection */
|
||||||
|
get id(): string {
|
||||||
|
return this.raw.connectionId
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Datacenter ID of the connected user */
|
||||||
|
get dcId(): number {
|
||||||
|
return this.raw.dcId
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Date when the connection was created */
|
||||||
|
get date(): Date {
|
||||||
|
return new Date(this.raw.date * 1000)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Whether the bot can reply on behalf of the user */
|
||||||
|
get canReply(): boolean {
|
||||||
|
return this.raw.canReply!
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Business account user that created the business connection */
|
||||||
|
get user(): User {
|
||||||
|
return new User(this._peers.user(this.raw.userId))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
makeInspectable(BusinessConnection)
|
||||||
|
memoizeGetters(BusinessConnection, ['user'])
|
|
@ -3,5 +3,6 @@ export * from './boost-slot.js'
|
||||||
export * from './boost-stats.js'
|
export * from './boost-stats.js'
|
||||||
export * from './business-account.js'
|
export * from './business-account.js'
|
||||||
export * from './business-chat-link.js'
|
export * from './business-chat-link.js'
|
||||||
|
export * from './business-connection.js'
|
||||||
export * from './business-intro.js'
|
export * from './business-intro.js'
|
||||||
export * from './business-work-hours.js'
|
export * from './business-work-hours.js'
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
import { tl } from '@mtcute/tl'
|
||||||
|
|
||||||
|
import { Message } from '../messages/message.js'
|
||||||
|
import { PeersIndex } from '../peers/peers-index.js'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update about a new or edited business message.
|
||||||
|
*/
|
||||||
|
export class BusinessMessage extends Message {
|
||||||
|
constructor(
|
||||||
|
readonly update: tl.RawUpdateBotNewBusinessMessage | tl.RawUpdateBotEditBusinessMessage,
|
||||||
|
readonly _peers: PeersIndex,
|
||||||
|
) {
|
||||||
|
super(update.message, _peers)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unique identifier of the business connection from which the message was received.
|
||||||
|
*/
|
||||||
|
get connectionId(): string {
|
||||||
|
return this.update.connectionId
|
||||||
|
}
|
||||||
|
|
||||||
|
get groupedIdUnique(): string {
|
||||||
|
return `${super.groupedIdUnique}|${this.update.connectionId}`
|
||||||
|
}
|
||||||
|
|
||||||
|
/** The replied message (if any) */
|
||||||
|
get replyTo(): Message | null {
|
||||||
|
return this.update.replyToMessage ? new Message(this.update.replyToMessage, this._peers) : null
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
import { tl } from '@mtcute/tl'
|
||||||
|
|
||||||
|
import { makeInspectable } from '../../utils/index.js'
|
||||||
|
import { memoizeGetters } from '../../utils/memoize.js'
|
||||||
|
import { Chat } from '../peers/chat.js'
|
||||||
|
import { PeersIndex } from '../peers/peers-index.js'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* One or more messages were deleted from a connected business account
|
||||||
|
*/
|
||||||
|
export class DeleteBusinessMessageUpdate {
|
||||||
|
constructor(
|
||||||
|
readonly raw: tl.RawUpdateBotDeleteBusinessMessage,
|
||||||
|
readonly _peers: PeersIndex,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
/** Unique identifier of the business connection */
|
||||||
|
get connectionId(): string {
|
||||||
|
return this.raw.connectionId
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IDs of the messages which were deleted
|
||||||
|
*/
|
||||||
|
get messageIds(): number[] {
|
||||||
|
return this.raw.messages
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Chat where the messages were deleted
|
||||||
|
*/
|
||||||
|
get chat(): Chat {
|
||||||
|
return Chat._parseFromPeer(this.raw.peer, this._peers)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
makeInspectable(DeleteBusinessMessageUpdate)
|
||||||
|
memoizeGetters(DeleteBusinessMessageUpdate, ['chat'])
|
|
@ -1,4 +1,4 @@
|
||||||
import type { Message } from '../../types/index.js'
|
import type { BusinessConnection, Message } from '../../types/index.js'
|
||||||
import { BotChatJoinRequestUpdate } from './bot-chat-join-request.js'
|
import { BotChatJoinRequestUpdate } from './bot-chat-join-request.js'
|
||||||
import { BotStoppedUpdate } from './bot-stopped.js'
|
import { BotStoppedUpdate } from './bot-stopped.js'
|
||||||
import { CallbackQuery, InlineCallbackQuery } from './callback-query.js'
|
import { CallbackQuery, InlineCallbackQuery } from './callback-query.js'
|
||||||
|
@ -7,7 +7,9 @@ import { ChatMemberUpdate } from './chat-member-update.js'
|
||||||
import { InlineQuery } from './inline-query.js'
|
import { InlineQuery } from './inline-query.js'
|
||||||
export type { ChatMemberUpdateType } from './chat-member-update.js'
|
export type { ChatMemberUpdateType } from './chat-member-update.js'
|
||||||
import { BotReactionCountUpdate, BotReactionUpdate } from './bot-reaction.js'
|
import { BotReactionCountUpdate, BotReactionUpdate } from './bot-reaction.js'
|
||||||
|
import { BusinessMessage } from './business-message.js'
|
||||||
import { ChosenInlineResult } from './chosen-inline-result.js'
|
import { ChosenInlineResult } from './chosen-inline-result.js'
|
||||||
|
import { DeleteBusinessMessageUpdate } from './delete-business-message-update.js'
|
||||||
import { DeleteMessageUpdate } from './delete-message-update.js'
|
import { DeleteMessageUpdate } from './delete-message-update.js'
|
||||||
import { DeleteStoryUpdate } from './delete-story-update.js'
|
import { DeleteStoryUpdate } from './delete-story-update.js'
|
||||||
import { HistoryReadUpdate } from './history-read-update.js'
|
import { HistoryReadUpdate } from './history-read-update.js'
|
||||||
|
@ -23,10 +25,12 @@ export {
|
||||||
BotReactionCountUpdate,
|
BotReactionCountUpdate,
|
||||||
BotReactionUpdate,
|
BotReactionUpdate,
|
||||||
BotStoppedUpdate,
|
BotStoppedUpdate,
|
||||||
|
BusinessMessage,
|
||||||
CallbackQuery,
|
CallbackQuery,
|
||||||
ChatJoinRequestUpdate,
|
ChatJoinRequestUpdate,
|
||||||
ChatMemberUpdate,
|
ChatMemberUpdate,
|
||||||
ChosenInlineResult,
|
ChosenInlineResult,
|
||||||
|
DeleteBusinessMessageUpdate,
|
||||||
DeleteMessageUpdate,
|
DeleteMessageUpdate,
|
||||||
DeleteStoryUpdate,
|
DeleteStoryUpdate,
|
||||||
HistoryReadUpdate,
|
HistoryReadUpdate,
|
||||||
|
@ -64,5 +68,10 @@ export type ParsedUpdate =
|
||||||
| { name: 'delete_story'; data: DeleteStoryUpdate }
|
| { name: 'delete_story'; data: DeleteStoryUpdate }
|
||||||
| { name: 'bot_reaction'; data: BotReactionUpdate }
|
| { name: 'bot_reaction'; data: BotReactionUpdate }
|
||||||
| { name: 'bot_reaction_count'; data: BotReactionCountUpdate }
|
| { name: 'bot_reaction_count'; data: BotReactionCountUpdate }
|
||||||
|
| { name: 'business_connection'; data: BusinessConnection }
|
||||||
|
| { name: 'new_business_message'; data: BusinessMessage }
|
||||||
|
| { name: 'edit_business_message'; data: BusinessMessage }
|
||||||
|
| { name: 'business_message_group'; data: BusinessMessage[] }
|
||||||
|
| { name: 'delete_business_message'; data: DeleteBusinessMessageUpdate }
|
||||||
|
|
||||||
// end-codegen
|
// end-codegen
|
||||||
|
|
|
@ -6,10 +6,13 @@ import {
|
||||||
BotReactionCountUpdate,
|
BotReactionCountUpdate,
|
||||||
BotReactionUpdate,
|
BotReactionUpdate,
|
||||||
BotStoppedUpdate,
|
BotStoppedUpdate,
|
||||||
|
BusinessConnection,
|
||||||
|
BusinessMessage,
|
||||||
CallbackQuery,
|
CallbackQuery,
|
||||||
ChatJoinRequestUpdate,
|
ChatJoinRequestUpdate,
|
||||||
ChatMemberUpdate,
|
ChatMemberUpdate,
|
||||||
ChosenInlineResult,
|
ChosenInlineResult,
|
||||||
|
DeleteBusinessMessageUpdate,
|
||||||
DeleteMessageUpdate,
|
DeleteMessageUpdate,
|
||||||
DeleteStoryUpdate,
|
DeleteStoryUpdate,
|
||||||
HistoryReadUpdate,
|
HistoryReadUpdate,
|
||||||
|
@ -94,6 +97,14 @@ export function _parseUpdate(update: tl.TypeUpdate, peers: PeersIndex): ParsedUp
|
||||||
return { name: 'bot_reaction', data: new BotReactionUpdate(update, peers) }
|
return { name: 'bot_reaction', data: new BotReactionUpdate(update, peers) }
|
||||||
case 'updateBotMessageReactions':
|
case 'updateBotMessageReactions':
|
||||||
return { name: 'bot_reaction_count', data: new BotReactionCountUpdate(update, peers) }
|
return { name: 'bot_reaction_count', data: new BotReactionCountUpdate(update, peers) }
|
||||||
|
case 'updateBotBusinessConnect':
|
||||||
|
return { name: 'business_connection', data: new BusinessConnection(update.connection, peers) }
|
||||||
|
case 'updateBotNewBusinessMessage':
|
||||||
|
return { name: 'new_business_message', data: new BusinessMessage(update, peers) }
|
||||||
|
case 'updateBotEditBusinessMessage':
|
||||||
|
return { name: 'edit_business_message', data: new BusinessMessage(update, peers) }
|
||||||
|
case 'updateBotDeleteBusinessMessage':
|
||||||
|
return { name: 'delete_business_message', data: new DeleteBusinessMessageUpdate(update, peers) }
|
||||||
default:
|
default:
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
|
@ -523,7 +523,8 @@ export class UpdatesManager {
|
||||||
|
|
||||||
switch (upd._) {
|
switch (upd._) {
|
||||||
case 'updateNewMessage':
|
case 'updateNewMessage':
|
||||||
case 'updateNewChannelMessage': {
|
case 'updateNewChannelMessage':
|
||||||
|
case 'updateBotNewBusinessMessage': {
|
||||||
const channelId = upd.message.peerId?._ === 'peerChannel' ? upd.message.peerId.channelId : 0
|
const channelId = upd.message.peerId?._ === 'peerChannel' ? upd.message.peerId.channelId : 0
|
||||||
|
|
||||||
const set = noDispatchMsg.get(channelId)
|
const set = noDispatchMsg.get(channelId)
|
||||||
|
@ -1260,7 +1261,11 @@ export class UpdatesManager {
|
||||||
if (this.noDispatchEnabled) {
|
if (this.noDispatchEnabled) {
|
||||||
const channelId = pending.channelId ?? 0
|
const channelId = pending.channelId ?? 0
|
||||||
const msgId =
|
const msgId =
|
||||||
upd._ === 'updateNewMessage' || upd._ === 'updateNewChannelMessage' ? upd.message.id : undefined
|
upd._ === 'updateNewMessage' ||
|
||||||
|
upd._ === 'updateNewChannelMessage' ||
|
||||||
|
upd._ === 'updateBotNewBusinessMessage' ?
|
||||||
|
upd.message.id :
|
||||||
|
undefined
|
||||||
|
|
||||||
// we first need to remove it from each index, and then check if it was there
|
// we first need to remove it from each index, and then check if it was there
|
||||||
const foundByMsgId = msgId && this.noDispatchMsg.get(channelId)?.delete(msgId)
|
const foundByMsgId = msgId && this.noDispatchMsg.get(channelId)?.delete(msgId)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { Message } from '../types/messages/index.js'
|
import { Message } from '../types/messages/index.js'
|
||||||
import { ParsedUpdate } from '../types/updates/index.js'
|
import { BusinessMessage, ParsedUpdate } from '../types/updates/index.js'
|
||||||
import { _parseUpdate } from '../types/updates/parse-update.js'
|
import { _parseUpdate } from '../types/updates/parse-update.js'
|
||||||
import { RawUpdateHandler } from './types.js'
|
import { RawUpdateHandler } from './types.js'
|
||||||
|
|
||||||
|
@ -54,10 +54,11 @@ export function makeParsedUpdateHandler(params: ParsedUpdateHandlerParams): RawU
|
||||||
onRawUpdate(update, peers)
|
onRawUpdate(update, peers)
|
||||||
|
|
||||||
if (parsed) {
|
if (parsed) {
|
||||||
if (parsed.name === 'new_message') {
|
if (parsed.name === 'new_message' || parsed.name === 'new_business_message') {
|
||||||
const group = parsed.data.groupedIdUnique
|
const group = parsed.data.groupedIdUnique
|
||||||
|
|
||||||
if (group) {
|
if (group) {
|
||||||
|
const isBusiness = parsed.name === 'new_business_message'
|
||||||
const pendingGroup = pending.get(group)
|
const pendingGroup = pending.get(group)
|
||||||
|
|
||||||
if (pendingGroup) {
|
if (pendingGroup) {
|
||||||
|
@ -66,7 +67,12 @@ export function makeParsedUpdateHandler(params: ParsedUpdateHandlerParams): RawU
|
||||||
const messages = [parsed.data]
|
const messages = [parsed.data]
|
||||||
const timeout = setTimeout(() => {
|
const timeout = setTimeout(() => {
|
||||||
pending.delete(group)
|
pending.delete(group)
|
||||||
|
|
||||||
|
if (isBusiness) {
|
||||||
|
onUpdate({ name: 'business_message_group', data: messages as BusinessMessage[] })
|
||||||
|
} else {
|
||||||
onUpdate({ name: 'message_group', data: messages })
|
onUpdate({ name: 'message_group', data: messages })
|
||||||
|
}
|
||||||
}, messageGroupingInterval)
|
}, messageGroupingInterval)
|
||||||
|
|
||||||
pending.set(group, [messages, timeout])
|
pending.set(group, [messages, timeout])
|
||||||
|
|
|
@ -173,6 +173,15 @@ export interface RpcCallOptions {
|
||||||
*/
|
*/
|
||||||
throw503?: boolean
|
throw503?: boolean
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the `X_MIGRATE_%d` errors should be handled locally on request level
|
||||||
|
* instead of changing the default datacenter for the entire client.
|
||||||
|
*
|
||||||
|
* Useful for `invokeWithBusinessConnection`, as it returns a `USER_MIGRATE_%d` error
|
||||||
|
* that is in fact not related to the user, but to the specific request.
|
||||||
|
*/
|
||||||
|
localMigrate?: boolean
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Some requests should be processed consecutively, and not in parallel.
|
* Some requests should be processed consecutively, and not in parallel.
|
||||||
* Using the same `chainId` for multiple requests will ensure that they are processed in the order
|
* Using the same `chainId` for multiple requests will ensure that they are processed in the order
|
||||||
|
@ -807,10 +816,15 @@ export class NetworkManager {
|
||||||
|
|
||||||
if (manager === this._primaryDc) {
|
if (manager === this._primaryDc) {
|
||||||
if (e.is('PHONE_MIGRATE_%d') || e.is('NETWORK_MIGRATE_%d') || e.is('USER_MIGRATE_%d')) {
|
if (e.is('PHONE_MIGRATE_%d') || e.is('NETWORK_MIGRATE_%d') || e.is('USER_MIGRATE_%d')) {
|
||||||
|
if (params?.localMigrate) {
|
||||||
|
manager = await this._getOtherDc(e.newDc)
|
||||||
|
} else {
|
||||||
this._log.info('Migrate error, new dc = %d', e.newDc)
|
this._log.info('Migrate error, new dc = %d', e.newDc)
|
||||||
|
|
||||||
await this.changePrimaryDc(e.newDc)
|
await this.changePrimaryDc(e.newDc)
|
||||||
manager = this._primaryDc!
|
manager = this._primaryDc!
|
||||||
|
}
|
||||||
|
|
||||||
multi = manager[kind]
|
multi = manager[kind]
|
||||||
|
|
||||||
continue
|
continue
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
const { types, toSentence, replaceSections, formatFile } = require('../../mtcute/scripts/generate-updates.cjs')
|
const { types, toSentence, replaceSections, formatFile } = require('../../core/scripts/generate-updates.cjs')
|
||||||
|
|
||||||
function generateHandler() {
|
function generateHandler() {
|
||||||
const lines = []
|
const lines = []
|
||||||
|
|
187
packages/dispatcher/src/context/business-message.ts
Normal file
187
packages/dispatcher/src/context/business-message.ts
Normal file
|
@ -0,0 +1,187 @@
|
||||||
|
import { BusinessMessage, OmitInputMessageId, ParametersSkip1 } from '@mtcute/core'
|
||||||
|
import { TelegramClient } from '@mtcute/core/client.js'
|
||||||
|
import {
|
||||||
|
DeleteMessagesParams,
|
||||||
|
ForwardMessageOptions,
|
||||||
|
SendCopyGroupParams,
|
||||||
|
SendCopyParams,
|
||||||
|
} from '@mtcute/core/methods.js'
|
||||||
|
|
||||||
|
import { UpdateContext } from './base.js'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Context of a business message related update.
|
||||||
|
*
|
||||||
|
* This is a subclass of {@link BusinessMessage}, so all fields
|
||||||
|
* of the message are available.
|
||||||
|
*
|
||||||
|
* For message groups, own fields are related to the last message
|
||||||
|
* in the group. To access all messages, use {@link BusinessMessageContext#messages}.
|
||||||
|
*/
|
||||||
|
export class BusinessMessageContext extends BusinessMessage implements UpdateContext<BusinessMessage> {
|
||||||
|
// this is primarily for proper types in filters, so don't bother much with actual value
|
||||||
|
readonly _name = 'new_business_message'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of messages in the message group.
|
||||||
|
*
|
||||||
|
* For other updates, this is a list with a single element (`this`).
|
||||||
|
*/
|
||||||
|
readonly messages: BusinessMessageContext[]
|
||||||
|
|
||||||
|
/** Whether this update is about a message group */
|
||||||
|
readonly isMessageGroup: boolean
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
readonly client: TelegramClient,
|
||||||
|
message: BusinessMessage | BusinessMessage[],
|
||||||
|
) {
|
||||||
|
const msg = Array.isArray(message) ? message[message.length - 1] : message
|
||||||
|
super(msg.update, msg._peers)
|
||||||
|
|
||||||
|
this.messages = Array.isArray(message) ? message.map((it) => new BusinessMessageContext(client, it)) : [this]
|
||||||
|
this.isMessageGroup = Array.isArray(message)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Get all custom emojis contained in this message (message group), if any */
|
||||||
|
getCustomEmojis() {
|
||||||
|
return this.client.getCustomEmojisFromMessages(this.messages)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Send a text message to the same chat (and topic, if applicable) as a given message */
|
||||||
|
answerText(...params: ParametersSkip1<TelegramClient['answerText']>) {
|
||||||
|
const [send, params_ = {}] = params
|
||||||
|
params_.businessConnectionId = this.update.connectionId
|
||||||
|
|
||||||
|
return this.client.answerText(this, send, params_)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Send a media to the same chat (and topic, if applicable) as a given message */
|
||||||
|
answerMedia(...params: ParametersSkip1<TelegramClient['answerMedia']>) {
|
||||||
|
const [send, params_ = {}] = params
|
||||||
|
params_.businessConnectionId = this.update.connectionId
|
||||||
|
|
||||||
|
return this.client.answerMedia(this, send, params_)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Send a media group to the same chat (and topic, if applicable) as a given message */
|
||||||
|
answerMediaGroup(...params: ParametersSkip1<TelegramClient['answerMediaGroup']>) {
|
||||||
|
const [send, params_ = {}] = params
|
||||||
|
params_.businessConnectionId = this.update.connectionId
|
||||||
|
|
||||||
|
return this.client.answerMediaGroup(this, send, params_)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Send a text message in reply to this message */
|
||||||
|
replyText(...params: ParametersSkip1<TelegramClient['replyText']>) {
|
||||||
|
const [send, params_ = {}] = params
|
||||||
|
params_.businessConnectionId = this.update.connectionId
|
||||||
|
|
||||||
|
return this.client.replyText(this, send, params_)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Send a media in reply to this message */
|
||||||
|
replyMedia(...params: ParametersSkip1<TelegramClient['replyMedia']>) {
|
||||||
|
const [send, params_ = {}] = params
|
||||||
|
params_.businessConnectionId = this.update.connectionId
|
||||||
|
|
||||||
|
return this.client.replyMedia(this, send, params_)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Send a media group in reply to this message */
|
||||||
|
replyMediaGroup(...params: ParametersSkip1<TelegramClient['replyMediaGroup']>) {
|
||||||
|
const [send, params_ = {}] = params
|
||||||
|
params_.businessConnectionId = this.update.connectionId
|
||||||
|
|
||||||
|
return this.client.replyMediaGroup(this, send, params_)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Send a text message in reply to this message */
|
||||||
|
quoteWithText(params: Parameters<TelegramClient['quoteWithText']>[1]) {
|
||||||
|
params.businessConnectionId = this.update.connectionId
|
||||||
|
|
||||||
|
return this.client.quoteWithText(this, params)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Send a media in reply to this message */
|
||||||
|
quoteWithMedia(params: Parameters<TelegramClient['quoteWithMedia']>[1]) {
|
||||||
|
params.businessConnectionId = this.update.connectionId
|
||||||
|
|
||||||
|
return this.client.quoteWithMedia(this, params)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Send a media group in reply to this message */
|
||||||
|
quoteWithMediaGroup(params: Parameters<TelegramClient['quoteWithMediaGroup']>[1]) {
|
||||||
|
params.businessConnectionId = this.update.connectionId
|
||||||
|
|
||||||
|
return this.client.quoteWithMediaGroup(this, params)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Delete this message (message group) */
|
||||||
|
delete(params?: DeleteMessagesParams) {
|
||||||
|
return this.client.deleteMessagesById(
|
||||||
|
this.chat.inputPeer,
|
||||||
|
this.messages.map((it) => it.id),
|
||||||
|
params,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Pin this message */
|
||||||
|
pin(params?: OmitInputMessageId<Parameters<TelegramClient['pinMessage']>[0]>) {
|
||||||
|
return this.client.pinMessage({
|
||||||
|
chatId: this.chat.inputPeer,
|
||||||
|
message: this.id,
|
||||||
|
...params,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Unpin this message */
|
||||||
|
unpin() {
|
||||||
|
return this.client.unpinMessage({
|
||||||
|
chatId: this.chat.inputPeer,
|
||||||
|
message: this.id,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Edit this message */
|
||||||
|
edit(params: OmitInputMessageId<Parameters<TelegramClient['editMessage']>[0]>) {
|
||||||
|
return this.client.editMessage({
|
||||||
|
chatId: this.chat.inputPeer,
|
||||||
|
message: this.id,
|
||||||
|
...params,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Forward this message (message group) */
|
||||||
|
forwardTo(params: ForwardMessageOptions) {
|
||||||
|
return this.client.forwardMessagesById({
|
||||||
|
fromChatId: this.chat.inputPeer,
|
||||||
|
messages: this.messages.map((it) => it.id),
|
||||||
|
...params,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Send a copy of this message (message group) */
|
||||||
|
copy(params: SendCopyParams & SendCopyGroupParams) {
|
||||||
|
if (this.isMessageGroup) {
|
||||||
|
return this.client.sendCopyGroup({
|
||||||
|
messages: this.messages,
|
||||||
|
...params,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.client.sendCopy({
|
||||||
|
message: this,
|
||||||
|
...params,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/** React to this message */
|
||||||
|
react(params: OmitInputMessageId<Parameters<TelegramClient['sendReaction']>[0]>) {
|
||||||
|
return this.client.sendReaction({
|
||||||
|
chatId: this.chat.inputPeer,
|
||||||
|
message: this.id,
|
||||||
|
...params,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,6 +2,7 @@ import { ParsedUpdate } from '@mtcute/core'
|
||||||
import { TelegramClient } from '@mtcute/core/client.js'
|
import { TelegramClient } from '@mtcute/core/client.js'
|
||||||
|
|
||||||
import { UpdateContextDistributed } from './base.js'
|
import { UpdateContextDistributed } from './base.js'
|
||||||
|
import { BusinessMessageContext } from './business-message.js'
|
||||||
import { CallbackQueryContext } from './callback-query.js'
|
import { CallbackQueryContext } from './callback-query.js'
|
||||||
import { ChatJoinRequestUpdateContext } from './chat-join-request.js'
|
import { ChatJoinRequestUpdateContext } from './chat-join-request.js'
|
||||||
import { ChosenInlineResultContext } from './chosen-inline-result.js'
|
import { ChosenInlineResultContext } from './chosen-inline-result.js'
|
||||||
|
@ -26,6 +27,10 @@ export function _parsedUpdateToContext(client: TelegramClient, update: ParsedUpd
|
||||||
return new ChatJoinRequestUpdateContext(client, update.data)
|
return new ChatJoinRequestUpdateContext(client, update.data)
|
||||||
case 'pre_checkout_query':
|
case 'pre_checkout_query':
|
||||||
return new PreCheckoutQueryContext(client, update.data)
|
return new PreCheckoutQueryContext(client, update.data)
|
||||||
|
case 'new_business_message':
|
||||||
|
case 'edit_business_message':
|
||||||
|
case 'business_message_group':
|
||||||
|
return new BusinessMessageContext(client, update.data)
|
||||||
}
|
}
|
||||||
|
|
||||||
const _update = update.data as UpdateContextDistributed<typeof update.data>
|
const _update = update.data as UpdateContextDistributed<typeof update.data>
|
||||||
|
|
|
@ -7,8 +7,10 @@ import {
|
||||||
BotReactionCountUpdate,
|
BotReactionCountUpdate,
|
||||||
BotReactionUpdate,
|
BotReactionUpdate,
|
||||||
BotStoppedUpdate,
|
BotStoppedUpdate,
|
||||||
|
BusinessConnection,
|
||||||
ChatJoinRequestUpdate,
|
ChatJoinRequestUpdate,
|
||||||
ChatMemberUpdate,
|
ChatMemberUpdate,
|
||||||
|
DeleteBusinessMessageUpdate,
|
||||||
DeleteMessageUpdate,
|
DeleteMessageUpdate,
|
||||||
DeleteStoryUpdate,
|
DeleteStoryUpdate,
|
||||||
HistoryReadUpdate,
|
HistoryReadUpdate,
|
||||||
|
@ -26,6 +28,7 @@ import {
|
||||||
import { TelegramClient } from '@mtcute/core/client.js'
|
import { TelegramClient } from '@mtcute/core/client.js'
|
||||||
|
|
||||||
import { UpdateContext } from './context/base.js'
|
import { UpdateContext } from './context/base.js'
|
||||||
|
import { BusinessMessageContext } from './context/business-message.js'
|
||||||
import {
|
import {
|
||||||
CallbackQueryContext,
|
CallbackQueryContext,
|
||||||
ChatJoinRequestUpdateContext,
|
ChatJoinRequestUpdateContext,
|
||||||
|
@ -43,17 +46,22 @@ import {
|
||||||
BotReactionCountUpdateHandler,
|
BotReactionCountUpdateHandler,
|
||||||
BotReactionUpdateHandler,
|
BotReactionUpdateHandler,
|
||||||
BotStoppedHandler,
|
BotStoppedHandler,
|
||||||
|
BusinessConnectionUpdateHandler,
|
||||||
|
BusinessMessageGroupHandler,
|
||||||
CallbackQueryHandler,
|
CallbackQueryHandler,
|
||||||
ChatJoinRequestHandler,
|
ChatJoinRequestHandler,
|
||||||
ChatMemberUpdateHandler,
|
ChatMemberUpdateHandler,
|
||||||
ChosenInlineResultHandler,
|
ChosenInlineResultHandler,
|
||||||
|
DeleteBusinessMessageHandler,
|
||||||
DeleteMessageHandler,
|
DeleteMessageHandler,
|
||||||
DeleteStoryHandler,
|
DeleteStoryHandler,
|
||||||
|
EditBusinessMessageHandler,
|
||||||
EditMessageHandler,
|
EditMessageHandler,
|
||||||
HistoryReadHandler,
|
HistoryReadHandler,
|
||||||
InlineCallbackQueryHandler,
|
InlineCallbackQueryHandler,
|
||||||
InlineQueryHandler,
|
InlineQueryHandler,
|
||||||
MessageGroupHandler,
|
MessageGroupHandler,
|
||||||
|
NewBusinessMessageHandler,
|
||||||
NewMessageHandler,
|
NewMessageHandler,
|
||||||
PollUpdateHandler,
|
PollUpdateHandler,
|
||||||
PollVoteHandler,
|
PollVoteHandler,
|
||||||
|
@ -1014,9 +1022,9 @@ export class Dispatcher<State extends object = never> {
|
||||||
if (typeof handler === 'number' || typeof handler === 'undefined') {
|
if (typeof handler === 'number' || typeof handler === 'undefined') {
|
||||||
this.addUpdateHandler(
|
this.addUpdateHandler(
|
||||||
{
|
{
|
||||||
name,
|
name: name,
|
||||||
callback: filter,
|
callback: filter,
|
||||||
},
|
} as UpdateHandler,
|
||||||
handler,
|
handler,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
@ -1025,7 +1033,7 @@ export class Dispatcher<State extends object = never> {
|
||||||
name,
|
name,
|
||||||
callback: handler,
|
callback: handler,
|
||||||
check: filter,
|
check: filter,
|
||||||
},
|
} as UpdateHandler,
|
||||||
group,
|
group,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1743,5 +1751,212 @@ export class Dispatcher<State extends object = never> {
|
||||||
this._addKnownHandler('bot_reaction_count', filter, handler, group)
|
this._addKnownHandler('bot_reaction_count', filter, handler, group)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a business connection update handler without any filters
|
||||||
|
*
|
||||||
|
* @param handler Business connection update handler
|
||||||
|
* @param group Handler group index
|
||||||
|
*/
|
||||||
|
onBusinessConnectionUpdate(handler: BusinessConnectionUpdateHandler['callback'], group?: number): void
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a business connection update handler with a filter
|
||||||
|
*
|
||||||
|
* @param filter Update filter
|
||||||
|
* @param handler Business connection update handler
|
||||||
|
* @param group Handler group index
|
||||||
|
*/
|
||||||
|
onBusinessConnectionUpdate<Mod>(
|
||||||
|
filter: UpdateFilter<UpdateContext<BusinessConnection>, Mod>,
|
||||||
|
handler: BusinessConnectionUpdateHandler<filters.Modify<UpdateContext<BusinessConnection>, Mod>>['callback'],
|
||||||
|
group?: number,
|
||||||
|
): void
|
||||||
|
|
||||||
|
/** @internal */
|
||||||
|
onBusinessConnectionUpdate(filter: any, handler?: any, group?: number): void {
|
||||||
|
this._addKnownHandler('business_connection', filter, handler, group)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a new business message handler without any filters
|
||||||
|
*
|
||||||
|
* @param handler New business message handler
|
||||||
|
* @param group Handler group index
|
||||||
|
*/
|
||||||
|
onNewBusinessMessage(
|
||||||
|
handler: NewBusinessMessageHandler<
|
||||||
|
BusinessMessageContext,
|
||||||
|
State extends never ? never : UpdateState<State>
|
||||||
|
>['callback'],
|
||||||
|
group?: number,
|
||||||
|
): void
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a new business message handler with a filter
|
||||||
|
*
|
||||||
|
* @param filter Update filter
|
||||||
|
* @param handler New business message handler
|
||||||
|
* @param group Handler group index
|
||||||
|
*/
|
||||||
|
onNewBusinessMessage<Mod>(
|
||||||
|
filter: UpdateFilter<BusinessMessageContext, Mod, State>,
|
||||||
|
handler: NewBusinessMessageHandler<
|
||||||
|
filters.Modify<BusinessMessageContext, Mod>,
|
||||||
|
State extends never ? never : UpdateState<State>
|
||||||
|
>['callback'],
|
||||||
|
group?: number,
|
||||||
|
): void
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a new business message handler with a filter
|
||||||
|
*
|
||||||
|
* @param filter Update filter
|
||||||
|
* @param handler New business message handler
|
||||||
|
* @param group Handler group index
|
||||||
|
*/
|
||||||
|
onNewBusinessMessage<Mod>(
|
||||||
|
filter: UpdateFilter<BusinessMessageContext, Mod>,
|
||||||
|
handler: NewBusinessMessageHandler<
|
||||||
|
filters.Modify<BusinessMessageContext, Mod>,
|
||||||
|
State extends never ? never : UpdateState<State>
|
||||||
|
>['callback'],
|
||||||
|
group?: number,
|
||||||
|
): void
|
||||||
|
|
||||||
|
/** @internal */
|
||||||
|
onNewBusinessMessage(filter: any, handler?: any, group?: number): void {
|
||||||
|
this._addKnownHandler('new_business_message', filter, handler, group)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register an edit business message handler without any filters
|
||||||
|
*
|
||||||
|
* @param handler Edit business message handler
|
||||||
|
* @param group Handler group index
|
||||||
|
*/
|
||||||
|
onEditBusinessMessage(
|
||||||
|
handler: EditBusinessMessageHandler<
|
||||||
|
BusinessMessageContext,
|
||||||
|
State extends never ? never : UpdateState<State>
|
||||||
|
>['callback'],
|
||||||
|
group?: number,
|
||||||
|
): void
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register an edit business message handler with a filter
|
||||||
|
*
|
||||||
|
* @param filter Update filter
|
||||||
|
* @param handler Edit business message handler
|
||||||
|
* @param group Handler group index
|
||||||
|
*/
|
||||||
|
onEditBusinessMessage<Mod>(
|
||||||
|
filter: UpdateFilter<BusinessMessageContext, Mod, State>,
|
||||||
|
handler: EditBusinessMessageHandler<
|
||||||
|
filters.Modify<BusinessMessageContext, Mod>,
|
||||||
|
State extends never ? never : UpdateState<State>
|
||||||
|
>['callback'],
|
||||||
|
group?: number,
|
||||||
|
): void
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register an edit business message handler with a filter
|
||||||
|
*
|
||||||
|
* @param filter Update filter
|
||||||
|
* @param handler Edit business message handler
|
||||||
|
* @param group Handler group index
|
||||||
|
*/
|
||||||
|
onEditBusinessMessage<Mod>(
|
||||||
|
filter: UpdateFilter<BusinessMessageContext, Mod>,
|
||||||
|
handler: EditBusinessMessageHandler<
|
||||||
|
filters.Modify<BusinessMessageContext, Mod>,
|
||||||
|
State extends never ? never : UpdateState<State>
|
||||||
|
>['callback'],
|
||||||
|
group?: number,
|
||||||
|
): void
|
||||||
|
|
||||||
|
/** @internal */
|
||||||
|
onEditBusinessMessage(filter: any, handler?: any, group?: number): void {
|
||||||
|
this._addKnownHandler('edit_business_message', filter, handler, group)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a business message group handler without any filters
|
||||||
|
*
|
||||||
|
* @param handler Business message group handler
|
||||||
|
* @param group Handler group index
|
||||||
|
*/
|
||||||
|
onBusinessMessageGroup(
|
||||||
|
handler: BusinessMessageGroupHandler<
|
||||||
|
BusinessMessageContext,
|
||||||
|
State extends never ? never : UpdateState<State>
|
||||||
|
>['callback'],
|
||||||
|
group?: number,
|
||||||
|
): void
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a business message group handler with a filter
|
||||||
|
*
|
||||||
|
* @param filter Update filter
|
||||||
|
* @param handler Business message group handler
|
||||||
|
* @param group Handler group index
|
||||||
|
*/
|
||||||
|
onBusinessMessageGroup<Mod>(
|
||||||
|
filter: UpdateFilter<BusinessMessageContext, Mod, State>,
|
||||||
|
handler: BusinessMessageGroupHandler<
|
||||||
|
filters.Modify<BusinessMessageContext, Mod>,
|
||||||
|
State extends never ? never : UpdateState<State>
|
||||||
|
>['callback'],
|
||||||
|
group?: number,
|
||||||
|
): void
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a business message group handler with a filter
|
||||||
|
*
|
||||||
|
* @param filter Update filter
|
||||||
|
* @param handler Business message group handler
|
||||||
|
* @param group Handler group index
|
||||||
|
*/
|
||||||
|
onBusinessMessageGroup<Mod>(
|
||||||
|
filter: UpdateFilter<BusinessMessageContext, Mod>,
|
||||||
|
handler: BusinessMessageGroupHandler<
|
||||||
|
filters.Modify<BusinessMessageContext, Mod>,
|
||||||
|
State extends never ? never : UpdateState<State>
|
||||||
|
>['callback'],
|
||||||
|
group?: number,
|
||||||
|
): void
|
||||||
|
|
||||||
|
/** @internal */
|
||||||
|
onBusinessMessageGroup(filter: any, handler?: any, group?: number): void {
|
||||||
|
this._addKnownHandler('business_message_group', filter, handler, group)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a delete business message handler without any filters
|
||||||
|
*
|
||||||
|
* @param handler Delete business message handler
|
||||||
|
* @param group Handler group index
|
||||||
|
*/
|
||||||
|
onDeleteBusinessMessage(handler: DeleteBusinessMessageHandler['callback'], group?: number): void
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a delete business message handler with a filter
|
||||||
|
*
|
||||||
|
* @param filter Update filter
|
||||||
|
* @param handler Delete business message handler
|
||||||
|
* @param group Handler group index
|
||||||
|
*/
|
||||||
|
onDeleteBusinessMessage<Mod>(
|
||||||
|
filter: UpdateFilter<UpdateContext<DeleteBusinessMessageUpdate>, Mod>,
|
||||||
|
handler: DeleteBusinessMessageHandler<
|
||||||
|
filters.Modify<UpdateContext<DeleteBusinessMessageUpdate>, Mod>
|
||||||
|
>['callback'],
|
||||||
|
group?: number,
|
||||||
|
): void
|
||||||
|
|
||||||
|
/** @internal */
|
||||||
|
onDeleteBusinessMessage(filter: any, handler?: any, group?: number): void {
|
||||||
|
this._addKnownHandler('delete_business_message', filter, handler, group)
|
||||||
|
}
|
||||||
|
|
||||||
// end-codegen
|
// end-codegen
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { MaybeArray, MaybePromise, Message } from '@mtcute/core'
|
import { MaybeArray, MaybePromise, Message } from '@mtcute/core'
|
||||||
|
|
||||||
|
import { BusinessMessageContext } from '../context/business-message.js'
|
||||||
import { MessageContext } from '../context/message.js'
|
import { MessageContext } from '../context/message.js'
|
||||||
import { chat } from './chat.js'
|
import { chat } from './chat.js'
|
||||||
import { and, or } from './logic.js'
|
import { and, or } from './logic.js'
|
||||||
|
@ -30,7 +31,7 @@ export const command = (
|
||||||
prefixes?: MaybeArray<string> | null
|
prefixes?: MaybeArray<string> | null
|
||||||
caseSensitive?: boolean
|
caseSensitive?: boolean
|
||||||
} = {},
|
} = {},
|
||||||
): UpdateFilter<MessageContext, { command: string[] }> => {
|
): UpdateFilter<MessageContext | BusinessMessageContext, { command: string[] }> => {
|
||||||
if (!Array.isArray(commands)) commands = [commands]
|
if (!Array.isArray(commands)) commands = [commands]
|
||||||
|
|
||||||
if (!caseSensitive) {
|
if (!caseSensitive) {
|
||||||
|
@ -51,7 +52,7 @@ export const command = (
|
||||||
|
|
||||||
const _prefixes = prefixes
|
const _prefixes = prefixes
|
||||||
|
|
||||||
const check = (msg: MessageContext): MaybePromise<boolean> => {
|
const check = (msg: MessageContext | BusinessMessageContext): MaybePromise<boolean> => {
|
||||||
if (msg.isMessageGroup) return check(msg.messages[0])
|
if (msg.isMessageGroup) return check(msg.messages[0])
|
||||||
|
|
||||||
for (const pref of _prefixes) {
|
for (const pref of _prefixes) {
|
||||||
|
@ -107,8 +108,10 @@ export const start = and(chat('private'), command('start'))
|
||||||
export const startGroup = and(or(chat('supergroup'), chat('group')), command('start'))
|
export const startGroup = and(or(chat('supergroup'), chat('group')), command('start'))
|
||||||
|
|
||||||
const deeplinkBase =
|
const deeplinkBase =
|
||||||
(base: UpdateFilter<MessageContext, { command: string[] }>) =>
|
(base: UpdateFilter<MessageContext | BusinessMessageContext, { command: string[] }>) =>
|
||||||
(params: MaybeArray<string | RegExp>): UpdateFilter<MessageContext, { command: string[] }> => {
|
(
|
||||||
|
params: MaybeArray<string | RegExp>,
|
||||||
|
): UpdateFilter<MessageContext | BusinessMessageContext, { command: string[] }> => {
|
||||||
if (!Array.isArray(params)) {
|
if (!Array.isArray(params)) {
|
||||||
return and(start, (_msg: Message) => {
|
return and(start, (_msg: Message) => {
|
||||||
const msg = _msg as Message & { command: string[] }
|
const msg = _msg as Message & { command: string[] }
|
||||||
|
|
|
@ -3,6 +3,7 @@ import {
|
||||||
Chat,
|
Chat,
|
||||||
ChatMemberUpdate,
|
ChatMemberUpdate,
|
||||||
ChatType,
|
ChatType,
|
||||||
|
DeleteBusinessMessageUpdate,
|
||||||
HistoryReadUpdate,
|
HistoryReadUpdate,
|
||||||
MaybeArray,
|
MaybeArray,
|
||||||
Message,
|
Message,
|
||||||
|
@ -58,6 +59,7 @@ export const chatId: {
|
||||||
| HistoryReadUpdate
|
| HistoryReadUpdate
|
||||||
| PollVoteUpdate
|
| PollVoteUpdate
|
||||||
| BotChatJoinRequestUpdate
|
| BotChatJoinRequestUpdate
|
||||||
|
| DeleteBusinessMessageUpdate
|
||||||
>>
|
>>
|
||||||
} = (id) => {
|
} = (id) => {
|
||||||
const indexId = new Set<number>()
|
const indexId = new Set<number>()
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { MaybePromise, Message } from '@mtcute/core'
|
import { MaybePromise, Message } from '@mtcute/core'
|
||||||
|
|
||||||
|
import { BusinessMessageContext } from '../context/business-message.js'
|
||||||
import { MessageContext } from '../context/message.js'
|
import { MessageContext } from '../context/message.js'
|
||||||
import { Modify, UpdateFilter } from './types.js'
|
import { Modify, UpdateFilter } from './types.js'
|
||||||
|
|
||||||
|
@ -15,9 +16,9 @@ import { Modify, UpdateFilter } from './types.js'
|
||||||
export function every<Mod, State extends object>(
|
export function every<Mod, State extends object>(
|
||||||
filter: UpdateFilter<Message, Mod, State>,
|
filter: UpdateFilter<Message, Mod, State>,
|
||||||
): UpdateFilter<
|
): UpdateFilter<
|
||||||
MessageContext,
|
MessageContext | BusinessMessageContext,
|
||||||
Mod & {
|
Mod & {
|
||||||
messages: Modify<MessageContext, Mod>[]
|
messages: Modify<MessageContext | BusinessMessageContext, Mod>[]
|
||||||
},
|
},
|
||||||
State
|
State
|
||||||
> {
|
> {
|
||||||
|
@ -61,7 +62,7 @@ export function some<State extends object>(
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
filter: UpdateFilter<Message, any, State>,
|
filter: UpdateFilter<Message, any, State>,
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
): UpdateFilter<MessageContext, {}, State> {
|
): UpdateFilter<MessageContext | BusinessMessageContext, {}, State> {
|
||||||
return (ctx, state) => {
|
return (ctx, state) => {
|
||||||
let i = 0
|
let i = 0
|
||||||
const upds = ctx.messages
|
const upds = ctx.messages
|
||||||
|
|
|
@ -18,6 +18,7 @@ import {
|
||||||
Video,
|
Video,
|
||||||
} from '@mtcute/core'
|
} from '@mtcute/core'
|
||||||
|
|
||||||
|
import { BusinessMessageContext } from '../context/business-message.js'
|
||||||
import { MessageContext } from '../index.js'
|
import { MessageContext } from '../index.js'
|
||||||
import { Modify, UpdateFilter } from './types.js'
|
import { Modify, UpdateFilter } from './types.js'
|
||||||
|
|
||||||
|
@ -237,14 +238,16 @@ export const sender =
|
||||||
export const replyTo =
|
export const replyTo =
|
||||||
<Mod, State extends object>(
|
<Mod, State extends object>(
|
||||||
filter?: UpdateFilter<Message, Mod, State>,
|
filter?: UpdateFilter<Message, Mod, State>,
|
||||||
): UpdateFilter<MessageContext, { getReplyTo: () => Promise<Message & Mod> }, State> =>
|
): UpdateFilter<MessageContext | BusinessMessageContext, { getReplyTo: () => Promise<Message & Mod> }, State> =>
|
||||||
async (msg, state) => {
|
async (msg, state) => {
|
||||||
if (!msg.replyToMessage?.id) return false
|
if (!msg.replyToMessage?.id) return false
|
||||||
|
|
||||||
const reply = await msg.getReplyTo()
|
const reply = msg._name === 'new_message' ? await msg.getReplyTo() : msg.replyTo
|
||||||
if (!reply) return false
|
if (!reply) return false
|
||||||
|
|
||||||
|
if (msg._name === 'new_message') {
|
||||||
msg.getReplyTo = () => Promise.resolve(reply)
|
msg.getReplyTo = () => Promise.resolve(reply)
|
||||||
|
}
|
||||||
|
|
||||||
if (!filter) return true
|
if (!filter) return true
|
||||||
|
|
||||||
|
|
|
@ -83,7 +83,9 @@ export const userId: {
|
||||||
return (upd) => {
|
return (upd) => {
|
||||||
switch (upd._name) {
|
switch (upd._name) {
|
||||||
case 'new_message':
|
case 'new_message':
|
||||||
case 'edit_message': {
|
case 'edit_message':
|
||||||
|
case 'new_business_message':
|
||||||
|
case 'edit_business_message': {
|
||||||
const sender = upd.sender
|
const sender = upd.sender
|
||||||
|
|
||||||
return (matchSelf && sender.isSelf) ||
|
return (matchSelf && sender.isSelf) ||
|
||||||
|
|
|
@ -2,8 +2,10 @@ import {
|
||||||
BotReactionCountUpdate,
|
BotReactionCountUpdate,
|
||||||
BotReactionUpdate,
|
BotReactionUpdate,
|
||||||
BotStoppedUpdate,
|
BotStoppedUpdate,
|
||||||
|
BusinessConnection,
|
||||||
ChatJoinRequestUpdate,
|
ChatJoinRequestUpdate,
|
||||||
ChatMemberUpdate,
|
ChatMemberUpdate,
|
||||||
|
DeleteBusinessMessageUpdate,
|
||||||
DeleteMessageUpdate,
|
DeleteMessageUpdate,
|
||||||
DeleteStoryUpdate,
|
DeleteStoryUpdate,
|
||||||
HistoryReadUpdate,
|
HistoryReadUpdate,
|
||||||
|
@ -19,6 +21,7 @@ import {
|
||||||
import { TelegramClient } from '@mtcute/core/client.js'
|
import { TelegramClient } from '@mtcute/core/client.js'
|
||||||
|
|
||||||
import { UpdateContext } from './context/base.js'
|
import { UpdateContext } from './context/base.js'
|
||||||
|
import { BusinessMessageContext } from './context/business-message.js'
|
||||||
import {
|
import {
|
||||||
CallbackQueryContext,
|
CallbackQueryContext,
|
||||||
ChatJoinRequestUpdateContext,
|
ChatJoinRequestUpdateContext,
|
||||||
|
@ -89,6 +92,29 @@ export type BotReactionCountUpdateHandler<T = UpdateContext<BotReactionCountUpda
|
||||||
'bot_reaction_count',
|
'bot_reaction_count',
|
||||||
T
|
T
|
||||||
>
|
>
|
||||||
|
export type BusinessConnectionUpdateHandler<T = UpdateContext<BusinessConnection>> = ParsedUpdateHandler<
|
||||||
|
'business_connection',
|
||||||
|
T
|
||||||
|
>
|
||||||
|
export type NewBusinessMessageHandler<T = BusinessMessageContext, S = never> = ParsedUpdateHandler<
|
||||||
|
'new_business_message',
|
||||||
|
T,
|
||||||
|
S
|
||||||
|
>
|
||||||
|
export type EditBusinessMessageHandler<T = BusinessMessageContext, S = never> = ParsedUpdateHandler<
|
||||||
|
'edit_business_message',
|
||||||
|
T,
|
||||||
|
S
|
||||||
|
>
|
||||||
|
export type BusinessMessageGroupHandler<T = BusinessMessageContext, S = never> = ParsedUpdateHandler<
|
||||||
|
'business_message_group',
|
||||||
|
T,
|
||||||
|
S
|
||||||
|
>
|
||||||
|
export type DeleteBusinessMessageHandler<T = UpdateContext<DeleteBusinessMessageUpdate>> = ParsedUpdateHandler<
|
||||||
|
'delete_business_message',
|
||||||
|
T
|
||||||
|
>
|
||||||
|
|
||||||
export type UpdateHandler =
|
export type UpdateHandler =
|
||||||
| RawUpdateHandler
|
| RawUpdateHandler
|
||||||
|
@ -114,5 +140,10 @@ export type UpdateHandler =
|
||||||
| DeleteStoryHandler
|
| DeleteStoryHandler
|
||||||
| BotReactionUpdateHandler
|
| BotReactionUpdateHandler
|
||||||
| BotReactionCountUpdateHandler
|
| BotReactionCountUpdateHandler
|
||||||
|
| BusinessConnectionUpdateHandler
|
||||||
|
| NewBusinessMessageHandler
|
||||||
|
| EditBusinessMessageHandler
|
||||||
|
| BusinessMessageGroupHandler
|
||||||
|
| DeleteBusinessMessageHandler
|
||||||
|
|
||||||
// end-codegen
|
// end-codegen
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { assertNever, MaybePromise, Peer } from '@mtcute/core'
|
import { assertNever, MaybePromise, Peer } from '@mtcute/core'
|
||||||
|
|
||||||
|
import { BusinessMessageContext } from '../context/business-message.js'
|
||||||
import { CallbackQueryContext, MessageContext } from '../context/index.js'
|
import { CallbackQueryContext, MessageContext } from '../context/index.js'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -10,7 +11,9 @@ import { CallbackQueryContext, MessageContext } from '../context/index.js'
|
||||||
* @param msg Message or callback from which to derive the key
|
* @param msg Message or callback from which to derive the key
|
||||||
* @param scene Current scene UID, or `null` if none
|
* @param scene Current scene UID, or `null` if none
|
||||||
*/
|
*/
|
||||||
export type StateKeyDelegate = (upd: MessageContext | CallbackQueryContext | Peer) => MaybePromise<string | null>
|
export type StateKeyDelegate = (
|
||||||
|
upd: MessageContext | BusinessMessageContext | CallbackQueryContext | Peer,
|
||||||
|
) => MaybePromise<string | null>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default state key delegate.
|
* Default state key delegate.
|
||||||
|
@ -29,7 +32,7 @@ export const defaultStateKeyDelegate: StateKeyDelegate = (upd): string | null =>
|
||||||
return String(upd.id)
|
return String(upd.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (upd._name === 'new_message') {
|
if (upd._name === 'new_message' || upd._name === 'new_business_message') {
|
||||||
switch (upd.chat.chatType) {
|
switch (upd.chat.chatType) {
|
||||||
case 'private':
|
case 'private':
|
||||||
case 'bot':
|
case 'bot':
|
||||||
|
|
Loading…
Reference in a new issue