У вас уже есть готовый работающий бот, которого мы написали в предыдущей части урока. Он умеет обрабатывать команды и отравлять сообщения на сервер. Теперь добавим нашему боту функции, чтобы перехватывать некоторые события. О чём идёт речь? например, запуск бота — это событие, подключение нового пользователя к серверу — это тоже событие, когда кто-то написал сообщение — тоже является событием.
Step 2
Приступим. Для того чтобы описать команду мы использовали декоратор @bot.command()
, а для того чтобы описать декоратор события мы будем использовать @bot.event()
При этом имя функции должно отображать то событие, которое бот должен перехватить и выполнить указанный с отступом код. В примере функция называется on_ready и она соответствует запуску бота. Все имена функций-событий зарезервированы и находятся в документации к API к discord.
В результате, когда вы запустите свой код на выполнение, событие on_ready() перехватит ход выполнения программы и выведет на экран информацию о запущенном боте.
Теперь напишем обработчик события поступления новых сообщений и будем его постепенно модифицировать. Создайте декоратор события on_message().
Запустите бот и напишите ему любой текст. Вы тут же увидите в консоли канал, отправителя и сам текст из сообщения. Казалось бы всё, но попробуйте теперь отправить боту одну из команд описанных выше и вы увидите, что теперь бот никак не реагирует на наши команды, хотя текст в консоли говорит нам о том, что мы эти команды получаем.
В чём проблема? Дело в том, что перехват события on_message() выполняется в первую очередь и не даёт объявленным функциям отработать согласно тексту команды.
Добавьте в конце функции строчкуawait bot.process_commands(message)
и проблема будет решена.
Полное описание и решение данной коллизии описано на официальном портале discord для разработчиков.
Теперь научим нашего бота отправлять ответные сообщения. Добавьте строчкуawait message.channel.send('Вот вам мой ответ!')
и теперь бот на любое сообщение будет присылать ‘Вот вам мой ответ!’
Остался небольшой штрих. Дело в том, что событие on_message() реагирует на каждое сообщение, даже если сообщение на сервере получено от бота. А зачем нам реагировать на сообщения, которые пишет сам бот? Немного изменим событие перехвата сообщения добавив к нему оператор ветвления if.
Самое важное здесь происходит в выражении следующим после ключевого слова if(строка 37). Если автором сообщения на сервере является сам бот, то мы выводим в консоль соответствующее предупреждение и просто выходим из функции ничего не возвращая. Просто завершаем её работу. Это позволит нам исключить зацикленность, когда бот начинает отвечать на свои же сообщения)
Теперь когда и команды и события работают так как нужно вы можете описать абсолютно любой алгоритм поведения бота. Ниже дам полезные ссылки.