Как считать сообщение из чата телеграмм python
Перейти к содержимому

Как считать сообщение из чата телеграмм python

Bot API v3. Автоматизируем работу в группах

⁠⁠ С момента публикации предыдущего урока и по состоянию на момент написания этого, Telegram выпустил одно крупное обновление Bot API (3.0), а также несколько мелких (3.1-3.3). Сразу отмечу, ни отправка видеосообщений, ни платежи (по ним есть отличный пример в репозитории pyTelegramBotAPI), ни работа со стикерами рассмотрены не будут.

Удаляем сообщения

Начнём с того, что научим нашего бота в группе удалять сообщения, в которых есть ссылки. Добавим бота в группу и назначим его администратором с правом удаления и блокировки (пригодится позже).

Выдача прав боту

Дабы избежать неприятных ситуаций, нам необходимо определить две вещи: в какой именно группе он будет удалять сообщения и как отличить сообщения с ссылками от всех остальных? Для начала узнаем и запишем куда-нибудь ID нашей группы. А что делать с ссылками? Неужели нам придётся использовать регулярные выражения, создавая себе ещё одну проблему? Конечно, нет! Все «особые» элементы, будь то ссылки, @юзернеймы, команды ботов и т.д. складываются в массив entities в объекте Message , нам остаётся лишь проверить тип объекта и решить, удалять конкретное сообщение или нет. За последнее отвечает метод delete_message , принимающий на вход два аргумента: ID чата и ID сообщения.

Перейдём непосредственно к коду. Дабы упростить себе жизнь, зададим нужные условия срабатывания (нужный ID чата и непустой массив entities) сразу в хэндлер, это сэкономит нам несколько лишних проверок.

GROUP_ID = -10012345 # Ваш ID группы @bot.message_handler(func=lambda message: message.entities is not None and message.chat.id == GROUP_ID) def delete_links(message): for entity in message.entities: # Пройдёмся по всем entities в поисках ссылок # url - обычная ссылка, text_link - ссылка, скрытая под текстом if entity.type in ["url", "text_link"]: # Мы можем не проверять chat.id, он проверяется ещё в хэндлере bot.delete_message(message.chat.id, message.message_id) else: return 

Запустим бота и попробуем отправить сообщение с ссылкой. Если вы всё сделали правильно, оно мгновенно исчезнет и в разделе «Недавние действия» (Recent Actions) появится запись об удалённом сообщении.

Сообщение удалено

Точно так же можно сделать удаление чего угодно: стикеров, репостов из неугодных каналов, матерных сообщений и т.д. Возможности (почти) безграничны!

Read-Only и прочие «мягкие» наказания

Представьте, что у вас есть группа, например, “Международный клуб любителей мяса”, в котором люди на разных языках делятся своими впечатлениями от поедания свинины, говядины, баранины и т.д.
Конечно, время от времени в чатик будут приходить вегетарианцы и высказывать недовольство, но так как мы терпеливые люди, не будем банить веганов, а просто запретим им писать сообщения некоторое время, дабы они успокоились и вели дискуссию в рамках тематики чата. Усложним себе задачу и будем оповещать пользователей о временном ограничении прав, исходя из их языковой принадлежности.

Начиная с Telegram 4.1, у администраторов групп появилась возможность точечно настраивать права и ограничения пользователей. В Bot API за операцию ограничения ответственен метод restrict_chat_member , принимающий на вход ID чата, ID юзера, список ограничений, а также параметр until_date со значением времени (Unix Time), до которого эти ограничения действуют, причём если указать время с разницей меньше 30 секунд или больше 366 дней от текущего, Telegram воспринимает это, как «навсегда». В нашем случае Read-Only режим будет выдаваться на 10 минут, т.е. 600 секунд.

Давайте теперь разберёмся, на каком языке отвечать пользователю. В объекте User есть поле language_code , содержащее языковую метку пользователя. Не всё так просто, ведь в зависимости от настроек системы и местоположения пользователя, его языковая метка может быть ru , en-GB , en-US или вообще какой-нибудь nan-Hant-TW . Подробно о строении таких меток можно прочесть здесь. В нашем случае задача немного упрощается, т.к. нам нужен только первый элемент (сам язык), независимо от региона (будем считать, к примеру, что «английский» английский и американский английский для нас одинаковы). Напишем наипростейшую определялку языка, которая будет возвращать ru для русского языка и en для всех остальных. В реальной жизни, конечно, стоит сделать поддержку большего числа языков.

