create qr-codes by tg bot
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
import { type QRCodeDocument } from "@hereconnect/types";
|
||||
import { Conversation } from "@grammyjs/conversations";
|
||||
import { InputFile } from "grammy";
|
||||
import type { MyContext } from "../../types/myContext";
|
||||
import { qrCodePlacements } from "../../models/types";
|
||||
import {
|
||||
buildPlacementKeyboard,
|
||||
buildActionsKeyboard,
|
||||
} from "../utils/keyboards";
|
||||
import { createQRCode } from "../../api/qrCodes";
|
||||
import { generateQRCodeImage } from "../../services/qrGenerator";
|
||||
|
||||
// Тип разговора (конверсии)
|
||||
type MyConversation = Conversation<MyContext>;
|
||||
|
||||
export async function newQRCodeConversation(
|
||||
conversation: MyConversation,
|
||||
ctx: MyContext,
|
||||
) {
|
||||
if (!ctx.userDoc) {
|
||||
await ctx.reply(
|
||||
"Не удалось определить вашего пользователя. Попробуйте позже.",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const userUuid = ctx.userDoc.user_uuid;
|
||||
if (!userUuid) {
|
||||
await ctx.reply(
|
||||
"У вашего профиля отсутствует UUID. Обратитесь в поддержку.",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// 1. Выбор типа объекта (placement)
|
||||
await ctx.reply("Выберите объект, для которого будет создан QR-код:", {
|
||||
reply_markup: {
|
||||
inline_keyboard: buildPlacementKeyboard(qrCodePlacements),
|
||||
},
|
||||
});
|
||||
|
||||
const placementChoice = await conversation.waitFor("callback_query:data");
|
||||
const placement = placementChoice.update.callback_query?.data;
|
||||
|
||||
// Проверяем, что выбранное значение входит в допустимые типы
|
||||
if (!qrCodePlacements.some((p) => p.type === placement)) {
|
||||
await ctx.reply("Неверный выбор. Попробуйте снова /new");
|
||||
return;
|
||||
}
|
||||
|
||||
// Преобразуем `placement` в строго типизированное значение
|
||||
const typedPlacement = placement as QRCodeDocument["placement"];
|
||||
|
||||
// Подтверждаем выбор
|
||||
await placementChoice.answerCallbackQuery({ text: "Объект выбран!" });
|
||||
|
||||
// 2. Ввод названия QR-кода
|
||||
await ctx.reply(
|
||||
"Введите название для вашего QR-кода (например: 'Моя машина'):",
|
||||
);
|
||||
const nameMsg = await conversation.waitFor("message:text");
|
||||
const name = nameMsg.message.text.trim();
|
||||
if (name.length < 2) {
|
||||
await ctx.reply(
|
||||
"Название должно содержать минимум 2 символа. Попробуйте снова /new.",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// 3. Выбор действий, доступных при сканировании
|
||||
await ctx.reply("Выберите доступные действия:", {
|
||||
reply_markup: {
|
||||
inline_keyboard: buildActionsKeyboard([
|
||||
{ action: "send_message", label: "Отправить сообщение" },
|
||||
{ action: "show_phone", label: "Показать номер телефона" },
|
||||
]),
|
||||
},
|
||||
});
|
||||
|
||||
const actionsMsg = await conversation.waitFor("callback_query:data");
|
||||
const chosenAction = actionsMsg.update.callback_query?.data;
|
||||
if (!chosenAction) {
|
||||
await ctx.reply("Вы не выбрали действие. Попробуйте снова /new.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Подтверждаем выбор
|
||||
await actionsMsg.answerCallbackQuery({ text: "Действие выбрано!" });
|
||||
|
||||
// Пока для MVP можно выбрать только одно действие, в будущем можно расширить
|
||||
const chosenActions = [chosenAction];
|
||||
|
||||
// 4. Создание документа в БД
|
||||
const { url, uri } = await createQRCode({
|
||||
userUuid,
|
||||
name,
|
||||
placement: typedPlacement,
|
||||
actions: chosenActions,
|
||||
});
|
||||
|
||||
// 5. Генерация QR-кода
|
||||
const pngBuffer = await generateQRCodeImage(url, { format: "png" });
|
||||
|
||||
// 6. Отправляем пользователю QR-код
|
||||
await ctx.reply("Ваш QR-код готов! Вот он:");
|
||||
|
||||
await ctx.replyWithPhoto(
|
||||
new InputFile(new Uint8Array(pngBuffer.buffer), "qr.png"),
|
||||
);
|
||||
|
||||
await ctx.reply(
|
||||
`Разместите этот код на вашем объекте. При сканировании по адресу ${url} посетители смогут взаимодействовать с вами.`,
|
||||
);
|
||||
|
||||
// Завершаем разговор
|
||||
}
|
||||
Reference in New Issue
Block a user