Initial commit: ULPgrammer

- Core Telegram monitoring pipeline (scraper, processor, notifier, downloaders)
- Textual TUI frontend with thread-safe event bus
- SQLite persistence, severity scoring, dedup cache
- Fixed ULP parser: handles https:// truncation, port+path URLs, semicolon separator
- Test suite: 88 tests across scorer, cache, database, processor
This commit is contained in:
2026-04-02 01:58:49 -03:00
commit 48f486ac97
41 changed files with 5270 additions and 0 deletions

68
core/bot_downloader.md Normal file
View File

@@ -0,0 +1,68 @@
# core/bot_downloader.py
Handles "click to download" inline button flows. Some Telegram channels post files via a bot behind a button rather than directly attaching them.
## Public API
```python
from core.bot_downloader import (
handle_bot_download_message,
has_download_button,
extract_password,
)
```
### `handle_bot_download_message(client, bot, msg, source_name, patterns, password=None)`
**async.** Full pipeline:
1. Detect download button
2. Click it (URL button → `/start payload` to the bot; callback button → `.click()`)
3. Wait up to `BOT_REPLY_TIMEOUT` seconds for the bot to send a file back
4. Hand each file response to `core.scraper.handle_message()`
### `has_download_button(msg) -> bool`
Returns `True` if the message contains a recognisable download button.
Checked in live handler and backfill before calling this module.
### `extract_password(msg) -> str | None`
Scans message text for `Pass: ...` / `Password: ...` / `Contraseña: ...` patterns.
Returns the extracted password string, or `None`.
---
## Button detection
Recognised button text keywords (case-insensitive):
```
DOWNLOAD, DESCARGAR, GET FILE, GET PACK, ⬇, 📥
```
---
## URL button flow (most common)
```
Button URL: https://t.me/SomeBot?start=ABC123
→ parse bot username + payload
→ client.send_message(bot_entity, "/start ABC123")
→ poll get_messages(bot_entity, limit=3) every 1s for BOT_REPLY_TIMEOUT seconds
→ return file messages found
```
## Callback button flow (fallback)
```
btn.click()
→ sleep 2s
→ get_messages(sender, limit=5)
→ return file messages found
```
---
## Constants
| Name | Value | Description |
|------|-------|-------------|
| `BOT_REPLY_TIMEOUT` | `10` | Seconds to wait for bot file reply |
| `DOWNLOAD_BUTTON_KEYWORDS` | see above | Button text triggers |
| `PASSWORD_PATTERN` | regex | Matches `Pass[word]: value` in message text |