Как создать игрового тг бота на python
Перейти к содержимому

Как создать игрового тг бота на python

  • автор:

Как создать бота с игрой в телеграмм c помощью Python.

Hello World!
Недавно я писал бота для телеграмм и один мой знакомый рассказал, что в телеграмме есть еще и игры. Мне стало интересно и я решил прогуглить. Идея игр в телеграмм мне понравилась и я подумал, что было бы хорошо интегрировать данную опцию в моего телеграмм бота, так как это добавит интерактивности. Телеграмм ботов я разрабатываю на Python, используя при этом библиотеку pyTelegramBotAPI. Вообщем, я начал искать и , к сожалению, не нашел нужной для меня информации, собранной в одном месте и на русском языке. Но как-то у меня получилось собрать все в кучу и немного разобраться с играми в телеграмм и теперь я хочу поделиться этим с вами. Сразу скажу, что в данной статье не будет каких-то детальных технических особенностей и тому подобных вещей. Начинаем.

Так, в статье я предполагаю, что у вас уже установлена библиотека pyTelegramBotAPI, а также вы более или менее понимаете, как создавать телеграмм ботов. В противном случае со всем этим вы можете ознакомиться в Интернете — информации достаточно.
Итак, импортируем библиотеку pyTelegramBotAPI, создаем бота с помощью BotFather и создаем объект бота используя токен, который выдал нам BotFather.

Хорошо, давайте теперь создадим игру. Делается это также с помощью BotFather. Пишем /newgame и следуем дальнейшим инструкциям.

Окей, дальше, когда вы согласитесь(или не согласитесь ��) с условиями пользователя, BotFather напишет, что ваш бот работает не в inline_mode, а бот с игрой должен работать именно в этом режиме. Но это не проблема. Просто пропишите команду /setinline и BotFather выдаст вам список ваших ботов и предложит выбрать какого из ботов вы хотите перевести в inline режим. Смело выбирайте какого-то из своих ботов.

«Угадай мелодию». Подготовка

Нашей целью будет создание простой игры из серии “Угадай мелодию”. В первом уроке мы договорились, что мы делаем прототип, поэтому в том боте, который мы получим, не будет ни таблицы рекордов, ни какой-либо статистики, ни поддержки групповых чатов. Зато мы научимся создавать кастомные клавиатуры, отправлять голосовые заметки и создавать мультишаговые команды.
Займёмся подготовкой базы данных для нашего бота.

Учимся уважать серверы Telegram

Итак, для начала, подготовим аудиофайлы для отправки. Чтобы не усложнять никому жизнь, будем отправлять аудио как голосовые заметки в формате OGG, а не как музыку. Я взял 5 никому не известных песен, сделал из них 15-20-секундные нарезки, сконвертировал в *.ogg и положил в папку “music”. А теперь делаем финт ушами. Смотрите: мы будем отправлять юзерам одни и те же файлы много-много раз, давайте же побережем свой трафик и дисковое пространство на серверах Telegram, благо в документации написано, что можно отправлять различные объекты не как файлы, а по file_id (если файлы уже предварительно загружены). Прекрасно! Попросим нашего бота прислать нам наши аудиофайлы и их file_id :

Обратите внимание, в последней строке мы больше не используем бесконечный цикл While, из-за изменений в используемой библиотеке. В данном случае по команде /test бот будет отправлять наши файлы вместе с их file_id. Записываем эти file_id куда-нибудь.

ВАЖНО!: Идентификаторы file_id уникальны для каждого бота по отдельности! То есть, если Вы хотите, чтобы бот А сохранил file_id файла Х, то именно этому боту и надо отправлять файлы. Если Вы попробуете воспользоваться для этого ботом B, идентификаторы станут невалидны.

ВАЖНО 2: При отправке медиафайлов большого размера вы можете столкнуться с ошибкой ConnectionError: (‘Connection aborted.’, timeout(‘The write operation timed out’,)) . Чтобы её избежать, при вызове методов для медиа send_audio , send_video и остальных аргумент timeout=ЧИСЛО , где значение ЧИСЛО укажите в соответствии с вашими потребностями (например, 5, 10 или что-то ещё, в зависимости от размера файла)

База, приём!

Раз уж мы имеем дело с перманентными данными, нам нужно где-то их хранить. В стандартной библиотеке Python есть 2 чудесных способа: при помощи БД SQLite3 и при помощи хранилищ типа “ключ-значение” shelve. Будем использовать оба варианта. Начнём с БД. Здесь и далее под “БД” или “Базой Данных” я буду понимать именно SQLite3, а под словом “хранилище” — shelve. Итак, при помощи бесплатной Windows-утилиты DB Browser for SQLite я создал базу данных с одной-единственной таблицей music и заполнил её сведениями о моих аудиофайлах. Чтобы была понятна примерная структура БД, посмотрите на скриншот:

