March 6

Пошаговая инструкция: Создание Telegram-бота с функцией "Обучение"

Что нам понадобится

  • Компьютер или сервер (например, домашний компьютер или облачный сервер, если у тебя есть).
  • Интернет.
  • Чуть-чуть терпения и желание повеселиться с ботом!

Шаг 1: Подготовка — Устанавливаем нужные штуки

Представь, что мы собираем ящик с инструментами для нашего бота.

Убедись, что у тебя есть Python:

    • Открой терминал (на Windows это "Командная строка" или PowerShell, на Linux/Mac — просто "Терминал").
    • Напиши:
python3 --version
    • Если видишь что-то вроде Python 3.9.2, всё круто! Если нет, попроси взрослого помочь установить Python с сайта python.org.

Установи "инструменты" для бота:

    • В том же терминале пиши по очереди:
pip3 install python-telegram-bot 
pip3 install openai
pip3 install python-dotenv
    • Это как скачать приложения для бота: одно для Telegram, другое для умных ответов (GPT), третье для хранения секретов.

Установи "экран" (screen), чтобы бот не выключался:

    • Если ты на Linux (например, сервер), пиши:
sudo apt install screen
    • Если что-то не получается, попроси взрослого помочь. На Windows это не нужно, если ты запускаешь дома.

Шаг 2: Создаём бота и собираем секреты

Теперь мы сделаем бота и дадим ему "ключи" для работы.

Создай бота в Telegram:

    • Открой Telegram на телефоне или компьютере.
    • Найди @BotFather (это такой "папа всех ботов").
    • Напиши ему /start, потом /newbot.
    • Дай боту имя (например, "УмныйВоваБот") и ник (например, @VovaSmartBot).
    • Он даст тебе код, типа 771456457973:AAGwsD0GetKrPtn-OuMyoV_uBMR45645diS7U. Запиши его!

Получи ключ для GPT:

    • Попроси взрослого зарегистрироваться на platform.openai.com.
    • Там в разделе "API Keys" нажми "Create new secret key".
    • Скопируй ключ, он выглядит как sk-proj-qBB9UQNZBXudTpDJff9aJoZecGrXTeCtgV3K2TzZ6YT4m-Tfhg4M5wozR5vWtCwDfghxE-v3j-boKhghKOymT3Blbорлрололр7jn2XJQBrJzuTWauMIZNjLYfghY2hDeDZ9kWowgf9kSriAj11фывф-Gp0U95FBLvEыквg4SyfgP0qvCK0A.

Создай секретный файл .env:

    • В терминале создай папку для бота:
mkdir my_cool_bot cd my_cool_bot
apt install nano
    • Открой текстовый редактор:
nano .env
    • Вставь свои ключи:
TELEGRAM_TOKEN=твой_код_от_BotFather 
OPENAI_API_KEY=твой_код_от_OpenAI
    • Сохрани: нажми Ctrl+O, потом Enter, и выйди с Ctrl+X.

Шаг 3: Пишем код для бота

Теперь дадим боту мозги! Мы заменим кнопку и добавим обучение.

  1. Создай файл bot.py:
    • В той же папке (my_cool_bot) пиши:
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()
  1. Сохрани файл:
    • Нажми Ctrl+O, потом Enter, и выйди с Ctrl+X.

Шаг 4: Запускаем бота, чтобы он не выключался

Теперь сделаем так, чтобы бот работал, даже если ты закроешь терминал.

Открой "экран":

    • В той же папке (my_cool_bot) пиши:
screen
    • Ты увидишь новый экран (может быть сообщение — нажми Enter).

Запусти бота:

    • Пиши:
python3 bot.py
    • Если всё ок, увидишь Я готов работать!.

Спрячь экран:

    • Нажми Ctrl+A, потом D.
    • Ты вернёшься назад, а бот будет работать!

Проверь, что он жив:

    • Пиши:
screen -ls
    • Увидишь что-то вроде 12345.pts-0 (Detached) — это значит, бот живёт.

Шаг 5: Проверяем, как всё работает

Теперь давай поиграем с ботом!

Открой Telegram:

    • Найди своего бота по его нику (например, @VovaSmartBot).
    • Напиши /start.
    • Увидишь меню с кнопками: "История", "Промт для бота", "Темы Постов", "Обучение".

Проверь "Обучение":

    • Нажми "Обучение".
    • Напиши что-нибудь, например:
      • https://ru.wikipedia.org/wiki/Кот
      • Или: Кот — это пушистое животное, которое мурлыкает.
    • Бот ответит что-то вроде:
Коты — пушистые и мурлыкают.
Благодаря тебе я теперь это знаю, Вове привет!

Проверь другие кнопки:

    • "История": Покажет, что ты писал.
    • "Промт для бота": Напиши "Ты - кот", и бот станет говорить как кот.
    • "Темы Постов": Даст 5 идей для постов, каждая в отдельном сообщении.

Поболтай с ботом:

    • Напиши "Привет, как дела?" — он ответит как помощник (или кот, если ты сменил промт).

Шаг 6: Что делать, если что-то сломалось

  • Бот не отвечает:
    • Вернись в экран:
screen -r
    • Посмотри, что он пишет. Если ошибка про TELEGRAM_TOKEN или OPENAI_API_KEY, проверь .env.
  • Не запускается:
    • Убедись, что ты в папке my_cool_bot:
cd my_cool_bot 
ls
    • Должны быть bot.py и .env.

Круто, ты сделал бота!

Теперь он умеет учиться, хранит данные в файле training_data.json (в той же папке), и будет жить в screen, пока сервер включён. Если хочешь остановить бота, зайди в screen (screen -r), нажми Ctrl+C, и выйди с exit.

Напиши, если что-то непонятно или не работает — я помогу! 😊