Для нас, детей 90-х, покемон - это область эмоций. Я до сих пор помню, как безумно собирал карты с покемонами, смотрел сериалы о покемонах по телевизору и участвовал в воображаемых драках с покемонами в школе. Таким образом, я подумал о создании чего-то связанного с покемонами. Отсюда и пришла в голову идея сделать что-то вроде Pokedex-бота. Для тех из вас, кто не знаком с тем, что такое Pokedex, это цифровой инструмент, содержащий информацию, связанную с покемонами. Размышляя о том, для какой платформы создать бота, я подумал, что Telegram - отличный выбор. Telegram превратился в большое сообщество, которое будет расти с каждым днем. Итак, приступим к созданию бота.

База данных Pokédex:

Первая задача, которую нам предстоит решить, - это то, как мы получим всю информацию о таком большом количестве покемонов. К счастью, наша работа облегчилась для нас. Поклонники покемонов создали для нас API покемонов, которым мы можем свободно пользоваться. Этот PokeAPI предоставляет нам RESTful API, который можно использовать для генерации всей информации о покемонах для нашего проекта. Чтобы узнать больше о RESTful API, посмотрите это видео.

Подождите, есть еще кое-что. Итак, часть данных решена, но, чтобы сделать нашего бота более привлекательным, мы собираемся добавить фотографии каждого покемона. Этот сайт творит за нас чудеса. Нам просто нужно указать идентификатор покемона и мы получим изображение покемона в формате PNG. Детали будут показаны в части кодирования.

Интеграция PokeAPI:

Для интеграции PokeAPI нам нужно больше узнать об API. Каждый хороший API предоставляет нам документацию. PokeAPI документация предоставляет нам все, что нам нужно знать об этом API. По сути, нам нужно предоставить конечной точке имя / идентификатор покемона при вызове API.

https://pokeapi.co/api/v2/pokemon/{id or name}/

Итак, нам нужно создать собственный модуль Python, который мы будем использовать в нашей основной программе Python для ботов. Назовем этот файл Python pokedex.py. В нашем pokedex.py нам нужно импортировать две библиотеки python: request и json. Установите его в свою систему с помощью pip.

pip insall requests

Другой пакет json предварительно собран с python. Мы будем использовать библиотеку requests для выполнения запроса на получение для вызова API, а пакет json, который мы собираемся использовать, предназначен для обработки выходных данных, которые мы получаем из вызов API. Вы видите, что результат, который мы получаем из ответа API, находится в формате JSON. Используя метод загрузки json, нам нужно сначала преобразовать вывод JSON в словарь Python.

output= ""
url = "https://pokeapi.co/api/v2/pokemon/{}/"
#get request for API information retrieval
final_url = url.format(id_name)
response = requests.get(final_url)
response = response.content
#json to python dictionary convertion
information=json.loads(response)

Давайте посмотрим на полученный образец ответа JSON. Это упростит нашу работу, отфильтровав всю необходимую нам информацию.

