Skip to main content
Go to Latest
class ConversationHandle
import { ConversationHandle } from "https://deno.land/x/grammy_conversations@v1.1.0/conversation.ts";

Internally used class which acts as a conversation handle.

Constructors

new
ConversationHandle(
ctx: C,
opLog: OpLog,
rsr: Resolver<ResolveOps>,
)

Properties

private
active: boolean
private
optional
currentCtx: C
private
mw: Composer<C>
private
replayIndex: ReplayIndex
readonly
_isReplaying

Internal flag, true if the conversation is currently replaying in order to jump back to an old state, and false otherwise. Do not use unless you know exactly what you are doing.

Utilities for building forms. Contains methods that let you wait for messages and automatically perform input validation.

session: C extends { session: any; } ? C["session"] : never

Safe alias for ctx.session. Use this instead of ctx.session when inside a conversation.

As you call conversation.wait several times throughout the conversation, your session data may evolve. The conversations plugin makes sure to track these changes so that your conversation can work correctly each time it is run. This means that there are several snapshots of the session throughout time which all co-exist. It can be cumbersome to always make sure to use the correct session so that the code does not alter history (this would lead to data loss). You should use this helper type to make sure you are accessing the correct session object at all times.

Methods

Internal method, deactivates the conversation handle. Do not use unless you know exactly what you are doing.

_finalize(slot: AsyncOrder)

Internal method, finalizes a previously generated slot. Do not use unless you know exactly what you are doing.

_logApi(method: string): ApiOp

Internal method, logs an API call and returns the assigned slot. Do not use unless you know exactly what you are doing.

_logExt(): ExtOp

Internal method, logs an external operation and returns the assigned slot. Do not use unless you know exactly what you are doing.

_logWait(op: WaitOp)

Internal method, logs a wait call. Do not use unless you know exactly what you are doing.

_replayApi(method: string): Promise<NonNullable<ApiOp["r"]>>

Internal method, replays an API call operation and advances the replay cursor. Do not use unless you know exactly what you are doing.

_replayExt(): Promise<NonNullable<ExtOp["r"]>>

Internal method, replays an external operation and advances the replay cursor. Do not use unless you know exactly what you are doing.

_replayWait(): Promise<C>

Internal method, replays a wait operation and advances the replay cursor. Do not use unless you know exactly what you are doing.

_resolveAt<T>(index: number, value?: T): Promise<T>

Internal method, creates a promise from a given value that will resolve at the given index in order to accurately restore the order in which different operations complete. Do not use unless you know exactly what you are doing.

Internal method, unlogs the most recent call. Do not use unless you know exactly what you are doing.

error(...args: Parameters<console.error>)

Safely perform console.error calls, but only when they should really be logged (so not during replay operations).

external<F extends (...args: any[]) => any, I = any>(op: F | { task: F; args?: Parameters<F>; beforeStore?: (value: Awaited<ReturnType<F>>) => I | Promise<I>; afterLoad?: (value: I) => ReturnType<F> | Promise<ReturnType<F>>; beforeStoreError?: (value: unknown) => unknown | Promise<unknown>; afterLoadError?: (value: unknown) => unknown; }): Promise<Awaited<ReturnType<F>>>

Safely performs an operation with side-effects. You must use this to wrap all communication with external systems that does not go through grammY, such as database communication or calls to external APIs.

This function will then make sure the operation is only performed once, and not every time a message is handled by the conversation.

It will need to be able to store the result value of this operation in the session. Hence, it must store and load the result of the operation according to your storage adapter. It is therefore best to only return primitive values or POJOs. If you need to transform your data before it can be stored, you can specify the beforeStore function. If you need to transform your data after it was loaded, you can specify the afterLoad function.

log(...args: Parameters<console.log>)

Safely perform console.log calls, but only when they should really be logged (so not during replay operations).

now()

Safely gets the value of Date.now(). You should use this instead of Date.now() in your conversation because the time value changes continuously, which may lead to unpredictable and non-deterministic behavior.

