Создадим бота, использующего API OpenAI. И так развернем его на сервере, чтобы не настраивать проксирование запросов к API OpenAI (который заблокирован для пользователей из России), и не использовать иностранные VPS.

Бот должен помогать осуществлять

  • Автоматизацию рутинных задач (написание кода, документации, тестов).

  • Предоставлять рекомендации и примеры кода.

  • Анализировать код, находить ошибки и давать предложения по улучшению.

  • Сокращать времени разработки и тестирования.

Планирование и дизайн бота

Функциональные требования:

  1. Приветственное сообщение при запуске.

  2. Генерация ответов через OpenAI API.

  3. Обработка команд, например, /bot или /start

  4. Логирование ошибок.

  5. Автоматическое повторное подключение при сбое.

Основные сценарии использования

  1. Запуск бота:

    • Пользователь запускает бота командой /start.

    • Бот отправляет приветственное сообщение.

  2. Запрос информации:

    • Пользователь отправляет команду /bot или любое текстовое сообщение.

    • Бот генерирует ответ с помощью OpenAI API и отправляет его пользователю.

  3. Обработка ошибок:

    • В случае ошибки бот записывает ее в лог и пытается восстановить соединение.

Выбор технологий и инструментов

Мы будем использовать следующие технологии и инструменты:

  • Python: Простота и легкость в изучении, большое количество библиотек и инструментов.

  • TeleBot: Простой интерфейс для взаимодействия с Telegram API.

  • OpenAI API: Использование модели GPT-3.5 для генерации текстовых ответов.

Написание кода телеграм-бота

Бот включает в себя несколько ключевых компонентов, которые обеспечивают его функциональность и взаимодействие с пользователями:

  1. Telegram Bot API: Этот компонент отвечает за прием и отправку сообщений пользователям через платформу Telegram.

  2. OpenAI API: Используется для генерации ответов на запросы пользователей с помощью модели GPT-3.5.

  3. Логирование: Ведет запись событий и ошибок для последующего анализа и отладки.

  4. Основной цикл (Event Loop): Обеспечивает непрерывную работу бота и обработку всех входящих сообщений.

Эти компоненты взаимодействуют следующим образом:

  • Пользователь отправляет сообщение боту в Telegram.

  • Бот принимает сообщение через Telegram Bot API и отправляет запрос к OpenAI API для генерации ответа.

  • Полученный ответ возвращается пользователю через Telegram.

  • Все события и ошибки записываются в лог для мониторинга и отладки.

1. Инициализация бота и API ключей OpenAI

Сначала необходимо настроить API ключи для OpenAI и Telegram.

import openai
import telebot
import logging
import os
import time

openai.api_key = 'Ваш Openai API ключ'
bot = telebot.TeleBot('Ваш Telegram токен')

Здесь мы импортируем необходимые библиотеки и устанавливаем ключи для доступа к API OpenAI и Telegram.

2. Настройка логирования

Логирование позволяет отслеживать события и ошибки в работе бота.

log_dir = os.path.join(os.path.dirname(__file__), 'ChatGPT_Logs')
if not os.path.exists(log_dir):
    os.makedirs(log_dir)
logging.basicConfig(filename=os.path.join(log_dir, 'error.log'), level=logging.ERROR,
                    format='%(levelname)s: %(asctime)s %(message)s', datefmt='%d/%m/%Y %H:%M:%S')

Мы создаем директорию для логов и настраиваем параметры логирования для удобства анализа.

3. Обработка команд и сообщений

Определим функции для обработки команд /start и /bot, а также любых текстовых сообщений.

@bot.message_handler(commands=['start'])
def send_welcome(message):
    bot.reply_to(message, 'Привет!\nЯ ChatGPT 3.5 Telegram Bot\U0001F916\nЗадай мне любой вопрос и я постараюсь на него ответить')

def generate_response(prompt):
    completion = openai.ChatCompletion.create(
        model="gpt-3.5-turbo",
        messages=[{"role": "user", "content": prompt}]
    )
    return completion.choices[0].message.content

@bot.message_handler(commands=['bot'])
def command_message(message):
    prompt = message.text
    response = generate_response(prompt)
    bot.reply_to(message, text=response)

