Свой Telegram бот на Python

Свой 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

Report Page