Структура БД

Столбец file_id содержит идентификатор аудиозаписи, right_answer и wrong_answer — правильный и неправильные ответы соответственно. Для чего мне нужно это разделение, объясню позднее. Итак, наша тестовая база создана, при помощи команды экспорт я сгенерировал файл с чудесным названием tttt.sql следующего содержания:

Затем я залил этот файл на свой Linux-сервер, в терминале которого выполнил команду sqlite3 music.db < tttt.sql , которая привела к созданию файла music.db, являющимся базой данных наших аудиозаписей.
Теперь создадим файл SQLighter.py . Т.к. Python изначально объектно-ориентированный язык, мне захотелось оформить работу с БД в виде класса. Пусть умные люди меня поправят, если я что-то сделал не так. Вот как выглядит наш класс:

При каждом создании объекта SQLighter будет открываться отдельное соединение с БД и впоследствии закрываться. Мне кажется, это правильный подход, тем более, что бот изначально многопоточный (особенность библиотеки).

Хранилище

Наверняка у кого-то возникнет справедливый вопрос: “А зачем нам нужно простое хранилище, если у нас уже есть полноценная база данных?”. Ответ: я просто не хочу лишний раз дёргать БД.

Идея с key-value хранилищем ложится здесь идеально. В чём состоит моя идея: когда юзер начинает игру, вместе с вопросом я сохраняю себе правильный ответ, и при выборе ответа пользователем я сравниваю его ответ с правильным. Совпало — молодец. Не совпало — не молодец. Затем запись удаляется из хранилища, чтобы не занимать лишнее место.

Простой Telegram-бот на Python за 30 минут

На Хабре, да и не только, про ботов рассказано уже так много, что даже слишком. Но заинтересовавшись пару недель назад данной темой, найти нормальный материал у меня так и не вышло: все статьи были либо для совсем чайников и ограничивались отправкой сообщения в ответ на сообщение пользователя, либо были неактуальны. Это и подтолкнуло меня на написание статьи, которая бы объяснила такому же новичку, как я, как написать и запустить более-менее осмысленного бота (с возможностью расширения функциональности).

Часть 1: Регистрация бота

Самая простая и описанная часть. Очень коротко: нужно найти бота @BotFather, написать ему /start, или /newbot, заполнить поля, которые он спросит (название бота и его короткое имя), и получить сообщение с токеном бота и ссылкой на документацию. Токен нужно сохранить, желательно надёжно, так как это единственный ключ для авторизации бота и взаимодействия с ним.

Часть 2: Подготовка к написанию кода

Как уже было сказано в заголовке, писать бота мы будем на Python’е. В данной статье будет описана работа с библиотекой PyTelegramBotAPI (Telebot). Если у вас не установлен Python, то сперва нужно сделать это: в терминале Linux нужно ввести

Если же вы пользуетесь Windows, то нужно скачать Python с официального сайта .

После, в терминале Linux, или командной строке Windows вводим

Теперь все готово для написания кода.

Часть 3: Получаем сообщения и говорим «Привет»

Небольшое отступление. Телеграмм умеет сообщать боту о действиях пользователя двумя способами: через ответ на запрос сервера (Long Poll), и через Webhook, когда сервер Телеграмма сам присылает сообщение о том, что кто-то написал боту. Второй способ явно выглядит лучше, но требует выделенного IP-адреса, и установленного SSL на сервере. В этой статье я хочу рассказать о написании бота, а не настройке сервера, поэтому пользоваться мы будем Long Poll’ом.

Открывайте ваш любимый текстовый редактор, и давайте писать код бота!

Первое, что нужно сделать это импортировать нашу библиотеку и подключить токен бота:

Теперь объявим метод для получения текстовых сообщений:

В этом участке кода мы объявили слушателя для текстовых сообщений и метод их обработки. Поле content_types может принимать разные значения, и не только одно, например

Будет реагировать на текстовые сообщения, документы и аудио. Более подробно можно почитать в официальной документации

Теперь добавим в наш метод немного функционала: если пользователь напишет нам «Привет», то скажем ему «Привет, чем я могу помочь?», а если нам напишут команду «/help», то скажем пользователю написать «Привет»:

Данный участок кода не требует комментариев, как мне кажется. Теперь нужно добавить в наш код только одну строчку (вне всех методов).

Теперь наш бот будет постоянно спрашивать у сервера Телеграмма «Мне кто-нибудь написал?», и если мы напишем нашему боту, то Телеграмм передаст ему наше сообщение. Сохраняем весь файл, и пишем в консоли

