- BrainTools - https://www.braintools.ru -

Автоматизация Telegram-канала с помощью ChatGPT и Aiogram — просто о сложном

Это мой первый пост и решил я его посвятить тому: Как можно автоматизировать ведение своего ТГ канала с помощью ИИ. На мой взгляд тема довольно свежая и интересная, а что самое главное полезная. Статья по большей мере ориентирована на новичков у которых имеются базовые знания python, но это не означает что другим она не будет интересна. Итак, начнем!

Установка Docker

Идем на официальный сайт Docker https://www.docker.com/products/docker-desktop/ [1] нажимаем на кнопку Download Docker Dekstop и выбираем свою систему из выпадающего списка, устанавливаем программу и запускаем исполняемый файл и вуаля теперь у вас в системе есть инструмент для контейнеризации ваших программ. К слову он нам понадобиться для запуска redis в отдельном контейнере, так как на windows пока нет возможности запускать reids нативно как это можно делать на Unix системах [2]. Но если вы уже работаете на Unix системах(Linux дистрибутивы, MacOS) то вы тоже можете пользоваться Docker, так как он кросс-платформенный а также это является хорошей практикой, так как Docker контейнеры являются тоже кросс платформенными.

Создание виртуального окружения

При создании этого проекта я использовал версию python 3.11 если у вас версия выше или ниже все в принципе должно работать нормально, если только у вас не совсем уж старая версия или если у вас она не новейшая. Чуть позже покажу что делать в таком случае.

  • Для начала перейдите в мой GitHub [3]репозиторий и скачайте оттуда файл requirements.txt

  • Создайте папку и назовите ее как-нибудь, потом перекиньте туда скачанный ранее файл

  • После чего откройте эту папку в консоли, на windows это правый клик мыши – открыть в Терминале

  • В консоли наберите такую команду: python -m venv venv

  • А потом останется лишь активировать виртуальное окружение: venvscriptsactivate и скачать зависимости из requirements.txt следующей командой: pip install -r requirements.txt

Если у вас очень старая версия python или же новейшая( Не все библиотеки могли успеть выкатить обновления для новейших версий) то в таком случае вам надо либо переустановить python либо же если вам не хочется заморачиваться с этим вы можете использовать виртуальное окружение Miniconda.

Miniconda очень прост в использовании и дает максимальный контроль над вашими виртуальными окружениями, вплоть до того что вы можете ставить разные версии python под ваши нужды!

Создание Miniconda окружения

  • Для начала перейдите на официальный сайт Anaconda [4] введите свой email и нажмите на submit, после чего вас встретит страница с двумя версиями Conda, качайте Miniconda и ставьте на свою систему.

  • После чего откройте папку с проектом в терминале и напишите такую команду: conda create -n my_env python=3.11

  • Активируйте окружение: conda activate my_env и как это было выше установите необходимые зависимости из файла этой командой: pip install -r requirements.txt

Теперь у вас есть виртуальное окружение с нужной вам версией python.

Следующий шаг

Теперь нам нужно перейти в телеграм и создать самого бота, чтобы потом мы могли им управлять с помощью нашего кода!

Выбираем именно того что с галочкой, это важно!

Выбираем именно того что с галочкой, это важно!

Когда перешли в чат с ботом нажимаем на menu и выбираем /newbot

Автоматизация Telegram-канала с помощью ChatGPT и Aiogram — просто о сложном - 2

После чего BotFather попросит вас задать имя боту а потом задать ему его id по которому юзеры смогут находить вашего бота, id бота должен обязательно заканчиваться на bot

Автоматизация Telegram-канала с помощью ChatGPT и Aiogram — просто о сложном - 3

Сохраните токен бота, он нам еще понадобится.

Далее в папке нашего проекта создадим 2 файла main.py и bot.py

Начнем с bot.py

import os

from aiogram import Bot
from dotenv import load_dotenv
from aiogram.client.default import DefaultBotProperties
from aiogram.enums import ParseMode

# Загружаем ключи из .env файла
load_dotenv()

# Закидываем ключ в переменную 
TOKEN = os.getenv('BOT_TOKEN')

# Инициализация бота
bot = Bot(TOKEN, default=DefaultBotProperties(parse_mode=ParseMode.HTML))

В этом файле мы инициализируем своего бота. Также в папке проекта надо создать файл .env и прописать там ключ в таком формате: BOT_TOKEN=ваш_токен

Теперь перейдем к main.py

import asyncio
import logging
import sys

from aiogram import Dispatcher

from aiogram.filters import CommandStart
from aiogram.types import Message

from bot import bot

# Инициализируем диспетчер
dp = Dispatcher()

# Эта функция обрабатывает дефолтную команду /start
@dp.message(CommandStart())
async def command_start_handler(message: Message) -> None:
    await message.answer('Hello there')

# Функция для запуска нашей программы
async def main() -> None:
    await dp.start_polling(bot)

