2158 lines
71 KiB
TypeScript
2158 lines
71 KiB
TypeScript
/* eslint-disable ts/no-unsafe-assignment */
|
|
/* eslint-disable ts/no-unsafe-argument */
|
|
/* eslint-disable ts/no-empty-object-type */
|
|
// ^^ will be looked into in MTQ-29
|
|
|
|
import type {
|
|
BotReactionCountUpdate,
|
|
BotReactionUpdate,
|
|
BotStoppedUpdate,
|
|
BusinessConnection,
|
|
ChatJoinRequestUpdate,
|
|
ChatMemberUpdate,
|
|
DeleteBusinessMessageUpdate,
|
|
DeleteMessageUpdate,
|
|
DeleteStoryUpdate,
|
|
HistoryReadUpdate,
|
|
MaybePromise,
|
|
ParsedUpdate,
|
|
PeersIndex,
|
|
PollUpdate,
|
|
PollVoteUpdate,
|
|
RawUpdateInfo,
|
|
StoryUpdate,
|
|
tl,
|
|
UserStatusUpdate,
|
|
UserTypingUpdate,
|
|
} from '@mtcute/core'
|
|
import type { TelegramClient } from '@mtcute/core/client.js'
|
|
import type { UpdateContext } from './context/base.js'
|
|
import type { BusinessMessageContext } from './context/business-message.js'
|
|
|
|
import type {
|
|
BusinessCallbackQueryContext,
|
|
CallbackQueryContext,
|
|
ChatJoinRequestUpdateContext,
|
|
ChosenInlineResultContext,
|
|
InlineCallbackQueryContext,
|
|
InlineQueryContext,
|
|
MessageContext,
|
|
PreCheckoutQueryContext,
|
|
} from './context/index.js'
|
|
import type { UpdateContextType } from './context/parse.js'
|
|
import type { filters, UpdateFilter } from './filters/index.js'
|
|
// begin-codegen-imports
|
|
import type {
|
|
BotChatJoinRequestHandler,
|
|
BotReactionCountUpdateHandler,
|
|
BotReactionUpdateHandler,
|
|
BotStoppedHandler,
|
|
BusinessCallbackQueryHandler,
|
|
BusinessConnectionUpdateHandler,
|
|
BusinessMessageGroupHandler,
|
|
CallbackQueryHandler,
|
|
ChatJoinRequestHandler,
|
|
ChatMemberUpdateHandler,
|
|
ChosenInlineResultHandler,
|
|
DeleteBusinessMessageHandler,
|
|
DeleteMessageHandler,
|
|
DeleteStoryHandler,
|
|
EditBusinessMessageHandler,
|
|
EditMessageHandler,
|
|
HistoryReadHandler,
|
|
InlineCallbackQueryHandler,
|
|
InlineQueryHandler,
|
|
MessageGroupHandler,
|
|
NewBusinessMessageHandler,
|
|
NewMessageHandler,
|
|
PollUpdateHandler,
|
|
PollVoteHandler,
|
|
PreCheckoutQueryHandler,
|
|
RawUpdateHandler,
|
|
StoryUpdateHandler,
|
|
UpdateHandler,
|
|
UserStatusUpdateHandler,
|
|
UserTypingHandler,
|
|
} from './handler.js'
|
|
// end-codegen-imports
|
|
import type { PropagationAction } from './propagation.js'
|
|
import type { IStateStorageProvider, StateKeyDelegate } from './state/index.js'
|
|
import { unknownToError } from '@fuman/utils'
|
|
import {
|
|
MtArgumentError,
|
|
} from '@mtcute/core'
|
|
import { _parsedUpdateToContext } from './context/parse.js'
|
|
import { SceneTransitionContext } from './context/scene-transition.js'
|
|
import { defaultStateKeyDelegate, UpdateState } from './state/index.js'
|
|
import { StateService } from './state/service.js'
|
|
|
|
export interface DispatcherParams {
|
|
/**
|
|
* If this dispatcher can be used as a scene, its unique name.
|
|
*
|
|
* Should not be set manually, use {@link Dispatcher.scene} instead
|
|
*/
|
|
sceneName?: string
|
|
|
|
/**
|
|
* Custom storage for this dispatcher and its children.
|
|
*
|
|
* @default Client's storage
|
|
*/
|
|
storage?: IStateStorageProvider
|
|
|
|
/**
|
|
* Custom key delegate for the dispatcher.
|
|
*/
|
|
key?: StateKeyDelegate
|
|
}
|
|
|
|
export interface DispatcherDependencies {
|
|
// intentionally empty, to be extended by consumers
|
|
}
|
|
|
|
/**
|
|
* Updates dispatcher
|
|
*/
|
|
export class Dispatcher<State extends object = never> {
|
|
private _groups: Map<number, Map<UpdateHandler['name'], UpdateHandler[]>> = new Map()
|
|
private _groupsOrder: number[] = []
|
|
|
|
private _client?: TelegramClient
|
|
|
|
private _parent?: Dispatcher<any>
|
|
private _children: Dispatcher<any>[] = []
|
|
|
|
private _scenes?: Map<string, Dispatcher<any>>
|
|
private _scene?: string
|
|
private _sceneScoped?: boolean
|
|
|
|
private _storage?: StateService
|
|
private _stateKeyDelegate?: StateKeyDelegate
|
|
|
|
private _customStateKeyDelegate?: StateKeyDelegate
|
|
private _customStorage?: StateService
|
|
|
|
private _deps: DispatcherDependencies = {}
|
|
|
|
private _errorHandler?: <T = {}>(
|
|
err: Error,
|
|
update: ParsedUpdate & T,
|
|
state?: UpdateState<State>,
|
|
) => MaybePromise<boolean>
|
|
|
|
private _preUpdateHandler?: <T = {}>(
|
|
update: ParsedUpdate & T,
|
|
state?: UpdateState<State>,
|
|
) => MaybePromise<PropagationAction | void>
|
|
|
|
private _postUpdateHandler?: <T = {}>(
|
|
handled: boolean,
|
|
update: ParsedUpdate & T,
|
|
state?: UpdateState<State>,
|
|
) => MaybePromise<void>
|
|
|
|
private _sceneTransitionHandler?: (
|
|
update: SceneTransitionContext,
|
|
state: UpdateState<State>,
|
|
) => MaybePromise<PropagationAction | void>
|
|
|
|
protected constructor(client?: TelegramClient, params?: DispatcherParams) {
|
|
this.dispatchRawUpdate = this.dispatchRawUpdate.bind(this)
|
|
this.dispatchUpdate = this.dispatchUpdate.bind(this)
|
|
|
|
// eslint-disable-next-line prefer-const
|
|
let { storage, key, sceneName } = params ?? {}
|
|
|
|
if (client) {
|
|
this.bindToClient(client)
|
|
|
|
if (storage) {
|
|
this._storage = new StateService(storage)
|
|
this._stateKeyDelegate = key ?? defaultStateKeyDelegate
|
|
}
|
|
} else {
|
|
// child dispatcher without client
|
|
|
|
if (storage) {
|
|
this._customStorage = new StateService(storage)
|
|
}
|
|
|
|
if (key) {
|
|
this._customStateKeyDelegate = key
|
|
}
|
|
|
|
if (sceneName) {
|
|
if (sceneName[0] === '$') {
|
|
throw new MtArgumentError('Scene name cannot start with $')
|
|
}
|
|
|
|
this._scene = sceneName
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Create a new dispatcher and bind it to the client.
|
|
*/
|
|
static for<State extends object = never>(
|
|
client: TelegramClient,
|
|
...args: [State] extends [never]
|
|
? [params?: DispatcherParams]
|
|
: [params: DispatcherParams & { storage: IStateStorageProvider }]
|
|
): Dispatcher<State>
|
|
|
|
static for<State extends object = never>(client: TelegramClient, params?: DispatcherParams): Dispatcher<State> {
|
|
return new Dispatcher<State>(client, params)
|
|
}
|
|
|
|
/**
|
|
* Create a new child dispatcher.
|
|
*/
|
|
static child<State extends object = never>(params?: DispatcherParams): Dispatcher<State> {
|
|
return new Dispatcher<State>(undefined, params)
|
|
}
|
|
|
|
/**
|
|
* Create a new scene dispatcher
|
|
*/
|
|
static scene<State extends object = Record<never, never>>(
|
|
name: string,
|
|
params?: Omit<DispatcherParams, 'sceneName'>,
|
|
): Dispatcher<State> {
|
|
return new Dispatcher<State>(undefined, { sceneName: name, ...params })
|
|
}
|
|
|
|
/** For scene dispatchers, name of the scene */
|
|
get sceneName(): string | undefined {
|
|
return this._scene
|
|
}
|
|
|
|
/**
|
|
* Inject a dependency to be available in this dispatcher and all its children.
|
|
*
|
|
* **Note**: This is only available for the root dispatcher.
|
|
*/
|
|
inject<Name extends keyof DispatcherDependencies>(name: Name, value: DispatcherDependencies[Name]): void
|
|
/**
|
|
* Inject dependencies to be available in this dispatcher and all its children.
|
|
*
|
|
* **Note**: This is only available for the root dispatcher.
|
|
*/
|
|
inject(deps: Partial<DispatcherDependencies>): void
|
|
inject<Name extends keyof DispatcherDependencies>(
|
|
name: Name | Partial<DispatcherDependencies>,
|
|
value?: DispatcherDependencies[Name],
|
|
): void {
|
|
if (this._parent) {
|
|
throw new MtArgumentError('Cannot inject dependencies to child dispatchers')
|
|
}
|
|
|
|
if (typeof name === 'object') {
|
|
for (const [k, v] of Object.entries(name)) {
|
|
(this._deps as any)[k] = v
|
|
}
|
|
} else {
|
|
this._deps[name] = value!
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get the dependencies injected into this dispatcher.
|
|
*/
|
|
get deps(): DispatcherDependencies {
|
|
return this._deps
|
|
}
|
|
|
|
/**
|
|
* Bind the dispatcher to the client.
|
|
* Called by the constructor automatically if
|
|
* `client` was passed.
|
|
*
|
|
* Dispatcher also uses bound client to throw errors
|
|
*/
|
|
bindToClient(client: TelegramClient): void {
|
|
client.onUpdate.add(this.dispatchUpdate)
|
|
client.onRawUpdate.add(this.dispatchRawUpdate)
|
|
|
|
this._client = client
|
|
}
|
|
|
|
/**
|
|
* Unbind a dispatcher from the client.
|
|
*/
|
|
unbind(): void {
|
|
if (this._client) {
|
|
this._client.onUpdate.remove(this.dispatchUpdate)
|
|
this._client.onRawUpdate.remove(this.dispatchRawUpdate)
|
|
|
|
this._client = undefined
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Destroy the dispatcher and all its children.
|
|
*
|
|
* When destroying, all the registered handlers are removed,
|
|
* and the underlying storage is freed.
|
|
*/
|
|
async destroy(): Promise<void> {
|
|
if (this._parent && this._customStorage) {
|
|
await this._customStorage.destroy()
|
|
} else if (!this._parent && this._storage) {
|
|
await this._storage.destroy()
|
|
}
|
|
|
|
this.removeUpdateHandler('all')
|
|
|
|
for (const child of this._children) {
|
|
await child.destroy()
|
|
}
|
|
|
|
for (const scene of this._scenes?.values() ?? []) {
|
|
await scene.destroy()
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Process a raw update with this dispatcher.
|
|
* Calling this method without bound client will not work.
|
|
*
|
|
* Under the hood asynchronously calls {@link dispatchRawUpdateNow}
|
|
* with error handler set to client's one.
|
|
*
|
|
* @param update Update to process
|
|
* @param peers Peers index
|
|
*/
|
|
dispatchRawUpdate({ update, peers }: RawUpdateInfo): void {
|
|
if (!this._client) return
|
|
|
|
// order does not matter in the dispatcher,
|
|
// so we can handle each update in its own task
|
|
this.dispatchRawUpdateNow(update, peers)
|
|
.catch(err => this._client!.onError.emit(unknownToError(err)))
|
|
}
|
|
|
|
/**
|
|
* Process a raw update right now in the current stack.
|
|
*
|
|
* Unlike {@link dispatchRawUpdate}, this does not schedule
|
|
* the update to be dispatched, but dispatches it immediately,
|
|
* and after `await`ing this method you can be certain that the update
|
|
* was fully processed by all the registered handlers, including children.
|
|
*
|
|
* @param update Update to process
|
|
* @param peers Peers map
|
|
* @returns Whether the update was handled
|
|
*/
|
|
async dispatchRawUpdateNow(update: tl.TypeUpdate | tl.TypeMessage, peers: PeersIndex): Promise<boolean> {
|
|
if (!this._client) return false
|
|
|
|
let handled = false
|
|
|
|
outer: for (const grp of this._groupsOrder) {
|
|
const group = this._groups.get(grp)!
|
|
|
|
if (group.has('raw')) {
|
|
const handlers = group.get('raw')! as RawUpdateHandler[]
|
|
|
|
for (const h of handlers) {
|
|
let result: void | PropagationAction
|
|
|
|
if (!h.check || (await h.check(this._client, update, peers))) {
|
|
result = await h.callback(this._client, update, peers)
|
|
handled = true
|
|
} else {
|
|
continue
|
|
}
|
|
|
|
switch (result) {
|
|
case 'continue':
|
|
continue
|
|
case 'stop':
|
|
break outer
|
|
case 'stop-children':
|
|
return handled
|
|
}
|
|
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
for (const child of this._children) {
|
|
const childHandled = await child.dispatchRawUpdateNow(update, peers)
|
|
handled ||= childHandled
|
|
}
|
|
|
|
return handled
|
|
}
|
|
|
|
/**
|
|
* Process an update with this dispatcher.
|
|
* Calling this method without bound client will not work.
|
|
*
|
|
* Under the hood asynchronously calls {@link dispatchUpdateNow}
|
|
* with error handler set to client's one.
|
|
*
|
|
* @param update Update to process
|
|
*/
|
|
dispatchUpdate(update: ParsedUpdate): void {
|
|
if (!this._client) return
|
|
|
|
// order does not matter in the dispatcher,
|
|
// so we can handle each update in its own task
|
|
this.dispatchUpdateNow(update)
|
|
.catch(err => this._client!.onError.emit(unknownToError(err)))
|
|
}
|
|
|
|
/**
|
|
* Process an update right now in the current stack.
|
|
*
|
|
* Unlike {@link dispatchUpdate}, this does not schedule
|
|
* the update to be dispatched, but dispatches it immediately,
|
|
* and after `await`ing this method you can be certain that the update
|
|
* was fully processed by all the registered handlers, including children.
|
|
*
|
|
* @param update Update to process
|
|
* @returns Whether the update was handled
|
|
*/
|
|
async dispatchUpdateNow(update: ParsedUpdate): Promise<boolean> {
|
|
return this._dispatchUpdateNowImpl(update)
|
|
}
|
|
|
|
private async _dispatchUpdateNowImpl(
|
|
update: ParsedUpdate,
|
|
// this is getting a bit crazy lol
|
|
parsedState?: UpdateState<State> | null,
|
|
parsedScene?: string | null,
|
|
forceScene?: true,
|
|
parsedContext?: UpdateContextType,
|
|
): Promise<boolean> {
|
|
if (!this._client) return false
|
|
|
|
if (parsedScene === undefined) {
|
|
if (
|
|
this._storage
|
|
&& this._scenes
|
|
&& (update.name === 'new_message'
|
|
|| update.name === 'edit_message'
|
|
|| update.name === 'callback_query'
|
|
|| update.name === 'message_group'
|
|
|| update.name === 'new_business_message'
|
|
|| update.name === 'edit_business_message'
|
|
|| update.name === 'business_message_group')
|
|
) {
|
|
// no need to fetch scene if there are no registered scenes
|
|
|
|
if (!parsedContext) parsedContext = _parsedUpdateToContext(this._client, update)
|
|
const key = await this._stateKeyDelegate!(parsedContext as any)
|
|
|
|
if (key) {
|
|
parsedScene = await this._storage.getCurrentScene(key)
|
|
} else {
|
|
parsedScene = null
|
|
}
|
|
} else {
|
|
parsedScene = null
|
|
}
|
|
}
|
|
|
|
if (!forceScene && parsedScene !== null) {
|
|
if (this._scene) {
|
|
if (this._scene !== parsedScene) {
|
|
// should not happen, but just in case
|
|
return false
|
|
}
|
|
} else {
|
|
if (!this._scenes || !this._scenes.has(parsedScene)) {
|
|
// not registered scene
|
|
return false
|
|
}
|
|
|
|
return this._scenes.get(parsedScene)!._dispatchUpdateNowImpl(update, parsedState, parsedScene, true)
|
|
}
|
|
}
|
|
|
|
if (parsedState === undefined) {
|
|
if (
|
|
this._storage
|
|
&& (update.name === 'new_message'
|
|
|| update.name === 'edit_message'
|
|
|| update.name === 'callback_query'
|
|
|| update.name === 'message_group'
|
|
|| update.name === 'new_business_message'
|
|
|| update.name === 'edit_business_message'
|
|
|| update.name === 'business_message_group')
|
|
) {
|
|
if (!parsedContext) parsedContext = _parsedUpdateToContext(this._client, update)
|
|
const key = await this._stateKeyDelegate!(parsedContext as any)
|
|
|
|
if (key) {
|
|
let customKey
|
|
|
|
if (
|
|
!this._customStateKeyDelegate
|
|
|| (customKey = await this._customStateKeyDelegate(parsedContext as any))
|
|
) {
|
|
parsedState = new UpdateState(
|
|
this._storage,
|
|
key,
|
|
this._scene ?? null,
|
|
this._sceneScoped,
|
|
this._customStorage,
|
|
customKey,
|
|
)
|
|
}
|
|
} else {
|
|
parsedState = null
|
|
}
|
|
} else {
|
|
parsedState = null
|
|
}
|
|
}
|
|
|
|
let shouldDispatch = true
|
|
let shouldDispatchChildren = true
|
|
let handled = false
|
|
|
|
switch (await this._preUpdateHandler?.(update, parsedState as any)) {
|
|
case 'stop':
|
|
shouldDispatch = false
|
|
break
|
|
case 'stop-children':
|
|
return false
|
|
}
|
|
|
|
if (shouldDispatch) {
|
|
outer: for (const grp of this._groupsOrder) {
|
|
const group = this._groups.get(grp)!
|
|
|
|
if (group.has(update.name)) {
|
|
// raw is not handled here, so we can safely assume this
|
|
const handlers = group.get(update.name)! as Exclude<UpdateHandler, RawUpdateHandler>[]
|
|
|
|
try {
|
|
for (const h of handlers) {
|
|
let result: void | PropagationAction
|
|
|
|
if (!parsedContext) parsedContext = _parsedUpdateToContext(this._client, update)
|
|
if (!h.check || (await h.check(parsedContext as any, parsedState as never))) {
|
|
result = await h.callback(parsedContext as any, parsedState as never)
|
|
handled = true
|
|
} else {
|
|
continue
|
|
}
|
|
|
|
if (parsedState && this._scenes) {
|
|
// check if scene transition was made
|
|
const newScene = parsedState.scene
|
|
|
|
if (parsedScene !== newScene) {
|
|
const nextDp = newScene ? this._scenes.get(newScene) : this._parent
|
|
|
|
if (!nextDp) {
|
|
throw new MtArgumentError(`Scene ${newScene} not found`)
|
|
}
|
|
|
|
if (nextDp._sceneTransitionHandler) {
|
|
const transition = new SceneTransitionContext(parsedScene, parsedContext)
|
|
const transitionResult = await nextDp._sceneTransitionHandler?.(
|
|
transition,
|
|
parsedState,
|
|
)
|
|
|
|
switch (transitionResult) {
|
|
case 'stop':
|
|
return true
|
|
case 'continue':
|
|
continue
|
|
case 'scene': {
|
|
const scene = parsedState.scene
|
|
const dp = scene ? nextDp._scenes!.get(scene)! : nextDp._parent!
|
|
|
|
// eslint-disable-next-line ts/return-await
|
|
return dp._dispatchUpdateNowImpl(update, undefined, scene, true)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
switch (result) {
|
|
case 'continue':
|
|
continue
|
|
case 'stop':
|
|
break outer
|
|
case 'stop-children':
|
|
shouldDispatchChildren = false
|
|
break outer
|
|
|
|
case 'scene': {
|
|
if (!parsedState) {
|
|
throw new MtArgumentError('Cannot use ToScene without state')
|
|
}
|
|
|
|
const scene = parsedState.scene
|
|
const dp = scene ? this._scenes!.get(scene)! : this._parent!
|
|
|
|
// eslint-disable-next-line ts/return-await
|
|
return dp._dispatchUpdateNowImpl(update, undefined, scene, true)
|
|
}
|
|
}
|
|
|
|
break
|
|
}
|
|
} catch (e: any) {
|
|
if (this._errorHandler) {
|
|
const handled = await this._errorHandler(e, update, parsedState as never)
|
|
if (!handled) throw e
|
|
} else {
|
|
throw e
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (shouldDispatchChildren) {
|
|
for (const child of this._children) {
|
|
const childHandled = await child._dispatchUpdateNowImpl(update)
|
|
handled ||= childHandled
|
|
}
|
|
}
|
|
|
|
await this._postUpdateHandler?.(handled, update, parsedState as any)
|
|
|
|
return handled
|
|
}
|
|
|
|
/**
|
|
* Add an update handler to a given handlers group
|
|
*
|
|
* @param handler Update handler
|
|
* @param group Handler group index
|
|
*/
|
|
addUpdateHandler(handler: UpdateHandler, group = 0): void {
|
|
if (!this._groups.has(group)) {
|
|
this._groups.set(group, new Map())
|
|
this._groupsOrder.push(group)
|
|
this._groupsOrder.sort((a, b) => a - b)
|
|
}
|
|
|
|
if (!this._groups.get(group)!.has(handler.name)) {
|
|
this._groups.get(group)!.set(handler.name, [])
|
|
}
|
|
|
|
this._groups.get(group)!.get(handler.name)!.push(handler)
|
|
}
|
|
|
|
/**
|
|
* Remove an update handler (or handlers) from a given
|
|
* handler group.
|
|
*
|
|
* @param handler Update handler to remove, its name or `'all'` to remove all
|
|
* @param group Handler group index (null to affect all groups)
|
|
*/
|
|
removeUpdateHandler(handler: UpdateHandler | UpdateHandler['name'] | 'all', group: number | null = 0): void {
|
|
if (group !== null && !this._groups.has(group)) {
|
|
return
|
|
}
|
|
|
|
if (typeof handler === 'string') {
|
|
if (handler === 'all') {
|
|
if (group === null) {
|
|
this._groups = new Map()
|
|
} else {
|
|
this._groups.delete(group)
|
|
}
|
|
} else if (group !== null) {
|
|
this._groups.get(group)!.delete(handler)
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
if (group === null) return
|
|
|
|
if (!this._groups.get(group)!.has(handler.name)) {
|
|
return
|
|
}
|
|
|
|
const idx = this._groups.get(group)!.get(handler.name)!.indexOf(handler)
|
|
|
|
if (idx > -1) {
|
|
this._groups.get(group)!.get(handler.name)!.splice(idx, 1)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Register an error handler.
|
|
*
|
|
* This is used locally within this dispatcher
|
|
* (does not affect children/parent) whenever
|
|
* an error is thrown inside an update handler.
|
|
* Not used for raw update handlers
|
|
*
|
|
* When an error is thrown, but there is no error
|
|
* handler, it is propagated to `TelegramClient`.
|
|
*
|
|
* There can be at most one error handler.
|
|
* Pass `null` to remove it.
|
|
*
|
|
* @param handler Error handler
|
|
*/
|
|
onError<T = {}>(
|
|
handler: ((err: Error, update: ParsedUpdate & T, state?: UpdateState<State>) => MaybePromise<boolean>) | null,
|
|
): void {
|
|
if (handler) this._errorHandler = handler
|
|
else this._errorHandler = undefined
|
|
}
|
|
|
|
/**
|
|
* Register pre-update middleware.
|
|
*
|
|
* This is used locally within this dispatcher
|
|
* (does not affect children/parent) before processing
|
|
* an update, and can be used to skip this update.
|
|
*
|
|
* There can be at most one pre-update middleware.
|
|
* Pass `null` to remove it.
|
|
*
|
|
* @param handler Pre-update middleware
|
|
*/
|
|
onPreUpdate<T = {}>(
|
|
handler:
|
|
| ((update: ParsedUpdate & T, state?: UpdateState<State>) => MaybePromise<PropagationAction | void>)
|
|
| null,
|
|
): void {
|
|
if (handler) this._preUpdateHandler = handler
|
|
else this._preUpdateHandler = undefined
|
|
}
|
|
|
|
/**
|
|
* Register post-update middleware.
|
|
*
|
|
* This is used locally within this dispatcher
|
|
* (does not affect children/parent) after successfully
|
|
* processing an update, and can be used for stats.
|
|
*
|
|
* There can be at most one post-update middleware.
|
|
* Pass `null` to remove it.
|
|
*
|
|
* @param handler Pre-update middleware
|
|
*/
|
|
onPostUpdate<T = {}>(
|
|
handler:
|
|
| ((handled: boolean, update: ParsedUpdate & T, state?: UpdateState<State>) => MaybePromise<void>)
|
|
| null,
|
|
): void {
|
|
if (handler) this._postUpdateHandler = handler
|
|
else this._postUpdateHandler = undefined
|
|
}
|
|
|
|
/**
|
|
* Set error handler that will propagate
|
|
* the error to the parent dispatcher
|
|
*/
|
|
propagateErrorToParent(err: Error, update: ParsedUpdate, state?: UpdateState<State>): MaybePromise<boolean> {
|
|
if (!this.parent) {
|
|
throw new MtArgumentError('This dispatcher is not a child')
|
|
}
|
|
|
|
if (this.parent._errorHandler) {
|
|
return this.parent._errorHandler(err, update, state as any)
|
|
}
|
|
throw err
|
|
}
|
|
|
|
// children //
|
|
|
|
/**
|
|
* Get parent dispatcher if current dispatcher is a child.
|
|
* Otherwise, return `null`
|
|
*/
|
|
get parent(): Dispatcher<any> | null {
|
|
return this._parent ?? null
|
|
}
|
|
|
|
private _prepareChild(child: Dispatcher<any>): void {
|
|
if (child._client) {
|
|
throw new MtArgumentError(
|
|
`Provided dispatcher is ${
|
|
child._parent
|
|
? 'already a child. Use parent.removeChild() before calling addChild()'
|
|
: 'already bound to a client. Use unbind() before calling addChild()'}`,
|
|
)
|
|
}
|
|
|
|
child._parent = this as any
|
|
child._client = this._client
|
|
child._storage = this._storage
|
|
child._deps = this._deps
|
|
child._scenes = this._scenes
|
|
child._stateKeyDelegate = this._stateKeyDelegate
|
|
child._customStorage ??= this._customStorage
|
|
child._customStateKeyDelegate ??= this._customStateKeyDelegate
|
|
}
|
|
|
|
/**
|
|
* Add a child dispatcher.
|
|
*
|
|
* Child dispatchers are called when dispatching updates
|
|
* just like normal, except they can be controlled
|
|
* externally. Additionally, child dispatcher have their own
|
|
* independent handler grouping that does not interfere with parent's,
|
|
* including `StopPropagation` (i.e. returning `StopPropagation` will
|
|
* still call children. To entirely stop, use `StopChildrenPropagation`)
|
|
*
|
|
* Note that child dispatchers share the same TelegramClient and
|
|
* storage binding as the parent, don't bind them manually.
|
|
*
|
|
* @param child Other dispatcher
|
|
*/
|
|
addChild(child: Dispatcher<State>): void {
|
|
if (this._children.includes(child)) return
|
|
|
|
this._prepareChild(child)
|
|
this._children.push(child)
|
|
}
|
|
|
|
/**
|
|
* Add a dispatcher as a scene with a non-scoped state.
|
|
*
|
|
* Scoped storage for a scene means that the scene will
|
|
* have its own storage, that is only available within
|
|
* the scene and does not interfere with global state.
|
|
* Non-scoped, on the other hand, is the same state as
|
|
* the one used for the root dispatcher
|
|
*
|
|
* @param uid UID of the scene
|
|
* @param scene Dispatcher representing the scene
|
|
* @param scoped Whether to use scoped FSM storage for the scene
|
|
*/
|
|
addScene(scene: Dispatcher<State>, scoped: false): void
|
|
/**
|
|
* Add a dispatcher as a scene with a scoped state
|
|
*
|
|
* Scoped storage for a scene means that the scene will
|
|
* have its own storage, that is only available within
|
|
* the scene and does not interfere with global state.
|
|
* Non-scoped, on the other hand, is the same state as
|
|
* the one used for the root dispatcher
|
|
*
|
|
* @param uid UID of the scene
|
|
* @param scene Dispatcher representing the scene
|
|
* @param scoped Whether to use scoped FSM storage for the scene (defaults to `true`)
|
|
*/
|
|
addScene(scene: Dispatcher<any>, scoped?: true): void
|
|
addScene(scene: Dispatcher<any>, scoped = true): void {
|
|
if (!this._scenes) this._scenes = new Map()
|
|
|
|
if (!scene._scene) {
|
|
throw new MtArgumentError(
|
|
'Non-scene dispatcher passed to addScene. Use `Dispatcher.scene()` to create one.',
|
|
)
|
|
}
|
|
|
|
if (this._scenes.has(scene._scene)) {
|
|
throw new MtArgumentError(`Scene with name ${scene._scene} is already registered!`)
|
|
}
|
|
|
|
this._prepareChild(scene)
|
|
scene._sceneScoped = scoped
|
|
this._scenes.set(scene._scene, scene)
|
|
}
|
|
|
|
/**
|
|
* Remove a child dispatcher.
|
|
*
|
|
* Removing child dispatcher will also remove
|
|
* child dispatcher's client binding.
|
|
*
|
|
* If the provided dispatcher is not a child of current,
|
|
* this function will silently fail.
|
|
*
|
|
* @param child Other dispatcher
|
|
*/
|
|
removeChild(child: Dispatcher<any>): void {
|
|
const idx = this._children.indexOf(child)
|
|
|
|
if (idx > -1) {
|
|
child._unparent()
|
|
this._children.splice(idx, 1)
|
|
}
|
|
}
|
|
|
|
private _unparent(): void {
|
|
this._parent = this._client = undefined
|
|
this._deps = {} // to avoid dangling references
|
|
this._stateKeyDelegate = undefined
|
|
this._storage = undefined
|
|
}
|
|
|
|
/**
|
|
* Extend current dispatcher by copying other dispatcher's
|
|
* handlers and children to the current.
|
|
*
|
|
* This might be more efficient for simple cases, but do note that the handler
|
|
* groups, children and scenes will get merged (unlike {@link addChild},
|
|
* where they are independent). Also note that unlike with children,
|
|
* when adding handlers to `other` *after* you extended
|
|
* the current dispatcher, changes will not be applied.
|
|
*
|
|
* @param other Other dispatcher
|
|
*/
|
|
extend(other: Dispatcher<State>): void {
|
|
if (other._customStorage || other._customStateKeyDelegate) {
|
|
throw new MtArgumentError('Provided dispatcher has custom storage and cannot be extended from.')
|
|
}
|
|
|
|
other._groupsOrder.forEach((group) => {
|
|
if (!this._groups.has(group)) {
|
|
this._groups.set(group, other._groups.get(group)!)
|
|
this._groupsOrder.push(group)
|
|
} else {
|
|
const otherGrp = other._groups.get(group)!
|
|
const selfGrp = this._groups.get(group)!
|
|
|
|
for (const typ of otherGrp.keys()) {
|
|
if (!selfGrp.has(typ)) {
|
|
selfGrp.set(typ, otherGrp.get(typ)!)
|
|
} else {
|
|
// selfGrp[typ].push(...otherGrp[typ])
|
|
selfGrp.get(typ)!.push(...otherGrp.get(typ)!)
|
|
}
|
|
}
|
|
}
|
|
})
|
|
|
|
other._children.forEach((it) => {
|
|
it._unparent()
|
|
this.addChild(it as any)
|
|
})
|
|
|
|
if (other._scenes) {
|
|
const otherScenes = other._scenes
|
|
if (!this._scenes) this._scenes = new Map()
|
|
const myScenes = this._scenes
|
|
|
|
for (const key of otherScenes.keys()) {
|
|
otherScenes.get(key)!._unparent()
|
|
|
|
if (myScenes.has(key)) {
|
|
// will be overwritten
|
|
myScenes.delete(key)
|
|
}
|
|
|
|
this.addScene(otherScenes.get(key) as any, otherScenes.get(key)!._sceneScoped as any)
|
|
}
|
|
}
|
|
|
|
this._groupsOrder.sort((a, b) => a - b)
|
|
}
|
|
|
|
/**
|
|
* Create a clone of this dispatcher, that has the same handlers,
|
|
* but is not bound to a client or to a parent dispatcher.
|
|
*
|
|
* Custom Storage and key delegate are copied too.
|
|
*
|
|
* By default, child dispatchers (and scenes) are ignored, since
|
|
* that requires cloning every single one of them recursively
|
|
* and then binding them back.
|
|
*
|
|
* @param children Whether to also clone children and scenes
|
|
*/
|
|
clone(children = false): Dispatcher<State> {
|
|
const dp = new Dispatcher<State>()
|
|
|
|
// copy handlers.
|
|
for (const key of this._groups.keys()) {
|
|
const idx = key as any as number
|
|
|
|
dp._groups.set(idx, new Map())
|
|
|
|
for (const type of this._groups.get(idx)!.keys()) {
|
|
// dp._groups.get(idx)!.set(type, [...this._groups.get(idx)!].get(type)!])
|
|
dp._groups.get(idx)!.set(type, [...this._groups.get(idx)!.get(type)!])
|
|
}
|
|
}
|
|
|
|
dp._groupsOrder = [...this._groupsOrder]
|
|
dp._errorHandler = this._errorHandler
|
|
dp._customStateKeyDelegate = this._customStateKeyDelegate
|
|
dp._customStorage = this._customStorage
|
|
|
|
if (children) {
|
|
this._children.forEach((it) => {
|
|
const child = it.clone(true)
|
|
dp.addChild(child as any)
|
|
})
|
|
|
|
if (this._scenes) {
|
|
for (const key of this._scenes.keys()) {
|
|
const scene = this._scenes.get(key)!.clone(true)
|
|
dp.addScene(scene as any, this._scenes.get(key)!._sceneScoped as any)
|
|
}
|
|
}
|
|
}
|
|
|
|
return dp
|
|
}
|
|
|
|
/**
|
|
* Get update state object for the given key.
|
|
*
|
|
* For custom keys, use prefix starting with `$` to avoid
|
|
* clashing with other keys (scene name can't start with `$`)
|
|
*
|
|
* @param key State storage key
|
|
* @template S State type, defaults to dispatcher's state type. Only checked at compile-time
|
|
*/
|
|
getState<S extends object = State>(key: string): UpdateState<S>
|
|
|
|
/**
|
|
* Get update state object for the given object.
|
|
*
|
|
* Equivalent to `getState(string)`, but derives
|
|
* the key with the registered {@link StateKeyDelegate},
|
|
* and since it could be async, this method is async too.
|
|
*
|
|
* @param object Object for which the state should be fetched
|
|
* @template S State type, defaults to dispatcher's state type. Only checked at compile-time
|
|
*/
|
|
getState<S extends object = State>(object: Parameters<StateKeyDelegate>[0]): Promise<UpdateState<S>>
|
|
getState<S extends object = State>(object: string | Parameters<StateKeyDelegate>[0]): MaybePromise<UpdateState<S>> {
|
|
if (!this._storage) {
|
|
throw new MtArgumentError('Cannot use getUpdateState() filter without state storage')
|
|
}
|
|
|
|
if (typeof object === 'string') {
|
|
return new UpdateState(this._storage, object, this._scene ?? null, this._sceneScoped, this._customStorage)
|
|
}
|
|
|
|
return Promise.resolve(this._stateKeyDelegate!(object)).then((key) => {
|
|
if (!key) {
|
|
throw new MtArgumentError('Cannot derive key from given object')
|
|
}
|
|
|
|
if (!this._customStateKeyDelegate) {
|
|
return new UpdateState(this._storage!, key, this._scene ?? null, this._sceneScoped, this._customStorage)
|
|
}
|
|
|
|
return Promise.resolve(this._customStateKeyDelegate(object)).then((customKey) => {
|
|
if (!customKey) {
|
|
throw new MtArgumentError('Cannot derive custom key from given object')
|
|
}
|
|
|
|
return new UpdateState(
|
|
this._storage!,
|
|
key,
|
|
this._scene ?? null,
|
|
this._sceneScoped,
|
|
this._customStorage,
|
|
customKey,
|
|
)
|
|
})
|
|
})
|
|
}
|
|
|
|
/**
|
|
* Get global state.
|
|
*
|
|
* This will load the state for the given object
|
|
* ignoring local custom storage, key delegate and scene scope.
|
|
*/
|
|
getGlobalState<T extends object>(object: Parameters<StateKeyDelegate>[0]): Promise<UpdateState<T>> {
|
|
if (!this._parent) {
|
|
throw new MtArgumentError('This dispatcher does not have a parent')
|
|
}
|
|
|
|
return Promise.resolve(this._stateKeyDelegate!(object)).then((key) => {
|
|
if (!key) {
|
|
throw new MtArgumentError('Cannot derive key from given object')
|
|
}
|
|
|
|
return new UpdateState(this._storage!, key, this._scene ?? null, false)
|
|
})
|
|
}
|
|
|
|
// addUpdateHandler convenience wrappers //
|
|
|
|
private _addKnownHandler(name: UpdateHandler['name'], filter: any, handler?: any, group?: number): void {
|
|
if (typeof handler === 'number' || typeof handler === 'undefined') {
|
|
this.addUpdateHandler(
|
|
{
|
|
name,
|
|
callback: filter,
|
|
} as UpdateHandler,
|
|
handler,
|
|
)
|
|
} else {
|
|
this.addUpdateHandler(
|
|
{
|
|
name,
|
|
callback: handler,
|
|
check: filter,
|
|
} as UpdateHandler,
|
|
group,
|
|
)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Register a raw update handler without any filters
|
|
*
|
|
* @param handler Raw update handler
|
|
* @param group Handler group index
|
|
*/
|
|
onRawUpdate(handler: RawUpdateHandler['callback'], group?: number): void
|
|
|
|
/**
|
|
* Register a raw update handler without any filters
|
|
*
|
|
* @param filter Update filter
|
|
* @param handler Raw update handler
|
|
* @param group Handler group index
|
|
*/
|
|
onRawUpdate(filter: RawUpdateHandler['check'], handler: RawUpdateHandler['callback'], group?: number): void
|
|
|
|
/** @internal */
|
|
onRawUpdate(filter: any, handler?: any, group?: number): void {
|
|
this._addKnownHandler('raw', filter, handler, group)
|
|
}
|
|
|
|
/**
|
|
* Register a scene transition handler
|
|
*
|
|
* This handler is called whenever a scene transition occurs
|
|
* in the context of the scene that is being entered,
|
|
* and before any of the its own handlers are called,
|
|
* and can be used to customize the transition behavior:
|
|
* - `Stop` to prevent dispatching the update any further **even if ToScene/ToRoot was used**
|
|
* - `Continue` same as Stop, but still dispatch the update to children
|
|
* - `ToScene` to prevent the transition and dispatch the update to the scene entered in the transition handler
|
|
*
|
|
* > **Note**: if multiple `state.enter()` calls were made within the same update,
|
|
* > this handler will only be called for the last one.
|
|
*
|
|
* @param handler Raw update handler
|
|
* @param group Handler group index
|
|
*/
|
|
onSceneTransition(
|
|
handler:
|
|
| ((ctx: SceneTransitionContext, state: UpdateState<State>) => MaybePromise<PropagationAction | void>)
|
|
| null,
|
|
): void {
|
|
if (handler) this._sceneTransitionHandler = handler
|
|
else this._sceneTransitionHandler = undefined
|
|
}
|
|
|
|
/**
|
|
* Register a callback query (both inline and non-inline) handler without any filters
|
|
*
|
|
* @param handler Callback query handler
|
|
* @param group Handler group index
|
|
*/
|
|
onAnyCallbackQuery(
|
|
handler: CallbackQueryHandler<
|
|
CallbackQueryContext | InlineCallbackQueryContext | BusinessCallbackQueryContext,
|
|
State extends never ? never : UpdateState<State>
|
|
>['callback'],
|
|
group?: number,
|
|
): void
|
|
|
|
/**
|
|
* Register a callback query (both inline and non-inline) handler with a filter
|
|
*
|
|
* @param filter Update filter
|
|
* @param handler Callback query handler
|
|
* @param group Handler group index
|
|
*/
|
|
onAnyCallbackQuery<Mod>(
|
|
filter: UpdateFilter<
|
|
CallbackQueryContext | InlineCallbackQueryContext | BusinessCallbackQueryContext,
|
|
Mod,
|
|
State
|
|
>,
|
|
handler: CallbackQueryHandler<
|
|
filters.Modify<CallbackQueryContext | InlineCallbackQueryContext | BusinessCallbackQueryContext, Mod>,
|
|
State extends never ? never : UpdateState<State>
|
|
>['callback'],
|
|
group?: number,
|
|
): void
|
|
|
|
/**
|
|
* Register a callback query (both inline and non-inline) handler with a filter
|
|
*
|
|
* @param filter Update filter
|
|
* @param handler Callback query handler
|
|
* @param group Handler group index
|
|
*/
|
|
onAnyCallbackQuery<Mod>(
|
|
filter: UpdateFilter<CallbackQueryContext | InlineCallbackQueryContext | BusinessCallbackQueryContext, Mod>,
|
|
handler: CallbackQueryHandler<
|
|
filters.Modify<CallbackQueryContext | InlineCallbackQueryContext | BusinessCallbackQueryContext, Mod>,
|
|
State extends never ? never : UpdateState<State>
|
|
>['callback'],
|
|
group?: number,
|
|
): void
|
|
|
|
/** @internal */
|
|
onAnyCallbackQuery(filter: any, handler?: any, group?: number): void {
|
|
this._addKnownHandler('callback_query', filter, handler, group)
|
|
this._addKnownHandler('inline_callback_query', filter, handler, group)
|
|
this._addKnownHandler('business_callback_query', filter, handler, group)
|
|
}
|
|
|
|
// begin-codegen
|
|
|
|
/**
|
|
* Register a new message handler without any filters
|
|
*
|
|
* @param handler New message handler
|
|
* @param group Handler group index
|
|
*/
|
|
onNewMessage(
|
|
handler: NewMessageHandler<MessageContext, State extends never ? never : UpdateState<State>>['callback'],
|
|
group?: number,
|
|
): void
|
|
|
|
/**
|
|
* Register a new message handler with a filter
|
|
*
|
|
* @param filter Update filter
|
|
* @param handler New message handler
|
|
* @param group Handler group index
|
|
*/
|
|
onNewMessage<Mod>(
|
|
filter: UpdateFilter<MessageContext, Mod, State>,
|
|
handler: NewMessageHandler<
|
|
filters.Modify<MessageContext, Mod>,
|
|
State extends never ? never : UpdateState<State>
|
|
>['callback'],
|
|
group?: number,
|
|
): void
|
|
|
|
/**
|
|
* Register a new message handler with a filter
|
|
*
|
|
* @param filter Update filter
|
|
* @param handler New message handler
|
|
* @param group Handler group index
|
|
*/
|
|
onNewMessage<Mod>(
|
|
filter: UpdateFilter<MessageContext, Mod>,
|
|
handler: NewMessageHandler<
|
|
filters.Modify<MessageContext, Mod>,
|
|
State extends never ? never : UpdateState<State>
|
|
>['callback'],
|
|
group?: number,
|
|
): void
|
|
|
|
/** @internal */
|
|
onNewMessage(filter: any, handler?: any, group?: number): void {
|
|
this._addKnownHandler('new_message', filter, handler, group)
|
|
}
|
|
|
|
/**
|
|
* Register an edit message handler without any filters
|
|
*
|
|
* @param handler Edit message handler
|
|
* @param group Handler group index
|
|
*/
|
|
onEditMessage(
|
|
handler: EditMessageHandler<MessageContext, State extends never ? never : UpdateState<State>>['callback'],
|
|
group?: number,
|
|
): void
|
|
|
|
/**
|
|
* Register an edit message handler with a filter
|
|
*
|
|
* @param filter Update filter
|
|
* @param handler Edit message handler
|
|
* @param group Handler group index
|
|
*/
|
|
onEditMessage<Mod>(
|
|
filter: UpdateFilter<MessageContext, Mod, State>,
|
|
handler: EditMessageHandler<
|
|
filters.Modify<MessageContext, Mod>,
|
|
State extends never ? never : UpdateState<State>
|
|
>['callback'],
|
|
group?: number,
|
|
): void
|
|
|
|
/**
|
|
* Register an edit message handler with a filter
|
|
*
|
|
* @param filter Update filter
|
|
* @param handler Edit message handler
|
|
* @param group Handler group index
|
|
*/
|
|
onEditMessage<Mod>(
|
|
filter: UpdateFilter<MessageContext, Mod>,
|
|
handler: EditMessageHandler<
|
|
filters.Modify<MessageContext, Mod>,
|
|
State extends never ? never : UpdateState<State>
|
|
>['callback'],
|
|
group?: number,
|
|
): void
|
|
|
|
/** @internal */
|
|
onEditMessage(filter: any, handler?: any, group?: number): void {
|
|
this._addKnownHandler('edit_message', filter, handler, group)
|
|
}
|
|
|
|
/**
|
|
* Register a message group handler without any filters
|
|
*
|
|
* @param handler Message group handler
|
|
* @param group Handler group index
|
|
*/
|
|
onMessageGroup(
|
|
handler: MessageGroupHandler<MessageContext, State extends never ? never : UpdateState<State>>['callback'],
|
|
group?: number,
|
|
): void
|
|
|
|
/**
|
|
* Register a message group handler with a filter
|
|
*
|
|
* @param filter Update filter
|
|
* @param handler Message group handler
|
|
* @param group Handler group index
|
|
*/
|
|
onMessageGroup<Mod>(
|
|
filter: UpdateFilter<MessageContext, Mod, State>,
|
|
handler: MessageGroupHandler<
|
|
filters.Modify<MessageContext, Mod>,
|
|
State extends never ? never : UpdateState<State>
|
|
>['callback'],
|
|
group?: number,
|
|
): void
|
|
|
|
/**
|
|
* Register a message group handler with a filter
|
|
*
|
|
* @param filter Update filter
|
|
* @param handler Message group handler
|
|
* @param group Handler group index
|
|
*/
|
|
onMessageGroup<Mod>(
|
|
filter: UpdateFilter<MessageContext, Mod>,
|
|
handler: MessageGroupHandler<
|
|
filters.Modify<MessageContext, Mod>,
|
|
State extends never ? never : UpdateState<State>
|
|
>['callback'],
|
|
group?: number,
|
|
): void
|
|
|
|
/** @internal */
|
|
onMessageGroup(filter: any, handler?: any, group?: number): void {
|
|
this._addKnownHandler('message_group', filter, handler, group)
|
|
}
|
|
|
|
/**
|
|
* Register a delete message handler without any filters
|
|
*
|
|
* @param handler Delete message handler
|
|
* @param group Handler group index
|
|
*/
|
|
onDeleteMessage(handler: DeleteMessageHandler['callback'], group?: number): void
|
|
|
|
/**
|
|
* Register a delete message handler with a filter
|
|
*
|
|
* @param filter Update filter
|
|
* @param handler Delete message handler
|
|
* @param group Handler group index
|
|
*/
|
|
onDeleteMessage<Mod>(
|
|
filter: UpdateFilter<UpdateContext<DeleteMessageUpdate>, Mod>,
|
|
handler: DeleteMessageHandler<filters.Modify<UpdateContext<DeleteMessageUpdate>, Mod>>['callback'],
|
|
group?: number,
|
|
): void
|
|
|
|
/** @internal */
|
|
onDeleteMessage(filter: any, handler?: any, group?: number): void {
|
|
this._addKnownHandler('delete_message', filter, handler, group)
|
|
}
|
|
|
|
/**
|
|
* Register a chat member update handler without any filters
|
|
*
|
|
* @param handler Chat member update handler
|
|
* @param group Handler group index
|
|
*/
|
|
onChatMemberUpdate(handler: ChatMemberUpdateHandler['callback'], group?: number): void
|
|
|
|
/**
|
|
* Register a chat member update handler with a filter
|
|
*
|
|
* @param filter Update filter
|
|
* @param handler Chat member update handler
|
|
* @param group Handler group index
|
|
*/
|
|
onChatMemberUpdate<Mod>(
|
|
filter: UpdateFilter<UpdateContext<ChatMemberUpdate>, Mod>,
|
|
handler: ChatMemberUpdateHandler<filters.Modify<UpdateContext<ChatMemberUpdate>, Mod>>['callback'],
|
|
group?: number,
|
|
): void
|
|
|
|
/** @internal */
|
|
onChatMemberUpdate(filter: any, handler?: any, group?: number): void {
|
|
this._addKnownHandler('chat_member', filter, handler, group)
|
|
}
|
|
|
|
/**
|
|
* Register an inline query handler without any filters
|
|
*
|
|
* @param handler Inline query handler
|
|
* @param group Handler group index
|
|
*/
|
|
onInlineQuery(handler: InlineQueryHandler['callback'], group?: number): void
|
|
|
|
/**
|
|
* Register an inline query handler with a filter
|
|
*
|
|
* @param filter Update filter
|
|
* @param handler Inline query handler
|
|
* @param group Handler group index
|
|
*/
|
|
onInlineQuery<Mod>(
|
|
filter: UpdateFilter<InlineQueryContext, Mod>,
|
|
handler: InlineQueryHandler<filters.Modify<InlineQueryContext, Mod>>['callback'],
|
|
group?: number,
|
|
): void
|
|
|
|
/** @internal */
|
|
onInlineQuery(filter: any, handler?: any, group?: number): void {
|
|
this._addKnownHandler('inline_query', filter, handler, group)
|
|
}
|
|
|
|
/**
|
|
* Register a chosen inline result handler without any filters
|
|
*
|
|
* @param handler Chosen inline result handler
|
|
* @param group Handler group index
|
|
*/
|
|
onChosenInlineResult(handler: ChosenInlineResultHandler['callback'], group?: number): void
|
|
|
|
/**
|
|
* Register a chosen inline result handler with a filter
|
|
*
|
|
* @param filter Update filter
|
|
* @param handler Chosen inline result handler
|
|
* @param group Handler group index
|
|
*/
|
|
onChosenInlineResult<Mod>(
|
|
filter: UpdateFilter<ChosenInlineResultContext, Mod>,
|
|
handler: ChosenInlineResultHandler<filters.Modify<ChosenInlineResultContext, Mod>>['callback'],
|
|
group?: number,
|
|
): void
|
|
|
|
/** @internal */
|
|
onChosenInlineResult(filter: any, handler?: any, group?: number): void {
|
|
this._addKnownHandler('chosen_inline_result', filter, handler, group)
|
|
}
|
|
|
|
/**
|
|
* Register a callback query handler without any filters
|
|
*
|
|
* @param handler Callback query handler
|
|
* @param group Handler group index
|
|
*/
|
|
onCallbackQuery(
|
|
handler: CallbackQueryHandler<
|
|
CallbackQueryContext,
|
|
State extends never ? never : UpdateState<State>
|
|
>['callback'],
|
|
group?: number,
|
|
): void
|
|
|
|
/**
|
|
* Register a callback query handler with a filter
|
|
*
|
|
* @param filter Update filter
|
|
* @param handler Callback query handler
|
|
* @param group Handler group index
|
|
*/
|
|
onCallbackQuery<Mod>(
|
|
filter: UpdateFilter<CallbackQueryContext, Mod, State>,
|
|
handler: CallbackQueryHandler<
|
|
filters.Modify<CallbackQueryContext, Mod>,
|
|
State extends never ? never : UpdateState<State>
|
|
>['callback'],
|
|
group?: number,
|
|
): void
|
|
|
|
/**
|
|
* Register a callback query handler with a filter
|
|
*
|
|
* @param filter Update filter
|
|
* @param handler Callback query handler
|
|
* @param group Handler group index
|
|
*/
|
|
onCallbackQuery<Mod>(
|
|
filter: UpdateFilter<CallbackQueryContext, Mod>,
|
|
handler: CallbackQueryHandler<
|
|
filters.Modify<CallbackQueryContext, Mod>,
|
|
State extends never ? never : UpdateState<State>
|
|
>['callback'],
|
|
group?: number,
|
|
): void
|
|
|
|
/** @internal */
|
|
onCallbackQuery(filter: any, handler?: any, group?: number): void {
|
|
this._addKnownHandler('callback_query', filter, handler, group)
|
|
}
|
|
|
|
/**
|
|
* Register an inline callback query handler without any filters
|
|
*
|
|
* @param handler Inline callback query handler
|
|
* @param group Handler group index
|
|
*/
|
|
onInlineCallbackQuery(
|
|
handler: InlineCallbackQueryHandler<
|
|
InlineCallbackQueryContext,
|
|
State extends never ? never : UpdateState<State>
|
|
>['callback'],
|
|
group?: number,
|
|
): void
|
|
|
|
/**
|
|
* Register an inline callback query handler with a filter
|
|
*
|
|
* @param filter Update filter
|
|
* @param handler Inline callback query handler
|
|
* @param group Handler group index
|
|
*/
|
|
onInlineCallbackQuery<Mod>(
|
|
filter: UpdateFilter<InlineCallbackQueryContext, Mod, State>,
|
|
handler: InlineCallbackQueryHandler<
|
|
filters.Modify<InlineCallbackQueryContext, Mod>,
|
|
State extends never ? never : UpdateState<State>
|
|
>['callback'],
|
|
group?: number,
|
|
): void
|
|
|
|
/**
|
|
* Register an inline callback query handler with a filter
|
|
*
|
|
* @param filter Update filter
|
|
* @param handler Inline callback query handler
|
|
* @param group Handler group index
|
|
*/
|
|
onInlineCallbackQuery<Mod>(
|
|
filter: UpdateFilter<InlineCallbackQueryContext, Mod>,
|
|
handler: InlineCallbackQueryHandler<
|
|
filters.Modify<InlineCallbackQueryContext, Mod>,
|
|
State extends never ? never : UpdateState<State>
|
|
>['callback'],
|
|
group?: number,
|
|
): void
|
|
|
|
/** @internal */
|
|
onInlineCallbackQuery(filter: any, handler?: any, group?: number): void {
|
|
this._addKnownHandler('inline_callback_query', filter, handler, group)
|
|
}
|
|
|
|
/**
|
|
* Register a business callback query handler without any filters
|
|
*
|
|
* @param handler Business callback query handler
|
|
* @param group Handler group index
|
|
*/
|
|
onBusinessCallbackQuery(
|
|
handler: BusinessCallbackQueryHandler<
|
|
BusinessCallbackQueryContext,
|
|
State extends never ? never : UpdateState<State>
|
|
>['callback'],
|
|
group?: number,
|
|
): void
|
|
|
|
/**
|
|
* Register a business callback query handler with a filter
|
|
*
|
|
* @param filter Update filter
|
|
* @param handler Business callback query handler
|
|
* @param group Handler group index
|
|
*/
|
|
onBusinessCallbackQuery<Mod>(
|
|
filter: UpdateFilter<BusinessCallbackQueryContext, Mod, State>,
|
|
handler: BusinessCallbackQueryHandler<
|
|
filters.Modify<BusinessCallbackQueryContext, Mod>,
|
|
State extends never ? never : UpdateState<State>
|
|
>['callback'],
|
|
group?: number,
|
|
): void
|
|
|
|
/**
|
|
* Register a business callback query handler with a filter
|
|
*
|
|
* @param filter Update filter
|
|
* @param handler Business callback query handler
|
|
* @param group Handler group index
|
|
*/
|
|
onBusinessCallbackQuery<Mod>(
|
|
filter: UpdateFilter<BusinessCallbackQueryContext, Mod>,
|
|
handler: BusinessCallbackQueryHandler<
|
|
filters.Modify<BusinessCallbackQueryContext, Mod>,
|
|
State extends never ? never : UpdateState<State>
|
|
>['callback'],
|
|
group?: number,
|
|
): void
|
|
|
|
/** @internal */
|
|
onBusinessCallbackQuery(filter: any, handler?: any, group?: number): void {
|
|
this._addKnownHandler('business_callback_query', filter, handler, group)
|
|
}
|
|
|
|
/**
|
|
* Register a poll update handler without any filters
|
|
*
|
|
* @param handler Poll update handler
|
|
* @param group Handler group index
|
|
*/
|
|
onPollUpdate(handler: PollUpdateHandler['callback'], group?: number): void
|
|
|
|
/**
|
|
* Register a poll update handler with a filter
|
|
*
|
|
* @param filter Update filter
|
|
* @param handler Poll update handler
|
|
* @param group Handler group index
|
|
*/
|
|
onPollUpdate<Mod>(
|
|
filter: UpdateFilter<UpdateContext<PollUpdate>, Mod>,
|
|
handler: PollUpdateHandler<filters.Modify<UpdateContext<PollUpdate>, Mod>>['callback'],
|
|
group?: number,
|
|
): void
|
|
|
|
/** @internal */
|
|
onPollUpdate(filter: any, handler?: any, group?: number): void {
|
|
this._addKnownHandler('poll', filter, handler, group)
|
|
}
|
|
|
|
/**
|
|
* Register a poll vote handler without any filters
|
|
*
|
|
* @param handler Poll vote handler
|
|
* @param group Handler group index
|
|
*/
|
|
onPollVote(handler: PollVoteHandler['callback'], group?: number): void
|
|
|
|
/**
|
|
* Register a poll vote handler with a filter
|
|
*
|
|
* @param filter Update filter
|
|
* @param handler Poll vote handler
|
|
* @param group Handler group index
|
|
*/
|
|
onPollVote<Mod>(
|
|
filter: UpdateFilter<UpdateContext<PollVoteUpdate>, Mod>,
|
|
handler: PollVoteHandler<filters.Modify<UpdateContext<PollVoteUpdate>, Mod>>['callback'],
|
|
group?: number,
|
|
): void
|
|
|
|
/** @internal */
|
|
onPollVote(filter: any, handler?: any, group?: number): void {
|
|
this._addKnownHandler('poll_vote', filter, handler, group)
|
|
}
|
|
|
|
/**
|
|
* Register an user status update handler without any filters
|
|
*
|
|
* @param handler User status update handler
|
|
* @param group Handler group index
|
|
*/
|
|
onUserStatusUpdate(handler: UserStatusUpdateHandler['callback'], group?: number): void
|
|
|
|
/**
|
|
* Register an user status update handler with a filter
|
|
*
|
|
* @param filter Update filter
|
|
* @param handler User status update handler
|
|
* @param group Handler group index
|
|
*/
|
|
onUserStatusUpdate<Mod>(
|
|
filter: UpdateFilter<UpdateContext<UserStatusUpdate>, Mod>,
|
|
handler: UserStatusUpdateHandler<filters.Modify<UpdateContext<UserStatusUpdate>, Mod>>['callback'],
|
|
group?: number,
|
|
): void
|
|
|
|
/** @internal */
|
|
onUserStatusUpdate(filter: any, handler?: any, group?: number): void {
|
|
this._addKnownHandler('user_status', filter, handler, group)
|
|
}
|
|
|
|
/**
|
|
* Register an user typing handler without any filters
|
|
*
|
|
* @param handler User typing handler
|
|
* @param group Handler group index
|
|
*/
|
|
onUserTyping(handler: UserTypingHandler['callback'], group?: number): void
|
|
|
|
/**
|
|
* Register an user typing handler with a filter
|
|
*
|
|
* @param filter Update filter
|
|
* @param handler User typing handler
|
|
* @param group Handler group index
|
|
*/
|
|
onUserTyping<Mod>(
|
|
filter: UpdateFilter<UpdateContext<UserTypingUpdate>, Mod>,
|
|
handler: UserTypingHandler<filters.Modify<UpdateContext<UserTypingUpdate>, Mod>>['callback'],
|
|
group?: number,
|
|
): void
|
|
|
|
/** @internal */
|
|
onUserTyping(filter: any, handler?: any, group?: number): void {
|
|
this._addKnownHandler('user_typing', filter, handler, group)
|
|
}
|
|
|
|
/**
|
|
* Register a history read handler without any filters
|
|
*
|
|
* @param handler History read handler
|
|
* @param group Handler group index
|
|
*/
|
|
onHistoryRead(handler: HistoryReadHandler['callback'], group?: number): void
|
|
|
|
/**
|
|
* Register a history read handler with a filter
|
|
*
|
|
* @param filter Update filter
|
|
* @param handler History read handler
|
|
* @param group Handler group index
|
|
*/
|
|
onHistoryRead<Mod>(
|
|
filter: UpdateFilter<UpdateContext<HistoryReadUpdate>, Mod>,
|
|
handler: HistoryReadHandler<filters.Modify<UpdateContext<HistoryReadUpdate>, Mod>>['callback'],
|
|
group?: number,
|
|
): void
|
|
|
|
/** @internal */
|
|
onHistoryRead(filter: any, handler?: any, group?: number): void {
|
|
this._addKnownHandler('history_read', filter, handler, group)
|
|
}
|
|
|
|
/**
|
|
* Register a bot stopped handler without any filters
|
|
*
|
|
* @param handler Bot stopped handler
|
|
* @param group Handler group index
|
|
*/
|
|
onBotStopped(handler: BotStoppedHandler['callback'], group?: number): void
|
|
|
|
/**
|
|
* Register a bot stopped handler with a filter
|
|
*
|
|
* @param filter Update filter
|
|
* @param handler Bot stopped handler
|
|
* @param group Handler group index
|
|
*/
|
|
onBotStopped<Mod>(
|
|
filter: UpdateFilter<UpdateContext<BotStoppedUpdate>, Mod>,
|
|
handler: BotStoppedHandler<filters.Modify<UpdateContext<BotStoppedUpdate>, Mod>>['callback'],
|
|
group?: number,
|
|
): void
|
|
|
|
/** @internal */
|
|
onBotStopped(filter: any, handler?: any, group?: number): void {
|
|
this._addKnownHandler('bot_stopped', filter, handler, group)
|
|
}
|
|
|
|
/**
|
|
* Register a bot chat join request handler without any filters
|
|
*
|
|
* @param handler Bot chat join request handler
|
|
* @param group Handler group index
|
|
*/
|
|
onBotChatJoinRequest(handler: BotChatJoinRequestHandler['callback'], group?: number): void
|
|
|
|
/**
|
|
* Register a bot chat join request handler with a filter
|
|
*
|
|
* @param filter Update filter
|
|
* @param handler Bot chat join request handler
|
|
* @param group Handler group index
|
|
*/
|
|
onBotChatJoinRequest<Mod>(
|
|
filter: UpdateFilter<ChatJoinRequestUpdateContext, Mod>,
|
|
handler: BotChatJoinRequestHandler<filters.Modify<ChatJoinRequestUpdateContext, Mod>>['callback'],
|
|
group?: number,
|
|
): void
|
|
|
|
/** @internal */
|
|
onBotChatJoinRequest(filter: any, handler?: any, group?: number): void {
|
|
this._addKnownHandler('bot_chat_join_request', filter, handler, group)
|
|
}
|
|
|
|
/**
|
|
* Register a chat join request handler without any filters
|
|
*
|
|
* @param handler Chat join request handler
|
|
* @param group Handler group index
|
|
*/
|
|
onChatJoinRequest(handler: ChatJoinRequestHandler['callback'], group?: number): void
|
|
|
|
/**
|
|
* Register a chat join request handler with a filter
|
|
*
|
|
* @param filter Update filter
|
|
* @param handler Chat join request handler
|
|
* @param group Handler group index
|
|
*/
|
|
onChatJoinRequest<Mod>(
|
|
filter: UpdateFilter<UpdateContext<ChatJoinRequestUpdate>, Mod>,
|
|
handler: ChatJoinRequestHandler<filters.Modify<UpdateContext<ChatJoinRequestUpdate>, Mod>>['callback'],
|
|
group?: number,
|
|
): void
|
|
|
|
/** @internal */
|
|
onChatJoinRequest(filter: any, handler?: any, group?: number): void {
|
|
this._addKnownHandler('chat_join_request', filter, handler, group)
|
|
}
|
|
|
|
/**
|
|
* Register a pre checkout query handler without any filters
|
|
*
|
|
* @param handler Pre checkout query handler
|
|
* @param group Handler group index
|
|
*/
|
|
onPreCheckoutQuery(handler: PreCheckoutQueryHandler['callback'], group?: number): void
|
|
|
|
/**
|
|
* Register a pre checkout query handler with a filter
|
|
*
|
|
* @param filter Update filter
|
|
* @param handler Pre checkout query handler
|
|
* @param group Handler group index
|
|
*/
|
|
onPreCheckoutQuery<Mod>(
|
|
filter: UpdateFilter<PreCheckoutQueryContext, Mod>,
|
|
handler: PreCheckoutQueryHandler<filters.Modify<PreCheckoutQueryContext, Mod>>['callback'],
|
|
group?: number,
|
|
): void
|
|
|
|
/** @internal */
|
|
onPreCheckoutQuery(filter: any, handler?: any, group?: number): void {
|
|
this._addKnownHandler('pre_checkout_query', filter, handler, group)
|
|
}
|
|
|
|
/**
|
|
* Register a story update handler without any filters
|
|
*
|
|
* @param handler Story update handler
|
|
* @param group Handler group index
|
|
*/
|
|
onStoryUpdate(handler: StoryUpdateHandler['callback'], group?: number): void
|
|
|
|
/**
|
|
* Register a story update handler with a filter
|
|
*
|
|
* @param filter Update filter
|
|
* @param handler Story update handler
|
|
* @param group Handler group index
|
|
*/
|
|
onStoryUpdate<Mod>(
|
|
filter: UpdateFilter<UpdateContext<StoryUpdate>, Mod>,
|
|
handler: StoryUpdateHandler<filters.Modify<UpdateContext<StoryUpdate>, Mod>>['callback'],
|
|
group?: number,
|
|
): void
|
|
|
|
/** @internal */
|
|
onStoryUpdate(filter: any, handler?: any, group?: number): void {
|
|
this._addKnownHandler('story', filter, handler, group)
|
|
}
|
|
|
|
/**
|
|
* Register a delete story handler without any filters
|
|
*
|
|
* @param handler Delete story handler
|
|
* @param group Handler group index
|
|
*/
|
|
onDeleteStory(handler: DeleteStoryHandler['callback'], group?: number): void
|
|
|
|
/**
|
|
* Register a delete story handler with a filter
|
|
*
|
|
* @param filter Update filter
|
|
* @param handler Delete story handler
|
|
* @param group Handler group index
|
|
*/
|
|
onDeleteStory<Mod>(
|
|
filter: UpdateFilter<UpdateContext<DeleteStoryUpdate>, Mod>,
|
|
handler: DeleteStoryHandler<filters.Modify<UpdateContext<DeleteStoryUpdate>, Mod>>['callback'],
|
|
group?: number,
|
|
): void
|
|
|
|
/** @internal */
|
|
onDeleteStory(filter: any, handler?: any, group?: number): void {
|
|
this._addKnownHandler('delete_story', filter, handler, group)
|
|
}
|
|
|
|
/**
|
|
* Register a bot reaction update handler without any filters
|
|
*
|
|
* @param handler Bot reaction update handler
|
|
* @param group Handler group index
|
|
*/
|
|
onBotReactionUpdate(handler: BotReactionUpdateHandler['callback'], group?: number): void
|
|
|
|
/**
|
|
* Register a bot reaction update handler with a filter
|
|
*
|
|
* @param filter Update filter
|
|
* @param handler Bot reaction update handler
|
|
* @param group Handler group index
|
|
*/
|
|
onBotReactionUpdate<Mod>(
|
|
filter: UpdateFilter<UpdateContext<BotReactionUpdate>, Mod>,
|
|
handler: BotReactionUpdateHandler<filters.Modify<UpdateContext<BotReactionUpdate>, Mod>>['callback'],
|
|
group?: number,
|
|
): void
|
|
|
|
/** @internal */
|
|
onBotReactionUpdate(filter: any, handler?: any, group?: number): void {
|
|
this._addKnownHandler('bot_reaction', filter, handler, group)
|
|
}
|
|
|
|
/**
|
|
* Register a bot reaction count update handler without any filters
|
|
*
|
|
* @param handler Bot reaction count update handler
|
|
* @param group Handler group index
|
|
*/
|
|
onBotReactionCountUpdate(handler: BotReactionCountUpdateHandler['callback'], group?: number): void
|
|
|
|
/**
|
|
* Register a bot reaction count update handler with a filter
|
|
*
|
|
* @param filter Update filter
|
|
* @param handler Bot reaction count update handler
|
|
* @param group Handler group index
|
|
*/
|
|
onBotReactionCountUpdate<Mod>(
|
|
filter: UpdateFilter<UpdateContext<BotReactionCountUpdate>, Mod>,
|
|
handler: BotReactionCountUpdateHandler<filters.Modify<UpdateContext<BotReactionCountUpdate>, Mod>>['callback'],
|
|
group?: number,
|
|
): void
|
|
|
|
/** @internal */
|
|
onBotReactionCountUpdate(filter: any, handler?: any, group?: number): void {
|
|
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
|
|
}
|