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:
68
core/bot_downloader.md
Normal file
68
core/bot_downloader.md
Normal 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 |
|
||||
Reference in New Issue
Block a user