Safely generates a random number from Math.random(). You should use this instead of Math.random() in your conversation because non-deterministic behavior is not allowed.

run(...middleware: Middleware<C>[])
skip(opts?: { drop?: boolean; })

Skips handling the update that was received in the last wait call. Once called, the conversation resets to the last wait call, as if the update had never been received. Unless { drop: true } is passed, the control flow is passed on immediately, so that middleware downstream of the conversation can continue handling the update.

Effectively, calling await conversation.skip() behaves as if this conversation had not received the update at all.

While the conversation rewinds its logs internally, it does not unsend messages that you send between the calls to wait and skip.

sleep(milliseconds: number): Promise<void>

This method is rarely useful because it freezes your bot and that's most likely not actually what you want to do. Consider using one of the variants of wait instead.

Freezes your bot for the specified number of milliseconds. The current middleware execution will simply stop for a while. Note that if you're processing updates concurrently (with grammY runner) then unrelated updates will still be handled in the meantime. Note further that sleeping during webhooks is dangerous because it can lead to duplicate updates.

You should use this instead of your own sleeping function so that you don't block the conversation while it is restoring a previous position.

wait(): Promise<C>

Waits for a new update (e.g. a message, callback query, etc) from the user. Once received, this method returns the new context object for the incoming update.

waitFor<Q extends FilterQuery>(query: Q | Q[], opts?: OtherwiseConfig<C>): Promise<Filter<C, Q>>

Waits for a new update (e.g. a message, callback query, etc) that matches the given filter query. As soon as an update arrives that matches the filter query, the corresponding context object is returned.

waitForCallbackQuery(trigger: MaybeArray<string | RegExp>, opts?: OtherwiseConfig<C>): Promise<CallbackQueryContext<C>>

Waits for an update which contains the given callback query, or for the callback query data to match the given regular expression. This uses the same logic as bot.callbackQuery.

waitForCommand<S extends string>(command: MaybeArray<StringWithSuggestions<
| S
| "start"
| "help"
| "settings"
>>
, opts?: OtherwiseConfig<C>
): Promise<CommandContext<C>>

Waits for the specified command. This uses the same logic as bot.command.

waitForGameQuery(trigger: MaybeArray<string | RegExp>, opts?: OtherwiseConfig<C>): Promise<GameQueryContext<C>>

Waits for an update which contains the given game query, or for the game query data to match the given regular expression. This uses the same logic as bot.gameQuery.

waitForHears(trigger: MaybeArray<string | RegExp>, opts?: OtherwiseConfig<C>): Promise<HearsContext<C>>

Waits for a new message or channel post that contains the given text, or that contains text which matches the given regular expression. This uses the same logic as bot.hears.

waitForReplyTo(message_id: number | { message_id: number; }, opts?: OtherwiseConfig<C>): Promise<Filter<C, "message" | "channel_post">>

Waits for a new message or channel post which replies to the specified message. As soon as an update arrives that contains such a message or channel post, the corresponding context object is returned.

waitFrom(user: number | User, opts?: OtherwiseConfig<C>): Promise<C & { from: User; }>

Waits for a new update (e.g. a message, callback query, etc) from the given user. As soon as an update arrives from this user, the corresponding context object is returned.

waitUnless(predicate: (ctx: C) => boolean | Promise<boolean>, opts?: OtherwiseConfig<C>): Promise<C>

Waits for a new update (e.g. a message, callback query, etc) that does not fulfil a certain condition. This condition is specified via the given predicate function. As soon as an update arrives for which the predicate function returns false, this method will return it.

waitUntil<D extends C>(predicate: (ctx: C) => ctx is D, opts?: OtherwiseConfig<C>): Promise<D>

Waits for a new update (e.g. a message, callback query, etc) that fulfils a certain condition. This condition is specified via the given predicate function. As soon as an update arrives for which the predicate function returns true, this method will return it.

waitUntil(predicate: (ctx: C) => boolean | Promise<boolean>, opts?: OtherwiseConfig<C>): Promise<C>