@bot.message_handler(func=lambda _: True)
def handle_message(message):
    prompt = message.text
    response = generate_response(prompt)
    bot.send_message(chat_id=message.from_user.id, text=response)
  • send_welcome: Отправляет приветственное сообщение при запуске бота.

  • generate_response: Генерирует ответ с помощью OpenAI API.

  • command_message и handle_message: Обрабатывают команды и текстовые сообщения, генерируя ответы с помощью OpenAI API.

4. Основной цикл

Запуск основного цикла для обработки сообщений и повторного подключения при сбоях.

print('ChatGPT Bot is working')

while True:
    try:
        bot.polling()
    except (telebot.apihelper.ApiException, ConnectionError) as e:
        logging.error(str(e))
        time.sleep(5)
        continue

Здесь мы запускаем основной цикл, который постоянно проверяет новые сообщения и обрабатывает их. В случае ошибки бот записывает ее в лог и пытается восстановить соединение.

Получаем готовый код для нашего бота

import openai
import telebot
import logging
import os
import time

openai.api_key = 'Openai_api_key'
bot = telebot.TeleBot('Telegram_token')

log_dir = os.path.join(os.path.dirname(__file__), 'ChatGPT_Logs')

if not os.path.exists(log_dir):
    os.makedirs(log_dir)

logging.basicConfig(filename=os.path.join(log_dir, 'error.log'), level=logging.ERROR,
                    format='%(levelname)s: %(asctime)s %(message)s', datefmt='%d/%m/%Y %H:%M:%S')

@bot.message_handler(commands=['start'])
def send_welcome(message):
    bot.reply_to(message, 'Привет!\nЯ ChatGPT 3.5 Telegram Bot\U0001F916\nЗадай мне любой вопрос и я постараюсь на него ответиь')

def generate_response(prompt):
        completion = openai.ChatCompletion.create(
            model="gpt-3.5-turbo",
            messages=[
                {"role": "user", "content": prompt}
            ]
        )
        return completion.choices[0].message.content


@bot.message_handler(commands=['bot'])
def command_message(message):
    prompt = message.text
    response = generate_response(prompt)
    bot.reply_to(message, text=response)


@bot.message_handler(func = lambda _: True)
def handle_message(message):
    prompt = message.text
    response = generate_response(prompt)
    bot.send_message(chat_id=message.from_user.id, text=response)


print('ChatGPT Bot is working')

while True:
    try:
        bot.polling()
    except (telebot.apihelper.ApiException, ConnectionError) as e:
        logging.error(str(e))
        time.sleep(5)
        continue

Развертывание на сервер c доступом к API OpenAI

Для развертывания мы остановимся на платформе Amvera.

Почему выбрали Amvera?

  • Amvera предоставляет встроенное бесплатное проксирование до API OpenAI. Вам не потребуется зарубежная виртуальная машина или VPN.

  • Развертывание идет максимально просто. Через загрузку кода в интерфейсе, либо через git push.

  • Стартовый баланс, который позволит протестировать сервис.

Запускаем нашего бота в облаке

Перейдем теперь к самой интересной части данной статьи, как развернуть бота так, чтобы не использовать иностранные серверы и не настраивать проксирование к API OpenAI.

Регистрация в сервисе

  1. На сайте Amvera нажимаем на кнопку "Регистрация".

  2. Заполняем последовательно все поля.

  3. Подтверждаем, что мы не робот, и тыкаем на большую синюю кнопку "Регистрация"

  4. Остается только подтвердить указанную почту, перейдя по ссылке в письме.

