Свой Telegram бот на Python
PythonGuru
Привет, любитель Python!
В этой статье мы напишем своего телеграм бота на пайтоне.
Telegram даёт возможность создавать ботов. Написание своего бота - самый лучший вариант понять, что такое API.
Создание бота
Начинаем мы с того, что создаём бота в @BotFather.
Бот получен, после этого заходим в него и отправляем ему любое сообщение (обязательно, это станет первым обновлением бота).
Для работы с API заходим в браузер и вставляем ссылку(вместо ваш-токен вписываем свой токен)
https://api.telegram.org/bot<ваш_токен>/getUpdates
Откроется страница в формате JSON, будет что-то вроде такого:
{
"ok":true,
"result":[{
"update_id":553349976,
"message":{
"message_id":53,
"from":{
"id":305262757,
"first_name":"Name"
},
"chat":{
"id":303262877,
"first_name":"Name",
"type":"private"
},
"date":1486823360,
"text":"Hi"
}
}]
}
Изучив раздел метода /sendMessage в документации, вы увидите, что он принимает два параметра: chat_id и text. Вы сможете создавать цепочки параметров в адресной строке браузера, используя ? для первого и & для всех последующих. Команда для отправки сообщения будет выглядеть так:
/sendMessage?chat_id=303262877&text=test
Попробуем получить ответ от вашего бота, подставив в качестве chat_id значение, полученное после вызова /getUpdates (в нашем примере — 303262877). Текст сообщения может быть любым. Запрос должен выглядеть примерно так:
https://api.telegram.org/bot<token>/sendMessage?chat_id=303262877&text=Hello
Подготовка
Версия пайтона не имеет значения, но мы будем использовать Python 3.6.
Ещё потребуется pip, он по умолчанию установлен в версиях выше 2.7.9.
Далее устанавливаем паке requests:
pip install requests
Написание кода
Теперь, после того как вы поняли что такое API, и установили всё необходимое, давайте напишем скрипт, который будет постоянно проверять обновления и отвечать на сообщения.
Сперва напишем код для проверки обновлений. Первое сообщение считается как самое свежее, но getUpdates возвращает все обновления за последние 24 часа.
Вот и сам скрипт:
import requests
url = "https://api.telegram.org/bot<ваш_токен>/"
def get_updates_json(request):
response = requests.get(request + 'getUpdates')
return response.json()
def last_update(data):
results = data['result']
total_updates = len(results) - 1
return results[total_updates]
Этот словарь обновлений состоит из двух элементов: ok и results. Нас интересует results - это список всех обновлений за последние 24 часа.
Больше об библиотеке results в документации.
Теперь нужно добавить ещё 2 функции. Первая будет доставать chat_id из обновления, а вторая отправлять сообщение:
def get_chat_id(update):
chat_id = update['message']['chat']['id']
return chat_id
def send_mess(chat, text):
params = {'chat_id': chat, 'text': text}
response = requests.post(url + 'sendMessage', data=params)
return response
Скрипт готов, но он не идеальный. Чтобы бот слушал сервер и получал обновления, нам нужно запустить основной цикл. Добавьте после import requests сторку from time import sleep После этого замените две последние строки на этот код:
def main():
update_id = last_update(get_updates_json(url))['update_id']
while True:
if update_id == last_update(get_updates_json(url))['update_id']:
send_mess(get_chat_id(last_update(get_updates_json(url))), 'test')
update_id += 1
sleep(1)
if __name__ == '__main__':
main()
Поскольку мы начали использовать в скрипте основной цикл, мы должны переключиться на длинные опросы. Изменим первую функцию, добавив в неё параметр timeout. Он не уменьшит частоту проверки обновлений и будет работать только в том случае, когда обновлений нет. Чтобы помечать уже просмотренные обновления, нужно добавить параметр сдвига offset:
def get_updates_json(request):
params = {'timeout': 100, 'offset': None}
response = requests.get(request + 'getUpdates', data=params)
return response.json()
Теперь уже лучше, но мы сделаем ещё лучше. Давайте инкапсулируем все функции в один класс. Должно получиться примерно это:
import requests
import datetime
class BotHandler:
def __init__(self, token):
self.token = token
self.api_url = "https://api.telegram.org/bot{}/".format(token)
def get_updates(self, offset=None, timeout=30):
method = 'getUpdates'
params = {'timeout': timeout, 'offset': offset}
resp = requests.get(self.api_url + method, params)
result_json = resp.json()['result']
return result_json
def send_message(self, chat_id, text):
params = {'chat_id': chat_id, 'text': text}
method = 'sendMessage'
resp = requests.post(self.api_url + method, params)
return resp
def get_last_update(self):
get_result = self.get_updates()
if len(get_result) > 0:
last_update = get_result[-1]
else:
last_update = get_result[len(get_result)]
return last_update
Последний штрих — объявим переменные и научим бота манерам. Сделаем так, чтобы бот приветствовал вас раз в день, при этом фраза должна зависеть от времени суток. Для этого добавьте следующий код в скрипт:
greet_bot = BotHandler(token)
greetings = ('привет', 'ку', 'здорово' 'здравствуй')
now = datetime.datetime.now()
def main():
new_offset = None
today = now.day
hour = now.hour
while True:
greet_bot.get_updates(new_offset)
last_update = greet_bot.get_last_update()
last_update_id = last_update['update_id']
last_chat_text = last_update['message']['text']
last_chat_id = last_update['message']['chat']['id']
last_chat_name = last_update['message']['chat']['first_name']
if last_chat_text.lower() in greetings and today == now.day and 6 <= hour < 12:
greet_bot.send_message(last_chat_id, 'Доброе утро, {}'.format(last_chat_name))
today += 1
elif last_chat_text.lower() in greetings and today == now.day and 12 <= hour < 17:
greet_bot.send_message(last_chat_id, 'Добрый день, {}'.format(last_chat_name))
today += 1
elif last_chat_text.lower() in greetings and today == now.day and 17 <= hour < 23:
greet_bot.send_message(last_chat_id, 'Добрый вечер, {}'.format(last_chat_name))
today += 1
new_offset = last_update_id + 1
if __name__ == '__main__':
try:
main()
except KeyboardInterrupt:
exit()
Дальше вы можете улучшать бота как угодно.
Сервер
Последним действием будет размещение нашего бота на бесплатном сервере Heroku.
Зарегистрируйтесь на GitHub и Heroku или войдите в свой аккаунт, и установите Git.
Windows и macOS:
https://git-scm.com/download/win
Linux:
sudo apt-get install git-all
Устанавливаем модуль virtualenv:
pip install virtualenv
Теперь вам нужно навести порядок в самих файлах. Создайте папку и перейдите в неё в терминале или командной строке. Инициализируйте в ней virtualenv:
virtualenv my_env
Имя не имеет значения, но лучше сделать его интуитивно понятным. Перейдите в папку my_env.
Теперь Вам нужно склонировать git-репозиторий:
git clone https://github.com/имя_вашего_профиля/имя_вашего_репозитория
Поместите скрипт в папку, полученную в результате выполнения команды git clone.
Вернитесь в папку my_env и запустите virtualenv:
Windows:
scripts\activate.bat
Linux/macOS:
source bin/activate
Если вы успешно запустили virtualenv, приглашение командной строки должно начинаться с my_env.
Перейдите в папку репозитория и опять установите модуль requests:
pip install requests
Теперь нужно создать список зависимостей Heroku:
pip freeze > requirements.txt
Создайте файл Procfile (Procfile.windows в случае с Windows). У него не должно быть других расширений. В этом файле вам нужно разместить инструкции по работе с вашим скриптом. Содержимое файла(вместо my_bot пишите имя вашего скрипта):
web: python my_bot.py
Обязательно добавьте файл __init__.py в вашу папку. Он может быть пустым.
Отправьте коммит с изменениями в репозиторий:
git init git add . git commit -m ‘короткое сообщение, описывающее изменения в коммите’ git push -u https://github.com/имя_вашего_профиля/имя_вашего_репозитория
Теперь развернём бота на Heroku. Можно использовать и панель управления на сайте, но мы будем делать всё через консоль. При возникании проблем перейдите к руководству.
Последним действием выполните следующие команды:
heroku login heroku create git push heroku master heroku ps:scale web=1 heroku open
Если вдруг, что-то пойдёт не так то проверьте логи:
heroku logs --tail
Коды ошибок смотрите на сайте Heroku
Бесплатный аккаунт накладывает небольшие ограничения. Не смотря на это у вас есть полностью рабочий бот — поздравляем!
Совершенствуй знания по Python каждый день у нас на канале, PythonGuru.
Вопросы, реклама - @pythonguru_admin
Поддержать проект (сбербанк):
4817760113082329