menya-zovut-aset-mne-22-let/bot.js

214 lines
7.9 KiB
JavaScript
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const { Bot } = require("grammy");
const fs = require("fs");
const path = require("path");
const bot = new Bot(process.env.BOT_TOKEN);
const PROGRESS_FILE = path.join(__dirname, "progress.json");
// База уроков: темы → слова/фразы
const LESSONS = {
accounting: {
name: "📊 Бухгалтерия",
words: [
{ en: "Advance report", ru: "Авансовый отчет" },
{ en: "Business trip", ru: "Командировка" },
{ en: "Invoice", ru: "Счет-фактура" },
{ en: "Receipt", ru: "Квитанция/чек" },
{ en: "Expense", ru: "Расход" },
{ en: "Budget", ru: "Бюджет" },
{ en: "Tax", ru: "Налог" },
{ en: "Audit", ru: "Аудит/проверка" },
{ en: "Payroll", ru: "Зарплатная ведомость" },
{ en: "Reimbursement", ru: "Возмещение расходов" }
]
},
travel: {
name: "✈️ Командировки",
words: [
{ en: "Flight ticket", ru: "Авиабилет" },
{ en: "Hotel booking", ru: "Бронь отеля" },
{ en: "Per diem", ru: "Суточные" },
{ en: "Travel allowance", ru: "Подъемные" },
{ en: "Boarding pass", ru: "Посадочный талон" },
{ en: "Departure", ru: "Вылет/отправление" },
{ en: "Arrival", ru: "Прилет/прибытие" },
{ en: "Luggage", ru: "Багаж" },
{ en: "Customs", ru: "Таможня" },
{ en: "Itinerary", ru: "Маршрутный лист" }
]
},
business: {
name: "💼 Деловая переписка",
words: [
{ en: "Dear colleague", ru: "Уважаемый коллега" },
{ en: "Best regards", ru: "С уважением" },
{ en: "Please find attached", ru: "Прилагаю" },
{ en: "In response to your request", ru: "В ответ на ваш запрос" },
{ en: "We confirm", ru: "Подтверждаем" },
{ en: "Please note", ru: "Обратите внимание" },
{ en: "For your information", ru: "Для вашего сведения" },
{ en: "Kindly request", ru: "Любезно просим" },
{ en: "As discussed", ru: "Как обсуждали" },
{ en: "Looking forward", ru: "С нетерпением ждем" }
]
},
phrases: {
name: "💬 Полезные фразы",
words: [
{ en: "Could you please clarify?", ru: "Не могли бы вы уточнить?" },
{ en: "I'll get back to you shortly", ru: "Я скоро вернусь к вам" },
{ en: "Please let me know", ru: "Пожалуйста, дайте знать" },
{ en: "I'm afraid I can't", ru: "Боюсь, я не могу" },
{ en: "Thank you for your cooperation", ru: "Спасибо за сотрудничество" },
{ en: "Is everything clear?", ru: "Все ли понятно?" },
{ en: "Keep me updated", ru: "Держите меня в курсе" },
{ en: "I'll check and confirm", ru: "Я проверю и подтвержу" }
]
}
};
function loadProgress() {
try {
return JSON.parse(fs.readFileSync(PROGRESS_FILE, "utf8"));
} catch (_) {
return {};
}
}
function saveProgress(progress) {
fs.writeFileSync(PROGRESS_FILE, JSON.stringify(progress, null, 2));
}
bot.command("start", async (ctx) => {
await ctx.reply(
`👋 Привет, ${ctx.from.first_name}!
Я твой тренер по английскому языку.
📚 Доступные темы:
1️⃣ ${LESSONS.accounting.name}
2️⃣ ${LESSONS.travel.name}
3️⃣ ${LESSONS.business.name}
4️⃣ ${LESSONS.phrases.name}
🎯 Что я умею:
• Учить слова и фразы
• Проводить тесты
• Показывать прогресс
Выбери тему цифрой (1-4) или напиши /test для теста.`
);
});
bot.command("test", async (ctx) => {
const progress = loadProgress();
const userId = String(ctx.from.id);
if (!progress[userId] || progress[userId].total === 0) {
await ctx.reply("Сначала пройди уроки! Выбери тему цифрой 1-4");
return;
}
const score = Math.round((progress[userId].correct / progress[userId].total) * 100);
await ctx.reply(
`📊 Твой прогресс:
✅ Правильно: ${progress[userId].correct}
❌ Ошибок: ${progress[userId].total - progress[userId].correct}
🎯 Точность: ${score}%
Продолжай учиться!`
);
});
bot.on("message:text", async (ctx) => {
const text = ctx.message.text.trim();
const userId = String(ctx.from.id);
const progress = loadProgress();
// Проверка: ждем ли мы ответ на тест?
if (progress[userId] && progress[userId].waitingAnswer) {
const currentWord = progress[userId].currentWord;
const correctIndex = progress[userId].correctIndex;
const answer = parseInt(text);
if (isNaN(answer) || answer < 1 || answer > 4) {
await ctx.reply("Напиши цифру от 1 до 4");
return;
}
const isCorrect = answer === correctIndex;
progress[userId].total = (progress[userId].total || 0) + 1;
if (isCorrect) {
progress[userId].correct = (progress[userId].correct || 0) + 1;
await ctx.reply(`✅ Правильно!\n\n"${currentWord.en}" = "${currentWord.ru}"`);
} else {
await ctx.reply(`❌ Ошибка.\n\n"${currentWord.en}" = "${currentWord.ru}"`);
}
progress[userId].waitingAnswer = false;
delete progress[userId].currentWord;
delete progress[userId].correctIndex;
saveProgress(progress);
// Предложить следующий тест
await ctx.reply("Напиши /test для проверки прогресса или выбери тему (1-4)");
return;
}
// Выбор темы
if (["1", "2", "3", "4"].includes(text)) {
const keys = Object.keys(LESSONS);
const topic = keys[parseInt(text) - 1];
if (!topic) {
await ctx.reply("Неверная тема. Выбери 1-4");
return;
}
const lesson = LESSONS[topic];
const randomWord = lesson.words[Math.floor(Math.random() * lesson.words.length)];
await ctx.reply(
`📖 ${lesson.name}\n\nСлово: *${randomWord.en}*\n\nПеревод: _${randomWord.ru}_\n\nНапиши /test для теста или выбери другую тему (1-4)`,
{ parse_mode: "Markdown" }
);
return;
}
// Тест с вариантами
if (text.toLowerCase() === "тест" || text.toLowerCase() === "test") {
const allWords = Object.values(LESSONS).flatMap(l => l.words);
const randomWord = allWords[Math.floor(Math.random() * allWords.length)];
// Генерируем 3 неправильных варианта
const wrongOptions = allWords
.filter(w => w.en !== randomWord.en)
.sort(() => Math.random() - 0.5)
.slice(0, 3)
.map(w => w.ru);
const options = [...wrongOptions, randomWord.ru].sort(() => Math.random() - 0.5);
const correctIndex = options.indexOf(randomWord.ru) + 1;
progress[userId] = progress[userId] || {};
progress[userId].waitingAnswer = true;
progress[userId].currentWord = randomWord;
progress[userId].correctIndex = correctIndex;
saveProgress(progress);
await ctx.reply(
`🧠 Тест: выбери правильный перевод\n\n*${randomWord.en}*\n\n` +
options.map((o, i) => `${i + 1}. ${o}`).join("\n") +
`\n\nНапиши цифру (1-4)`,
{ parse_mode: "Markdown" }
);
return;
}
// Обычное сообщение
await ctx.reply(
"Напиши:\n• 1-4 — выбрать тему\n• /test — тест и прогресс\n• test — начать тест"
);
});
bot.start();
console.log("🇬🇧 English Trainer Bot запущен!");