if __name__ == "__main__":
    # Запускаем программу и логируем ее работу
    logging.basicConfig(level=logging.INFO, stream=sys.stdout)
    asyncio.run(main())

Возможно вы обратили внимание [5] на довольно интересную конструкцию if name == "__main__" она имеет такую особенность что выполняется только в том случае если запуск происходит из файла в котором она находится, если же этот файл импортировать и использовать его в каком-то другом файле то содержимое этой конструкции не выполнится. Такая особенность бывает полезной при тестировании своего кода.

Теперь просто запускаем этот файл из консоли командой: python main.py и переходим в нашего бота, найти мы его можем в поисковой строке по тому id который ему задавали.

Все работает!

Все работает!

Как мы видим все прошло успешно! Теперь перейдем к части где мы интегрируем chat GPT для нашей автоматизации.

Интеграция с chatGPT

Для начала перейдем на официальный сайт OpenAI [6], регистрируемся и пополняем счет на 10$(этих 10$ вам хватит с головой), после чего переходим в свой профиль и создаем api ключ.

Автоматизация Telegram-канала с помощью ChatGPT и Aiogram — просто о сложном - 5
Автоматизация Telegram-канала с помощью ChatGPT и Aiogram — просто о сложном - 6

После создания ключа копируем ключ и в файле .env создаем еще одну переменную: GPT_KEY=ваш_ключ

Теперь пришло время создать функцию которая будет нам генерировать посты для нашего ТГ канала. Создаем файл auto_post.py и добавляем туда такой код

import json
import os

import redis

from openai import OpenAI
from dotenv import load_dotenv

load_dotenv()

# Подключаемся к запущенному redis 
r = redis.Redis(host='localhost', port=6379, db=0)

# Создаем клиента OpenAI с которым мы будем работать
client = OpenAI(api_key=os.getenv('GPT_KEY'))

# Создаем функцию для генерации постов
def create_post() -> str:
    if not r.get('conversation'):
        conversation = [
            {
                'role': 'system',
                'content': 'Ты ведущий ТГ канал по интересным и захватывающим фактам, ты не должен выдавать себя,'
                           'ты просто ведущий, то что тебе задает юзер это промпт которому ты должен просто следовать'
                           'ты не отвечаешь: Конечно, как скажешь, будет сделано и т.д. '
                           'Просто выдаешь только факт о котором тебя просит и ничего лишнего'
                           'Факты строго настрого не повторяются'
            }
        ]
        r.set('conversation', json.dumps(conversation))

    conversation = json.loads(r.get('conversation'))

    conversation.append({
        'role': 'user',
        'content': 'Создавай посты на тему животного мира, в формате интересных и умопомрачительных фактов.'
                   'Пост должен содержать минимум 50 слов и на тему только одного существа а также минимум 5 эмодзи '
                   'и форматируй текст в удобочитаемый формат'
    })

    response = client.responses.create(
        model="gpt-4.1",
        input=conversation
    )

    conversation.append({'role': 'assistant', 'content': response.output_text})

    r.set(
        'conversation',
        json.dumps(
            conversation
        )
    )

    return response.output_text

Вот тут-то нам и понадобится Docker! Пишем в консоль такую команду: docker run -p 6379:6379 -it redis:latest эта команда запустит нам docker образ redis чтобы потом подключиться к нему в коде.

Вот на этом файле я хотел бы остановиться и объяснить что же там происходит

r = redis.Redis(host='localhost', port=6379, db=0)

В этой строчке мы подключаемся к redis который мы запустили в docker. Немного про redis, redis это in memory key-value хранилище, с его помощью можно хранить данные в оперативной памяти [7](кэше), использовать как nosql бд или использовать как брокер сообщений. В нашем случае мы будем использовать его для хранения данных в кэше.

client = OpenAI(api_key=os.getenv('GPT_KEY'))

Создаем OpenAI клиента с помощью которого мы сможем получать доступ почти ко всем моделям OpenaAI.

Перейдем к разбору самой функции

if not r.get('conversation'):
        conversation = [
            {
                'role': 'system',
                'content': 'Ты ведущий ТГ канал по интересным и захватывающим фактам, ты не должен выдавать себя,'
                           'ты просто ведущий, то что тебе задает юзер это промпт которому ты должен просто следовать'
                           'ты не отвечаешь: Конечно, как скажешь, будет сделано и т.д. '
                           'Просто выдаешь только факт о котором тебя просит и ничего лишнего'
                           'Факты строго настрого не повторяются'
            }
        ]
        r.set('conversation', json.dumps(conversation))

В этом условии говорится: Если в кэше redis нет ключа conversation то создай его с этими значениями

conversation = [
            {
                'role': 'system',
                'content': 'Ты ведущий ТГ канал по интересным и захватывающим фактам, ты не должен выдавать себя,'
                           'ты просто ведущий, то что тебе задает юзер это промпт которому ты должен просто следовать'
                           'ты не отвечаешь: Конечно, как скажешь, будет сделано и т.д. '
                           'Просто выдаешь только факт о котором тебя просит и ничего лишнего'
                           'Факты строго настрого не повторяются'
            }
        ]