def get_language(lang_code): # Иногда language_code может быть None if not lang_code: return "en" if "-" in lang_code: lang_code = lang_code.split("-")[0] if lang_code == "ru": return "ru" else: return "en" 

И подготовим небольшой JSON со строками:

strings = < "ru": < "ro_msg": "Вам запрещено отправлять сюда сообщения в течение 10 минут." >, "en": < "ro_msg": "You're not allowed to send messages here for 10 minutes." > 

Теперь напишем обработчик, который будет реагировать на набор фраз, выдавать режим Read-Only пользователю на 10 минут и уведомлять его на родном языке. Не забудьте импортировать метод time из одноимённого модуля!

restricted_messages = ["я веган", "i am vegan"] # Выдаём Read-only за определённые фразы @bot.message_handler(func=lambda message: message.text and message.text.lower() in restricted_messages and message.chat.id == GROUP_ID) def set_ro(message): bot.restrict_chat_member(message.chat.id, message.from_user.id, until_date=time()+600) bot.send_message(message.chat.id, strings.get(get_language(message.from_user.language_code)).get("ro_msg"), reply_to_message_id=message.message_id) 

Запустим бота и попросим людей с разными language_code выступить в роли противников мяса:

Бот-полиглот

Заключение

В этом уроке мы кратко ознакомились с новыми фишками третьей версии Telegram Bot API, научились удалять сообщения, если они соответствуют одному из заданных критериев и научились «мягко» ограничивать пользователей, не удаляя их из группы. Помимо restrict_chat_member существует метод promote_chat_member для наделения пользователя определёнными администраторскими правами, он остаётся для самостоятельного изучения.

Исходный код бота этого урока, как обычно, расположен на Github.

Отправка сообщений в Telegram при помощи Python

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

Реализовать функцию отправки сообщения в Telegram при помощи Python довольно просто. План действий:

  1. Создать Telegram-бота с помощью BotFather от Telegram
  2. Получить идентификатор чата
  3. Послать сообщение Telegram с помощью Python

Создание Telegram-бота

  1. Откройте приложение Telegram и найдите BotFather. Это встроенный бот Telegram, который помогает создавать пользовательские боты.
  2. Введите /newbot , чтобы создать нового бота.
  3. Дайте своему боту имя и уникальный username
  4. Скопируйте токен вашего нового бота Telegram

Примечание: не загружайте свой токен в интернет, так как любой пользователь с вашим токеном имеет полный контроль над вашим Telegram-ботом.

Получение идентификатора чата

В Telegram каждый чат имеет ID. Нам он нужен, чтобы отправлять в наш чат сообщения.

Отправьте своему Telegram-боту любое сообщение. После этого запустите скрипт Python, чтобы найти ID вашего чата:

import requests TOKEN = "Сюда вставьте свой токен" url = f"https://api.telegram.org/bot/getUpdates" print(requests.get(url).json())

Примечание редакции Pythonist: если у вас не установлена библиотека requests , нужно сперва ее установить:

$ python -m pip install requests

Этот скрипт вызывает функцию getUpdates , которая как бы проверяет наличие новых сообщений. Мы можем найти ID нашего чата из возвращаемого JSON (на иллюстрации выделен красным цветом).

Примечание: если вы не отправите сообщение своему Telegram-боту, результаты могут быть пустыми.

Найдя идентификатор чата, скопируйте его.

Отправка сообщения Telegram с помощью Python

Скопируйте и вставьте в следующий скрипт Python токен вашего Telegram-бота и ID чата из предыдущих двух шагов. Также напишите собственное сообщение.

import requests TOKEN = "Сюда вставьте свой токен" chat_id = "Сюда вставьте ID чата" message = "Здесь напишите свое сообщение" url = f"https://api.telegram.org/bot/sendMessage?chat_id=&text=" print(requests.get(url).json()) # Эта строка отсылает сообщение

Запустите скрипт и проверьте свой Telegram!

Подслушиваем чат телеграма с помощью своего клиента