{
  "id": 12,
  "name": "butterfree",
  "base_experience": 178,
  "height": 11,
  "is_default": true,
  "order": 16,
  "weight": 320,
  "abilities": [
    {
      "is_hidden": true,
      "slot": 3,
      "ability": {
        "name": "tinted-lens",
        "url": "https://pokeapi.co/api/v2/ability/110/"
      }
    }
  ],
  "forms": [
    {
      "name": "butterfree",
      "url": "https://pokeapi.co/api/v2/pokemon-form/12/"
    }
  ],
  "game_indices": [
    {
      "game_index": 12,
      "version": {
        "name": "white-2",
        "url": "https://pokeapi.co/api/v2/version/22/"
      }
    }
  ],
  "held_items": [
    {
      "item": {
        "name": "silver-powder",
        "url": "https://pokeapi.co/api/v2/item/199/"
      },
      "version_details": [
        {
          "rarity": 5,
          "version": {
            "name": "y",
            "url": "https://pokeapi.co/api/v2/version/24/"
          }
        }
      ]
    }
  ],
  "location_area_encounters": "https://pokeapi.co/api/v2/pokemon/12/encounters",
  "moves": [
    {
      "move": {
        "name": "flash",
        "url": "https://pokeapi.co/api/v2/move/148/"
      },
      "version_group_details": [
        {
          "level_learned_at": 0,
          "version_group": {
            "name": "x-y",
            "url": "https://pokeapi.co/api/v2/version-group/15/"
          },
          "move_learn_method": {
            "name": "machine",
            "url": "https://pokeapi.co/api/v2/move-learn-method/4/"
          }
        }
      ]
    }
  ],
  "species": {
    "name": "butterfree",
    "url": "https://pokeapi.co/api/v2/pokemon-species/12/"
  },
  "sprites": {
    "back_female": "http://pokeapi.co/media/sprites/pokemon/back/female/12.png",
    "back_shiny_female": "http://pokeapi.co/media/sprites/pokemon/back/shiny/female/12.png",
    "back_default": "http://pokeapi.co/media/sprites/pokemon/back/12.png",
    "front_female": "http://pokeapi.co/media/sprites/pokemon/female/12.png",
    "front_shiny_female": "http://pokeapi.co/media/sprites/pokemon/shiny/female/12.png",
    "back_shiny": "http://pokeapi.co/media/sprites/pokemon/back/shiny/12.png",
    "front_default": "http://pokeapi.co/media/sprites/pokemon/12.png",
    "front_shiny": "http://pokeapi.co/media/sprites/pokemon/shiny/12.png",
    "other": {
      "dream_world": {},
      "official-artwork": {}
    },
    "versions": {
      "generation-i": {
        "red-blue": {},
        "yellow": {}
      },
      "generation-ii": {
        "crystal": {},
        "gold": {},
        "silver": {}
      },
      "generation-iii": {
        "emerald": {},
        "firered-leafgreen": {},
        "ruby-sapphire": {}
      },
      "generation-iv": {
        "diamond-pearl": {},
        "heartgold-soulsilver": {},
        "platinum": {}
      },
      "generation-v": {
        "black-white": {}
      },
      "generation-vi": {
        "omegaruby-alphasapphire": {},
        "x-y": {}
      },
      "generation-vii": {
        "icons": {},
        "ultra-sun-ultra-moon": {}
      },
      "generation-viii": {
        "icons": {}
      }
    }
  },
  "stats": [
    {
      "base_stat": 70,
      "effort": 0,
      "stat": {
        "name": "speed",
        "url": "https://pokeapi.co/api/v2/stat/6/"
      }
    }
  ],
  "types": [
    {
      "slot": 2,
      "type": {
        "name": "flying",
        "url": "https://pokeapi.co/api/v2/type/3/"
      }
    }
  ]
}

Для нашего бота Pokedex мы собираемся показать идентификатор, имя, рост, вес, типы и ходы. Поэтому удобно отфильтровать всю эту информацию и поместить ее в строку output.

output += f"<b>ID:</b> {str(information['id'])} \n"
output += f"<b>Name:</b> {str(information['name'])}\n"
output += f"<b>Height:</b> {str(information['height'])}\n"
output += f"<b>Weight:</b> {str(information['weight'])}\n"
all_types=information['types']
types = ""
for type_ in all_types:
    types += f"{type_['type']['name']} "
output += f"<b>Types:</b> {str(types)} \n"
all_moves=information['moves']
moves = ""
#getting 5 moves of the pokemon
if len(all_moves) < 6:
    for i in range(len(all_moves)):
        moves += f"<b>{i+1}:</b> {all_moves[i]['move']['name']} \n"
else:
    for i in range(6):
        moves += f"<b>{i+1}:</b> {all_moves[i]['move']['name']} \n"
output += f"<b>Moves:\n</b> {moves} \n"

По умолчанию бот показывает максимум 5 ходов, поэтому первые 5 ходов отфильтровываются, если их больше. Если вам интересно, почему здесь используется полужирный тег HTML, это потому, что библиотека, которую мы собираемся использовать в боте, поддерживает режим синтаксического анализа HTML. Это сделает текст более привлекательным.

Теперь осталось только вывести изображение покемона. Это можно сделать с помощью веб-сайта, указанного в части базы данных.