Создание проекта и размещение бота

  1. На появившейся после входа странице нажимаем на кнопку "Создать" или "Создать первый!".

  2. Выбираем тариф. Может показаться, что тарифные планы предоставляют слишком мало ресурса по сравнению с VPS. Однако в VPS часть ресурсов используется операционной системой, а тут весь выделенный ресурс уходит только на развертываемое приложение. Нам хватит тарифа Пробный, но первый запуск лучше осуществить на одном из старших тарифов, чтобы убедиться, что все работает.

    Окно создания нового проекта
    Окно создания нового проекта
  3. Создадим конфигурационный yaml файл. Это можно сделать самостоятельно на основании документации, однако я рекомендую воспользоваться автоматическим графическим инструментом генерации либо сделать это в личном кабинете во вкладке Конфигурация.

    Графический инструмент генерации .yaml файлов
    Графический инструмент генерации .yaml файлов

    1. Мы используем Python, укажем его версию.

    2. requirements.txt - файл с зависимостями. Очень важно указать все используемые в проекте библиотеки в этом файле, чтобы сервис смог их скачать через pip. Необходимо прописать все библиотеки в формате библиотека==версия.

    3. Указываем путь до файла, содержащего точку входа в программу (тот файл, который вы указываете интерпретатору питона, когда запускаете приложение) либо команду запуска.

    4. Если в процессе работы ваш бот использует SQLite, сохраняйте данные в постоянное хранилище /data. В противном случае при перезапуске проекта все данные будут потеряны!

    5. Порт можно указать тот, который используется в коде вашего приложения. Не забудьте изменить локалхост на 0.0.0.0

    6. Нажимаем на кнопку Generate YAML, после чего начинается загрузка файла amvera.yml.

  4. Скачанный файл кладем в корень нашего проекта

  5. Инициируем Git-репозиторий и загружаем наш проект.

    • В корне нашего проекта выполняем команду: git init (если гит уже инициализирован в вашем проекте, то этого делать не нужно)

    • Привязываем наш локальный гит репозиторий к удаленному репозиторию через команду, которая указана на странице проекта в amvera (имеет формат git remote add amvera <https://git.amvera.ru/ваш_юзернейм/ваш_проект>)

      1. Делаем git add . и git commit -m "Initial commit"

      2. Делаем push с нашим проектом, выполняя команду git push amvera master, вводя учетные данные, которые использовались при регистрации в сервисе.

  6. После того как проект запушится в систему, на странице проекта статус поменяется на "Выполняется сборка".

    Успешно развернутый проект
    Успешно развернутый проект
  7. Как только проект соберется, он перейдет в стадию: "Выполняется развертывание", а после в статус "Успешно развернуто".

    Успешно развернутый проект
    Успешно развернутый проект
  8. Если по какой-то причине проект не развернулся, можно обратиться к логам сборки и логам приложения для отладки. Если Проект завис в статусе "Сборка" на долгое время, а логи сборки не отображаются, то стоит ещё раз проверить корректность amvera.yml файла.

Ура, все работает! Теперь наш Telegram-бот развернут и готов к использованию. Вы можете проделать все шаги из статьи и протестировать его, отправив команды и сообщения, чтобы увидеть, как он работает с API OpenAI.

Автор материала: Алексей Пономарёв

Комментарии (14)


  1. mnnoee
    18.07.2024 19:36
    +15

    Telegram bot, взаимодействующий с API OpenAI без проксирования.

    Amvera предоставляет встроенное бесплатное проксирование до API OpenAI.

    да.


  1. Robastik
    18.07.2024 19:36
    +1

    Как альтернатива, можно использовать облако Гугла. И бесплатно, и реально без прокси.


  1. markoni
    18.07.2024 19:36
    +2

    Казалось бы - при чем здесь Telegram-bot к рекламе?
    Streamlit + несколько строк - разве не тоже самое делают?


    1. Data4
      18.07.2024 19:36

      А как вам Streamlit поможет обойти блокировку со стороны OpenAI российских IP?


  1. Pol1mus
    18.07.2024 19:36
    +3

    Вместо библиотеки openai можно использовать litellm, код почти такой же но легким движением руки можно будет заменить chatgpt на клода, джемини итп, и можно даже сделать фолбек, если один не ответил передать запрос другому.

    from litellm import completion
    import os
    
    ## set ENV variables
    os.environ["OPENAI_API_KEY"] = "your-openai-key"
    os.environ["COHERE_API_KEY"] = "your-cohere-key"
    
    messages = [{ "content": "Hello, how are you?","role": "user"}]
    
    # openai call
    response = completion(model="gpt-3.5-turbo", messages=messages)
    
    # cohere call
    response = completion(model="command-nightly", messages=messages)
    print(response)


  1. ArtyomO
    18.07.2024 19:36

    На сайте компании ничего не указано о соблюдении 152 фз. Если бы было без проксирования, то сервер получается находится за пределами РФ, но тогда не понятно в чём фокус, так можно на любом зарубежном сервере разворачивать без какого либо проксирования. Как маркетинговый ход, чтобы заинтересовались заголовком работает, но потом конечно вызывает чувство разочарования. Так можно и «бесплатный» VPN подсунуть в любую статью и сказать, что «без проксирования». Смогли бы заключить договор с OpenAi, чтобы ваши ip исключили из чёрного списка, вот тогда бы даже заголовок полностью соответствовал истине…


    1. kirillkosolapov
      18.07.2024 19:36

      Так смысл в том, что серверы находятся в РФ, на которых проект крутится. И все соблюдается, просто трафик до OpenAI Amvera сама выделяет и проксирует за вас. Как это работает есть в статье https://habr.com/ru/companies/amvera/articles/820325/

      А так - да, можно развернуть на иностранном сервере. Но с высокой долей вероятности там вас попросят иностранную карту привязать, и еще с некоторой вероятностью - просто заблокируют как пользователя из России в неожиданный для вас момент. Поэтому в некоторых случаях размещать проекты у Российских провайдеров имеет смысл


      1. ArtyomO
        18.07.2024 19:36

        На сайте не смог найти очевидных упоминаний где сервера и про соблюдение 152 ФЗ. Если сравнивать с Яндекс Облаком, который об этом сначала писал вообще как о главном преимуществе, а потом поменял дизайн, но всё равно упоминает очень явным образом. Если сервера в РФ всё соблюдается, пока персональные данные не передали обратившись по API в OpenAI например с запросом "вот скан паспорта, напиши какие здесь ФИО, дата и место рождения". Возможно к вашему рекламному "Поддержка API OpenAI", хорошо бы подошёл жирный дисклеймер про 152 ФЗ и риски нарушить закон при не правильном использовании этого API. А так то новые игроки на этом рынке с удобными инструментами это здорово, но не всегда понятно, не является ли новый игрок просто маленьким ООО, который продаёт ресурсы западного облака и делая просто серьёзную надбавку за провод платежей с РФ карт и локализованную панель управления.


        1. Data4
          18.07.2024 19:36

          Конкретно Amvera сейчас базируется на серверах Яндекс Облака и облака Онланты (и это все есть в публичной оферте на сайте). По сути Amvera - это надстройка для удобного деплоя проектов и прочей автоматизации. Как Heroku работает на мощностях AWS, так и Amvera на мощностях низкоуровневых облачных провайдеров. Т.е. это просто облачный провайдер, представляющий высокоуровневую автоматизацию. И да - OpenAI никак не сможет может получить неправомерный доступ к вашим данным, это же разные сервисы. Т.е. тут рисков не больше, чем хостить в Яндексе, AWS, или любом VPS, если вы сами в OpenAI свои данные не отправите, он их никак не может получить.


  1. t0rr
    18.07.2024 19:36

    Взять любой зарубежный сервер и поднять бота? Не, пойдём к какой-то конторе, чтобы пользоваться их проксированием...

    Взять aiogram на asyncio? Не, возьмём telebot на threading ...

    Череда странных решений


    1. AgentDaun
      18.07.2024 19:36

      А при чем здесь asyncio/threading(откуда он взялся вообще в telebot?)

      Рейтлимит у openai небольшой, в чём профит использования эвент лупа? Чем треды будут хуже? Хватит, пожалуйста, пропагандировать асинхронность там, где она не нужна(именно что пропагандировать, понятное дело что советовать, с объяснением, будет очень круто)


  1. Ryav
    18.07.2024 19:36
    +2

    Серьёзно?
    Серьёзно?


  1. Vaszaduet
    18.07.2024 19:36
    +1

    Круто! Спасибо за полезную информацию


  1. Ivstrek
    18.07.2024 19:36

    Мне понравилась статья.

    А как реализовать запоминание чата с историей сообщений?