import { Observable } from 'rxjs'; import Telegraf, { Context } from 'telegraf'; import { Message } from 'telegraf/typings/telegram-types'; import { IInputOpts } from '../common/input-opts'; import { IReplyMessage } from '../common/reply-message'; import { IBotSettings } from '../create-bot'; /** * Marks a class as the bot implementation logic and prepares a platform for * other decorators such as `state()`, `action()` and `@command()`. * * This decorators adds bunch of new functions to the class, hence for type * safety, you can write an empty interface extending `IBot` with the same * name of your class. Hence, you will get your type definitions. * * @example * ```js * export interface SearchBot extends IBot {} * * @bot() * export class SearchBot { * // Implementation here * } * ``` * * @export * @param {IBotSettings} [opts] Options for the bot. * @returns */ export declare function bot(opts?: IBotSettings): {}>(constr: T) => T; export interface IBot { /** * Reference to the Telegraf instance. * * @type {Telegraf} * @memberof IBot */ readonly ref: Telegraf; /** * Initializes the class and provides a platform for other decorated * properties and functions. * * This function should be called at the beginning of the bot, if, * the start function is implemented manually. * * @memberof IBot */ init(): void; /** * Runs the bot. * * This function calls `init()` to initialize the environment of the bot * and `launch()` and `startPolling()` functions of the Telegraf instance * **if this is not defined manually**. * * @memberof IBot */ run(): void; /** * Resets all of the bot states for the executing user. * * @memberof IBot */ resetStates(): void; /** * Expects an input from the user. * * @param {(IInputOpts | string)} obj Input options or just the message. * @returns {(Promise)} A promise of string or false. * - Resolves with false when user input is not matched according to given * `match` option and no trials left. * - Resolves with the string of user input if user input is matching with * the given regular expression. If no `match` is set, then this is the * message user replied. * * @memberof IBot */ input$(obj: IInputOpts | string): Promise; /** * Sends a message to the user. * * @param {(IReplyMessage | string)} obj Message options or just the message. * @returns {Promise} A promise that will be resolved when * the message is sent. * - Resolves with false if the `obj` was containing a message to edit and * the contents of the message were equal. * - Resolves with message sent by the bot on success, resolves with true * otherwise. * * @memberof IBot */ message$(obj: IReplyMessage | string): Promise; /** * Checks whether the input returned from `input$()` was cancel symbol * or not. So you can check whether the previous operation is cancelled * or not. * * This is expected when, user takes an action without sending a message. * Since the action itself is treated as a return from user, the * `WaitingStates` will resolve the message, although the user did not * sent any. * * Therefore, always use this after you resolve the user input if you also * provide actions with the input message. * * @example * ``` * const selection = await this.input$({ * input: `Please choose an index: ${indexList}`, * match: /^(next|prev|cancel|\d\d?)$/i, * extra: Extra.markup(Markup.inlineKeyboard([ * { text: 'Prev', callback_data: 'didPrevClick', hide: false }, * { text: 'Next', callback_data: 'didNextClick', hide: false }, * ])), * edit: this._messageToUpdate, * cancelPrevious: true, * didMessageSend: message => { this._messageToUpdate = message } * }) * * if (this.isCancelled(selection)) { * // Simply return, the message is sent by the `WaitingStates`, not by * // the user, hence it could be skipped. The selection above is probably * // used in generator and replaced with the new page after an action * // and the previous promise returned from the old page is useless. * return * } * ``` * * @param {*} thing The message resolved from the `input$()` function. * @returns {boolean} `true` if the message is a cancel symbol. * @memberof IBot */ isCancelled(thing: any): boolean; /** * Cancels awaiting an input. Use this function in cleanup functions, such * as discards, cancels, and similar actions. * * @example * ```js * class SearchBot { * @state() private query = '' * @state() private index = 0 * * @action() * async didCancelPress() { * this.cancelInput() * this.query = '' * this.index = 0 * } * } * ``` * * @returns {boolean} `true` if cancelled, `false` if it was not awaited. * @memberof IBot */ cancelInput(): boolean; /** * Returns an observable for listening events emitted from this class. * * @returns {Observable} An observable for listening events. * @memberof IBot */ listenEvents$(): Observable; /** * The current message context. * * @type {ContextMessageUpdate} * @memberof IBot */ readonly context: Context; /** * The last match of the `@hears` decorated function. * * @type {RegExpMatchArray} * @memberof IBot */ readonly lastMatch?: RegExpMatchArray; /** * The whole last match. * * @type {string} * @memberof IBot */ readonly $0?: string; /** * The first group in the last match. * * @type {string} * @memberof IBot */ readonly $1?: string; /** * The second group in the last match. * * @type {string} * @memberof IBot */ readonly $2?: string; /** * The thirhd group in the last match. * * @type {string} * @memberof IBot */ readonly $3?: string; /** * The fourth group in the last match. * * @type {string} * @memberof IBot */ readonly $4?: string; /** * The fifth group in the last match. * * @type {string} * @memberof IBot */ readonly $5?: string; /** * The sixty group in the last match. * * @type {string} * @memberof IBot */ readonly $6?: string; /** * The seventh group in the last match. * * @type {string} * @memberof IBot */ readonly $7?: string; /** * The eighth group in the last match. * * @type {string} * @memberof IBot */ readonly $8?: string; /** * The ninth group in the last match. * * @type {string} * @memberof IBot */ readonly $9?: string; }