Захотелось как-то мне, чтобы сообщения одного из чатов телеграма сохранялись у меня на диске (не запуская обычного клиента). Не буду раскрывать своих побудительных мотивов, но возможность эта показалась мне нужной и полезной.

Для этого в телеграме есть боты. На Хабре есть несколько статей, посвященных ботам, например: «Чат-помощник на сайт».

Бот позволяет читать и посылать сообщения, для регистрации бота не нужен телефон и количество ботов может быть любым. Но название бота включает в себя слово «bot», что может вызвать у хозяина чата ненужные вопросы.

Но, как говорится, правильно поставленный вопрос — половина ответа.

Оказывается кроме «API telegram bot» существует еще и «API telegram client», т.е. API для создания собственных клиентов.

Клиент также может посылать и читать сообщения, но только от зарегестрированного (привязанного к телефону) пользователя, что мне как раз подходит (я уже зарегестрирован в чате).

На сайте телеграма есть список API для разных платформ: https://telegram.org/apps#source-code

Однако, самой простой в использовании оказалась библиотека на python: Pure Python 3 MTProto API Telegram client library под названием «telethon»

Только вот проблема. Я не знаю питон. Ну что ж, есть повод познакомиться.
Как утверждает мануал по телетону, инсталляция его очень простая. Достаточно запустить команду в командной строке:

pip3 install telethon

Подводные камни, встреченные мною при инсталляции:

  • не инсталлирован pip3 (инсталлятор для питона).

sudo apt-get -y install python3-pip

  • Библиотека работает только на питоне версии >3.5. Так что, возможно, придется его обновить.

Все установилось. Листаем readme.txt дальше.

Следущим пунктом идет создание клиента телеграма… Как, уже? Ну да, все просто. Правда, сперва нужно зарегистритровать себя как создателя клиента.

Заходим на сайт телеграма: https://my.telegram.org
Вводим телефон и ждем код подтверждения на родном клиенте телеграма. Он довольно длинный (12 символов) и неудобный для ввода.

