Skip to content

Commit 96dfccb

Browse files
Bot
1 parent 1ea4aca commit 96dfccb

File tree

1 file changed

+166
-12
lines changed

1 file changed

+166
-12
lines changed

getting-started/index.rst

Lines changed: 166 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,169 @@
1-
.. _getting-started:
1+
#!/usr/bin/env python3
2+
# bot.py — простой Telegram FAQ-бот с ссылкой на материалы курса
3+
# Требуется: python 3.10+ и python-telegram-bot v20+
4+
# Установка:
5+
# pip install python-telegram-bot==20.6
26

3-
===============
4-
Getting started
5-
===============
7+
import os
8+
import logging
9+
from typing import Dict, List
10+
from telegram import (
11+
Update,
12+
InlineKeyboardButton,
13+
InlineKeyboardMarkup,
14+
)
15+
from telegram.ext import (
16+
ApplicationBuilder,
17+
CommandHandler,
18+
CallbackQueryHandler,
19+
ContextTypes,
20+
)
621

7-
.. toctree::
8-
:maxdepth: 5
22+
# Настройка логов
23+
logging.basicConfig(
24+
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", level=logging.INFO
25+
)
26+
logger = logging.getLogger(__name__)
927

10-
setup-building
11-
fixing-issues
12-
git-boot-camp
13-
pull-request-lifecycle
14-
getting-help
15-
generative-ai
28+
# --------------------------
29+
# Настройки — поменяй здесь
30+
# --------------------------
31+
BOT_TOKEN = os.getenv("BOT_TOKEN") # рекомендую задать в окружении
32+
if not BOT_TOKEN:
33+
# Можно временно вставить токен прямо сюда (не рекомендуется публиковать)
34+
BOT_TOKEN = "ВАШ_TELEGRAM_BOT_TOKEN_ЗДЕСЬ"
35+
36+
# Ссылка на материалы курса (Google Drive, LMS и т.д.)
37+
COURSE_MATERIALS_LINK = "https://drive.google.com/your-course-materials-link"
38+
39+
# Админ (необязательно) — Telegram user_id, который может расширять функционал в будущем
40+
ADMIN_USER_ID = None
41+
42+
# --------------------------
43+
# Часто задаваемые вопросы
44+
# --------------------------
45+
# Пример: список словарей с 'id','question','answer'
46+
FAQS: List[Dict[str, str]] = [
47+
{
48+
"id": "schedule",
49+
"question": "Расписание занятий",
50+
"answer": "Занятия проходят по расписанию: Понедельник и Среда 14:00–16:00, Аудитория 204. Полное расписание — в календаре курса."
51+
},
52+
{
53+
"id": "contacts",
54+
"question": "Контакты кафедры",
55+
"answer": "Кафедра: +7 (727) 123-45-67, email: [email protected]. Ответственный: Иванов И.И."
56+
},
57+
{
58+
"id": "papers_rules",
59+
"question": "Правила оформления работ",
60+
"answer": "Формат: A4, шрифт Times New Roman 12, межстрочный интервал 1.5. Список литературы — в конце. Строго по шаблону (см. файл 'Template.docx' в материалах)."
61+
},
62+
{
63+
"id": "deadlines",
64+
"question": "Сроки сдачи работ",
65+
"answer": "Промежуточные отчёты: 1 октября и 1 ноября. Итоговая работа — до 15 декабря (точные даты уточняйте в LMS)."
66+
},
67+
{
68+
"id": "useful_links",
69+
"question": "Полезные ресурсы",
70+
"answer": "1) Электронная библиотека — https://elib.example.edu\n2) Руководства по цитированию — https://citation.example.edu\n3) Лекции и презентации — в разделе 'Материалы курса'."
71+
},
72+
{
73+
"id": "materials",
74+
"question": "Материалы курса (Google Drive / LMS)",
75+
"answer": f"Все материалы курса доступны по ссылке: {COURSE_MATERIALS_LINK}"
76+
},
77+
# При желании добавь ещё 3–4 вопроса аналогично
78+
]
79+
80+
# Вспомогательная функция: строит клавиатуру из FAQS
81+
def build_faq_keyboard() -> InlineKeyboardMarkup:
82+
buttons = []
83+
for item in FAQS:
84+
buttons.append([InlineKeyboardButton(text=item["question"], callback_data=f"faq:{item['id']}")])
85+
# Добавим отдельную кнопку "Материалы курса" (если хочется)
86+
buttons.append([InlineKeyboardButton(text="Материалы курса", callback_data="materials")])
87+
return InlineKeyboardMarkup(buttons)
88+
89+
# --------------------------
90+
# Обработчики команд/кнопок
91+
# --------------------------
92+
async def start_handler(update: Update, context: ContextTypes.DEFAULT_TYPE):
93+
user = update.effective_user
94+
text = (
95+
f"Привет, {user.first_name if user else 'студент'}!\n\n"
96+
"Я — помощник по курсу. Могу ответить на часто задаваемые вопросы и дать ссылку на материалы.\n\n"
97+
"Выбери вопрос в меню или введи /faq для списка вопросов."
98+
)
99+
keyboard = build_faq_keyboard()
100+
await update.message.reply_text(text, reply_markup=keyboard)
101+
102+
103+
async def faq_command_handler(update: Update, context: ContextTypes.DEFAULT_TYPE):
104+
# Отправляем список вопросов (текст + кнопки)
105+
keyboard = build_faq_keyboard()
106+
await update.message.reply_text("Выберите вопрос:", reply_markup=keyboard)
107+
108+
109+
async def materials_command_handler(update: Update, context: ContextTypes.DEFAULT_TYPE):
110+
await update.message.reply_text(
111+
f"Материалы курса: {COURSE_MATERIALS_LINK}\n\n"
112+
"Если ссылка не открывается, сообщите преподавателю или напишите в поддержку LMS."
113+
)
114+
115+
116+
async def help_handler(update: Update, context: ContextTypes.DEFAULT_TYPE):
117+
await update.message.reply_text(
118+
"Доступные команды:\n"
119+
"/start — приветствие и меню\n"
120+
"/faq — часто задаваемые вопросы\n"
121+
"/materials — ссылка на материалы курса\n"
122+
"/help — помощь"
123+
)
124+
125+
126+
async def callback_query_handler(update: Update, context: ContextTypes.DEFAULT_TYPE):
127+
query = update.callback_query
128+
await query.answer() # убирает 'нажатие'
129+
data = query.data or ""
130+
131+
if data.startswith("faq:"):
132+
faq_id = data.split(":", 1)[1]
133+
faq_item = next((f for f in FAQS if f["id"] == faq_id), None)
134+
if faq_item:
135+
await query.edit_message_text(text=f"*{faq_item['question']}*\n\n{faq_item['answer']}", parse_mode="Markdown")
136+
else:
137+
await query.edit_message_text(text="Извините, этот вопрос не найден.")
138+
elif data == "materials":
139+
await query.edit_message_text(text=f"Материалы курса: {COURSE_MATERIALS_LINK}")
140+
else:
141+
await query.edit_message_text(text="Неизвестная команда. Попробуйте /faq или /help.")
142+
143+
144+
# --------------------------
145+
# Запуск приложения
146+
# --------------------------
147+
def main() -> None:
148+
if BOT_TOKEN is None or BOT_TOKEN.strip() == "" or "8428197715: AAHLL0wShvvMw0jgpsttYn4PbRF
149+
o-FzUmLQ" in BOT_TOKEN:
150+
logger.error("Токен бота не задан. Укажи BOT_TOKEN в переменных окружения или прямо в коде.")
151+
return
152+
153+
app = ApplicationBuilder().token(BOT_TOKEN).build()
154+
155+
# Команды
156+
app.add_handler(CommandHandler("start", start_handler))
157+
app.add_handler(CommandHandler("faq", faq_command_handler))
158+
app.add_handler(CommandHandler("materials", materials_command_handler))
159+
app.add_handler(CommandHandler("help", help_handler))
160+
161+
# Кнопки
162+
app.add_handler(CallbackQueryHandler(callback_query_handler))
163+
164+
# Запуск (long polling)
165+
logger.info("Бот запущен (polling). Нажми Ctrl+C для остановки.")
166+
app.run_polling()
167+
168+
if __name__ == "__main__":
169+
main()

0 commit comments

Comments
 (0)