Fix logger system
Remove someuseless function
This commit is contained in:
parent
2d4d3f265e
commit
b719850b15
6
.dockerignore
Normal file
6
.dockerignore
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
/TODO.txt
|
||||||
|
/venv/
|
||||||
|
/.idea
|
||||||
|
/.env
|
||||||
|
/.gitignore
|
||||||
|
/.git
|
||||||
20
Dockerfile
20
Dockerfile
@ -1,9 +1,23 @@
|
|||||||
FROM python:3.11.9-slim
|
FROM python:3.11.9-slim
|
||||||
LABEL authors="UdoChudo"
|
LABEL authors="UdoChudo"
|
||||||
|
# Установим необходимые пакеты
|
||||||
|
RUN apt-get update && apt-get install -y \
|
||||||
|
build-essential \
|
||||||
|
libpq-dev \
|
||||||
|
gcc \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Установим рабочую директорию
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Скопируем файлы проекта
|
||||||
COPY . /app
|
COPY . /app
|
||||||
RUN pip install gunicorn
|
|
||||||
RUN pip install --no-cache-dir -r requests.txt
|
# Установим зависимости проекта
|
||||||
|
RUN pip install --no-cache-dir -r requirements.txt
|
||||||
|
|
||||||
|
# Откроем порт для нашего приложения
|
||||||
EXPOSE 5000
|
EXPOSE 5000
|
||||||
ENV FLASK_APP=telezab.py
|
ENV FLASK_APP=telezab.py
|
||||||
CMD ["gunicorn", "--bind", "0.0.0.0:5000", "telezab:app"]
|
# Запуск Gunicorn
|
||||||
|
CMD ["python3", "telezab.py"]
|
||||||
@ -1,23 +1,25 @@
|
|||||||
anyio==4.4.0
|
aiohttp==3.9.5
|
||||||
|
aiosignal==1.3.1
|
||||||
|
attrs==23.2.0
|
||||||
blinker==1.8.2
|
blinker==1.8.2
|
||||||
certifi==2024.6.2
|
certifi==2024.7.4
|
||||||
charset-normalizer==3.3.2
|
charset-normalizer==3.3.2
|
||||||
click==8.1.7
|
click==8.1.7
|
||||||
colorama==0.4.6
|
colorama==0.4.6
|
||||||
Flask==3.0.3
|
Flask==3.0.3
|
||||||
h11==0.14.0
|
frozenlist==1.4.1
|
||||||
httpcore==1.0.5
|
|
||||||
httpx==0.27.0
|
|
||||||
idna==3.7
|
idna==3.7
|
||||||
itsdangerous==2.2.0
|
itsdangerous==2.2.0
|
||||||
Jinja2==3.1.4
|
Jinja2==3.1.4
|
||||||
MarkupSafe==2.1.5
|
MarkupSafe==2.1.5
|
||||||
|
multidict==6.0.5
|
||||||
packaging==24.1
|
packaging==24.1
|
||||||
pyTelegramBotAPI==4.19.2
|
pika==1.3.2
|
||||||
|
pyTelegramBotAPI==4.21.0
|
||||||
python-dotenv==1.0.1
|
python-dotenv==1.0.1
|
||||||
python-telegram-bot==21.3
|
pyzabbix==1.3.1
|
||||||
requests==2.32.3
|
requests==2.32.3
|
||||||
sniffio==1.3.1
|
|
||||||
telebot==0.0.5
|
telebot==0.0.5
|
||||||
urllib3==2.2.2
|
urllib3==2.2.2
|
||||||
Werkzeug==3.0.3
|
Werkzeug==3.0.3
|
||||||
|
yarl==1.9.4
|
||||||
156
telezab.py
156
telezab.py
@ -14,7 +14,7 @@ import pika
|
|||||||
import json
|
import json
|
||||||
from concurrent.futures import ThreadPoolExecutor
|
from concurrent.futures import ThreadPoolExecutor
|
||||||
from pyzabbix import ZabbixAPI
|
from pyzabbix import ZabbixAPI
|
||||||
import requests # Добавлено для имитации POST запроса
|
import requests
|
||||||
|
|
||||||
# Load environment variables
|
# Load environment variables
|
||||||
load_dotenv()
|
load_dotenv()
|
||||||
@ -27,19 +27,72 @@ if DEBUG_LOGGING:
|
|||||||
else:
|
else:
|
||||||
log_level = 'INFO'
|
log_level = 'INFO'
|
||||||
|
|
||||||
|
# Чтение переменных окружения
|
||||||
|
ENABLE_CONSOLE_LOGGING = os.getenv('ENABLE_CONSOLE_LOGGING', 'true').lower() in ['true', '1', 'yes']
|
||||||
|
ENABLE_WSGI_LOGGING = os.getenv('ENABLE_WSGI_LOGGING', 'true').lower() in ['true', '1', 'yes']
|
||||||
|
ENABLE_FILE_LOGGING_CONSOLE = os.getenv('ENABLE_FILE_LOGGING_CONSOLE', 'false').lower() in ['true', '1', 'yes']
|
||||||
|
ENABLE_FILE_LOGGING_FLASK = os.getenv('ENABLE_FILE_LOGGING_FLASK', 'false').lower() in ['true', '1', 'yes']
|
||||||
|
|
||||||
|
# Определение путей для файлов логирования
|
||||||
|
LOG_PATH_CONSOLE = os.getenv('LOG_PATH_CONSOLE', 'logs/console.log')
|
||||||
|
LOG_PATH_FLASK = os.getenv('LOG_PATH_FLASK', 'logs/flask.log')
|
||||||
|
|
||||||
|
# Создание директории для логов, если она не существует
|
||||||
|
os.makedirs(os.path.dirname(LOG_PATH_CONSOLE), exist_ok=True)
|
||||||
|
os.makedirs(os.path.dirname(LOG_PATH_FLASK), exist_ok=True)
|
||||||
|
|
||||||
|
# Определение обработчиков на основе переменных окружения
|
||||||
|
handlers = {}
|
||||||
|
if ENABLE_CONSOLE_LOGGING:
|
||||||
|
handlers['console'] = {
|
||||||
|
'class': 'logging.StreamHandler',
|
||||||
|
'stream': 'ext://sys.stdout', # Вывод в консоль
|
||||||
|
'formatter': 'console',
|
||||||
|
}
|
||||||
|
if ENABLE_WSGI_LOGGING:
|
||||||
|
handlers['wsgi'] = {
|
||||||
|
'class': 'logging.StreamHandler',
|
||||||
|
'stream': 'ext://flask.logging.wsgi_errors_stream', # Логирование ошибок WSGI
|
||||||
|
'formatter': 'flask',
|
||||||
|
}
|
||||||
|
if ENABLE_FILE_LOGGING_CONSOLE:
|
||||||
|
handlers['file_console'] = {
|
||||||
|
'class': 'logging.FileHandler',
|
||||||
|
'filename': LOG_PATH_CONSOLE,
|
||||||
|
'formatter': 'console',
|
||||||
|
}
|
||||||
|
if ENABLE_FILE_LOGGING_FLASK:
|
||||||
|
handlers['file_flask'] = {
|
||||||
|
'class': 'logging.FileHandler',
|
||||||
|
'filename': LOG_PATH_FLASK,
|
||||||
|
'formatter': 'flask',
|
||||||
|
}
|
||||||
|
|
||||||
dictConfig({
|
dictConfig({
|
||||||
'version': 1,
|
'version': 1,
|
||||||
'formatters': {'default': {
|
'formatters': {
|
||||||
'format': '[%(asctime)s] %(levelname)s in %(module)s: %(message)s',
|
'default': {
|
||||||
}},
|
'format': '[%(asctime)s] %(levelname)s %(module)s: %(message)s [Location: %(extra)s]',
|
||||||
'handlers': {'wsgi': {
|
},
|
||||||
'class': 'logging.StreamHandler',
|
'console': {
|
||||||
'stream': 'ext://flask.logging.wsgi_errors_stream',
|
'format': '[Location: console] [%(asctime)s] %(levelname)s %(module)s: %(message)s ',
|
||||||
'formatter': 'default'
|
},
|
||||||
}},
|
'flask': {
|
||||||
|
'format': '[Location: flask] [%(asctime)s] %(levelname)s %(module)s: %(message)s ',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'handlers': handlers,
|
||||||
|
'loggers': {
|
||||||
|
'werkzeug': { # Flask логер
|
||||||
|
'level': 'INFO',
|
||||||
|
'handlers': ['console'] if ENABLE_CONSOLE_LOGGING else [],
|
||||||
|
'propagate': False,
|
||||||
|
'formatter': 'flask',
|
||||||
|
}
|
||||||
|
},
|
||||||
'root': {
|
'root': {
|
||||||
'level': log_level,
|
'level': 'INFO',
|
||||||
'handlers': ['wsgi']
|
'handlers': [handler for handler in handlers.keys()],
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -257,6 +310,11 @@ def cancel_settings_timer(chat_id):
|
|||||||
user_timers[chat_id].cancel()
|
user_timers[chat_id].cancel()
|
||||||
del user_timers[chat_id]
|
del user_timers[chat_id]
|
||||||
|
|
||||||
|
def reset_settings_timer(chat_id):
|
||||||
|
if chat_id in user_timers:
|
||||||
|
user_timers[chat_id].cancel()
|
||||||
|
start_settings_timer(chat_id)
|
||||||
|
|
||||||
def transition_to_notification_mode(chat_id):
|
def transition_to_notification_mode(chat_id):
|
||||||
set_user_state(chat_id, NOTIFICATION_MODE)
|
set_user_state(chat_id, NOTIFICATION_MODE)
|
||||||
bot.send_message(chat_id, "Вы были автоматически переведены в режим получения уведомлений.")
|
bot.send_message(chat_id, "Вы были автоматически переведены в режим получения уведомлений.")
|
||||||
@ -303,6 +361,7 @@ def handle_menu_selection(message):
|
|||||||
text = message.text.strip().lower()
|
text = message.text.strip().lower()
|
||||||
|
|
||||||
if user_states.get(chat_id, NOTIFICATION_MODE) == SETTINGS_MODE:
|
if user_states.get(chat_id, NOTIFICATION_MODE) == SETTINGS_MODE:
|
||||||
|
reset_settings_timer(chat_id)
|
||||||
handle_settings_menu_selection(message)
|
handle_settings_menu_selection(message)
|
||||||
else:
|
else:
|
||||||
if text == 'регистрация':
|
if text == 'регистрация':
|
||||||
@ -323,6 +382,8 @@ def handle_settings_menu_selection(message):
|
|||||||
chat_id = message.chat.id
|
chat_id = message.chat.id
|
||||||
text = message.text.strip().lower()
|
text = message.text.strip().lower()
|
||||||
|
|
||||||
|
reset_settings_timer(chat_id)
|
||||||
|
|
||||||
if text == 'подписаться':
|
if text == 'подписаться':
|
||||||
handle_subscribe(message)
|
handle_subscribe(message)
|
||||||
elif text == 'отписаться':
|
elif text == 'отписаться':
|
||||||
@ -535,9 +596,18 @@ def process_add_region(message):
|
|||||||
|
|
||||||
@bot.callback_query_handler(func=lambda call: call.data.startswith("replace_") or call.data.startswith("reactivate_"))
|
@bot.callback_query_handler(func=lambda call: call.data.startswith("replace_") or call.data.startswith("reactivate_"))
|
||||||
def handle_region_action(call):
|
def handle_region_action(call):
|
||||||
action, region_id, region_name = call.data.split("_", 2)
|
parts = call.data.split("_", 2)
|
||||||
|
action = parts[0]
|
||||||
|
region_id = parts[1]
|
||||||
|
region_name = parts[2] if len(parts) > 2 else None
|
||||||
chat_id = call.message.chat.id
|
chat_id = call.message.chat.id
|
||||||
|
|
||||||
|
if not region_name:
|
||||||
|
bot.send_message(chat_id, "Ошибка: Недостаточно данных для выполнения действия.")
|
||||||
|
bot.answer_callback_query(call.id) # Завершение обработки callback
|
||||||
|
bot.delete_message(chat_id, call.message.message_id)
|
||||||
|
return show_settings_menu(chat_id)
|
||||||
|
|
||||||
with db_lock:
|
with db_lock:
|
||||||
conn = sqlite3.connect('telezab.db')
|
conn = sqlite3.connect('telezab.db')
|
||||||
cursor = conn.cursor()
|
cursor = conn.cursor()
|
||||||
@ -556,6 +626,7 @@ def handle_region_action(call):
|
|||||||
conn.commit()
|
conn.commit()
|
||||||
conn.close()
|
conn.close()
|
||||||
|
|
||||||
|
bot.answer_callback_query(call.id) # Завершение обработки callback
|
||||||
show_settings_menu(chat_id)
|
show_settings_menu(chat_id)
|
||||||
|
|
||||||
def process_remove_region(message):
|
def process_remove_region(message):
|
||||||
@ -654,16 +725,19 @@ def handle_active_regions(message):
|
|||||||
bot.send_message(chat_id, f"Активные регионы:\n{regions_list}")
|
bot.send_message(chat_id, f"Активные регионы:\n{regions_list}")
|
||||||
show_settings_menu(chat_id)
|
show_settings_menu(chat_id)
|
||||||
|
|
||||||
|
|
||||||
# RabbitMQ configuration
|
# RabbitMQ configuration
|
||||||
RABBITMQ_HOST = os.getenv('RABBITMQ_HOST', 'localhost')
|
RABBITMQ_HOST = os.getenv('RABBITMQ_HOST', 'localhost')
|
||||||
RABBITMQ_QUEUE = 'telegram_notifications'
|
RABBITMQ_QUEUE = 'telegram_notifications'
|
||||||
|
|
||||||
|
|
||||||
def rabbitmq_connection():
|
def rabbitmq_connection():
|
||||||
connection = pika.BlockingConnection(pika.ConnectionParameters(RABBITMQ_HOST))
|
connection = pika.BlockingConnection(pika.ConnectionParameters(RABBITMQ_HOST))
|
||||||
channel = connection.channel()
|
channel = connection.channel()
|
||||||
channel.queue_declare(queue=RABBITMQ_QUEUE, durable=True)
|
channel.queue_declare(queue=RABBITMQ_QUEUE, durable=True)
|
||||||
return connection, channel
|
return connection, channel
|
||||||
|
|
||||||
|
|
||||||
def send_to_queue(message):
|
def send_to_queue(message):
|
||||||
connection, channel = rabbitmq_connection()
|
connection, channel = rabbitmq_connection()
|
||||||
channel.basic_publish(
|
channel.basic_publish(
|
||||||
@ -675,6 +749,7 @@ def send_to_queue(message):
|
|||||||
))
|
))
|
||||||
connection.close()
|
connection.close()
|
||||||
|
|
||||||
|
|
||||||
async def consume_from_queue():
|
async def consume_from_queue():
|
||||||
connection, channel = rabbitmq_connection()
|
connection, channel = rabbitmq_connection()
|
||||||
|
|
||||||
@ -693,6 +768,7 @@ async def consume_from_queue():
|
|||||||
|
|
||||||
connection.close()
|
connection.close()
|
||||||
|
|
||||||
|
|
||||||
async def send_message(chat_id, message, is_notification=False):
|
async def send_message(chat_id, message, is_notification=False):
|
||||||
try:
|
try:
|
||||||
if is_notification:
|
if is_notification:
|
||||||
@ -712,14 +788,17 @@ async def send_message(chat_id, message, is_notification=False):
|
|||||||
if is_notification:
|
if is_notification:
|
||||||
rate_limit_semaphore.release()
|
rate_limit_semaphore.release()
|
||||||
|
|
||||||
|
|
||||||
async def send_notification_message(chat_id, message):
|
async def send_notification_message(chat_id, message):
|
||||||
await send_message(chat_id, message, is_notification=True)
|
await send_message(chat_id, message, is_notification=True)
|
||||||
|
|
||||||
|
|
||||||
async def run_in_executor(func, *args):
|
async def run_in_executor(func, *args):
|
||||||
loop = asyncio.get_event_loop()
|
loop = asyncio.get_event_loop()
|
||||||
with ThreadPoolExecutor() as pool:
|
with ThreadPoolExecutor() as pool:
|
||||||
return await loop.run_in_executor(pool, func, *args)
|
return await loop.run_in_executor(pool, func, *args)
|
||||||
|
|
||||||
|
|
||||||
async def check_telegram_api():
|
async def check_telegram_api():
|
||||||
try:
|
try:
|
||||||
async with aiohttp.ClientSession() as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
@ -731,6 +810,7 @@ async def check_telegram_api():
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
app.logger.error(f"Error checking Telegram API: {e}")
|
app.logger.error(f"Error checking Telegram API: {e}")
|
||||||
|
|
||||||
|
|
||||||
@app.route('/webhook', methods=['POST'])
|
@app.route('/webhook', methods=['POST'])
|
||||||
def webhook():
|
def webhook():
|
||||||
data = request.get_json()
|
data = request.get_json()
|
||||||
@ -777,6 +857,7 @@ def webhook():
|
|||||||
|
|
||||||
return jsonify({"status": "success"}), 200
|
return jsonify({"status": "success"}), 200
|
||||||
|
|
||||||
|
|
||||||
def format_message(data):
|
def format_message(data):
|
||||||
return (f"Zabbix Alert\n"
|
return (f"Zabbix Alert\n"
|
||||||
f"Host: {data['host']}\n"
|
f"Host: {data['host']}\n"
|
||||||
@ -784,6 +865,7 @@ def format_message(data):
|
|||||||
f"Trigger: {data['trigger']}\n"
|
f"Trigger: {data['trigger']}\n"
|
||||||
f"Value: {data['value']}")
|
f"Value: {data['value']}")
|
||||||
|
|
||||||
|
|
||||||
# Handle active triggers
|
# Handle active triggers
|
||||||
def handle_active_triggers(message):
|
def handle_active_triggers(message):
|
||||||
chat_id = message.chat.id
|
chat_id = message.chat.id
|
||||||
@ -794,6 +876,7 @@ def handle_active_triggers(message):
|
|||||||
markup = create_region_markup(regions, start_index, regions_per_page)
|
markup = create_region_markup(regions, start_index, regions_per_page)
|
||||||
bot.send_message(chat_id, "По какому региону хотите получить активные проблемы:", reply_markup=markup)
|
bot.send_message(chat_id, "По какому региону хотите получить активные проблемы:", reply_markup=markup)
|
||||||
|
|
||||||
|
|
||||||
def create_region_markup(regions, start_index, regions_per_page):
|
def create_region_markup(regions, start_index, regions_per_page):
|
||||||
markup = telebot.types.InlineKeyboardMarkup()
|
markup = telebot.types.InlineKeyboardMarkup()
|
||||||
end_index = min(start_index + regions_per_page, len(regions))
|
end_index = min(start_index + regions_per_page, len(regions))
|
||||||
@ -812,18 +895,22 @@ def create_region_markup(regions, start_index, regions_per_page):
|
|||||||
markup.row(*row_buttons)
|
markup.row(*row_buttons)
|
||||||
return markup
|
return markup
|
||||||
|
|
||||||
|
|
||||||
@bot.callback_query_handler(func=lambda call: call.data.startswith("region_"))
|
@bot.callback_query_handler(func=lambda call: call.data.startswith("region_"))
|
||||||
def handle_region_selection(call):
|
def handle_region_selection(call):
|
||||||
region_id = call.data.split("_")[1]
|
region_id = call.data.split("_")[1]
|
||||||
chat_id = call.message.chat.id
|
chat_id = call.message.chat.id
|
||||||
|
|
||||||
# Mocking the Zabbix triggers for the given region_id
|
# Получение триггеров из реального Zabbix API
|
||||||
triggers = get_mocked_zabbix_triggers(region_id)
|
triggers = get_zabbix_triggers(region_id)
|
||||||
if not triggers:
|
if not triggers:
|
||||||
bot.send_message(chat_id, "Нет активных проблем по указанному региону за последние 24 часа.")
|
bot.send_message(chat_id, "Нет активных проблем по указанному региону за последние 24 часа.")
|
||||||
else:
|
else:
|
||||||
bot.send_message(chat_id, triggers, parse_mode="Markdown")
|
bot.send_message(chat_id, triggers, parse_mode="Markdown")
|
||||||
|
|
||||||
|
bot.answer_callback_query(call.id) # Завершение обработки callback
|
||||||
|
|
||||||
|
|
||||||
@bot.callback_query_handler(func=lambda call: call.data.startswith("prev_") or call.data.startswith("next_"))
|
@bot.callback_query_handler(func=lambda call: call.data.startswith("prev_") or call.data.startswith("next_"))
|
||||||
def handle_pagination(call):
|
def handle_pagination(call):
|
||||||
direction, index = call.data.split("_")
|
direction, index = call.data.split("_")
|
||||||
@ -839,22 +926,25 @@ def handle_pagination(call):
|
|||||||
markup = create_region_markup(regions, start_index, regions_per_page)
|
markup = create_region_markup(regions, start_index, regions_per_page)
|
||||||
bot.edit_message_reply_markup(call.message.chat.id, call.message.message_id, reply_markup=markup)
|
bot.edit_message_reply_markup(call.message.chat.id, call.message.message_id, reply_markup=markup)
|
||||||
|
|
||||||
def get_mocked_zabbix_triggers(region_id):
|
bot.answer_callback_query(call.id) # Завершение обработки callback
|
||||||
# Mocked Zabbix triggers
|
|
||||||
triggers = [
|
|
||||||
{
|
# Функция для получения активных триггеров из Zabbix API
|
||||||
"triggerid": "1",
|
def get_zabbix_triggers(region_id):
|
||||||
"description": f"Проблема {region_id}-1",
|
zapi = ZabbixAPI(ZABBIX_URL)
|
||||||
"priority": "4",
|
zapi.login(api_token=ZABBIX_API_TOKEN)
|
||||||
"hosts": [{"hostid": region_id, "name": f"Хост {region_id}-1"}]
|
|
||||||
},
|
# Получение триггеров уровня "Высокая" и "Авария" за последние 24 часа
|
||||||
{
|
triggers = zapi.trigger.get(
|
||||||
"triggerid": "2",
|
output=["triggerid", "description", "priority"],
|
||||||
"description": f"Проблема {region_id}-2",
|
selectHosts=["hostid", "name"],
|
||||||
"priority": "5",
|
filter={"priority": ["4", "5"], "value": "1"},
|
||||||
"hosts": [{"hostid": region_id, "name": f"Хост {region_id}-2"}]
|
search={"host": region_id},
|
||||||
}
|
only_true=1,
|
||||||
]
|
active=1,
|
||||||
|
withLastEventUnacknowledged=1,
|
||||||
|
limit=100
|
||||||
|
)
|
||||||
|
|
||||||
priority_map = {
|
priority_map = {
|
||||||
'4': 'Высокая',
|
'4': 'Высокая',
|
||||||
@ -872,6 +962,7 @@ def get_mocked_zabbix_triggers(region_id):
|
|||||||
|
|
||||||
return "\n\n---\n\n".join(trigger_messages)
|
return "\n\n---\n\n".join(trigger_messages)
|
||||||
|
|
||||||
|
|
||||||
# Test functions for admin
|
# Test functions for admin
|
||||||
def simulate_event(message):
|
def simulate_event(message):
|
||||||
chat_id = message.chat.id
|
chat_id = message.chat.id
|
||||||
@ -888,12 +979,13 @@ def simulate_event(message):
|
|||||||
app.logger.info(f"Response from webhook: {response.status_code} - {response.text}")
|
app.logger.info(f"Response from webhook: {response.status_code} - {response.text}")
|
||||||
bot.send_message(chat_id, f"Тестовое событие отправлено. Статус ответа: {response.status_code}")
|
bot.send_message(chat_id, f"Тестовое событие отправлено. Статус ответа: {response.status_code}")
|
||||||
|
|
||||||
|
|
||||||
def simulate_triggers(message):
|
def simulate_triggers(message):
|
||||||
chat_id = message.chat.id
|
chat_id = message.chat.id
|
||||||
regions = ["12", "19", "35", "40"]
|
regions = ["12", "19", "35", "40"]
|
||||||
trigger_messages = []
|
trigger_messages = []
|
||||||
for region_id in regions:
|
for region_id in regions:
|
||||||
triggers = get_mocked_zabbix_triggers(region_id)
|
triggers = get_zabbix_triggers(region_id)
|
||||||
if triggers:
|
if triggers:
|
||||||
trigger_messages.append(f"Регион {region_id}:\n{triggers}")
|
trigger_messages.append(f"Регион {region_id}:\n{triggers}")
|
||||||
|
|
||||||
@ -902,9 +994,11 @@ def simulate_triggers(message):
|
|||||||
else:
|
else:
|
||||||
bot.send_message(chat_id, "Нет активных проблем по указанным регионам за последние 24 часа.")
|
bot.send_message(chat_id, "Нет активных проблем по указанным регионам за последние 24 часа.")
|
||||||
|
|
||||||
|
|
||||||
def run_polling():
|
def run_polling():
|
||||||
bot.polling(none_stop=True, interval=0)
|
bot.polling(none_stop=True, interval=0)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
init_db()
|
init_db()
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user