tgdata 0.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- tgdata-0.0.0/PKG-INFO +309 -0
- tgdata-0.0.0/README.md +283 -0
- tgdata-0.0.0/setup.cfg +4 -0
- tgdata-0.0.0/setup.py +30 -0
- tgdata-0.0.0/tgdata/__init__.py +57 -0
- tgdata-0.0.0/tgdata/connection_engine.py +316 -0
- tgdata-0.0.0/tgdata/message_engine.py +299 -0
- tgdata-0.0.0/tgdata/models.py +69 -0
- tgdata-0.0.0/tgdata/progress.py +105 -0
- tgdata-0.0.0/tgdata/smoke_tests/__init__.py +1 -0
- tgdata-0.0.0/tgdata/smoke_tests/my_test.py +149 -0
- tgdata-0.0.0/tgdata/smoke_tests/test_00_connection.py +286 -0
- tgdata-0.0.0/tgdata/smoke_tests/test_01_list_group_chats.py +408 -0
- tgdata-0.0.0/tgdata/smoke_tests/test_02_get_message_count.py +73 -0
- tgdata-0.0.0/tgdata/smoke_tests/test_03_get_all_messages.py +69 -0
- tgdata-0.0.0/tgdata/smoke_tests/test_04_get_all_messages_in_batches.py +98 -0
- tgdata-0.0.0/tgdata/smoke_tests/test_06_advanced_features.py +253 -0
- tgdata-0.0.0/tgdata/smoke_tests/test_10_polling.py +244 -0
- tgdata-0.0.0/tgdata/tgdata.py +554 -0
- tgdata-0.0.0/tgdata/utils.py +247 -0
- tgdata-0.0.0/tgdata.egg-info/PKG-INFO +309 -0
- tgdata-0.0.0/tgdata.egg-info/SOURCES.txt +23 -0
- tgdata-0.0.0/tgdata.egg-info/dependency_links.txt +1 -0
- tgdata-0.0.0/tgdata.egg-info/requires.txt +2 -0
- tgdata-0.0.0/tgdata.egg-info/top_level.txt +1 -0
tgdata-0.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: tgdata
|
|
3
|
+
Version: 0.0.0
|
|
4
|
+
Summary: A production-grade Python library for extracting and processing Telegram group and channel messages
|
|
5
|
+
Author: enes kuzucu
|
|
6
|
+
Classifier: Development Status :: 3 - Alpha
|
|
7
|
+
Classifier: Intended Audience :: Developers
|
|
8
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.7
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Requires-Python: >=3.7
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
Requires-Dist: Telethon
|
|
18
|
+
Requires-Dist: pandas
|
|
19
|
+
Dynamic: author
|
|
20
|
+
Dynamic: classifier
|
|
21
|
+
Dynamic: description
|
|
22
|
+
Dynamic: description-content-type
|
|
23
|
+
Dynamic: requires-dist
|
|
24
|
+
Dynamic: requires-python
|
|
25
|
+
Dynamic: summary
|
|
26
|
+
|
|
27
|
+
# tgdata
|
|
28
|
+
|
|
29
|
+
A production-grade Python library for extracting and processing Telegram group and channel messages. Designed for ETL pipelines, data analysis, and archival purposes.
|
|
30
|
+
|
|
31
|
+
## Features
|
|
32
|
+
|
|
33
|
+
- 🚀 **Production-Ready**: Built for reliability and scale in ETL pipelines
|
|
34
|
+
- 📊 **Efficient Data Extraction**: Fetch messages from groups and channels with rate limit handling
|
|
35
|
+
- 🔄 **Incremental Updates**: Fetch only new messages with `after_id` parameter
|
|
36
|
+
- 📈 **Progress Tracking**: Monitor long-running operations with real-time progress
|
|
37
|
+
- 🔌 **Clean Architecture**: Focused on data extraction with minimal dependencies
|
|
38
|
+
- 🛡️ **Robust Error Handling**: Automatic retries with exponential backoff
|
|
39
|
+
- 📁 **Multiple Export Formats**: Export to CSV, JSON, or integrate with your data pipeline
|
|
40
|
+
- 🔔 **Real-time Updates**: Listen for new messages with event handlers
|
|
41
|
+
- ⏱️ **Polling Support**: Poll for new messages at configurable intervals
|
|
42
|
+
|
|
43
|
+
## Installation
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
pip install tgdata
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Quick Start
|
|
50
|
+
|
|
51
|
+
```python
|
|
52
|
+
from tgdata import TgData
|
|
53
|
+
import asyncio
|
|
54
|
+
|
|
55
|
+
async def main():
|
|
56
|
+
# Initialize the client
|
|
57
|
+
tg = TgData()
|
|
58
|
+
|
|
59
|
+
# List available groups and channels
|
|
60
|
+
groups = await tg.list_groups()
|
|
61
|
+
print(f"Found {len(groups)} groups/channels")
|
|
62
|
+
|
|
63
|
+
# Fetch messages from a specific group
|
|
64
|
+
messages = await tg.get_messages(
|
|
65
|
+
group_id=-1001234567890, # Your group ID
|
|
66
|
+
limit=1000,
|
|
67
|
+
with_progress=True
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
# Export to CSV
|
|
71
|
+
tg.export_messages(messages, "messages.csv")
|
|
72
|
+
|
|
73
|
+
# Get message statistics
|
|
74
|
+
stats = tg.get_statistics(messages)
|
|
75
|
+
print(f"Total messages: {stats['total_messages']}")
|
|
76
|
+
print(f"Date range: {stats['date_range']['first']} to {stats['date_range']['last']}")
|
|
77
|
+
|
|
78
|
+
asyncio.run(main())
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Configuration
|
|
82
|
+
|
|
83
|
+
Create a `config.ini` file with your Telegram API credentials:
|
|
84
|
+
|
|
85
|
+
```ini
|
|
86
|
+
[telegram]
|
|
87
|
+
api_id = YOUR_API_ID
|
|
88
|
+
api_hash = YOUR_API_HASH
|
|
89
|
+
session_file = telegram_session
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Get your API credentials from [https://my.telegram.org/apps](https://my.telegram.org/apps)
|
|
93
|
+
|
|
94
|
+
## Advanced Usage
|
|
95
|
+
|
|
96
|
+
### ETL Pipeline Integration
|
|
97
|
+
|
|
98
|
+
```python
|
|
99
|
+
from tgdata import TgData
|
|
100
|
+
from datetime import datetime, timedelta
|
|
101
|
+
import asyncio
|
|
102
|
+
|
|
103
|
+
async def etl_pipeline():
|
|
104
|
+
tg = TgData()
|
|
105
|
+
|
|
106
|
+
# Fetch recent messages for ETL processing
|
|
107
|
+
yesterday = datetime.now() - timedelta(days=1)
|
|
108
|
+
messages = await tg.get_messages(
|
|
109
|
+
group_id=-1001234567890,
|
|
110
|
+
start_date=yesterday,
|
|
111
|
+
with_progress=True
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
# Filter messages
|
|
115
|
+
filtered = tg.filter_messages(
|
|
116
|
+
messages,
|
|
117
|
+
keyword="important",
|
|
118
|
+
start_date=yesterday
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
# Export for data pipeline
|
|
122
|
+
tg.export_messages(filtered, "daily_extract.json", format="json")
|
|
123
|
+
|
|
124
|
+
# Get metrics
|
|
125
|
+
metrics = await tg.get_metrics()
|
|
126
|
+
print(f"Processed {len(filtered)} messages")
|
|
127
|
+
|
|
128
|
+
asyncio.run(etl_pipeline())
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Incremental Message Fetching
|
|
132
|
+
|
|
133
|
+
```python
|
|
134
|
+
from tgdata import TgData
|
|
135
|
+
|
|
136
|
+
async def incremental_fetch():
|
|
137
|
+
tg = TgData()
|
|
138
|
+
|
|
139
|
+
# Get the latest message ID from your storage
|
|
140
|
+
last_processed_id = load_checkpoint() # Your implementation
|
|
141
|
+
|
|
142
|
+
# Fetch only messages after that ID
|
|
143
|
+
new_messages = await tg.get_messages(
|
|
144
|
+
group_id=-1001234567890,
|
|
145
|
+
after_id=last_processed_id
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
if not new_messages.empty:
|
|
149
|
+
# Process new messages
|
|
150
|
+
process_messages(new_messages)
|
|
151
|
+
|
|
152
|
+
# Save new checkpoint
|
|
153
|
+
save_checkpoint(new_messages['MessageId'].max())
|
|
154
|
+
|
|
155
|
+
print(f"New messages: {len(new_messages)}")
|
|
156
|
+
|
|
157
|
+
asyncio.run(incremental_fetch())
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Progress Monitoring
|
|
161
|
+
|
|
162
|
+
```python
|
|
163
|
+
async def monitor_extraction():
|
|
164
|
+
tg = TgData()
|
|
165
|
+
|
|
166
|
+
def progress_callback(current, total, rate):
|
|
167
|
+
percent = (current / total * 100) if total else 0
|
|
168
|
+
print(f"Progress: {current}/{total} ({percent:.1f}%) - {rate:.1f} msg/s")
|
|
169
|
+
|
|
170
|
+
messages = await tg.get_messages(
|
|
171
|
+
group_id=-1001234567890,
|
|
172
|
+
limit=10000,
|
|
173
|
+
progress_callback=progress_callback
|
|
174
|
+
)
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### Real-time Message Monitoring
|
|
178
|
+
|
|
179
|
+
```python
|
|
180
|
+
async def monitor_real_time():
|
|
181
|
+
tg = TgData()
|
|
182
|
+
|
|
183
|
+
# Register handler for new messages
|
|
184
|
+
@tg.on_new_message(group_id=-1001234567890)
|
|
185
|
+
async def handle_message(event):
|
|
186
|
+
print(f"New message from {event.sender_id}: {event.message.text}")
|
|
187
|
+
|
|
188
|
+
# React to commands
|
|
189
|
+
if event.message.text == "!ping":
|
|
190
|
+
await event.reply("Pong!")
|
|
191
|
+
|
|
192
|
+
# Run event loop
|
|
193
|
+
await tg.run_with_event_loop()
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### Polling for New Messages
|
|
197
|
+
|
|
198
|
+
```python
|
|
199
|
+
async def poll_messages():
|
|
200
|
+
tg = TgData()
|
|
201
|
+
|
|
202
|
+
# Define callback for new messages
|
|
203
|
+
async def process_batch(messages_df):
|
|
204
|
+
print(f"Got {len(messages_df)} new messages")
|
|
205
|
+
# Process messages here
|
|
206
|
+
|
|
207
|
+
# Poll every 30 seconds
|
|
208
|
+
await tg.poll_for_messages(
|
|
209
|
+
group_id=-1001234567890,
|
|
210
|
+
interval=30,
|
|
211
|
+
callback=process_batch,
|
|
212
|
+
max_iterations=10 # Stop after 10 polls
|
|
213
|
+
)
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
## API Reference
|
|
217
|
+
|
|
218
|
+
### TgData
|
|
219
|
+
|
|
220
|
+
Main class for interacting with Telegram groups and channels.
|
|
221
|
+
|
|
222
|
+
#### Methods
|
|
223
|
+
|
|
224
|
+
**Core Methods:**
|
|
225
|
+
- `list_groups()` - List all accessible groups and channels
|
|
226
|
+
- `get_messages()` - Fetch messages with various filters
|
|
227
|
+
- `search_messages()` - Search for specific content
|
|
228
|
+
- `filter_messages()` - Filter messages by criteria
|
|
229
|
+
- `export_messages()` - Export to CSV or JSON
|
|
230
|
+
- `get_statistics()` - Get message statistics
|
|
231
|
+
- `get_metrics()` - Get session metrics
|
|
232
|
+
- `get_message_count()` - Get total message count without fetching all
|
|
233
|
+
|
|
234
|
+
**Real-time & Polling:**
|
|
235
|
+
- `on_new_message()` - Decorator to register real-time message handlers
|
|
236
|
+
- `poll_for_messages()` - Poll for new messages at intervals
|
|
237
|
+
- `run_with_event_loop()` - Run client with event loop for real-time events
|
|
238
|
+
|
|
239
|
+
### Checkpoint Management
|
|
240
|
+
|
|
241
|
+
For production ETL pipelines, implement your own checkpoint logic:
|
|
242
|
+
|
|
243
|
+
```python
|
|
244
|
+
# Save last processed message ID to your database
|
|
245
|
+
last_id = messages['MessageId'].max()
|
|
246
|
+
await save_to_database(group_id, last_id)
|
|
247
|
+
|
|
248
|
+
# On next run, fetch only new messages
|
|
249
|
+
last_id = await load_from_database(group_id)
|
|
250
|
+
new_messages = await tg.get_messages(group_id=group_id, after_id=last_id)
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
## Production Deployment
|
|
254
|
+
|
|
255
|
+
### Best Practices
|
|
256
|
+
|
|
257
|
+
1. **Use environment variables for credentials**:
|
|
258
|
+
```python
|
|
259
|
+
import os
|
|
260
|
+
config_path = os.getenv("TELEGRAM_CONFIG", "config.ini")
|
|
261
|
+
tg = TgData(config_path=config_path)
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
2. **Implement error handling**:
|
|
265
|
+
```python
|
|
266
|
+
try:
|
|
267
|
+
messages = await tg.get_messages(group_id=group_id)
|
|
268
|
+
except Exception as e:
|
|
269
|
+
logger.error(f"Failed to fetch messages: {e}")
|
|
270
|
+
# Implement retry logic or alerting
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
3. **Monitor rate limits**:
|
|
274
|
+
```python
|
|
275
|
+
health = await tg.health_check()
|
|
276
|
+
if not health['primary_connection']:
|
|
277
|
+
# Handle connection issues
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
### Performance Tips
|
|
281
|
+
|
|
282
|
+
- Use connection pooling for parallel operations
|
|
283
|
+
- Implement checkpoint logic for incremental processing
|
|
284
|
+
- Implement progress callbacks for visibility
|
|
285
|
+
- Export data incrementally for large datasets
|
|
286
|
+
|
|
287
|
+
## Requirements
|
|
288
|
+
|
|
289
|
+
- Python 3.7+
|
|
290
|
+
- Telegram API credentials (not bot tokens)
|
|
291
|
+
- Group/channel membership
|
|
292
|
+
|
|
293
|
+
## License
|
|
294
|
+
|
|
295
|
+
MIT License - see LICENSE file for details
|
|
296
|
+
|
|
297
|
+
## Contributing
|
|
298
|
+
|
|
299
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
300
|
+
|
|
301
|
+
## Support
|
|
302
|
+
|
|
303
|
+
- Documentation: [Full documentation](https://github.com/yourusername/tgdata)
|
|
304
|
+
- Issues: [GitHub Issues](https://github.com/yourusername/tgdata/issues)
|
|
305
|
+
- Examples: See the [examples/](examples/) directory
|
|
306
|
+
|
|
307
|
+
## Disclaimer
|
|
308
|
+
|
|
309
|
+
This tool is for legitimate data collection and analysis only. Users must comply with Telegram's Terms of Service and applicable laws. Always respect user privacy and platform rate limits.
|
tgdata-0.0.0/README.md
ADDED
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
# tgdata
|
|
2
|
+
|
|
3
|
+
A production-grade Python library for extracting and processing Telegram group and channel messages. Designed for ETL pipelines, data analysis, and archival purposes.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🚀 **Production-Ready**: Built for reliability and scale in ETL pipelines
|
|
8
|
+
- 📊 **Efficient Data Extraction**: Fetch messages from groups and channels with rate limit handling
|
|
9
|
+
- 🔄 **Incremental Updates**: Fetch only new messages with `after_id` parameter
|
|
10
|
+
- 📈 **Progress Tracking**: Monitor long-running operations with real-time progress
|
|
11
|
+
- 🔌 **Clean Architecture**: Focused on data extraction with minimal dependencies
|
|
12
|
+
- 🛡️ **Robust Error Handling**: Automatic retries with exponential backoff
|
|
13
|
+
- 📁 **Multiple Export Formats**: Export to CSV, JSON, or integrate with your data pipeline
|
|
14
|
+
- 🔔 **Real-time Updates**: Listen for new messages with event handlers
|
|
15
|
+
- ⏱️ **Polling Support**: Poll for new messages at configurable intervals
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
pip install tgdata
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Quick Start
|
|
24
|
+
|
|
25
|
+
```python
|
|
26
|
+
from tgdata import TgData
|
|
27
|
+
import asyncio
|
|
28
|
+
|
|
29
|
+
async def main():
|
|
30
|
+
# Initialize the client
|
|
31
|
+
tg = TgData()
|
|
32
|
+
|
|
33
|
+
# List available groups and channels
|
|
34
|
+
groups = await tg.list_groups()
|
|
35
|
+
print(f"Found {len(groups)} groups/channels")
|
|
36
|
+
|
|
37
|
+
# Fetch messages from a specific group
|
|
38
|
+
messages = await tg.get_messages(
|
|
39
|
+
group_id=-1001234567890, # Your group ID
|
|
40
|
+
limit=1000,
|
|
41
|
+
with_progress=True
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
# Export to CSV
|
|
45
|
+
tg.export_messages(messages, "messages.csv")
|
|
46
|
+
|
|
47
|
+
# Get message statistics
|
|
48
|
+
stats = tg.get_statistics(messages)
|
|
49
|
+
print(f"Total messages: {stats['total_messages']}")
|
|
50
|
+
print(f"Date range: {stats['date_range']['first']} to {stats['date_range']['last']}")
|
|
51
|
+
|
|
52
|
+
asyncio.run(main())
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Configuration
|
|
56
|
+
|
|
57
|
+
Create a `config.ini` file with your Telegram API credentials:
|
|
58
|
+
|
|
59
|
+
```ini
|
|
60
|
+
[telegram]
|
|
61
|
+
api_id = YOUR_API_ID
|
|
62
|
+
api_hash = YOUR_API_HASH
|
|
63
|
+
session_file = telegram_session
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Get your API credentials from [https://my.telegram.org/apps](https://my.telegram.org/apps)
|
|
67
|
+
|
|
68
|
+
## Advanced Usage
|
|
69
|
+
|
|
70
|
+
### ETL Pipeline Integration
|
|
71
|
+
|
|
72
|
+
```python
|
|
73
|
+
from tgdata import TgData
|
|
74
|
+
from datetime import datetime, timedelta
|
|
75
|
+
import asyncio
|
|
76
|
+
|
|
77
|
+
async def etl_pipeline():
|
|
78
|
+
tg = TgData()
|
|
79
|
+
|
|
80
|
+
# Fetch recent messages for ETL processing
|
|
81
|
+
yesterday = datetime.now() - timedelta(days=1)
|
|
82
|
+
messages = await tg.get_messages(
|
|
83
|
+
group_id=-1001234567890,
|
|
84
|
+
start_date=yesterday,
|
|
85
|
+
with_progress=True
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
# Filter messages
|
|
89
|
+
filtered = tg.filter_messages(
|
|
90
|
+
messages,
|
|
91
|
+
keyword="important",
|
|
92
|
+
start_date=yesterday
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
# Export for data pipeline
|
|
96
|
+
tg.export_messages(filtered, "daily_extract.json", format="json")
|
|
97
|
+
|
|
98
|
+
# Get metrics
|
|
99
|
+
metrics = await tg.get_metrics()
|
|
100
|
+
print(f"Processed {len(filtered)} messages")
|
|
101
|
+
|
|
102
|
+
asyncio.run(etl_pipeline())
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Incremental Message Fetching
|
|
106
|
+
|
|
107
|
+
```python
|
|
108
|
+
from tgdata import TgData
|
|
109
|
+
|
|
110
|
+
async def incremental_fetch():
|
|
111
|
+
tg = TgData()
|
|
112
|
+
|
|
113
|
+
# Get the latest message ID from your storage
|
|
114
|
+
last_processed_id = load_checkpoint() # Your implementation
|
|
115
|
+
|
|
116
|
+
# Fetch only messages after that ID
|
|
117
|
+
new_messages = await tg.get_messages(
|
|
118
|
+
group_id=-1001234567890,
|
|
119
|
+
after_id=last_processed_id
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
if not new_messages.empty:
|
|
123
|
+
# Process new messages
|
|
124
|
+
process_messages(new_messages)
|
|
125
|
+
|
|
126
|
+
# Save new checkpoint
|
|
127
|
+
save_checkpoint(new_messages['MessageId'].max())
|
|
128
|
+
|
|
129
|
+
print(f"New messages: {len(new_messages)}")
|
|
130
|
+
|
|
131
|
+
asyncio.run(incremental_fetch())
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Progress Monitoring
|
|
135
|
+
|
|
136
|
+
```python
|
|
137
|
+
async def monitor_extraction():
|
|
138
|
+
tg = TgData()
|
|
139
|
+
|
|
140
|
+
def progress_callback(current, total, rate):
|
|
141
|
+
percent = (current / total * 100) if total else 0
|
|
142
|
+
print(f"Progress: {current}/{total} ({percent:.1f}%) - {rate:.1f} msg/s")
|
|
143
|
+
|
|
144
|
+
messages = await tg.get_messages(
|
|
145
|
+
group_id=-1001234567890,
|
|
146
|
+
limit=10000,
|
|
147
|
+
progress_callback=progress_callback
|
|
148
|
+
)
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### Real-time Message Monitoring
|
|
152
|
+
|
|
153
|
+
```python
|
|
154
|
+
async def monitor_real_time():
|
|
155
|
+
tg = TgData()
|
|
156
|
+
|
|
157
|
+
# Register handler for new messages
|
|
158
|
+
@tg.on_new_message(group_id=-1001234567890)
|
|
159
|
+
async def handle_message(event):
|
|
160
|
+
print(f"New message from {event.sender_id}: {event.message.text}")
|
|
161
|
+
|
|
162
|
+
# React to commands
|
|
163
|
+
if event.message.text == "!ping":
|
|
164
|
+
await event.reply("Pong!")
|
|
165
|
+
|
|
166
|
+
# Run event loop
|
|
167
|
+
await tg.run_with_event_loop()
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Polling for New Messages
|
|
171
|
+
|
|
172
|
+
```python
|
|
173
|
+
async def poll_messages():
|
|
174
|
+
tg = TgData()
|
|
175
|
+
|
|
176
|
+
# Define callback for new messages
|
|
177
|
+
async def process_batch(messages_df):
|
|
178
|
+
print(f"Got {len(messages_df)} new messages")
|
|
179
|
+
# Process messages here
|
|
180
|
+
|
|
181
|
+
# Poll every 30 seconds
|
|
182
|
+
await tg.poll_for_messages(
|
|
183
|
+
group_id=-1001234567890,
|
|
184
|
+
interval=30,
|
|
185
|
+
callback=process_batch,
|
|
186
|
+
max_iterations=10 # Stop after 10 polls
|
|
187
|
+
)
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
## API Reference
|
|
191
|
+
|
|
192
|
+
### TgData
|
|
193
|
+
|
|
194
|
+
Main class for interacting with Telegram groups and channels.
|
|
195
|
+
|
|
196
|
+
#### Methods
|
|
197
|
+
|
|
198
|
+
**Core Methods:**
|
|
199
|
+
- `list_groups()` - List all accessible groups and channels
|
|
200
|
+
- `get_messages()` - Fetch messages with various filters
|
|
201
|
+
- `search_messages()` - Search for specific content
|
|
202
|
+
- `filter_messages()` - Filter messages by criteria
|
|
203
|
+
- `export_messages()` - Export to CSV or JSON
|
|
204
|
+
- `get_statistics()` - Get message statistics
|
|
205
|
+
- `get_metrics()` - Get session metrics
|
|
206
|
+
- `get_message_count()` - Get total message count without fetching all
|
|
207
|
+
|
|
208
|
+
**Real-time & Polling:**
|
|
209
|
+
- `on_new_message()` - Decorator to register real-time message handlers
|
|
210
|
+
- `poll_for_messages()` - Poll for new messages at intervals
|
|
211
|
+
- `run_with_event_loop()` - Run client with event loop for real-time events
|
|
212
|
+
|
|
213
|
+
### Checkpoint Management
|
|
214
|
+
|
|
215
|
+
For production ETL pipelines, implement your own checkpoint logic:
|
|
216
|
+
|
|
217
|
+
```python
|
|
218
|
+
# Save last processed message ID to your database
|
|
219
|
+
last_id = messages['MessageId'].max()
|
|
220
|
+
await save_to_database(group_id, last_id)
|
|
221
|
+
|
|
222
|
+
# On next run, fetch only new messages
|
|
223
|
+
last_id = await load_from_database(group_id)
|
|
224
|
+
new_messages = await tg.get_messages(group_id=group_id, after_id=last_id)
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
## Production Deployment
|
|
228
|
+
|
|
229
|
+
### Best Practices
|
|
230
|
+
|
|
231
|
+
1. **Use environment variables for credentials**:
|
|
232
|
+
```python
|
|
233
|
+
import os
|
|
234
|
+
config_path = os.getenv("TELEGRAM_CONFIG", "config.ini")
|
|
235
|
+
tg = TgData(config_path=config_path)
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
2. **Implement error handling**:
|
|
239
|
+
```python
|
|
240
|
+
try:
|
|
241
|
+
messages = await tg.get_messages(group_id=group_id)
|
|
242
|
+
except Exception as e:
|
|
243
|
+
logger.error(f"Failed to fetch messages: {e}")
|
|
244
|
+
# Implement retry logic or alerting
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
3. **Monitor rate limits**:
|
|
248
|
+
```python
|
|
249
|
+
health = await tg.health_check()
|
|
250
|
+
if not health['primary_connection']:
|
|
251
|
+
# Handle connection issues
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
### Performance Tips
|
|
255
|
+
|
|
256
|
+
- Use connection pooling for parallel operations
|
|
257
|
+
- Implement checkpoint logic for incremental processing
|
|
258
|
+
- Implement progress callbacks for visibility
|
|
259
|
+
- Export data incrementally for large datasets
|
|
260
|
+
|
|
261
|
+
## Requirements
|
|
262
|
+
|
|
263
|
+
- Python 3.7+
|
|
264
|
+
- Telegram API credentials (not bot tokens)
|
|
265
|
+
- Group/channel membership
|
|
266
|
+
|
|
267
|
+
## License
|
|
268
|
+
|
|
269
|
+
MIT License - see LICENSE file for details
|
|
270
|
+
|
|
271
|
+
## Contributing
|
|
272
|
+
|
|
273
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
274
|
+
|
|
275
|
+
## Support
|
|
276
|
+
|
|
277
|
+
- Documentation: [Full documentation](https://github.com/yourusername/tgdata)
|
|
278
|
+
- Issues: [GitHub Issues](https://github.com/yourusername/tgdata/issues)
|
|
279
|
+
- Examples: See the [examples/](examples/) directory
|
|
280
|
+
|
|
281
|
+
## Disclaimer
|
|
282
|
+
|
|
283
|
+
This tool is for legitimate data collection and analysis only. Users must comply with Telegram's Terms of Service and applicable laws. Always respect user privacy and platform rate limits.
|
tgdata-0.0.0/setup.cfg
ADDED
tgdata-0.0.0/setup.py
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
from setuptools import setup, find_packages
|
|
2
|
+
|
|
3
|
+
setup(
|
|
4
|
+
name='tgdata', # Package name
|
|
5
|
+
version='0.0.0', # Version of your package
|
|
6
|
+
author='enes kuzucu', # Your name
|
|
7
|
+
|
|
8
|
+
description='A production-grade Python library for extracting and processing Telegram group and channel messages',
|
|
9
|
+
long_description=open('README.md').read(), # Long description from a README file
|
|
10
|
+
long_description_content_type='text/markdown', # Type of the long description
|
|
11
|
+
|
|
12
|
+
packages=find_packages(), # Automatically find packages in the directory
|
|
13
|
+
install_requires=[
|
|
14
|
+
'Telethon',
|
|
15
|
+
'pandas', # Optional but recommended for better performance
|
|
16
|
+
],
|
|
17
|
+
|
|
18
|
+
classifiers=[
|
|
19
|
+
'Development Status :: 3 - Alpha', # Development status
|
|
20
|
+
'Intended Audience :: Developers',
|
|
21
|
+
'License :: OSI Approved :: MIT License', # License as you choose
|
|
22
|
+
'Programming Language :: Python :: 3', # Supported Python versions
|
|
23
|
+
'Programming Language :: Python :: 3.7',
|
|
24
|
+
'Programming Language :: Python :: 3.8',
|
|
25
|
+
'Programming Language :: Python :: 3.9',
|
|
26
|
+
'Programming Language :: Python :: 3.10',
|
|
27
|
+
'Operating System :: OS Independent',
|
|
28
|
+
],
|
|
29
|
+
python_requires='>=3.7', # Minimum version requirement of Python
|
|
30
|
+
)
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"""
|
|
2
|
+
tgdata - Telegram Data Extraction Library
|
|
3
|
+
|
|
4
|
+
A production-grade Python library for extracting and processing Telegram group and channel messages.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
# Main class
|
|
8
|
+
from .tgdata import TgData
|
|
9
|
+
|
|
10
|
+
# Models
|
|
11
|
+
from .models import (
|
|
12
|
+
MessageData,
|
|
13
|
+
GroupInfo,
|
|
14
|
+
ConnectionConfig,
|
|
15
|
+
RateLimitInfo
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
# Utilities
|
|
19
|
+
from .utils import (
|
|
20
|
+
format_message_for_display,
|
|
21
|
+
export_to_json,
|
|
22
|
+
export_to_csv,
|
|
23
|
+
filter_messages_by_sender,
|
|
24
|
+
filter_messages_by_content,
|
|
25
|
+
get_message_statistics,
|
|
26
|
+
save_profile_photos,
|
|
27
|
+
create_metrics_report
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
# Progress tracking
|
|
31
|
+
from .progress import ProgressTracker
|
|
32
|
+
|
|
33
|
+
__version__ = "0.0.0"
|
|
34
|
+
|
|
35
|
+
__all__ = [
|
|
36
|
+
# Main class
|
|
37
|
+
"TgData",
|
|
38
|
+
|
|
39
|
+
# Models
|
|
40
|
+
"MessageData",
|
|
41
|
+
"GroupInfo",
|
|
42
|
+
"ConnectionConfig",
|
|
43
|
+
"RateLimitInfo",
|
|
44
|
+
|
|
45
|
+
# Utilities
|
|
46
|
+
"format_message_for_display",
|
|
47
|
+
"export_to_json",
|
|
48
|
+
"export_to_csv",
|
|
49
|
+
"filter_messages_by_sender",
|
|
50
|
+
"filter_messages_by_content",
|
|
51
|
+
"get_message_statistics",
|
|
52
|
+
"save_profile_photos",
|
|
53
|
+
"create_metrics_report",
|
|
54
|
+
|
|
55
|
+
# Progress
|
|
56
|
+
"ProgressTracker"
|
|
57
|
+
]
|