Прослушка чата для Telegram с сохранением в БД и Web-интерфейсом (Telethon, Sqllite, Flask)

D2

Администратор
Регистрация
19 Фев 2025
Сообщения
4,380
Реакции
0
Написал: rand
Эксклюзивно для: XSS.is
Версия Python 3.12, Flask 3.0.3, Telethon 1.6.1, asqlite 1.1.0

Всем привет, давно ничего не выкладывал, возможно кому-то будет полезно. В некоторых интересных чатах телеги иногда проскакивает очень интересная информация, которая может быть удалена. В таком случае нам ничего не мешает установить своего клиентского бота и прослушивать чат, сохраняя все текстовые сообщения в бд, а для удобства отображения таблицы в БД, я сделал клиента на Flask. Пишу в БД только дату сообщения, id пользователя, username, nickname, message (при желании можно ещё добавить столбец с телефоном при его открытости у юзера).

Софт состоит из серверной и клиентской части.

Получается как-то так:
1725431326616.png


Для запуска устанавливаем:
Bash: Скопировать в буфер обмена
Код:
pip install telethon==1.6.1
pip install aiosqlite==1.1.0
pip install flask==3.0.3

Сначала запускаем серверную часть и начинаем собирать информацию, это у нас server.py , подробности по запуску читайте в комментариях к коду, там ничего сложного:
Python: Скопировать в буфер обмена
Код:
import aiosqlite
import datetime
from telethon import TelegramClient, events
from telethon.errors import SessionPasswordNeededError

# Получаем параметры для подключения к API по адресу:
# api_hash from https://my.telegram.org, under API Development, данные в переменных ниже указаны левые для понимания что нужно вписывать.
api_id = 24555555
api_hash = '1eabd90d39d2977fc66894e3a1355555'
chat = 4581555555 # Чат айди сами загуглите как искать (или с клиента Telegram на PC заходите в продвинутые настройки-экспериментальные настройки-включаете отображение ID в профиле и прибавляете -100 в начале, если не сработает прописываете айди которое указано в профиле)

client = TelegramClient('komandos_kolya', api_id, api_hash, device_model="AMD B550", system_version="Windows 10")
client.connect()
phone = input("Enter phone: ")
client.send_code_request(phone, force_sms=False)
value = input("Enter login code: ")
try:
    me = client.sign_in(phone, code=value)
# Если на акке выставленно 2Ф, будет запрос на авторизацию
except SessionPasswordNeededError:
    password = input("Enter password: ")
    me = client.sign_in(password=password)

# Создаем декоратор на событие в чате
@client.on(events.NewMessage(chats=[chat]))
async def handler(event):
    # Получаем дату и время сообщения
    message_datetime = datetime.datetime.now()
    #message_datetime = event.message.to_dict()['date'] # Не спрашивайте меня почему я не сделал так =)
    # Получаем дату и время сообщения

    user_id = event.sender_id # Получаем ID пользователя
    user_text = event.raw_text # Получаем текст сообщения

    # Получаем имя пользователя @mmmm, first name, lastname
    user_entity = await client.get_entity(user_id)
    if user_entity.username:
        user_name = user_entity.username
    else:
        user_name = "Имени нет"
    user_nick = user_entity.first_name + " " + user_entity.last_name
    # Получаем имя пользователя @mmmm, first name, lastname, дату сообщения
    ### Для отладки
    #print(message_datetime)
    #print(user_id)
    #print(user_name)
    #print(user_nick)
    #print(user_text)
    ### Для отладки
    # Пишем переменные в БД
    await insert_message_table(message_datetime, user_id, user_name, user_nick, user_text)

# Работаем с бд (использую асинхронный драйвер aiosqlite)
async def insert_message_table(message_datetime, user_id, user_name, user_nick, user_text):
    try:
        sqlite_connection = await aiosqlite.connect('chat_tg.db') # Подключаемся к базе
        cursor = await sqlite_connection.cursor() # Курсор для работы с БД
        print("Подключен к SQLite")

        # Вставляем переменные сообщения в БД
        sqlite_insert_with_param = """INSERT INTO message
                              (message_date, user_id, user_name, user_nickname, message_text)
                              VALUES (?, ?, ?, ?, ?);""" # Запрос на запись в бд переменных сообщения

        data_tuple = (message_datetime, user_id, user_name, user_nick, user_text)
        await cursor.execute(sqlite_insert_with_param, data_tuple)
        await sqlite_connection.commit()
        print("Данные сообщения успешно вставлены в таблицу message")
        await cursor.close()

    except aiosqlite.Error as error:
        print("Ошибка при работе с SQLite", error)
    finally:
        if sqlite_connection:
            await sqlite_connection.close()
            print("Соединение с SQLite закрыто")
# Работаем с бд (использую асинхронный драйвер aiosqlite)

client.start()
client.run_until_disconnected()

Клиентская часть на Flask состоит из 3-х файлов (client.py, base.html, basic_table.html)
client.py:
Python: Скопировать в буфер обмена
Код:
from flask import Flask, render_template
import sqlite3

# Создание экземпляра Flask
app = Flask(__name__)

# Делаю маршрут URL по умолчанию
@app.route('/')
def home():
    # Подключаемся к бд "chat_tg.db"
    conn = sqlite3.connect('chat_tg.db')
    # Создаем курсор для выполнения запросов к SQL
    c = conn.cursor()
    # Выполняем запрос к таблице
    c.execute('SELECT * FROM message')
    # Получаем все данные из таблицы message
    messages = c.fetchall()
    # Закрываем соединение с БД
    conn.close()
    # Визуализируем таблицу бд в index.html
    return render_template('basic_table.html', messages=messages)


if __name__ == '__main__':
    app.run(debug=True)

base.html:
HTML: Скопировать в буфер обмена
Код:
<!doctype html>
<html>
  <head>
    <title>Прослушка чата by XSS.is</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-+0n0xVW2eSR5OomGNYDnhzAbDsOXxcvSN1TPprVMTNDbiYZCxYbOOl7+AMvyTG2x" crossorigin="anonymous">
    <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.25/css/dataTables.bootstrap5.css">
  </head>
  <body>
    <div class="container">
      <h1>Прослушка чата: test</h1>
      <hr>
      {% block content %}{% endblock %}
    </div>
    <script type="text/javascript" charset="utf8" src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.10.25/js/jquery.dataTables.js"></script>
    <script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.10.25/js/dataTables.bootstrap5.js"></script>
    {% block scripts %}{% endblock %}
  </body>
</html>
basic_table.html:
HTML: Скопировать в буфер обмена
Код:
{% extends "base.html" %}

{% block content %}
  <table id="data" class="table table-striped">
    <thead>
      <tr>
        <th>№</th>
        <th>Date</th>
        <th>ID</th>
        <th>Username</th>
        <th>Nickname</th>
        <th>Message</th>
      </tr>
    </thead>
    <tbody>
      {% for message in messages %}
        <tr>
          <td>{{ loop.index }}</td>
          <td>{{ message[0] }}</td>
          <td>{{ message[1] }}</td>
          <td>{{ message[2] }}</td>
          <td>{{ message[3] }}</td>
          <td>{{ message[4] }}</td>
        </tr>
      {% endfor %}
    </tbody>
  </table>
{% endblock %}

{% block scripts %}
  <script>
    $(document).ready(function () {
      $('#data').DataTable({
      });
    });
  </script>
{% endblock %}

P.S. Полный исходник с БД и со всей правильной структурой прикрепил в ZIP.
 
Сверху Снизу