-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path4_dronealertbot_webhook_new_features.py
More file actions
198 lines (162 loc) · 8.05 KB
/
4_dronealertbot_webhook_new_features.py
File metadata and controls
198 lines (162 loc) · 8.05 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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
import os
import json
import asyncio
import logging
import time
import re
from fastapi import FastAPI, Request
from telethon import TelegramClient, events
from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup
from telegram.ext import ApplicationBuilder, CommandHandler, ContextTypes,CallbackQueryHandler
import nest_asyncio
import uvicorn
nest_asyncio.apply()
# ---------------------- CONFIGURATION ----------------------
api_id = 'api id'
api_hash = 'api hash'
bot_token = 'bot token'
WEBHOOK_URL = "https://bot.fastnotify.org/webhook"
# Channels to monitor
channels_to_monitor = ['chyste_nebo', 'vseok450','AerisRimor','kyivmonitoring1','mon1tor_ua','monitoring_kiev']
# Regex patterns for detecting mentions of cities
words_sets = {
"Set 1": {
"Ірп": re.compile(r'\bІрп\w*\b', re.IGNORECASE),
"Буч": re.compile(r'\bБуч\w*\b', re.IGNORECASE),
"Гостом": re.compile(r'\bГостом\w*\b', re.IGNORECASE),
"Коцюбин": re.compile(r'\bКоцюбин\w*\b', re.IGNORECASE),
"Ворзел": re.compile(r'\bВорзел\w*\b', re.IGNORECASE),
},
"Set 2": {
"Троє": re.compile(r'\bТроє\w*\b', re.IGNORECASE),
"Погреб": re.compile(r'\bПогреб\w*\b', re.IGNORECASE),
"Зазим": re.compile(r'\bЗазим\w*\b', re.IGNORECASE),
"Осещин": re.compile(r'\bОсещин\w*\b', re.IGNORECASE),
"Оболон": re.compile(r'\bОболон\w*\b', re.IGNORECASE),
"Бровар": re.compile(r'\bБровар\w*\b', re.IGNORECASE),
"Воскресен": re.compile(r'\bВоскресен\w*\b', re.IGNORECASE),
"Деснянськ": re.compile(r'\bДеснянськ\w*\b', re.IGNORECASE),
"Лісов": re.compile(r'\bЛісов\w*\b', re.IGNORECASE),
},
}
selected_set = "Set 1" # Default set
regex_patterns = words_sets[selected_set] # Default to Set 1
# File to store user configurations
USER_CONFIG_FILE = 'user_configs.json'
def load_user_configs():
if os.path.exists(USER_CONFIG_FILE):
with open(USER_CONFIG_FILE, 'r') as f:
return json.load(f)
return {}
def save_user_configs(configs):
with open(USER_CONFIG_FILE, 'w') as f:
json.dump(configs, f)
# Global dictionary to hold user configurations (chat_id and selected set)
user_configs = load_user_configs()
# ---------------------- FASTAPI SETUP ----------------------
app = FastAPI()
# ---------------------- BOT SETUP ----------------------
# Command to register a user and set default configuration
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
global user_configs
user_chat_id = str(update.effective_chat.id)
# If new user, set default configuration ("Set 1")
if user_chat_id not in user_configs:
user_configs[user_chat_id] = "Set 1"
save_user_configs(user_configs)
await update.message.reply_text("✅ Notifications will be sent here when a keyword is detected.")
# Function to send a notification using the bot.
async def send_notification(text: str, application, chat_id: int):
await application.bot.send_message(chat_id=chat_id, text=text)
# Command to display location options via inline keyboard
async def set_words(update: Update, context: ContextTypes.DEFAULT_TYPE):
keyboard = [
[InlineKeyboardButton("Set 1 Ірпінь", callback_data="Set 1")], # callback_data will be aviable in telegram.CallbackQuery.data.
[InlineKeyboardButton("Set 2 Троєщина", callback_data="Set 2")],
]
reply_markup = InlineKeyboardMarkup(keyboard)
await update.message.reply_text("🔹 Select the location you want to monitor:", reply_markup=reply_markup)
# Handler for inline keyboard button press to update user's location choice
async def select_word_set(update: Update, context: ContextTypes.DEFAULT_TYPE):
global user_configs
query = update.callback_query
await query.answer() # Acknowledge the button press
selected_set = query.data # The chosen set from the button
# Update this user's configuration in the JSON
user_chat_id = str(query.message.chat.id)
user_configs[user_chat_id] = selected_set
save_user_configs(user_configs)
await query.edit_message_text(text=f"✅ You have selected **{selected_set}**. The bot will now monitor for this area.")
# Helper function to notify all registered users
async def notify_all_users(message: str, application):
for user_id in user_configs:
try:
await send_notification(message, application, int(user_id))
except Exception as e:
print(f"Error sending notification to user {user_id}: {e}")
# ---------------------- WEBHOOK HANDLER ----------------------
@app.post("/webhook")
async def telegram_webhook(update_data: dict):
"""Handle incoming updates from Telegram."""
update = Update.de_json(update_data, application.bot)
await application.initialize() # Ensure the bot is initialized before processing
await application.process_update(update)
return {"ok": True}
# ---------------------- MAIN FUNCTION ----------------------
async def main():
global telethon_client, user_configs, application, bot
#Initialize the Telegram bot application
application = ApplicationBuilder().token(bot_token).build()
#Register handlers
application.add_handler(CommandHandler("start", start))
application.add_handler(CommandHandler("location", set_words))
application.add_handler(CallbackQueryHandler(select_word_set))
#Ensure no old webhook is active
async with application.bot as bot:
await bot.delete_webhook(drop_pending_updates=True)
await bot.set_webhook(url=WEBHOOK_URL)
print(f"✅ Webhook set to {WEBHOOK_URL}")
await application.initialize()
await application.start()
#Initialize and start the Telethon client
telethon_client = TelegramClient('session_name', api_id, api_hash)
await telethon_client.start()
print("✅ Telethon client started!")
#Notify all users that the bot is active again
await notify_all_users("✅ Bot is now active again.", application)
#Define the Telethon event handler
@telethon_client.on(events.NewMessage(chats=channels_to_monitor))
async def telethon_handler(event):
message_text = event.raw_text
channel_title = event.chat.title if event.chat and hasattr(event.chat, 'title') else "Unknown Channel"
# Iterate through each word set and check if the message matches any keyword.
for set_name, patterns in words_sets.items():
match_found = False
match_key = None
for key, pattern in patterns.items():
if pattern.search(message_text):
match_found = True
match_key = key
break
# If a match is found for this set, notify all users who have selected this set.
if match_found:
for user_id, user_set in user_configs.items():
if user_set == set_name:
notification_text = f"⚠️ Keyword '{match_key}' found in '{channel_title}':\n\n{message_text}"
try:
await send_notification(notification_text, application, int(user_id))
except Exception as e:
print(f"Error sending message to user {user_id}: {e}")
print("🚀 Bot and Telethon are running...")
#Run FastAPI server for webhook
config = uvicorn.Config(app, host="0.0.0.0", port=8000, log_level="info")
server = uvicorn.Server(config)
await server.serve()
await telethon_client.run_until_disconnected()
# ---------------------- ENTRY POINT ----------------------
if __name__ == '__main__':
logging.basicConfig(
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
level=logging.INFO
)
asyncio.run(main())