Данная статья написана по видео-ролику «ChatGPT OpenAI в Telegram на Python / Пишем Telegram-бота ChatGPT на Питоне» c небольшим дополнением — добавил в код проверку по id в телеграме.
Как ограничить доступ к боту телеграм (aiogram) — об этом читайте в конце данной статьи.
Если вы не сталкивались с питоном, то необходимо установить его. О том, как это сделать, подробно описано здесь.
Теперь приступим к созданию бота ChatGPT в Telegram.
Установка библиотек для телеграм-бота:
Первое, что нам нужно сделать — это установить библиотеки aiogram и OpenAI:
- Чтобы установить aiogram, введите в терминале:
pip install aiogram
- Чтобы установить OpenAI, введите в терминале:
pip install openai
Регистрация в OpenAI:
Чтобы добавить функционал ChatGPT в Telegram, для начала, необходимо зарегистрироваться здесь — https://platform.openai.com, о том как зарегистрировать аккаунт в ChatGPT на территории РФ, снято уже очень много видео.
Далее переходим в раздел API Keys и нажимаем кнопку «Create new secret key», копируем получившийся ключ.
Как создать бота в телеграм:
Создаем бота в телеграме — https://t.me/BotFather :
- Переходим по ссылке выше и запускаем бота, нажимаем кнопку «Меню»
- Вводим любое имя для нашего бота, отправляем сообщение
- Вводим логин нашего бота, по которому мы сможем его найти. Важно: login должен оканчиваться на bot (Пример правильного логина: illarion_bot), а так же логин должен быть уникальным
- Копируем токен API нашего бота (начинается после слов — «Use this token to access the HTTP API:»)
Пишем код телеграм-бота на Python:
Создаем любой файл с расширением .py , а в сам файл вставляем следующий код:
import openai
from aiogram import Bot, types
from aiogram.dispatcher import Dispatcher
from aiogram.utils import executor
token = 'TELEGRAM_BOT_TOKEN'
openai.api_key = 'OPENAI_KEY'
bot = Bot(token)
dp = Dispatcher(bot)
@dp.message_handler()
async def send(message: types.Message):
response = openai.Completion.create(
model="text-davinci-003",
prompt=message.text,
temperature=0.9,
max_tokens=4000,
top_p=1.0,
frequency_penalty=0.0,
presence_penalty=0.6,
stop=[" Human:", " AI:"]
)
await message.answer(response['choices'][0]['text'])
executor.start_polling(dp, skip_updates=True)
Замените токены Телеграм и OpenAI в коде на те, что мы получили выше.
Прописываются они здесь (строки кода номер 7 и 8):
token = 'TELEGRAM_BOT_TOKEN'
openai.api_key = 'OPENAI_KEY'
В данном коде используется языковая модель text-davinci-003, т.е. — Чат. Чтобы использовать другие модули — перейдите в раздел «Examples«, выберите необходимый модуль и замените фрагмент кода:
response = openai.Completion.create(
model="text-davinci-003",
prompt=message.text,
temperature=0.9,
max_tokens=4000,
top_p=1.0,
frequency_penalty=0.0,
presence_penalty=0.6,
stop=[" Human:", " AI:"]
)
Замените данный фрагмент на аналогичный код из описания нужного модуля (начинается с «response =» и заканчивается «)»
Все это было пересказом видео одного программиста, бот мы создали и теперь то, зачем я пишу данную статью и то, что может помочь многим начинающим разработчикам на python.
Если вы запускаете код на GNU/Linux дистрибутивах, то на вторую строчку, после фрагмента import openai вставьте следующую строку:
import os
Как ограничить доступ к боту телеграм (aiogram)?
Находим строку 12, (пустая строка после dp = Dispatcher(bot), и в пустой строке вставляем следующий код:
users = {tg_id1,tg_id2}
accepted_users = lambda message: message.from_user.id not in users
@dp.message_handler(accepted_users, content_types=['any'])
async def handle_unwanted_users(message: types.Message):
await message.answer("Извините, бот работает только для одобренных пользователей. Если вы хотите написать такой же бот - перейдите по ссылке: https://nikonorow.ru/pishem-telegram-bota-chatgpt-na-python/")
return
users = {tg_id1,tg_id2} — в фигурных скобках, через запятую, перечисляется id пользователей телеграма (вводить только числа), которые допущены к данному боту.
Узнать свой id в телеграме можно тут. Подставляем свои id, заменяем текст в скобках после message.answer (если это необходимо, так же не забывайте обернуть свой текст в кавычки «»)
Как сделать проверку по количеству введенных символов пользователя в aiogram?
Если количество введенных символов превышает 2000 — выводится ошибка с пояснением. Код следующий:
max_symbols = lambda message: int(len(message.text)) > 2000
@dp.message_handler(max_symbols, content_types=['any'])
async def handle_unwanted_users(message: types.Message):
await message.answer("Ошибка! Введенное количество символов превышает максимальное значение в 2000" + "\n\nКоличество введенных символов: " + str(len(message.text)) + "\n\nСократите Ваш запрос")
return
Если вы не делали проверку по id телеграм, то код вставляем на строку номер 12, (пустая строка после dp = Dispatcher(bot), и в пустой строке вставляем данный код.
Если вы сделали проверку по id, то вставляем после через строку после кода ограничения
Число 2000 в проверке — приблизительное. Читать подробнее об ограничениях OpenAI API >
Готово! ChatGPT в Telegram работает. Смотрите так же другие статьи, правда они в основном касаются веб-разработки.
Дата создания статьи: 09.02.2023
Рубрика: Разработка ПО
все токены вставил и не получается нифига. можете у себя запустить готовый код с моими токенами ?
Добрый день, есть несколько уточнений:
1. Что выдает консоль при запуске скрипта?
2. Пайтон и все библиотеки стоят?
3. Запускаете скрипт на сервере или локально?
Если все стоит, включая библиотеки OpenAI и aiogram, и все равно не работает — пишите мне в телегу, попробую запустить.
Очень круто, спасибо! Получилось. Вопрос — чтобы ограничить пользователей, как надо вставлять их айди в скобках? (tg_4534345345) или просто цифры без tg? Или как-то еще? Пробовал и так и так — все-равно люди с чужих айди могут пользоваться.
Доброй ночи, спасибо за комментарий!
Просто цифры, без tg. Примерно так: users = (111111111,2222222222)
если айди лишь 1, то вместо обычных скобок используйте фигурные
пример: users = {123456789}
переписал данный момент в статье
Спасибо тебе, все сделал по инструкции, оно работает!)))
Доброй ночи, благодарю за комментарий! Рад, что все получилось)
Добрый день, попытался стартануть бота на replit.com, стартует нормально, но при запуске бота из телеги ошибка на сервере
Task exception was never retrieved
future: <Task finished name='Task-11' coro=<Dispatcher._process_polling_updates() done, defined at /home/runner/DiscreteOvercookedValue/venv/lib/python3.10/site-packages/aiogram/dispatcher/dispatcher.py:407> exception=TypeError("argument of type 'int' is not iterable")>
Traceback (most recent call last):
File "/home/runner/DiscreteOvercookedValue/venv/lib/python3.10/site-packages/aiogram/dispatcher/dispatcher.py", line 415, in _process_polling_updates
for responses in itertools.chain.from_iterable(await self.process_updates(updates, fast)):
File "/home/runner/DiscreteOvercookedValue/venv/lib/python3.10/site-packages/aiogram/dispatcher/dispatcher.py", line 235, in process_updates
return await asyncio.gather(*tasks)
File "/home/runner/DiscreteOvercookedValue/venv/lib/python3.10/site-packages/aiogram/dispatcher/handler.py", line 117, in notify
response = await handler_obj.handler(*args, **partial_data)
File "/home/runner/DiscreteOvercookedValue/venv/lib/python3.10/site-packages/aiogram/dispatcher/dispatcher.py", line 256, in process_update
return await self.message_handlers.notify(update.message)
File "/home/runner/DiscreteOvercookedValue/venv/lib/python3.10/site-packages/aiogram/dispatcher/handler.py", line 108, in notify
data.update(await check_filters(handler_obj.filters, args))
File "/home/runner/DiscreteOvercookedValue/venv/lib/python3.10/site-packages/aiogram/dispatcher/filters/filters.py", line 77, in check_filters
f = await execute_filter(filter_, args)
File "/home/runner/DiscreteOvercookedValue/venv/lib/python3.10/site-packages/aiogram/dispatcher/filters/filters.py", line 63, in execute_filter
return filter_.filter(*args, **filter_.kwargs)
File "main.py", line 17, in <lambda>
accepted_users = lambda message: message.from_user.id not in users
TypeError: argument of type 'int' is not iterable
методом исключения не работает эта часть
users = (tg_id1,tg_id2)
accepted_users = lambda message: message.from_user.id not in users
@dp.message_handler(accepted_users, content_types=['any'])
async def handle_unwanted_users(message: types.Message):
await message.answer("Извините, бот работает только для одобренных пользователей. Если вы хотите написать такой же бот - перейдите по ссылке: https://nikonorow.ru/pishem-telegram-bota-chatgpt-na-python/")
return
users = (123456789) указанно в таком виде
Добрый день, благодарю за комментарий.
Если id только 1 — то используйте фигурные или квадратные скобки вместо обычных.
не
users = (123456789), а users = {123456789} или users = [123456789]Речь идет о форматировании строк, можете погуглить подробнее, если интересно или почитайте тред на stackoverflow
привет, локально все работает а при загрузке на сервер (pythonanywhere)
нет, что делать?))
Привет, вроде как у pythonanywhere есть ограничения в бесплатном тарифе на исходящие подключения.
Но это не точно, лучше проверить ограничения тарифов на самом сайте или пробовать деплоиться на другом сервере.
Получилось на таймвебе 👍👍👍
Отлично! Какова цена вопроса, если это не секрет?
188 ₽ в месяц, — самый дешевый тариф, я еще на это этом хостинге ВПН свой поднял.
Не знаешь как сделать чтобы показывалась инфа что бот печатает, (как обычно бывает в чатах) ?
в web интерфейсе chatGPT это есть
И еще заметил что ответы и в веб интерфесе лучше, он запоминает диалог и можно развивать тему.
А в ТГ боте он каждый вопрос воспринимает как новый
Спасибо! Теперь по пунктам:
Подробнее об ограничениях в бесплатной версии OpenAI API можно прочесть здесь, если коротко, то: в одном задании к API дается приблизительно 3000 слов на вопрос и на ответ в сумме, если предоставлять доступ к истории, то запросы пользователя должны быть ограничены в параметре max_tokens, иначе API будет выдавать ответ об ошибке.
По вопросу предоставления истории запросов, подробнее можно посмотреть на Хабре
А как переработать код под дискорд?
Доброй ночи, не задавался данным вопросом. Для начала нужно гуглить как создать бота для данного сервиса, затем уже адаптировать код под него.
Круто всё работает =)
Спасибо за обратную связь!)