Где bot.py – имя нашего файла.

Теперь можно написать боту и посмотреть на результат:

image

Часть 4: Кнопки и ветки сообщений

Отправлять сообщения это несомненно весело, но ещё веселее вести с пользователем диалог: задавать ему вопросы и получать на них ответы. Допустим, теперь наш бот будет спрашивать у пользователя по очереди его имя, фамилию и возраст. Для этого мы будем использовать метод register_next_step_handler бота:

И так, данные пользователя мы записали. В этом примере показан очень упрощённый пример, по хорошему, хранить промежуточные данные и состояния пользователя нужно в БД, но мы сегодня работаем с ботом, а не с базами данных. Последний штрих – запросим у пользователей подтверждение того, что все введено верно, да не просто так, а с кнопками! Для этого немного отредактируем код метода get_age

И теперь наш бот отправляет клавиатуру, но если на нее нажать, то ничего не произойдёт. Потому что мы не написали метод-обработчик. Давайте напишем:

Telegram-bot: игра "Угадай число"

Я программирую не так давно и очень хотелось бы попробовать написать небольшого игрового Telegram бота.

В планах было создание, собственно, игры "угадай число" и создание ответов бота на некоторые сообщения. Представлял я себе это очень легко, но когда скачал библиотеку понеслась нервотрепка.

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

При запуске игры возникает ошибка ValueError: invalid literal for int() with base 10: ‘игра’ , т.к. видимо строка ‘игра’ попадает в переменную guess , чего быть не должно.

При введении строки ‘привет’ или ‘как дела’ бот не отвечает. Если же функции digitgames и send_texts поменять местами, то бот успешно отвечает, но запуск игры при этом не работает, причем ошибку нигде не выдает.

Вот код (токен бота скрыт специально):

Woopertail's user avatar

Во первых, в PyTelegramBotAPI (и не только) весь функционал бота строится на декораторах. В вашем же случае вы запихнули ответ на ‘как дела’ и ‘привет’ в одну функцию, что не совсем хорошо если рассуждать со стороны эстетики языка Python, каждая функция дожна отвечать за определенный фнукционал, их можно было отделить в отдельные функции и указать в декораторе, определенные условия при которых срабатывала бы функция. То есть вот так:

Такая же проблема и с функцией digitgames:

Во вторых, у вас два одинковых декоратора: @bot.message_handler(content_types=[‘text’]) , из-за этого у вас бот не хотел реагировать на слова ‘как дела’ и ‘привет’. То есть если у вас будет два определенных условии в декораторах, и сообщение пользывателя бота будет попадать под эти два условия, то будет срабатывать только первый декоратор, давайте возьмем за основу ваш пример:

Как видите у нас есть две фнукции с декораторами, и в обеих декортаорах указано чтобы обе функции срабатывали на тип контента text (текст). Допустим вы напишите боту "привет", то по идее бот должен ответит вам "Ну привет)", но он вам ответит "Noting else". А почему? А потому что, функция digitgames стоит первой и его декоратор срабатывает на любой текст так же как и второй декоратор фнукции send_texts, но так как digitgames стоит первой и content_types=[‘text’] сообщении является True, то соотвественно вторая фнукция уже не срабатыватает.

В третих, что это такое?

Почему digit и counter у вас через запятую отделён от основного текста сообщени? send_message — это обычная функция, и она как любая другая функция принимает определеные аргументы, это вам не print(), где можно бесконечно указывать аргументы и все они будут восприниматся как текст:

Функция send_message в целом принимает много аргументов. Самые главные из них chat_id и text, chat_id вы верно указали — message.chat.id, а вот text не совсем коректно, вот правильный пример:

В четвортых, разработка бота это вам не халам-балам, хорошо что вы используете PyTelegramBotAPI, есть библиотека aiogram, это настоящии ад, она асинхронная, а чтобы понять ассинхронность нужно достаточно хорошо понимать Python (aiogram — это PyTelegramBotAPI на стеройдах).

guess=int(message.text) , Cтрока ‘игра’ попадает в переменную guess, чего быть не должно. — В разработке Телеграмм бота нету фнукции input(), есть кое-что похожее, но работает она совсем по другому принципу — bot.register_next_step_handler. Посмотрите вот этот пример: https://github.com/eternnoir/pyTelegramBotAPI/blob/master/examples/step_example.py

Вот сообвственно ваш пофикшенный код:

Совет: никогда не используйте глобальные переменные в ботах, я в примере реализовал костыль в виде функции init_storage, set_data_storage и get_data_storage заместо глобальных переменных.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *