Пишем Бот для Telegram на Python.

Давно хотелось попробовать создать простенького бота для Telegram, по этому поехали.

Самым первым делом нам надо собственно зарегистрировать(создать) бота. Для этого качаем Telegram на компьютер. Затем находим пользователя BotFather (такая забавная отсылка к Крестному Отцу).

Пишем команду /newbot . Далее нас просят ввести Имя бота, далее просят ввести Имя пользователя для Бота ( имя под каким он будет в телеге). После этого вы получите bot<token> для использования API . Каждому боту при создании присваивается уникальный токен вида 123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11

Все запросы к Telegram Bot API должны осуществляться через HTTPS в следующем виде: https://api.telegram.org/bot<token>/НАЗВАНИЕ_МЕТОДА. Допускаются GET и POST запросы . Ответ придёт в виде JSON-объекта, в котором всегда будет булево поле ok и опциональное строковое поле description, содержащее человекочитаемое описание результата. (Это не я придумал, это написано в манулае).

Писать всю работу с Bot API мы будем на Питоне с использование библиотеке requests . Давайте воспользуемся первым методом (он же является тестовым можно сказать) getMe .

Простой способ тестирования токена аутентификации вашего бота. Не требует параметров. Возвращает основную информацию о боте в виде пользовательского объекта.

getMe
import requests
URL = 'https://api.telegram.org/bot<Token>/'
url = URL + 'getMe'
r = requests.get(url)
print(r.text)

Нам вернеться словарь с данными (поле result)

{«ok»:true, «result»{"is_bot":true,"first_name":"Boto_bot","username":"Linuxblog_bot"}}

Окей , бот работает. Давайте теперь ему что нибудь напишем )

Теперь давайте получим обновления от бота методом getupdates.

getupdates(offset, limit 0-100 , timeout) Этот метод используется для получения обновлений через long polling . Ответ возвращается в виде массива объектов Update. Входящие обновления будут храниться на сервере до тех пор, пока вы их не обработаете. offset — Идентификатор первого обновления, которое будет возвращено. Должно быть больше на единицу, чем самый высокий среди идентификаторов ранее полученных обновлений. По умолчанию возвращаются обновления, начиная с самого раннего неподтвержденного обновления. Обновление считается подтвержденным, как только get Updates вызывается со смещением выше, чем его update_id. Отрицательное смещение можно задать для получения обновлений, начиная с-offset update из конца очереди обновлений. Все предыдущие обновления будут забыты.

getUpdates?offset = -1
def get_update():
    url = URL + 'getupdates'
    r = requests.get(url)
    print(r.text)
{"ok":true,"result":[{"update_id":565003052,"message":{"message_id":5,"from":{"id":689692596,"is_bot":false,"first_name":"Semen","language_code":"ru"},"chat":{"id":689692596,"first_name":"Semen","type":"private"},"date":1563222843,"text":"/start","entities":[{"offset":0,"length":6,"type":"bot_command"}]}},{"update_id":565003055,
 "message":{"message_id":6,"from":{"id":689692596,"is_bot":false,"first_name":"Semen","language_code":"ru"},"chat":{"id":689692596,"first_name":"Semen","type":"private"},"date":1563222896,"text":"\u041f\u0440\u0438\u0432\u0435\u0442 \u0436\u0435\u043b\u0435\u0437\u044f\u043a\u0430 )"}}]}

Тут полно всякой информации. Например имя кто послал сообщение «first_name»:»Semen»,»type»:»private» , текст сообщения «text»:»\u041f\u0440\u0438\u0432\u0435\u0442 \u0436\u0435\u043b\u0435\u0437\u044f\u043a\u0430 .

Но нам потребуется сейчас только chat - "id":689692596 индификатор чата что бы ответить и поле "text":"/start" собственно само сообщение. Еще нам нужно поле "update_id":565003055 , мы потом будем его использовать. Перепишем нашу функцию что бы она делала запроси и из ответа возвращала нужные нам поля.

def get_update():
    url = URL + 'getupdates'
    r = requests.get(url)
    r = r.json()
    chat_id = r['result'][-1]['message']['chat']['id']
    mess_text = r['result'][-1]['message']['text']
    update_id = r['result'][-1]['update_id']
    return chat_id, mess_text, update_id

Не монго поясню как мы получили данные : нам вернулся словарь. Мы взяли последний элемент [-1] словаря result в нем нашли значения словаря message в нем взяли словарь chat в нем получили элемент id и т.д. Немного сложно, но надо проcто ответ разложить в более понятой форме

({'message': {'text': 'Привет железяка )',
              'date': 1563222896,
              'from': {'id': 689692596,
                       'is_bot': False,
                       'language_code': 'ru',
                       'first_name': 'Semen'},
              'message_id': 6,
              'chat': {'id': 689692596,
                       'type': 'private',
                       'first_name': 'Semen'}
              },
 'update_id': 565003055)

JSON (англ. JavaScript Object Notation) — текстовый формат обмена данными, основанный на JavaScript. Как и многие другие текстовые форматы, JSON легко читается людьми.

Набор пар ключ: значение. В различных языках это реализовано как запись, структура, словарь, хеш-таблица, список с ключом или ассоциативный массив

Теперь нам нужно научиться отвечать. Для этого будем использовать метод sendMessage . Ну и давайте напишем функцию для отправки сообщения :

sendMessage ( chat_id, text ) Использовать этот метод для отправки текстовых сообщений. При успешном выполнении возвращается отправленное сообщение.

https://api.telegram.org/bot<Token>/ sendmessage?chat_id=123456&text=Ваш текст
def send_mess(chat_id, text = 'Моя твоя не понимает (:'):

    url = URL + 'sendmessage?chat_id={}&text={}'.format(chat_id, text)
    requests.get(url)

chat_id, text, update_id = get_update()
send_mess(chat_id)

Финишная прямая. Теперь нам надо как то обрабатывать запросы и выдавать что то полезное. Например заголовки статей с сайта 3Dnew, к стати парсер для этого сайта мы писали в этой статье, его и будем использовать. А команда для парсинга будет у нас /3dnews .

import requests
from bs4 import BeautifulSoup
from time import sleep

global last_update_ip
last_update_ip = 0
URL = 'https://api.telegram.org/bot<token>'

def get_html(url):
    r = requests.get(url)
    r.encoding = 'utf8'
    return r.text

def get_head(html):
    soup = BeautifulSoup(html, 'lxml')
    head = soup.find('div', id='section-content').find_all('h1')
    heads = []
    for i in head:
       heads.append(i.string)
    return heads

def get_update():
    url = URL + 'getupdates'
    r = requests.get(url)
    r = r.json()
    chat_id = r['result'][-1]['message']['chat']['id']
    mess_text = r['result'][-1]['message']['text']
    update_id = r['result'][-1]['update_id']
    return chat_id, mess_text, update_id

def send_mess(chat_id, text = 'Моя твоя не понимает (:'):
    url = URL + 'sendmessage?chat_id={}&text={}'.format(chat_id, text)
    requests.get(url)

while True:
    chat_id, mess_text, update_id = get_update()
    if update_id != last_update_ip:
        if mess_text == '/3dnews':
            mess_sender=get_head(get_html('https://3dnews.ru/news'))
            text = ''
            for text_tmp in mess_sender:
                text = text + text_tmp + '\n' + '\n'
            send_mess(chat_id, text)
            last_update_ip = update_id
        else:
            send_mess(chat_id)
            last_update_ip = update_id
    sleep(10)

Вот мы и написали очень простого бота для Телеграм используя только API. Продолжение следует )))