if information['id'] <= 890:
    photo_url = f"https://pokeres.bastionbot.org/images/pokemon/{information['id']}.png"

Мы собираемся показать покемонов до 890, поскольку это предел, на который база данных может предоставлять изображения.

Чтобы навести порядок, давайте создадим функцию Pokedex, которая принимает идентификатор / имя покемона в качестве параметра. Окончательный код модуля Pokedex выглядит так.

Главный бот:

Наконец, идет часть бота. Теперь нам нужно подключиться к Telegram и отправить ответ, когда кто-то запрашивает данные. Telegram предоставляет для этого собственный API. Мы не собираемся использовать их API напрямую, а воспользуемся одним очень популярным пакетом для создания телеграмм-ботов, известным как python-telegram-bot. Давайте установим это в нашу систему

pip install python-telegram-bot

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

Создание бота:

Перейдите в botfather, чтобы создать нового бота.

Скопируйте код токена API и создайте новый файл Python «config_file.py» и вставьте код токена в переменную api_key.

api_key = ''

А теперь давайте сделаем основную часть бота. Создайте новый файл Python bot.py. Сделайте две функции для команды запуска и команды справки. Еще одна функция нужна для обработки ошибок, если наш бот столкнется с какой-либо ошибкой во время работы.

def start_command(update,context):
    username = update.message.chat.first_name
    update.message.reply_text(f"How are you {username}.Welcome to the pokemon world.Enter a valid pokemon name or ID (upto 890) to get started")
def error(update,context):
    print(f"{update} caused error {context.error}")
def help_command(update,context):
    
    update.message.reply_text("Please Enter a valid pokemon name or ID (upto 890) to get info")

Команда запуска (/ start) запрашивает у пользователя имя / идентификатор покемона и приветствует их по имени. Эти обработчики команд принимают два параметра update и context. Метод текста ответа используется для ответа на текст, отправленный пользователем. Чтобы узнать больше о различных методах и функциях, перейдите в документацию.

Следующая функция будет использоваться для ответа, когда пользователь отправляет сообщение боту.

def message_response(update,context):
text = str(update.message.text).lower()
    username = update.message.chat.first_name
    print(username)
    if text in ("hi","hello","yo","whats up"):
        response = (f"<b>How are you doing {username}.Enter a pokemon name or id to get info </b>")
    else:
        response,photo_url = pokedex(text)
        if response != None and photo_url != None:
            chat_id = update.message.chat_id
            context.bot.send_photo(chat_id=chat_id,photo=photo_url)
        else:
            response = "Sorry didn't understand you. Please Enter a <b>valid</b> pokemon name or <b>ID (upto 890)</b> to get info"

Здесь мы снова приветствуем пользователя, если он посылает сообщение типа «привет» / «привет». В противном случае ответ с информацией о покемоне вместе с изображением покемона дается в соответствии с именем / идентификатором покемона, предоставленным пользователем. Если не указано действительное имя или идентификатор покемона, мы просим пользователя ввести действительное имя или идентификатор.

Мы подошли к нашей последней части - основной функции.

def main():
    updater = Updater(config_file.api_key,use_context = True)
    dp = updater.dispatcher
    dp.add_handler(CommandHandler("start",start_command))
    dp.add_handler(CommandHandler("help",help_command))
    dp.add_handler(MessageHandler(Filters.text,message_response))
    dp.add_error_handler(error)
    updater.start_polling(3)
    updater.idle()

Прежде всего, программа обновления инициализируется с помощью api_key, который мы сохранили ранее. После этого инициализируется диспетчер. Затем мы добавляем два обработчика команд, которые будут использоваться для обработки команд / start или / help в телеграмме. Обработчик сообщений также добавлен для обработки любого сообщения, отправленного пользователем. Последний - добавление обработчика ошибок. Метод запуска опроса вызывается для обновления каждые 3 секунды.

На этом наш бот готов. Собираем все вместе финальный файл bot.py выглядит так.

Просто перейдите в каталог bot.py и запустите файл python. Вуаля! Волшебство начинается. Зайдите к своему боту в Telegram и начните отправлять сообщения, чтобы увидеть волшебство.

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