select predefined messages
Deploy db-migrations / db-migrations (push) Successful in 49s
Deploy service message-delivery-method-web-push / service message-delivery-method-web-push (push) Successful in 1m9s
Deploy app frontend / app frontend (push) Successful in 1m53s
Deploy service tg-bot / service tg-bot (push) Successful in 1m36s
Deploy db-migrations / db-migrations (push) Successful in 49s
Deploy service message-delivery-method-web-push / service message-delivery-method-web-push (push) Successful in 1m9s
Deploy app frontend / app frontend (push) Successful in 1m53s
Deploy service tg-bot / service tg-bot (push) Successful in 1m36s
This commit is contained in:
@@ -0,0 +1,325 @@
|
||||
import { MyContext } from "../../types/myContext";
|
||||
import { Conversation } from "@grammyjs/conversations";
|
||||
import { defaultMessages } from "@hereconnect/constants";
|
||||
import { InlineKeyboardMarkup } from "@grammyjs/types";
|
||||
|
||||
// Тип разговора
|
||||
type MyConversation = Conversation<MyContext>;
|
||||
export async function selectPredefinedMessages(
|
||||
conversation: MyConversation,
|
||||
ctx: MyContext,
|
||||
placement: keyof typeof defaultMessages,
|
||||
): Promise<string[]> {
|
||||
const messages: string[] = [...defaultMessages[placement]];
|
||||
let mode: "default" | "edit" | "sort" = "default";
|
||||
let selectedIndex: number | null = null;
|
||||
let sortOrder: number[] = [];
|
||||
|
||||
const updateKeyboard = (): InlineKeyboardMarkup => ({
|
||||
inline_keyboard: messages
|
||||
.map((message, index) => {
|
||||
const prefix =
|
||||
mode === "edit" && selectedIndex === index
|
||||
? "📝 "
|
||||
: mode === "sort" && sortOrder.includes(index)
|
||||
? `${sortOrder.indexOf(index) + 1}. `
|
||||
: "";
|
||||
return [
|
||||
{
|
||||
text: `${prefix}${message}`,
|
||||
callback_data: `select:${index}`,
|
||||
},
|
||||
];
|
||||
})
|
||||
.concat(
|
||||
mode === "sort"
|
||||
? [
|
||||
[{ text: "✅ Завершить сортировку", callback_data: "done_sort" }],
|
||||
[
|
||||
{
|
||||
text: "❌ Отменить сортировку",
|
||||
callback_data: "cancel_sort",
|
||||
},
|
||||
],
|
||||
]
|
||||
: mode === "edit" && selectedIndex !== null
|
||||
? [
|
||||
[
|
||||
{
|
||||
text: `❌ Удалить «${messages[selectedIndex]}»`,
|
||||
callback_data: `delete:${selectedIndex}`,
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
text: "❌ Отменить редактирование",
|
||||
callback_data: "cancel_edit",
|
||||
},
|
||||
],
|
||||
]
|
||||
: messages.length > 0
|
||||
? [
|
||||
[{ text: "🔀 Поменять порядок", callback_data: "sort" }],
|
||||
[{ text: "✅ Готово", callback_data: "done" }],
|
||||
]
|
||||
: [[{ text: "✅ Готово", callback_data: "done" }]],
|
||||
),
|
||||
});
|
||||
|
||||
// Функция для отправки или редактирования сообщения
|
||||
const sendOrEditMessage = async (
|
||||
text: string,
|
||||
options: {
|
||||
reply_markup: InlineKeyboardMarkup;
|
||||
parse_mode?: "Markdown" | "MarkdownV2" | "HTML";
|
||||
},
|
||||
forceNew = false,
|
||||
) => {
|
||||
try {
|
||||
if (forceNew && ctx.session.messageId) {
|
||||
try {
|
||||
await ctx.api.deleteMessage(ctx.chat!.id, ctx.session.messageId);
|
||||
ctx.session.messageId = undefined;
|
||||
console.log("deleteMessage", ctx.session.messageId);
|
||||
} catch (deleteErr) {
|
||||
console.warn(
|
||||
"Ошибка удаления старого сообщения:",
|
||||
ctx.session.messageId,
|
||||
deleteErr,
|
||||
);
|
||||
ctx.session.messageId = undefined;
|
||||
}
|
||||
}
|
||||
if (ctx.session.messageId) {
|
||||
await ctx.api.editMessageText(
|
||||
ctx.chat!.id,
|
||||
ctx.session.messageId,
|
||||
text,
|
||||
options,
|
||||
);
|
||||
} else {
|
||||
const replyMessage = await ctx.reply(text, options);
|
||||
console.log("replyMessage.message_id", replyMessage.message_id);
|
||||
ctx.session.messageId = replyMessage.message_id;
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(
|
||||
"Ошибка обновления сообщения, создаем новое:",
|
||||
ctx.session.messageId,
|
||||
err,
|
||||
);
|
||||
if (ctx.session.messageId) {
|
||||
try {
|
||||
await ctx.api.deleteMessage(ctx.chat!.id, ctx.session.messageId);
|
||||
console.log("deleteMessage", ctx.session.messageId);
|
||||
} catch (deleteErr) {
|
||||
console.warn(
|
||||
"Ошибка удаления старого сообщения:",
|
||||
ctx.session.messageId,
|
||||
deleteErr,
|
||||
);
|
||||
}
|
||||
}
|
||||
const newMessage = await ctx.reply(text, options);
|
||||
console.log("newMessage.message_id", newMessage.message_id);
|
||||
ctx.session.messageId = newMessage.message_id;
|
||||
}
|
||||
};
|
||||
|
||||
// Начальное сообщение
|
||||
await sendOrEditMessage(
|
||||
`**Настройка предустановленных сообщений**
|
||||
Эти сообщения будут предлагаться пользователю при сканировании QR‑кода. Он сможет выбрать одно из них или написать своё.
|
||||
|
||||
Напишите сообщение для добавления, нажмите на сообщение для редактирования или выберите "🔀 Поменять порядок" для сортировки.`,
|
||||
{ parse_mode: "Markdown", reply_markup: updateKeyboard() },
|
||||
);
|
||||
|
||||
while (true) {
|
||||
const actionChoice = await conversation.waitFor([
|
||||
"callback_query:data",
|
||||
"message:text",
|
||||
]);
|
||||
const choice = actionChoice.update.callback_query?.data;
|
||||
|
||||
if (!choice && !actionChoice.message) {
|
||||
if (choice) {
|
||||
// await actionChoice.answerCallbackQuery({
|
||||
// text: "Произошла ошибка. Попробуйте снова.",
|
||||
// });
|
||||
continue;
|
||||
}
|
||||
ctx.session.messageId = undefined;
|
||||
break;
|
||||
}
|
||||
|
||||
const messageText = actionChoice.message?.text.trim();
|
||||
|
||||
if (!choice) {
|
||||
if (messageText) {
|
||||
if (mode === "edit" && selectedIndex !== null) {
|
||||
messages[selectedIndex] = messageText;
|
||||
mode = "default";
|
||||
selectedIndex = null;
|
||||
// await ctx.reply(`Сообщение обновлено: ${messageText}`);
|
||||
await sendOrEditMessage(
|
||||
"Сообщение обновлено.",
|
||||
{
|
||||
parse_mode: "Markdown",
|
||||
reply_markup: updateKeyboard(),
|
||||
},
|
||||
true,
|
||||
);
|
||||
} else {
|
||||
messages.push(messageText);
|
||||
// await ctx.reply(`Сообщение добавлено: ${messageText}`);
|
||||
await sendOrEditMessage(
|
||||
"Сообщение добавлено.",
|
||||
{
|
||||
parse_mode: "Markdown",
|
||||
reply_markup: updateKeyboard(),
|
||||
},
|
||||
true,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
await ctx.reply(`Введите текст сообщения.`);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (choice === "done") {
|
||||
// await actionChoice.answerCallbackQuery({ text: "Настройка завершена!" });
|
||||
await ctx.api.deleteMessage(ctx.chat!.id, ctx.session.messageId!);
|
||||
ctx.session.messageId = undefined;
|
||||
break;
|
||||
}
|
||||
|
||||
if (choice === "sort") {
|
||||
mode = "sort";
|
||||
sortOrder.length = 0;
|
||||
// await actionChoice.answerCallbackQuery({ text: "Режим сортировки." });
|
||||
await sendOrEditMessage("Нажмите на сообщения по порядку.", {
|
||||
parse_mode: "Markdown",
|
||||
reply_markup: updateKeyboard(),
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mode === "sort" && choice.startsWith("select:")) {
|
||||
const index = parseInt(choice.replace("select:", ""), 10);
|
||||
|
||||
if (sortOrder.includes(index)) {
|
||||
sortOrder.splice(sortOrder.indexOf(index), 1);
|
||||
} else {
|
||||
sortOrder.push(index);
|
||||
}
|
||||
|
||||
const sortedMessages: string[] = [];
|
||||
sortOrder.forEach((sortIndex, messagesIndex) => {
|
||||
sortedMessages[messagesIndex] = messages[sortIndex];
|
||||
});
|
||||
messages.forEach((message, index) => {
|
||||
if (!sortOrder.includes(index)) {
|
||||
sortedMessages.push(message);
|
||||
}
|
||||
});
|
||||
|
||||
// Обновляем порядок сообщений
|
||||
for (let i = 0; i < sortedMessages.length; i++) {
|
||||
messages[i] = sortedMessages[i];
|
||||
}
|
||||
for (let i = 0; i < sortOrder.length; i++) {
|
||||
sortOrder[i] = i;
|
||||
}
|
||||
|
||||
// await actionChoice.answerCallbackQuery({ text: "Сообщение перемещено." });
|
||||
await sendOrEditMessage(
|
||||
"Нажмите на сообщения по порядку, начиная с первого.",
|
||||
{ parse_mode: "Markdown", reply_markup: updateKeyboard() },
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (choice === "cancel_sort") {
|
||||
mode = "default";
|
||||
sortOrder.length = 0;
|
||||
// await actionChoice.answerCallbackQuery({ text: "Сортировка отменена." });
|
||||
await sendOrEditMessage(
|
||||
"Сортировка отменена. Возврат к стандартному режиму.",
|
||||
{ parse_mode: "Markdown", reply_markup: updateKeyboard() },
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (choice === "done_sort") {
|
||||
mode = "default";
|
||||
sortOrder.length = 0;
|
||||
// await actionChoice.answerCallbackQuery({ text: "Сортировка завершена." });
|
||||
await sendOrEditMessage("Сортировка завершена.", {
|
||||
parse_mode: "Markdown",
|
||||
reply_markup: updateKeyboard(),
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
if (choice.startsWith("select:")) {
|
||||
const index = parseInt(choice.replace("select:", ""), 10);
|
||||
|
||||
if (selectedIndex === index) {
|
||||
// await actionChoice.answerCallbackQuery({
|
||||
// text: "Редактирование отменено.",
|
||||
// });
|
||||
mode = "default";
|
||||
selectedIndex = null;
|
||||
await sendOrEditMessage("Редактирование отменено.", {
|
||||
parse_mode: "Markdown",
|
||||
reply_markup: updateKeyboard(),
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
mode = "edit";
|
||||
selectedIndex = index;
|
||||
|
||||
// await actionChoice.answerCallbackQuery({
|
||||
// text: `Редактирование сообщения: "${messages[index]}"`,
|
||||
// });
|
||||
await sendOrEditMessage(
|
||||
`Редактирование сообщения: "${messages[index]}"`,
|
||||
{ parse_mode: "Markdown", reply_markup: updateKeyboard() },
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (choice === "cancel_edit") {
|
||||
mode = "default";
|
||||
selectedIndex = null;
|
||||
// await actionChoice.answerCallbackQuery({
|
||||
// text: "Редактирование отменено.",
|
||||
// });
|
||||
await sendOrEditMessage("Редактирование отменено.", {
|
||||
parse_mode: "Markdown",
|
||||
reply_markup: updateKeyboard(),
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
if (choice.startsWith("delete:")) {
|
||||
const index = parseInt(choice.replace("delete:", ""), 10);
|
||||
const deletedMessage = messages.splice(index, 1)[0];
|
||||
mode = "default";
|
||||
selectedIndex = null;
|
||||
// await actionChoice.answerCallbackQuery({
|
||||
// text: `Сообщение "${deletedMessage}" удалено.`,
|
||||
// });
|
||||
await sendOrEditMessage(`Сообщение "${deletedMessage}" удалено.`, {
|
||||
parse_mode: "Markdown",
|
||||
reply_markup: updateKeyboard(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return messages;
|
||||
}
|
||||
Reference in New Issue
Block a user