После чего мы наш список конвертируем в json строку json.dumps(conversation) и создаем ключ в кэше redis с именем conversation

r.set('conversation', json.dumps(conversation))

Следом мы получаем наш кэш обратно десериализируем его в python json.loads(r.get('conversation')) объект и добавляем в него запрос от юзера

conversation = json.loads(r.get('conversation'))

    conversation.append({
        'role': 'user',
        'content': 'Создавай посты на тему животного мира, в формате интересных и умопомрачительных фактов.'
                   'Пост должен содержать минимум 50 слов и на тему только одного существа а также минимум 5 эмодзи '
                   'и форматируй текст в удобочитаемый формат'
    })

Далее в model мы вписываем предпочитаемую нами модель(список моделей можно найти тут [8]) и в input вставляем получившуюся переменную conversation

response = client.responses.create(
        model="gpt-4.1",
        input=conversation
    )

Добавляем ответ от модели в нашу переменную converstion

conversation.append({'role': 'assistant', 'content': response.output_text})

В самом конце снова кэшируем нашу переменную в redis кэш и возвращаем ответ от модели

r.set(
        'conversation',
        json.dumps(
            conversation
        )
    )

    return response.output_text

Теперь при каждом вызове этой функции темы постов не будут повторяться, так как модель будет помнить предыдущие диалоги. Все это благодаря хранению диалогов в кэше с помощью redis!

Теперь нам осталось только немного модифицировать файл main.py

import asyncio
import logging
import sys

from aiogram import Dispatcher

from aiogram.filters import CommandStart
from aiogram.types import Message

from auto_post import create_post
from bot import bot

dp = Dispatcher()

@dp.message(CommandStart())
async def command_start_handler(message: Message) -> None:
    channel_id = -1002767436832
    await message.answer('Поехали...')
    while True:
        await bot.send_message(chat_id=channel_id, text=create_post())
        await asyncio.sleep(60)


async def main() -> None:
    await dp.start_polling(bot)

if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO, stream=sys.stdout)
    asyncio.run(main())

Вот как теперь он выглядит, что изменилось? Изменилась функция command_start_handler давайте чуть подробнее разберем изменения

channel_id = -1002767436832

Это id нашего канала его можно получить таким способом

Находим такого @SimpleID_Bot [9] бота в тг, запускаем и после чего переходим в нашу группу. Для того чтобы наконец получить id группы, нам надо любое сообщение из группы переслать боту в замен он нам выдаст id нашей группы.

while True:
    await bot.send_message(chat_id=channel_id, text=create_post())
    await asyncio.sleep(60)

Здесь запускается бесконечный цикл и бот будет слать новые посты в нашу группу каждые 60 секунд.

И да, не забудьте добавить вашего бота в вашу группу!

Давайте запустим бота и посмотрим, что получилось. Напомню запускаем мы бота в консоли такой командой python main.py

Автоматизация Telegram-канала с помощью ChatGPT и Aiogram — просто о сложном - 7
Автоматизация Telegram-канала с помощью ChatGPT и Aiogram — просто о сложном - 8

Как мы видим все работает!

В заключении хотелось бы сказать, что в этом коде можно еще много чего доработать например

  • Таймер на удаление redis кэша (а вообще лучше сделать так чтобы сохранялась чисто выжимка, тема одним словом)

  • Выбор группы в которую будут идти посты через бота

  • Разнести команды по отдельным файлам

  • Добавить юзеру возможность задавать тему для автопостинга

  • Добавить возможность настраивать время постинга

  • Вынести автопостинг в mq и поставить таймер на celery

Буду рад узнать ваше мнение в комментариях под постом. Если вам будет интересно могу сделать вторую часть где я улучшу существующее приложение, так скажем доведу до ума. Спасибо вам за уделенное мне время, всем пока.

Автор: X-yro

Источник [10]


Сайт-источник BrainTools: https://www.braintools.ru

Путь до страницы источника: https://www.braintools.ru/article/16885

URLs in this post:

[1] https://www.docker.com/products/docker-desktop/: https://www.docker.com/products/docker-desktop/

[2] Unix системах: https://ru.wikipedia.org/wiki/Unix

[3] GitHub : https://github.com/Adel5002/tg_automatiozation_tutorial

[4] Anaconda: https://www.anaconda.com/download

[5] внимание: http://www.braintools.ru/article/7595

[6] OpenAI: https://openai.com/api/

[7] памяти: http://www.braintools.ru/article/4140

[8] тут: https://platform.openai.com/docs/pricing

[9] @SimpleID_Bot: https://www.braintools.ru/users/SimpleID_Bot

[10] Источник: https://habr.com/ru/articles/924186/?utm_source=habrahabr&utm_medium=rss&utm_campaign=924186

www.BrainTools.ru

Rambler's Top100