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 запущен!");