Initial commit
This commit is contained in:
commit
f5ae48a7e9
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
/telezab.db
|
||||||
|
/.env
|
||||||
|
/.idea
|
||||||
23
requests.txt
Normal file
23
requests.txt
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
anyio==4.4.0
|
||||||
|
blinker==1.8.2
|
||||||
|
certifi==2024.6.2
|
||||||
|
charset-normalizer==3.3.2
|
||||||
|
click==8.1.7
|
||||||
|
colorama==0.4.6
|
||||||
|
Flask==3.0.3
|
||||||
|
h11==0.14.0
|
||||||
|
httpcore==1.0.5
|
||||||
|
httpx==0.27.0
|
||||||
|
idna==3.7
|
||||||
|
itsdangerous==2.2.0
|
||||||
|
Jinja2==3.1.4
|
||||||
|
MarkupSafe==2.1.5
|
||||||
|
packaging==24.1
|
||||||
|
pyTelegramBotAPI==4.19.2
|
||||||
|
python-dotenv==1.0.1
|
||||||
|
python-telegram-bot==21.3
|
||||||
|
requests==2.32.3
|
||||||
|
sniffio==1.3.1
|
||||||
|
telebot==0.0.5
|
||||||
|
urllib3==2.2.2
|
||||||
|
Werkzeug==3.0.3
|
||||||
512
telezab.py
Normal file
512
telezab.py
Normal file
@ -0,0 +1,512 @@
|
|||||||
|
from flask import Flask, request, jsonify
|
||||||
|
import telebot
|
||||||
|
from dotenv import load_dotenv
|
||||||
|
import os
|
||||||
|
import hashlib
|
||||||
|
import logging
|
||||||
|
from logging.config import dictConfig
|
||||||
|
from threading import Thread, Lock
|
||||||
|
import sqlite3
|
||||||
|
import time
|
||||||
|
import re
|
||||||
|
# Load environment variables
|
||||||
|
load_dotenv()
|
||||||
|
|
||||||
|
# Configure logging
|
||||||
|
DEBUG_LOGGING = os.getenv('DEBUG_LOGGING', 'false').lower() == 'true'
|
||||||
|
|
||||||
|
if DEBUG_LOGGING:
|
||||||
|
log_level = 'DEBUG'
|
||||||
|
else:
|
||||||
|
log_level = 'INFO'
|
||||||
|
|
||||||
|
dictConfig({
|
||||||
|
'version': 1,
|
||||||
|
'formatters': {'default': {
|
||||||
|
'format': '[%(asctime)s] %(levelname)s in %(module)s: %(message)s',
|
||||||
|
}},
|
||||||
|
'handlers': {'wsgi': {
|
||||||
|
'class': 'logging.StreamHandler',
|
||||||
|
'stream': 'ext://flask.logging.wsgi_errors_stream',
|
||||||
|
'formatter': 'default'
|
||||||
|
}},
|
||||||
|
'root': {
|
||||||
|
'level': log_level,
|
||||||
|
'handlers': ['wsgi']
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
app = Flask(__name__)
|
||||||
|
|
||||||
|
# Get the token from environment variables
|
||||||
|
TOKEN = os.getenv('TELEGRAM_TOKEN')
|
||||||
|
if not TOKEN:
|
||||||
|
raise ValueError("No TELEGRAM_TOKEN found in environment variables")
|
||||||
|
|
||||||
|
ADMIN_CHAT_IDS = os.getenv('ADMIN_CHAT_IDS', '').split(',')
|
||||||
|
|
||||||
|
bot = telebot.TeleBot(TOKEN)
|
||||||
|
|
||||||
|
# Lock for database operations
|
||||||
|
db_lock = Lock()
|
||||||
|
|
||||||
|
# Initialize SQLite database
|
||||||
|
def init_db():
|
||||||
|
with db_lock:
|
||||||
|
conn = sqlite3.connect('telezab.db')
|
||||||
|
cursor = conn.cursor()
|
||||||
|
|
||||||
|
# Create events table
|
||||||
|
cursor.execute('''CREATE TABLE IF NOT EXISTS events (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
hash TEXT UNIQUE,
|
||||||
|
data TEXT,
|
||||||
|
delivered BOOLEAN)''')
|
||||||
|
|
||||||
|
# Create subscriptions table with username
|
||||||
|
cursor.execute('''CREATE TABLE IF NOT EXISTS subscriptions (
|
||||||
|
chat_id INTEGER,
|
||||||
|
region_id TEXT,
|
||||||
|
username TEXT,
|
||||||
|
skip BOOLEAN DEFAULT FALSE,
|
||||||
|
UNIQUE(chat_id, region_id))''')
|
||||||
|
|
||||||
|
# Create whitelist table
|
||||||
|
cursor.execute('''CREATE TABLE IF NOT EXISTS whitelist (
|
||||||
|
chat_id INTEGER PRIMARY KEY)''')
|
||||||
|
|
||||||
|
# Create regions table
|
||||||
|
cursor.execute('''CREATE TABLE IF NOT EXISTS regions (
|
||||||
|
region_id TEXT PRIMARY KEY,
|
||||||
|
region_name TEXT)''')
|
||||||
|
|
||||||
|
# Insert sample regions
|
||||||
|
cursor.execute('''INSERT OR IGNORE INTO regions (region_id, region_name) VALUES
|
||||||
|
('01', 'Адыгея'),
|
||||||
|
('02', 'Башкортостан (Уфа)'),
|
||||||
|
('04', 'Алтай'),
|
||||||
|
('19', 'Республика Хакасия')''')
|
||||||
|
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
# Hash the incoming data
|
||||||
|
def hash_data(data):
|
||||||
|
return hashlib.sha256(str(data).encode('utf-8')).hexdigest()
|
||||||
|
|
||||||
|
# Check if user is in whitelist
|
||||||
|
def is_whitelisted(chat_id):
|
||||||
|
with db_lock:
|
||||||
|
conn = sqlite3.connect('telezab.db')
|
||||||
|
cursor = conn.cursor()
|
||||||
|
query = 'SELECT COUNT(*) FROM whitelist WHERE chat_id = ?'
|
||||||
|
app.logger.debug(f"Executing query: {query} with chat_id={chat_id}")
|
||||||
|
cursor.execute(query, (chat_id,))
|
||||||
|
count = cursor.fetchone()[0]
|
||||||
|
conn.close()
|
||||||
|
return count > 0
|
||||||
|
|
||||||
|
# Add user to whitelist
|
||||||
|
def add_to_whitelist(chat_id):
|
||||||
|
with db_lock:
|
||||||
|
conn = sqlite3.connect('telezab.db')
|
||||||
|
cursor = conn.cursor()
|
||||||
|
query = 'INSERT OR IGNORE INTO whitelist (chat_id) VALUES (?)'
|
||||||
|
app.logger.debug(f"Executing query: {query} with chat_id={chat_id}")
|
||||||
|
cursor.execute(query, (chat_id,))
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
# Remove user from whitelist
|
||||||
|
def remove_from_whitelist(chat_id):
|
||||||
|
with db_lock:
|
||||||
|
conn = sqlite3.connect('telezab.db')
|
||||||
|
cursor = conn.cursor()
|
||||||
|
query = 'DELETE FROM whitelist WHERE chat_id = ?'
|
||||||
|
app.logger.debug(f"Executing query: {query} with chat_id={chat_id}")
|
||||||
|
cursor.execute(query, (chat_id,))
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
# Get list of regions
|
||||||
|
def get_regions():
|
||||||
|
with db_lock:
|
||||||
|
conn = sqlite3.connect('telezab.db')
|
||||||
|
cursor = conn.cursor()
|
||||||
|
cursor.execute('SELECT region_id, region_name FROM regions')
|
||||||
|
regions = cursor.fetchall()
|
||||||
|
conn.close()
|
||||||
|
return regions
|
||||||
|
|
||||||
|
# Get list of regions a user is subscribed to
|
||||||
|
def get_user_subscribed_regions(chat_id):
|
||||||
|
with db_lock:
|
||||||
|
conn = sqlite3.connect('telezab.db')
|
||||||
|
cursor = conn.cursor()
|
||||||
|
cursor.execute('''
|
||||||
|
SELECT regions.region_id, regions.region_name
|
||||||
|
FROM subscriptions
|
||||||
|
JOIN regions ON subscriptions.region_id = regions.region_id
|
||||||
|
WHERE subscriptions.chat_id = ? AND subscriptions.skip = FALSE
|
||||||
|
''', (chat_id,))
|
||||||
|
regions = cursor.fetchall()
|
||||||
|
conn.close()
|
||||||
|
return regions
|
||||||
|
|
||||||
|
# Format regions list
|
||||||
|
def format_regions_list(regions):
|
||||||
|
return '\n'.join([f"{region_id} - {region_name}" for region_id, region_name in regions])
|
||||||
|
|
||||||
|
# Handle /start command
|
||||||
|
@bot.message_handler(commands=['start'])
|
||||||
|
def handle_start(message):
|
||||||
|
chat_id = message.chat.id
|
||||||
|
if not is_whitelisted(chat_id):
|
||||||
|
bot.send_message(chat_id, "Вы не авторизованы для использования этого бота.")
|
||||||
|
app.logger.info(f"Unauthorized access attempt by {chat_id}")
|
||||||
|
return
|
||||||
|
|
||||||
|
username = message.from_user.username
|
||||||
|
if username:
|
||||||
|
username = f"@{username}"
|
||||||
|
else:
|
||||||
|
username = "N/A"
|
||||||
|
|
||||||
|
bot.send_message(chat_id, "Выполните комманду /register для начала работы")
|
||||||
|
app.logger.info(f"User {chat_id} ({username}) started receiving alerts.")
|
||||||
|
|
||||||
|
# Handle /stop command to stop receiving messages
|
||||||
|
@bot.message_handler(commands=['stop'])
|
||||||
|
def handle_stop(message):
|
||||||
|
chat_id = message.chat.id
|
||||||
|
if not is_whitelisted(chat_id):
|
||||||
|
bot.send_message(chat_id, "Вы не авторизованы для использования этого бота.")
|
||||||
|
app.logger.info(f"Unauthorized access attempt by {chat_id}")
|
||||||
|
return
|
||||||
|
|
||||||
|
with db_lock:
|
||||||
|
conn = sqlite3.connect('telezab.db')
|
||||||
|
cursor = conn.cursor()
|
||||||
|
query = 'DELETE FROM subscriptions WHERE chat_id = ?'
|
||||||
|
app.logger.debug(f"Executing query: {query} with chat_id={chat_id}")
|
||||||
|
cursor.execute(query, (chat_id,))
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
bot.send_message(chat_id, "Вы перестали получать события Zabbix'а :c")
|
||||||
|
app.logger.info(f"User {chat_id} stopped receiving alerts.")
|
||||||
|
|
||||||
|
|
||||||
|
# Handle /subscribe command to subscribe to a region
|
||||||
|
@bot.message_handler(commands=['subscribe'])
|
||||||
|
def handle_subscribe(message):
|
||||||
|
chat_id = message.chat.id
|
||||||
|
if not is_whitelisted(chat_id):
|
||||||
|
bot.send_message(chat_id, "Вы не авторизованы для использования этого бота.")
|
||||||
|
app.logger.info(f"Unauthorized access attempt by {chat_id}")
|
||||||
|
return
|
||||||
|
|
||||||
|
username = message.from_user.username
|
||||||
|
if username:
|
||||||
|
username = f"@{username}"
|
||||||
|
else:
|
||||||
|
username = "N/A"
|
||||||
|
|
||||||
|
regions_list = format_regions_list(get_regions())
|
||||||
|
bot.send_message(chat_id, f"Отправьте номер или номера регионов, на которые хотите подписаться (через запятую):\n{regions_list}\n\nНапишите 'отмена' для отмены.")
|
||||||
|
bot.register_next_step_handler(message, process_subscription, chat_id, username)
|
||||||
|
|
||||||
|
def process_subscription(message, chat_id, username):
|
||||||
|
if message.text.lower() == 'отмена':
|
||||||
|
bot.send_message(chat_id, "Действие отменено.")
|
||||||
|
return
|
||||||
|
|
||||||
|
region_ids = message.text.split(',')
|
||||||
|
# Проверка формата ввода
|
||||||
|
if not all(re.match(r'^\d+$', region_id.strip()) for region_id in region_ids):
|
||||||
|
bot.send_message(chat_id, "Неверный формат команды. Пожалуйста, введите только цифры, разделенные запятыми.")
|
||||||
|
bot.register_next_step_handler(message, process_subscription, chat_id, username)
|
||||||
|
return
|
||||||
|
|
||||||
|
invalid_regions = []
|
||||||
|
already_subscribed = []
|
||||||
|
with db_lock:
|
||||||
|
conn = sqlite3.connect('telezab.db')
|
||||||
|
cursor = conn.cursor()
|
||||||
|
for region_id in region_ids:
|
||||||
|
region_id = region_id.strip()
|
||||||
|
# Проверка существования региона в таблице regions
|
||||||
|
cursor.execute('SELECT COUNT(*) FROM regions WHERE region_id = ?', (region_id,))
|
||||||
|
if cursor.fetchone()[0] == 0:
|
||||||
|
invalid_regions.append(region_id)
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Проверка существующей подписки
|
||||||
|
cursor.execute('SELECT COUNT(*) FROM subscriptions WHERE chat_id = ? AND region_id = ?', (chat_id, region_id))
|
||||||
|
if cursor.fetchone()[0] > 0:
|
||||||
|
already_subscribed.append(region_id)
|
||||||
|
continue
|
||||||
|
|
||||||
|
query = 'INSERT OR IGNORE INTO subscriptions (chat_id, region_id, username) VALUES (?, ?, ?)'
|
||||||
|
app.logger.debug(f"Executing query: {query} with chat_id={chat_id}, region_id={region_id}, username={username}")
|
||||||
|
cursor.execute(query, (chat_id, region_id, username))
|
||||||
|
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
if invalid_regions:
|
||||||
|
bot.send_message(chat_id, f"Следующие регионы не существуют: {', '.join(invalid_regions)}. Пожалуйста, проверьте и введите снова.")
|
||||||
|
bot.register_next_step_handler(message, process_subscription, chat_id, username)
|
||||||
|
return
|
||||||
|
|
||||||
|
if already_subscribed:
|
||||||
|
bot.send_message(chat_id, f"Вы уже подписаны на следующие регионы: {', '.join(already_subscribed)}.")
|
||||||
|
if len(already_subscribed) == len(region_ids):
|
||||||
|
bot.register_next_step_handler(message, process_subscription, chat_id, username)
|
||||||
|
return
|
||||||
|
|
||||||
|
subscribed_regions = [region_id for region_id in region_ids if region_id not in invalid_regions and region_id not in already_subscribed]
|
||||||
|
if subscribed_regions:
|
||||||
|
bot.send_message(chat_id, f"Подписка на регионы: {', '.join(subscribed_regions)} оформлена.")
|
||||||
|
app.logger.info(f"User {chat_id} ({username}) subscribed to regions: {', '.join(subscribed_regions)}.")
|
||||||
|
else:
|
||||||
|
bot.send_message(chat_id, "Не удалось оформить подписку на указанные регионы. Пожалуйста, попробуйте снова.")
|
||||||
|
bot.register_next_step_handler(message, process_subscription, chat_id, username)
|
||||||
|
|
||||||
|
|
||||||
|
# Handle /unsubscribe command to unsubscribe from a region
|
||||||
|
@bot.message_handler(commands=['unsubscribe'])
|
||||||
|
def handle_unsubscribe(message):
|
||||||
|
chat_id = message.chat.id
|
||||||
|
if not is_whitelisted(chat_id):
|
||||||
|
bot.send_message(chat_id, "Вы не авторизованы для использования этого бота.")
|
||||||
|
app.logger.info(f"Unauthorized access attempt by {chat_id}")
|
||||||
|
return
|
||||||
|
|
||||||
|
user_regions = get_user_subscribed_regions(chat_id)
|
||||||
|
if not user_regions:
|
||||||
|
bot.send_message(chat_id, "Вы ещё не подписались ни на один регион для получения событий")
|
||||||
|
else:
|
||||||
|
regions_list = format_regions_list(user_regions)
|
||||||
|
bot.send_message(chat_id, f"Отправьте номер или номера регионов, от которых хотите отписаться (через запятую):\n{regions_list}\n\nНапишите 'отмена' для прекращения процедуры подписки.")
|
||||||
|
bot.register_next_step_handler(message, process_unsubscription, chat_id)
|
||||||
|
|
||||||
|
def process_unsubscription(message, chat_id):
|
||||||
|
if message.text.lower() == 'отмена':
|
||||||
|
bot.send_message(chat_id, "Действие отменено.")
|
||||||
|
return
|
||||||
|
|
||||||
|
region_ids = message.text.split(',')
|
||||||
|
# Проверка формата ввода
|
||||||
|
if not all(re.match(r'^\d+$', region_id.strip()) for region_id in region_ids):
|
||||||
|
bot.send_message(chat_id, "Неверный формат команды. Пожалуйста, введите только цифры, разделенные запятыми.")
|
||||||
|
bot.register_next_step_handler(message, process_unsubscription, chat_id)
|
||||||
|
return
|
||||||
|
|
||||||
|
invalid_unsubscriptions = []
|
||||||
|
valid_unsubscriptions = []
|
||||||
|
with db_lock:
|
||||||
|
conn = sqlite3.connect('telezab.db')
|
||||||
|
cursor = conn.cursor()
|
||||||
|
for region_id in region_ids:
|
||||||
|
region_id = region_id.strip()
|
||||||
|
# Проверка существования подписки
|
||||||
|
cursor.execute('SELECT COUNT(*) FROM subscriptions WHERE chat_id = ? AND region_id = ?', (chat_id, region_id))
|
||||||
|
if cursor.fetchone()[0] == 0:
|
||||||
|
invalid_unsubscriptions.append(region_id)
|
||||||
|
else:
|
||||||
|
valid_unsubscriptions.append(region_id)
|
||||||
|
query = 'DELETE FROM subscriptions WHERE chat_id = ? AND region_id = ?'
|
||||||
|
app.logger.debug(f"Executing query: {query} with chat_id={chat_id}, region_id={region_id}")
|
||||||
|
cursor.execute(query, (chat_id, region_id))
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
if invalid_unsubscriptions:
|
||||||
|
bot.send_message(chat_id, f"Вы не подписаны на следующие регионы: {', '.join(invalid_unsubscriptions)}.")
|
||||||
|
if valid_unsubscriptions:
|
||||||
|
bot.send_message(chat_id, f"Отписка от регионов: {', '.join(valid_unsubscriptions)} выполнена.")
|
||||||
|
app.logger.info(f"User {chat_id} unsubscribed from regions: {', '.join(valid_unsubscriptions)}.")
|
||||||
|
if not invalid_unsubscriptions and not valid_unsubscriptions:
|
||||||
|
bot.send_message(chat_id, "Не удалось выполнить отписку. Пожалуйста, попробуйте снова.")
|
||||||
|
bot.register_next_step_handler(message, process_unsubscription, chat_id)
|
||||||
|
|
||||||
|
|
||||||
|
# Handle /help command to provide instructions
|
||||||
|
@bot.message_handler(commands=['help'])
|
||||||
|
def handle_help(message):
|
||||||
|
help_text = (
|
||||||
|
"/subscribe - Подписаться на рассылку событий по региону.\n"
|
||||||
|
"/unsubscribe - Отписаться от рассылки событий по региону.\n"
|
||||||
|
"/register - Запросить регистрацию в боте"
|
||||||
|
)
|
||||||
|
bot.send_message(message.chat.id, help_text)
|
||||||
|
|
||||||
|
# Handle /register command for new user registration
|
||||||
|
@bot.message_handler(commands=['register'])
|
||||||
|
def handle_register(message):
|
||||||
|
chat_id = message.chat.id
|
||||||
|
username = message.from_user.username
|
||||||
|
if username:
|
||||||
|
username = f"@{username}"
|
||||||
|
else:
|
||||||
|
username = "N/A"
|
||||||
|
|
||||||
|
bot.send_message(chat_id, f"Your chat ID is {chat_id} and your username is {username}. Requesting admin approval...")
|
||||||
|
|
||||||
|
for admin_chat_id in ADMIN_CHAT_IDS:
|
||||||
|
bot.send_message(
|
||||||
|
admin_chat_id,
|
||||||
|
f"User {username} ({chat_id}) is requesting to register.\n"
|
||||||
|
f"Do you approve this action?\n"
|
||||||
|
f"/add_whitelist {chat_id}"
|
||||||
|
)
|
||||||
|
app.logger.info(f"User {chat_id} ({username}) requested registration.")
|
||||||
|
|
||||||
|
# Handle /add_whitelist command to add a user to the whitelist (Admin only)
|
||||||
|
@bot.message_handler(commands=['add_whitelist'])
|
||||||
|
def handle_add_whitelist(message):
|
||||||
|
chat_id = message.chat.id
|
||||||
|
if str(chat_id) not in ADMIN_CHAT_IDS:
|
||||||
|
bot.send_message(chat_id, "Вы не авторизованы для использования этой команды.")
|
||||||
|
app.logger.info(f"Unauthorized admin command attempt by {chat_id}")
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
new_chat_id = int(message.text.split()[1])
|
||||||
|
add_to_whitelist(new_chat_id)
|
||||||
|
bot.send_message(chat_id, f"Chat ID {new_chat_id} added to the whitelist.")
|
||||||
|
app.logger.info(f"Admin {chat_id} added {new_chat_id} to the whitelist.")
|
||||||
|
except (IndexError, ValueError):
|
||||||
|
bot.send_message(chat_id, "Invalid command format. Use /add_whitelist <chat_id>")
|
||||||
|
|
||||||
|
# Handle /remove_whitelist command to remove a user from the whitelist (Admin only)
|
||||||
|
@bot.message_handler(commands=['remove_whitelist'])
|
||||||
|
def handle_remove_whitelist(message):
|
||||||
|
chat_id = message.chat.id
|
||||||
|
if str(chat_id) not in ADMIN_CHAT_IDS:
|
||||||
|
bot.send_message(chat_id, "Вы не авторизованы для использования этой команды.")
|
||||||
|
app.logger.info(f"Unauthorized admin command attempt by {chat_id}")
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
remove_chat_id = int(message.text.split()[1])
|
||||||
|
remove_from_whitelist(remove_chat_id)
|
||||||
|
bot.send_message(chat_id, f"Chat ID {remove_chat_id} removed from the whitelist.")
|
||||||
|
app.logger.info(f"Admin {chat_id} removed {remove_chat_id} from the whitelist.")
|
||||||
|
except (IndexError, ValueError):
|
||||||
|
bot.send_message(chat_id, "Invalid command format. Use /remove_whitelist <chat_id>")
|
||||||
|
|
||||||
|
# Handle /add_region command to add a new region (Admin only)
|
||||||
|
@bot.message_handler(commands=['add_region'])
|
||||||
|
def handle_add_region(message):
|
||||||
|
chat_id = message.chat.id
|
||||||
|
if str(chat_id) not in ADMIN_CHAT_IDS:
|
||||||
|
bot.send_message(chat_id, "Вы не авторизованы для использования этой команды.")
|
||||||
|
app.logger.info(f"Unauthorized admin command attempt by {chat_id}")
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
region_id, region_name = message.text.split()[1], ' '.join(message.text.split()[2:])
|
||||||
|
with db_lock:
|
||||||
|
conn = sqlite3.connect('telezab.db')
|
||||||
|
cursor = conn.cursor()
|
||||||
|
query = 'INSERT OR IGNORE INTO regions (region_id, region_name) VALUES (?, ?)'
|
||||||
|
app.logger.debug(f"Executing query: {query} with region_id={region_id}, region_name={region_name}")
|
||||||
|
cursor.execute(query, (region_id, region_name))
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
bot.send_message(chat_id, f"Region {region_id} - {region_name} added.")
|
||||||
|
app.logger.info(f"Admin {chat_id} added region {region_id} - {region_name}.")
|
||||||
|
except (IndexError, ValueError):
|
||||||
|
bot.send_message(chat_id, "Invalid command format. Use /add_region <region_id> <region_name>")
|
||||||
|
|
||||||
|
# Handle /remove_region command to remove a region (Admin only)
|
||||||
|
@bot.message_handler(commands=['remove_region'])
|
||||||
|
def handle_remove_region(message):
|
||||||
|
chat_id = message.chat.id
|
||||||
|
if str(chat_id) not in ADMIN_CHAT_IDS:
|
||||||
|
bot.send_message(chat_id, "Вы не авторизованы для использования этой команды.")
|
||||||
|
app.logger.info(f"Unauthorized admin command attempt by {chat_id}")
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
region_id = message.text.split()[1]
|
||||||
|
with db_lock:
|
||||||
|
conn = sqlite3.connect('telezab.db')
|
||||||
|
cursor = conn.cursor()
|
||||||
|
query = 'DELETE FROM regions WHERE region_id = ?'
|
||||||
|
app.logger.debug(f"Executing query: {query} with region_id={region_id}")
|
||||||
|
cursor.execute(query, (region_id,))
|
||||||
|
query = 'UPDATE subscriptions SET skip = TRUE WHERE region_id = ?'
|
||||||
|
app.logger.debug(f"Executing query: {query} with region_id={region_id}")
|
||||||
|
cursor.execute(query, (region_id,))
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
bot.send_message(chat_id, f"Region {region_id} removed and all subscriptions updated.")
|
||||||
|
app.logger.info(f"Admin {chat_id} removed region {region_id} and updated subscriptions.")
|
||||||
|
except IndexError:
|
||||||
|
bot.send_message(chat_id, "Invalid command format. Use /remove_region <region_id>")
|
||||||
|
|
||||||
|
@app.route('/webhook', methods=['POST'])
|
||||||
|
def webhook():
|
||||||
|
data = request.get_json()
|
||||||
|
app.logger.info(f"Received data: {data}")
|
||||||
|
|
||||||
|
event_hash = hash_data(data)
|
||||||
|
|
||||||
|
with db_lock:
|
||||||
|
conn = sqlite3.connect('telezab.db')
|
||||||
|
cursor = conn.cursor()
|
||||||
|
cursor.execute('SELECT COUNT(*) FROM events')
|
||||||
|
count = cursor.fetchone()[0]
|
||||||
|
|
||||||
|
if count >= 200:
|
||||||
|
query = 'DELETE FROM events WHERE id = (SELECT MIN(id) FROM events)'
|
||||||
|
app.logger.debug(f"Executing query: {query}")
|
||||||
|
cursor.execute(query)
|
||||||
|
|
||||||
|
query = 'INSERT OR IGNORE INTO events (hash, data, delivered) VALUES (?, ?, ?)'
|
||||||
|
app.logger.debug(f"Executing query: {query} with hash={event_hash}, data={data}, delivered={False}")
|
||||||
|
cursor.execute(query, (event_hash, str(data), False))
|
||||||
|
|
||||||
|
# Fetch chat_ids to send the alert
|
||||||
|
region_id = data.get("region")
|
||||||
|
query = 'SELECT chat_id, username FROM subscriptions WHERE region_id = ? AND skip = FALSE'
|
||||||
|
app.logger.debug(f"Executing query: {query} with region_id={region_id}")
|
||||||
|
cursor.execute(query, (region_id,))
|
||||||
|
results = cursor.fetchall()
|
||||||
|
|
||||||
|
message = format_message(data)
|
||||||
|
for chat_id, username in results:
|
||||||
|
try:
|
||||||
|
app.logger.debug(f"Sending message: {message} to chat_id={chat_id}, username={username}")
|
||||||
|
bot.send_message(chat_id, message)
|
||||||
|
app.logger.info(f"Sent alert to {chat_id} ({username}) for region {region_id}")
|
||||||
|
except telebot.apihelper.ApiTelegramException as e:
|
||||||
|
app.logger.error(f"Failed to send message to {chat_id} ({username}): {e}")
|
||||||
|
except Exception as e:
|
||||||
|
app.logger.error(f"Error sending message to {chat_id} ({username}): {e}")
|
||||||
|
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
return jsonify({"status": "success"}), 200
|
||||||
|
|
||||||
|
def format_message(data):
|
||||||
|
return (f"Zabbix Alert\n"
|
||||||
|
f"Host: {data['host']}\n"
|
||||||
|
f"Item: {data['item']}\n"
|
||||||
|
f"Trigger: {data['trigger']}\n"
|
||||||
|
f"Value: {data['value']}")
|
||||||
|
|
||||||
|
def run_polling():
|
||||||
|
bot.polling(none_stop=True, interval=0)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
init_db()
|
||||||
|
|
||||||
|
# Start Flask app in a separate thread
|
||||||
|
Thread(target=app.run, kwargs={'port': 5000, 'debug': False}, daemon=True).start()
|
||||||
|
|
||||||
|
# Start bot polling
|
||||||
|
run_polling()
|
||||||
Loading…
x
Reference in New Issue
Block a user