March 6
Пошаговая инструкция: Создание Telegram-бота с функцией "Обучение"
Что нам понадобится
- Компьютер или сервер (например, домашний компьютер или облачный сервер, если у тебя есть).
- Интернет.
- Чуть-чуть терпения и желание повеселиться с ботом!
Шаг 1: Подготовка — Устанавливаем нужные штуки
Представь, что мы собираем ящик с инструментами для нашего бота.
Убедись, что у тебя есть Python:
python3 --version
Установи "инструменты" для бота:
pip3 install python-telegram-bot pip3 install openai pip3 install python-dotenv
Установи "экран" (screen), чтобы бот не выключался:
sudo apt install screen
Шаг 2: Создаём бота и собираем секреты
Теперь мы сделаем бота и дадим ему "ключи" для работы.
- Попроси взрослого зарегистрироваться на platform.openai.com.
- Там в разделе "API Keys" нажми "Create new secret key".
- Скопируй ключ, он выглядит как sk-proj-qBB9UQNZBXudTpDJff9aJoZecGrXTeCtgV3K2TzZ6YT4m-Tfhg4M5wozR5vWtCwDfghxE-v3j-boKhghKOymT3Blbорлрололр7jn2XJQBrJzuTWauMIZNjLYfghY2hDeDZ9kWowgf9kSriAj11фывф-Gp0U95FBLvEыквg4SyfgP0qvCK0A.
mkdir my_cool_bot cd my_cool_bot apt install nano
nano .env
TELEGRAM_TOKEN=твой_код_от_BotFather OPENAI_API_KEY=твой_код_от_OpenAI
Шаг 3: Пишем код для бота
Теперь дадим боту мозги! Мы заменим кнопку и добавим обучение.
nano bot.py
import os
import json
from dotenv import load_dotenv
from telegram import Update, ReplyKeyboardMarkup
from telegram.ext import Application, CommandHandler, MessageHandler, filters, ContextTypes
from openai import OpenAI
# Загружаем секретные ключи
load_dotenv()
TELEGRAM_TOKEN = os.getenv("TELEGRAM_TOKEN")
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
# Подключаемся к GPT
client = OpenAI(api_key=OPENAI_API_KEY)
# Хранилища для данных
user_prompts = {}
user_history = {}
user_training_data = {}
# Загружаем данные обучения из файла, если он есть
def load_training_data():
global user_training_data
try:
with open("training_data.json", "r") as f:
user_training_data = json.load(f)
except FileNotFoundError:
user_training_data = {}
# Сохраняем данные обучения в файл
def save_training_data():
with open("training_data.json", "w") as f:
json.dump(user_training_data, f)
# Загружаем данные при старте
load_training_data()
# Меню с кнопками
main_menu = ReplyKeyboardMarkup([
["История", "Промт для бота"],
["Темы Постов", "Обучение"]
], resize_keyboard=True)
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
print(f"Кто-то сказал /start! ID: {update.message.from_user.id}")
await update.message.reply_text(
"Привет! Я твой умный бот. Выбери что-нибудь в меню или просто поболтай со мной!",
reply_markup=main_menu
)
async def handle_message(update: Update, context: ContextTypes.DEFAULT_TYPE):
user_id = update.message.from_user.id
text = update.message.text
print(f"Сообщение от {user_id}: {text}")
if text == "История":
history = user_history.get(user_id, "История пуста.")
await update.message.reply_text(history)
elif text == "Промт для бота":
await update.message.reply_text("Напиши, кем я должен быть (например, 'Ты - повар' или 'Ты - учитель').")
elif text == "Темы Постов":
prompt = user_prompts.get(user_id, "Ты - универсальный помощник.")
post_ideas = get_post_ideas_from_gpt(prompt)
if "Ошибка" not in post_ideas:
ideas = post_ideas.split("\n\n")
for idea in ideas:
if idea.strip():
await update.message.reply_text(idea.strip())
else:
await update.message.reply_text(post_ideas)
elif text == "Обучение":
await update.message.reply_text("Пришли мне ссылку, текст или что-то интересное, чтобы я научился!")
else:
# После "Промт для бота"
if "Промт для бота" in context.user_data.get("last_command", ""):
user_prompts[user_id] = text
await update.message.reply_text("Круто, я теперь это умею!")
# После "Обучение"
elif "Обучение" in context.user_data.get("last_command", ""):
if user_id not in user_training_data:
user_training_data[user_id] = []
user_training_data[user_id].append(text)
save_training_data() # Сохраняем в файл
summary = process_training_data(text)
await update.message.reply_text(f"{summary}\nБлагодаря тебе я теперь это знаю, Вове привет!")
# Просто болтаем
else:
prompt = user_prompts.get(user_id, "Ты - универсальный помощник.")
response = get_chat_response(prompt, text)
await update.message.reply_text(response)
# Записываем в историю
if user_id not in user_history:
user_history[user_id] = ""
user_history[user_id] += f"Ты сказал: {text}\n"
context.user_data["last_command"] = text
def get_post_ideas_from_gpt(prompt):
try:
print(f"Спрашиваю GPT про посты с промтом: {prompt}")
response = client.chat.completions.create(
model="gpt-4o",
messages=[
{"role": "system", "content": f"{prompt} Дай 5 идей для постов на март 2025. Раздели их пустой строкой."},
{"role": "user", "content": "Дай мне идеи!"}
],
max_tokens=500
)
return response.choices[0].message.content
except Exception as e:
return f"Упс, ошибка с GPT: {str(e)}"
def get_chat_response(prompt, user_input):
try:
print(f"Болтаю с GPT: {user_input}")
response = client.chat.completions.create(
model="gpt-4o",
messages=[
{"role": "system", "content": prompt},
{"role": "user", "content": user_input}
],
max_tokens=500
)
return response.choices[0].message.content
except Exception as e:
return f"Ой, ошибка с GPT: {str(e)}"
def process_training_data(data):
try:
print(f"Учусь на этом: {data}")
response = client.chat.completions.create(
model="gpt-4o",
messages=[
{"role": "system", "content": "Ты - ученик. Дай очень краткий обзор того, что понял из текста или ссылки."},
{"role": "user", "content": f"Что это: {data}"}
],
max_tokens=50
)
return response.choices[0].message.content
except Exception as e:
return f"Не понял, что это: {str(e)}"
def main():
application = Application.builder().token(TELEGRAM_TOKEN).build()
application.add_handler(CommandHandler("start", start))
application.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_message))
print("Я готов работать!")
application.run_polling()
if __name__ == "__main__":
main()Шаг 4: Запускаем бота, чтобы он не выключался
Теперь сделаем так, чтобы бот работал, даже если ты закроешь терминал.
screen
python3 bot.py
screen -ls
Шаг 5: Проверяем, как всё работает
Теперь давай поиграем с ботом!
Коты — пушистые и мурлыкают. Благодаря тебе я теперь это знаю, Вове привет!Шаг 6: Что делать, если что-то сломалось
screen -r
cd my_cool_bot ls
Круто, ты сделал бота!
Теперь он умеет учиться, хранит данные в файле training_data.json (в той же папке), и будет жить в screen, пока сервер включён. Если хочешь остановить бота, зайди в screen (screen -r), нажми Ctrl+C, и выйди с exit.