A Python-based tool to forward messages from public Telegram channels to Discord using webhooks embeds. Disgram scrapes Telegram's public preview pages and forwards messages, including text, images, and formatted content, to Discord channels through webhooks.
flowchart TD
A[Start: python main.py] --> B[Load config.py]
B --> C[Initialize Logging]
C --> D{Thread ID Exists?}
D --> |Yes| E[Launch threadhook.py]
D --> |No| F[Launch webhook.py]
%% threadhook.py workflow
E --> G1[URL: webhook?thread_ID]
G1 --> H1[Read Log for Last Message]
H1 --> I1[Start Main Loop]
%% webhook.py workflow
F --> G2[URL: webhook]
G2 --> H2[Read Log for Last Message]
H2 --> I2[Start Main Loop]
%% Common workflow for both scripts
I1 --> J[Scrape Telegram Prev Page]
I2 --> J
J --> K{New Message Found?}
K --> |No| L[Wait and Retry]
L --> J
K --> |Yes| M[Parse and Extract Content]
M --> N[Text Content]
M --> O[Media Content]
M --> P[Grouped Media]
N --> Q[Format Text for Discord]
O --> Q
P --> Q
Q --> R[Create Discord Embed]
R --> S[Add Source Credits]
S --> T[Send Message]
T --> |threadhook.py| U[Send to Thread]
T --> |webhook.py| V[Send to Channel]
U --> W{Send Successful?}
V --> W
W --> |No| X[Error & Retry Logic]
X --> Y[Log Error to Disgram.log]
Y --> Z{Retry Available?}
Z --> |Yes| AA[Wait and Retry]
AA --> T
Z --> |No| AB[Skip Message]
W --> |Yes| AC[Update Disgram.log]
AC --> AD[Continue to Next Message]
AB --> AD
AD --> AE[Wait for Cooldown]
AE --> J
%% Error Logging
AF[Error Logging] -.-> Y
AF -.-> AC
AF -.-> AD
%% Rate Limit Handling
AG[Rate Limit Handling] -.-> U
AG -.-> J
AG -.-> V
%% Shutdown
AH[Shutdown: Ctrl + C] --> AI[Terminate All Processes]
AI --> AJ[Wait for Termination]
AJ --> AK[Exit Program]
classDef startEnd fill:#2E8B57,stroke:#000,stroke-width:3px,color:#fff
classDef process fill:#4169E1,stroke:#000,stroke-width:2px,color:#fff
classDef decision fill:#FF6B35,stroke:#000,stroke-width:3px,color:#fff
classDef error fill:#DC143C,stroke:#000,stroke-width:3px,color:#fff
classDef support fill:#FFD700,stroke:#000,stroke-width:2px,color:#000
classDef thread fill:#9370DB,stroke:#000,stroke-width:2px,color:#fff
classDef channel fill:#20B2AA,stroke:#000,stroke-width:2px,color:#fff
class A,AK startEnd
class B,C,G1,G2,H1,H2,I1,I2,J,L,M,N,O,P,Q,R,S,T,AC,AD,AE process
class D,K,W,Z decision
class X,Y,AA,AB,AI,AJ error
class AF,AG,AH support
class E,U thread
class F,V channel
- No Telegram or Discord Bots required
- Forward messages from multiple Telegram channels to Discord
- Automated message source crediting in embeds
- Preserve message formatting (bold, italic, links, code blocks, etc.)
- Support for text and media content
- Automatic handling of missing messages
- Robust error handling and retry mechanisms
- Send messages to Discord threads using
DISCORD_THREAD_ID - Advanced Rate Limiting: Full Discord API compliance with bucket-based rate limiting
- Comprehensive Media Handling: Support for images, videos, and grouped media collections
- Smart Grouped Media Processing: Automatically detects and handles grouped media messages
- Embed Formatting: Rich Discord embeds with author avatars, names, and proper formatting
- Health Monitoring: Real-time health status at
/healthendpoint with rate limit tracking - Log Viewing: View application logs via
/logsendpoint for debugging - Process Management: Automatic process spawning for multiple channels
- Python 3.6 or higher
- Discord Webhook URL
- Public Telegram Channel links
-
Clone the repository:
git clone https://github.com/SimpNick6703/Disgram.git cd Disgram -
Install the required dependencies:
pip install -r requirements.txt
-
Copy
.env.exampleto.envand fill in the required environment variables:cp .env.example .envDISCORD_WEBHOOK_URL: Your Discord webhook URL.DISCORD_THREAD_ID(Optional): The ID of the Discord thread to send messages to.TELEGRAM_CHANNELS: Comma-separated list of public Telegram channel URLs.EMBED_COLOR: Hex color code for embeds (e.g., 89a7d9 or 0x89a7d9).
-
(Optional) Modify
config.pyfor advanced settings:COOLDOWN: Interval between checks (Suggested 300s or more to avoid IP bans).ERROR_PLACEHOLDER: Message shown for unparseable content.
Tip
Starting from specific messages: Instead of simply providing channel links in TELEGRAM_CHANNELS, you can provide specific message links in it to start forwarding from particular points.
- Start the bot:
python main.py - The bot will create separate processes for each channel and begin forwarding messages.
- To stop the bot, press
Ctrl + C.
The bot maintains logs at /logs endpoint that lets you view Disgram.log with the following information:
- Error messages
- New message notifications
- Operational status updates
Disgram uses comprehensive Discord API rate limiting logic:
- Per-Route Rate Limiting: Tracks individual webhook endpoint limits
- Global Rate Limiting: Respects Discord's global rate limits (50 requests/second)
- Bucket-Based Tracking: Uses Discord's rate limit bucket system
- 429 Response Handling: Automatic retry with proper wait times
- Exponential Backoff: Smart retry logic for network errors
- Rate Limit Headers: Parses and respects Discord's rate limit headers
The bot includes a health check endpoint at /health for monitoring:
- URL:
http://localhost:5000/health(or your server's address) - Method: GET
- Returns: JSON with health status including rate limit information
- Status Codes:
200- All systems healthy500- Issues detected (check logs for details)
Access application logs via the /logs endpoint:
- URL:
http://localhost:5000/logs(or your server's address) - Method: GET
- Returns: Recent log entries from
Disgram.log - Features: Real-time log viewing for debugging and monitoring
Clear the contents of Disgram.log while preserving the latest message links via the /logs/clear endpoint:
- URL:
http://localhost:5000/logs/clear(or your server's address) - Method: POST
- Returns: JSON response with status, number of preserved channel links, and the latest message URLs
- Features:
- Removes all timestamped log entries
- Preserves the header line
- Extracts and preserves the latest message link for each channel (not the initial starting points)
- Useful for managing log file size while maintaining progress
Example:
curl -X POST http://localhost:5000/logs/clearResponse:
{
"status": "success",
"message": "Disgram.log cleared successfully",
"preserved_links": 9,
"latest_messages": [
"https://t.me/Galaxy_leak/3649",
"https://t.me/Seele_WW_Leak/3728",
"..."
]
}- Rate Limiting: Discord rate limits are handled automatically with intelligent retry logic but be mindful of Telegram Preview Page's rates as well, in order to avoid IP bans.
- Message Source: Messages are fetched from Telegram's public preview page (https://t.me/s/{channel})
- Channel Requirements: Only works with public Telegram channels with accessible preview pages
- Media Processing: Supports single images, videos, and grouped media collections automatically
- Thread vs Channel: The bot automatically chooses between
webhook.py(channel) andthreadhook.py(thread) based onDISCORD_THREAD_IDconfiguration - Process Management: Each Telegram channel runs in a separate process for better performance and isolation
- Image quality of compressed images is too low to scrap from preview page. Use Telegram app for higher quality.
- Video URL extraction depends on video size, which determines if the Telegram public preview page will preview the video or not. If the video is too large, it won't be previewed and thus can't be scraped.
- The bot can not fully parse messages reliably with following content for now:
- Uncompressed Media
- Documents
- Messages with replies
Contributions are welcome! Please feel free to submit a Pull Request.
This project is licensed under the MIT License - see the LICENSE file for details.