Prompt Plugin 
A plugin that provides Prompt and Wait methods
NOTE
We recommend considering scenes instead. Please see the comparison of prompt and scenes
Installation 
npm install @gramio/promptyarn add @gramio/promptpnpm add @gramio/promptbun install @gramio/promptUsage 
import { Bot, format, bold } from "gramio";
import { prompt } from "@gramio/prompt";
const bot = new Bot(process.env.BOT_TOKEN as string)
    .extend(prompt())
    .command("start", async (context) => {
        const answer = await context.prompt(
            "message",
            format`What's your ${bold`name`}?`
        );
        return context.send(`✨ Your name is ${answer.text}`);
    })
    .onStart(console.log);
bot.start();Prompt 
Prompt with text + params 
const answer = await context.prompt("What's your name?");
// or with SendMessageParams
const answer = await context.prompt("True or false?", {
    reply_markup: new Keyboard().text("true").row().text("false"),
});answer is MessageContext or CallbackQueryContext
Prompt with text + params and the specified event 
const answer = await context.prompt("message", "What's your name?");
const answer = await context.prompt("callback_query", "True or false?", {
    reply_markup: new InlineKeyboard()
        .text("true", "true")
        .row()
        .text("false", "false"),
});answer is CallbackQueryContext
Validation 
You can define a handler in params to validate the user's answer. If handler returns false, the message will be repeated.
const answer = await context.prompt(
    "message",
    "Enter a string that contains russian letter",
    {
        validate: (context) => /[а-яА-Я]/.test(context.text),
        //... and some SendMessageParams
    }
);Transform 
const name = await context.prompt(
    "message",
    format`What's your ${bold`name`}?`,
    {
        transform: (context) => context.text || context.caption || "",
    }
);name is string
Wait 
Wait for the next event from the user 
const answer = await context.wait();answer is MessageContext or CallbackQueryContext
Wait for the next event from the user ignoring events not listed 
const answer = await context.wait("message");answer is CallbackQueryContext
Wait for the next event from the user ignoring non validated answers 
You can define a handler in params to validate the user's answer. If handler return false, the message will be ignored
const answer = await context.wait((context) => /[а-яА-Я]/.test(context.text));
// or combine with event
const answer = await context.wait("message", (context) =>
    /[а-яА-Я]/.test(context.text)
);Wait for the next event from the user ignoring non validated answers with transformer 
You can define a handler in params to transform the user's answer.
const answer = await context.wait((context) => /[а-яА-Я]/.test(context.text));
// or combine with event
const answer = await context.wait("message", {
    validate: (context) => /[а-яА-Я]/.test(context.text),
    transform: (context) => c.text || "",
});answer is string
waitWithAction 
This function is similar to wait but allows executing an action while waiting for an event and get both results.
const [answer, sentMessage] = await context.waitWithAction(
    "message",
    () => context.send("Please enter your name"),
    {
        validate: (ctx) => !!ctx.text,
        transform: (ctx) => ctx.text.toUpperCase(),
        onValidateError: "Please enter a valid name!",
    }
);
// answer has type `string`
// sentMessage has type `MessageContext`Timeout 
Allows setting a response timeout. After timeout expiration, a PromptCancelError (timeout) error will be thrown (based on timeoutStrategy). The timeout (in milliseconds) can be passed in any method's options.
new Bot()
    .extend(
        prompt({
            timeoutStrategy: "on-timer", // or "on-answer" (default)
        })
    )
    .onError("message", ({ error, kind, context }) => {
        if (kind === "prompt-cancel") {
            // Currently only contains timeout type of error, but this will change
            return context.send("Response time expired :(");
        }
        console.error(error);
        return context.send("An error occurred");
    })
    .command("start", async (context) => {
        const [answer, sentMessage] = await context.waitWithAction(
            "message",
            () => context.send("Please enter your name"),
            {
                timeout: 10_000, // 10 seconds
            }
        );
        return Promise.all([
            sentMessage.delete(),
            context.send(`Thank you, ${answer.text}!`),
        ]);
    });Configuration 
import { prompt, type PromptsType } from "@gramio/prompt";
const mySharedMap: PromptsType = new Map();
new Bot().extend(
    prompt({
        timeoutStrategy: "on-timer",
        defaults: {
            timeout: 30_000, // 30 seconds
            validate: (ctx) => ctx.hasText(),
            transform: (ctx) => ctx.text.toUpperCase(),
            onValidateError: "Validation failed. Please try again.",
        },
        map: mySharedMap,
    })
);timeoutStrategy 
Controls how Timeout error is triggered:
- "on-answer"(default) -- Timeouterror occurs if user sends message AFTER timeout expiration
- "on-timer"-- Timeouterror occurs immediately when timer expires via- setTimeout
defaults 
Allows setting default values for methods.
map 
Enables providing a custom Map for state storage. This allows modifying it from anywhere.