Files
hereconnect/services/tg-bot/src/bot/conversations/newQRCodeConversation.ts
T

154 lines
4.9 KiB
TypeScript
Raw Normal View History

2024-12-10 13:21:38 +02:00
import { type QRCodeDocument } from "@hereconnect/types";
import { Conversation } from "@grammyjs/conversations";
import { InputFile } from "grammy";
import type { MyContext } from "../../types/myContext";
import { qrCodePlacements } from "../../types/models";
2024-12-10 13:21:38 +02:00
import {
buildPlacementKeyboard,
buildActionsKeyboard,
} from "../utils/keyboards";
import { createQRCode } from "../../api/qrCodes";
import { generateQRCodeImage } from "../../services/qrGenerator";
2024-12-12 17:45:01 +02:00
import { selectMultipleActions } from "./selectMultipleActions";
2024-12-17 02:41:14 +02:00
import { defaultMessages } from "@hereconnect/constants";
import { selectPredefinedMessages } from "./selectPredefinedMessages";
2024-12-19 11:39:28 +02:00
import { publicSettingsDb } from "../../dbs";
2024-12-10 13:21:38 +02:00
export async function newQRCodeConversation(
conversation: Conversation<MyContext>,
2024-12-10 13:21:38 +02:00
ctx: MyContext,
) {
if (!ctx.userDoc) {
await ctx.reply(
"Не удалось определить вашего пользователя. Попробуйте позже.",
);
return;
}
const userUuid = ctx.userDoc.user_uuid;
if (!userUuid) {
await ctx.reply(
"У вашего профиля отсутствует UUID. Обратитесь в поддержку.",
);
return;
}
2024-12-17 02:41:14 +02:00
// Выбор типа объекта (placement)
2024-12-10 13:21:38 +02:00
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: "Объект выбран!" });
2024-12-17 02:41:14 +02:00
// Выбор действий
const availableActions = [
{ action: "sendMessage", label: "Отправить сообщение" },
{ action: "viewContactInfo", label: "Посмотреть контактные данные" },
] as const;
const chosenActions = await selectMultipleActions(
conversation,
ctx,
availableActions,
);
if (chosenActions.length === 0) {
await ctx.reply("Вы не выбрали ни одного действия. Попробуйте снова /new.");
return;
}
// Ввод названия QR-кода
2024-12-16 21:41:32 +02:00
let exampleName: string;
switch (typedPlacement) {
case "car":
exampleName = "Моя машина";
break;
case "pet":
exampleName = "Ошейник Барсика";
break;
case "door":
exampleName = "Входная дверь квартиры";
break;
case "store":
exampleName = "Магазин на углу";
break;
case "restaurant_table":
exampleName = "Столик №12";
break;
case "other":
exampleName = "Что-то другое";
break;
}
2024-12-17 02:41:14 +02:00
let predefinedMessages: QRCodeDocument["predefinedMessages"] = undefined;
if (chosenActions.includes("sendMessage")) {
predefinedMessages = await selectPredefinedMessages(
conversation,
ctx,
typedPlacement,
);
}
2024-12-16 21:41:32 +02:00
// Отправляем сообщение пользователю с примером
2024-12-10 13:21:38 +02:00
await ctx.reply(
2024-12-16 21:41:32 +02:00
`Введите название для вашего QR-кода (например: «${exampleName}»):`,
2024-12-10 13:21:38 +02:00
);
2024-12-16 21:41:32 +02:00
2024-12-10 13:21:38 +02:00
const nameMsg = await conversation.waitFor("message:text");
const name = nameMsg.message.text.trim();
2024-12-17 02:41:14 +02:00
// Уведомление о создании QR-кода
await ctx.reply("Создаём QR-код…");
2024-12-10 13:21:38 +02:00
2024-12-17 02:41:14 +02:00
// Создание документа в БД
2024-12-12 17:45:01 +02:00
const { url } = await createQRCode({
2024-12-10 13:21:38 +02:00
userUuid,
name,
placement: typedPlacement,
actions: chosenActions,
2024-12-17 02:41:14 +02:00
predefinedMessages,
2024-12-10 13:21:38 +02:00
});
2024-12-17 02:41:14 +02:00
// Генерация QR-кода
2024-12-10 13:21:38 +02:00
const pngBuffer = await generateQRCodeImage(url, { format: "png" });
2024-12-17 02:41:14 +02:00
// Отправляем пользователю QR-код
2024-12-10 13:21:38 +02:00
await ctx.reply("Ваш QR-код готов! Вот он:");
await ctx.replyWithPhoto(
new InputFile(new Uint8Array(pngBuffer.buffer), "qr.png"),
);
2024-12-19 11:39:28 +02:00
const { value: instruction } = await publicSettingsDb
.get(`public_settings:placement_instructions_${typedPlacement}`)
.catch((error) => {
console.error(error);
return { value: "Разместите этот код на вашем объекте." };
});
2024-12-10 13:21:38 +02:00
await ctx.reply(
2024-12-19 11:46:11 +02:00
`${instruction}\n\nВ этом QR-коде хранится ссылка ${url}`.trim(),
{
parse_mode: "Markdown",
},
2024-12-10 13:21:38 +02:00
);
// Завершаем разговор
}