import { Bot, Context, InlineKeyboard } from "grammy"; import { type AbortSignal } from "grammy/out/shim.node"; import { qrCodePlacements } from "@hereconnect/constants"; import type { QRCodeDocument } from "@hereconnect/types"; const BOT_TOKEN = process.env.BOT_TOKEN; if (!BOT_TOKEN) { throw new Error("Необходимо указать BOT_TOKEN в переменных окружения."); } export const bot = new Bot(BOT_TOKEN); export const init = async (signal: AbortSignal) => { await bot.init(signal); // Настройка команд для английского языка (по умолчанию) await bot.api.setMyCommands([ { command: "create_qr", description: "Create a QR code" }, { command: "help", description: "Get help" }, ]); // Настройка команд для русского языка await bot.api.setMyCommands( [ { command: "create_qr", description: "Создать QR-код" }, { command: "help", description: "Получить помощь" }, ], { language_code: "ru" }, ); }; const actionsOptions = [ { type: "sendMessage", label: "Отправить сообщение", }, { type: "viewContactInfo", label: "Посмотреть ваши контактные данные" }, ]; bot.command("start", async (ctx) => { const user = ctx.from; const message = `Привет${user?.first_name ? ", " + user?.first_name : ""}!\n\nЯ бот сервиса "НаСвязи". Помогу вам создать QR-код (для автомобиля, питомца, входной двери и т.д.).!`; // Отправляем сообщение return ctx.reply(message, { reply_markup: { inline_keyboard: [ [ { text: "Создать QR-код", callback_data: "create_qr", }, ], ], }, }); }); const createQrCode = async (ctx: Context) => { const keyboard = new InlineKeyboard(); for (const { type, label } of qrCodePlacements) { keyboard.text(label, `select_placement=${type}`); } await ctx.reply( "Где вы хотите разместить QR‑код?\n\nЭтот выбор поможет настроить QR‑код с подходящими действиями.", { reply_markup: { inline_keyboard: keyboard.toFlowed(1).inline_keyboard } }, ); }; bot.command("create_qr", createQrCode); bot.callbackQuery("cancel", async (ctx) => { await ctx.deleteMessage(); }); bot.callbackQuery( /^(select_action=|select_placement=|create_qr$)/, async (ctx) => { const selectedActions: QRCodeDocument["actions"] = []; const keyboard = new InlineKeyboard(); for (const { type, label } of actionsOptions) { keyboard.text( (selectedActions.includes(type) ? "✓ " : "") + label, `select_action=${type}`, ); } await ctx.reply( "Выберите доступные действия?\n\nУкажите, какие действия будут доступны для сканирующих QR‑код.\nВы сможете изменить эти настройки позже.", { reply_markup: { inline_keyboard: keyboard.inline_keyboard } }, ); }, ); if (process.argv.includes("start")) { const abortController = new AbortController(); process.on("SIGINT", async () => { abortController.abort(); setTimeout(() => process.exit(1), 1_000).unref(); }); init(abortController.signal as AbortSignal) .then(() => bot.start()) .then(() => console.log("Bot started")) .catch((error) => console.error(error)); }