Заходим в пункт «API». Ищем «Telegram API» и заходим в «Creating an application» (https://my.telegram.org/apps).

Заполняем поля App title и Short name, нажимаем «Create application» и запоминаем две переменные: api_id и api_hash.

Пришла пора делать клиента.

from telethon import TelegramClient, sync # Вставляем api_id и api_hash api_id = 12345 api_hash = '0123456789abcdef0123456789abcdef' client = TelegramClient('session_name', api_id, api_hash) client.start()

session_name — можно вставить любое имя. Вас попросят ввести телефон и пришлют код подтверждения. После этого клиент будет работать без запроса телефона (до тех пор, пока не поменяете session_name). Рядом с вашей программой появится файл session_name.session

Если ошибок нет, клиент готов. Только вот, ничего не выводит. Попробуем получить полезную инфорфмацию.

Узнаем немного о себе:

print(client.get_me().stringify())

результат выдается в виде:

User( photo=None, last_name='Pupkin', first_name='Vasya', phone='79041234567', . - что-то еще. )

Можем послать сообщение от себя:

client.send_message('username', 'Hello! Talking to you from Telethon')

Можно и картинку

client.send_file('username', '/home/myself/Pictures/holidays.jpg')

Как меня видят другие:

client.download_profile_photo('me')

Смотрим, на какие чаты мы подписаны:

print all chats name for dialog in client.iter_dialogs(): print(dialog.title)

читаем все сообщения чата «chat_name» (осторожно, сообщений может быть очень много)

messages = client.get_entity('chat_name') print(messages)

просмотр всех пользователей чата

participants = client.get_participants('chat_name') print(participants)

Побаловались?
Теперь, собственно, делаем то, ради чего мы все это затеяли.

Нам нужна программка, следящая за новыми сообщениями в определенном канале.

Чтобы клиент не заканчивал работу, после client.start() вставляем строку:

client.run_until_disconnected()

Эта конструкция (вставляется перед client.start()) выводит только новые сообщения:

@client.on(events.NewMessage(chats=('chat_name'))) async def normal_handler(event): # print(event.message) print(event.message.to_dict()['message'])
@client.on(events.NewMessage(chats=('chat_name')))

создает событие, срабатывающее при появлении нового сообщения

 print(event.message)

выводит сообщение в таком виде:

Message(edit_date=None, views=None, reply_markup=None, fwd_from=None, entities=[], post=False, mentioned=False, via_bot_id=None, media_unread=False, out=True, media=None, date=datetime.datetime(2018, 10, 1, 9, 26, 21, tzinfo=datetime.timezone.utc), to_id=PeerChannel(channel_id=123456789), reply_to_msg_id=None, from_id=123456789, silent=False, grouped_id=None, post_author=None, message='hello telegram')

Из всего этого нам нужно поле: «message=’hello telegram'»:

 print(event.message.to_dict()['message'])

Сообщение получили, но от кого оно, непонятно, т.к. в сообщение только ID пользователя. Чтобы сопоставить ID и имя пользователя, скачиваем всех пользователей чата и помещаем их в словарь (хэш) в виде d[id]=»first_name last_name»

participants = client.get_participants(group) users=<> for partic in client.iter_participants(group): lastname="" if partic.last_name: lastname=partic.last_name users[partic.id]=partic.first_name+" "+lastname

Теперь мы можем узнать, кто послал сообщение:

s_user_id=event.message.to_dict()['from_id'] user_id=int(s_user_id) user=d.get(user_id)

В принципе, можно получить имя пользователя из телеграма напрямую, но если пользователей немного, проще со словарем.

Вытаскиваем из сообщения дату отправки:

mess_date=event.message.to_dict()['date']

Все, все данные у нас есть. Осталось записать их в файл.
Для этого сначала откроем файл на запись:

f=open('messages_from_chat', 'a') 

И запишем сообщение:

f.write(mess_date.strftime("%d-%m-%Y %H:%M")+"\n") f.write(user+"\n") f.write(user_mess+"\n\n") f.flush()

Вот и все! Все, что мне было нужно, программка делает. Утилитка, конечно, сыровата, но свою задачу выполняет.

Python оказался не таким уж и сложным как его малюют, тем более описание и разных библиотек в интернете полным-полно. Написать еще пару утилиток и привыкнув к нему, можно использовать его как скриптовый язык вместо bash.

Весь текст утилиты:

from telethon import TelegramClient, sync, events api_id = 12345 api_hash = '0123456789abcdef0123456789abcdef' client = TelegramClient('session_name', api_id, api_hash) @client.on(events.NewMessage(chats=('chat_name'))) async def normal_handler(event): # print(event.message) user_mess=event.message.to_dict()['message'] s_user_id=event.message.to_dict()['from_id'] user_id=int(s_user_id) user=d.get(user_id) mess_date=event.message.to_dict()['date'] f.write(mess_date.strftime("%d-%m-%Y %H:%M")+"\n") f.write(user+"\n") f.write(user_mess+"\n\n") f.flush() client.start() group='group_name' participants = client.get_participants(group) users=<> for partic in client.iter_participants(group): lastname="" if partic.last_name: lastname=partic.last_name users[partic.id]=partic.first_name+" "+lastname f=open('messages_from_chat', 'a') client.run_until_disconnected() f.close()

Парсим данные в Telegram на Python. Часть 2. Читаем и анализируем сообщения из чатов

Пишем парсер для Telegram: собираем сообщения из каналов и чатов.

Иллюстрация: Катя Павловская для Skillbox Media

Антон Яценко

Антон Яценко
Изучает Python, его библиотеки и занимается анализом данных. Любит путешествовать в горах.

Сегодня мы научимся парсить чаты из Telegram: разберёмся в том, какие модули нам пригодятся, и настроим сбор сообщений. Всё это с помощью библиотеки Telethon для Python.

Это второй урок по парсингу в Telegram. В первом мы создали парсер списка участников каналов и чатов и научились работать с инструментами разработчика API мессенджера. Если вы ещё не читали первую часть, то обязательно начните с неё.

Что у нас сейчас есть?

В первой части урока мы:

  • настроили инструменты разработчика API Telegram и научились использовать их для подключения к клиенту мессенджера;
  • установили и импортировали библиотеку Telethon, позволяющую работать с API Telegram, выбрав нужные нам классы, функции и типы;
  • научились парсить список групп и чатов из мессенджера;
  • написали код для парсинга списка пользователей в чате или мессенджере, сохраняющий их в удобном для чтения и последующего анализа виде.

У нас остаётся одна задача — спарсить сообщения из чатов. Мы сохраним только содержание чатов без дополнительной информации о времени их отправки и самом отправителе. В дальнейшем эти данные можно будет использовать для анализа переписки: например, узнать о самых часто встречающихся словах и предположить самые популярные темы для обсуждения.

Добавляем новые импорты

Откроем в IDE код из первой части урока. Мы продолжим работать с ним, а не будем писать всё с нуля. Чтобы спарсить сообщения из чатов, необходимо импортировать новый метод и функцию в начало кода:

Всё получилось. Откроем нашу директорию. Теперь в ней два файла в формате CSV: members.csv и chats.csv. Откроем последний:

Мы видим, что сохранились не только сами сообщения, но и техническая информация про их id, id запроса и так далее. Такой результат нам не подходит. Вернёмся к циклу while и добавим к методу message параметр message. Он позволяет сохранять только само сообщение.

Теперь всё работает как надо. Сохранились только сообщения без служебной информации о запросах.

Код парсера для Telegram на Python полностью

В двух частях урока по парсингу информации из Telegram мы написали много кода. Посмотрим на него полностью:

from xmlrpc.client import DateTime from telethon.sync import TelegramClient from telethon.tl.functions.messages import GetDialogsRequest from telethon.tl.types import InputPeerEmpty from telethon.tl.functions.messages import GetHistoryRequest from telethon.tl.types import PeerChannel import csv api_id = 18377495 api_hash = "a0c785ad0fd3e92e7c131f0a70987987" phone = "+79991669331" client = TelegramClient(phone, api_id, api_hash) client.start() chats = [] last_date = None chunk_size = 200 groups=[] result = client(GetDialogsRequest( offset_date=last_date, offset_id=0, offset_peer=InputPeerEmpty(), limit=chunk_size, hash = 0 )) chats.extend(result.chats) for chat in chats: try: if chat.megagroup== True: groups.append(chat) except: continue print("Выберите группу для парсинга сообщений и членов группы:") i=0 for g in groups: print(str(i) + "- " + g.title) i+=1 g_index = input("Введите нужную цифру: ") target_group=groups[int(g_index)] print("Узнаём пользователей. ") all_participants = [] all_participants = client.get_participants(target_group) print("Сохраняем данные в файл. ") with open("members.csv", "w", encoding="UTF-8") as f: writer = csv.writer(f,delimiter=",",lineterminator="\n") writer.writerow(["username", "name","group"]) for user in all_participants: if user.username: username= user.username else: username= "" if user.first_name: first_name= user.first_name else: first_name= "" if user.last_name: last_name= user.last_name else: last_name= "" name= (first_name + ' ' + last_name).strip() writer.writerow([username,name,target_group.title]) print("Парсинг участников группы успешно выполнен.") offset_id = 0 limit = 100 all_messages = [] total_messages = 0 total_count_limit = 0 while True: history = client(GetHistoryRequest( peer=target_group, offset_id=offset_id, offset_date=None, add_offset=0, limit=limit, max_id=0, min_id=0, hash=0 )) if not history.messages: break messages = history.messages for message in messages: all_messages.append(message.message) offset_id = messages[len(messages) - 1].id if total_count_limit != 0 and total_messages >= total_count_limit: break print("Сохраняем данные в файл. ") with open("chats.csv", "w", encoding="UTF-8") as f: writer = csv.writer(f, delimiter=",", lineterminator="\n") for message in all_messages: writer.writerow([message]) print('Парсинг сообщений группы успешно выполнен.')

Что дальше?

Библиотека Telethon используется не только для парсинга информации о пользователях и сообщений в каналах и чатах, но и для автоматизации работы с Telegram. Например, администраторы каналов могут создать бота, позволяющего писать сообщения, отправлять стикеры и управлять списком участников. Эти примеры разобраны в документации библиотеки.

Читайте также:

  • Парсим данные в Telegram на Python. Часть 1. Выбираем библиотеку и изучаем подписчиков
  • Тест: угадайте, где эзотерические языки программирования, а где нет
  • Python для новичков: сферы применения и возможности

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *