-
Notifications
You must be signed in to change notification settings - Fork 24
Expand file tree
/
Copy pathtelegram_handler.py
More file actions
128 lines (111 loc) · 5.02 KB
/
Copy pathtelegram_handler.py
File metadata and controls
128 lines (111 loc) · 5.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import time
import requests
import json
import os
from datetime import datetime
from dotenv import load_dotenv
# Load environment variables from .env file
load_dotenv()
class TelegramBot:
def __init__(self):
# Fetch credentials from environment
self.BOT_TOKEN = os.getenv("TELEGRAM_BOT_TOKEN")
self.CHAT_ID = os.getenv("TELEGRAM_CHAT_ID")
self.url = f'https://api.telegram.org/bot{self.BOT_TOKEN}/'
self.update_id_file = "last_update_id.txt"
def send_message(self, text):
"""Send a plain text message to Telegram."""
try:
response = requests.post(f'{self.url}sendMessage', data={'chat_id': self.CHAT_ID, 'text': text})
print("Sent message:", text)
return response
except Exception as e:
self.log_error(f"Failed to send message: {e}")
def send_video_file(self, video_path, caption=None):
"""Send a video file as a document to Telegram.Please Note that you can only send file upto 50 MB as per telegram bot rules"""
try:
with open(video_path, 'rb') as video_file:
files = {'document': video_file}
data = {'chat_id': self.CHAT_ID}
if caption:
data['caption'] = caption
response = requests.post(f'{self.url}sendDocument', data=data, files=files)
print("Sent video file:", video_path)
return response
except Exception as e:
self.log_error(f"Failed to send video file: {e}")
def get_updates(self, offset=None):
"""Fetch new updates from Telegram."""
params = {'timeout': 10, 'offset': offset}
try:
response = requests.get(f'{self.url}getUpdates', params=params)
return response.json()
except Exception as e:
self.log_error(f"Error fetching updates: {e}")
return {}
def extract_json_from_message(self, msg_text):
"""Extract and parse JSON if message starts with 'from:'."""
msg_text = msg_text.strip()
if msg_text.lower().startswith('from:'):
try:
raw_json_lines = msg_text.split(':', 1)[1].strip().splitlines()
raw_json = ' '.join(line.strip() for line in raw_json_lines if line.strip())
print("Extracted JSON string:\n", raw_json)
data = json.loads(raw_json)
print("Parsed data:\n", data)
return data
except json.JSONDecodeError as e:
self.log_error(f"JSON decode error: {e}\nText:\n{msg_text}")
else:
print("Message does not start with 'from:'")
return None
def is_valid_list_of_dicts(self, data):
"""Check if data is a list of dictionaries."""
valid = isinstance(data, list) and all(isinstance(d, dict) for d in data)
print("Is valid list of dicts:", valid)
return valid
def get_last_update_id(self):
"""Read last update ID from file."""
try:
with open(self.update_id_file, "r") as f:
return int(f.read().strip())
except (FileNotFoundError, ValueError):
return None
def set_last_update_id(self, last_update_id):
"""Write the last processed update ID to a file."""
with open(self.update_id_file, "w") as f:
f.write(str(last_update_id))
def poll_for_content(self, timeout_minutes=15):
"""Poll for messages for a specific duration."""
print("Polling for content...")
self.send_message("Please send your data in format:\nfrom: [ {...}, {...} ]")
start_time = time.time()
last_update_id = self.get_last_update_id()
while time.time() - start_time < timeout_minutes * 60:
updates = self.get_updates(last_update_id)
results = updates.get('result', [])
for update in results:
last_update_id = update['update_id'] + 1
self.set_last_update_id(last_update_id)
message = update.get('message', {})
text = message.get('text')
if text:
print("New message received:", text)
data = self.extract_json_from_message(text)
if data and self.is_valid_list_of_dicts(data):
self.send_message("Content accepted and added to DB.")
return list(data)
else:
self.send_message("Invalid format. Please resend as:\nfrom: [ {...}, {...} ]")
time.sleep(3)
self.send_message("Timeout: No valid content received in 15 minutes.")
def log_error(self, message):
"""Log an error to a file with timestamp."""
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
with open("errors.log", "a") as f:
f.write(f"[{timestamp}] {message}\n")
# if __name__ == "__main__":
# bot = TelegramBot()
# data = bot.poll_for_content()
# if data:
# print("Received data:", data)