add bot
This commit is contained in:
parent
96929c25bc
commit
3ec90da1e0
|
@ -9,7 +9,7 @@ services:
|
||||||
command: [redis-server, --protected-mode yes, --port 6379, --requirepass, P@ssw0rd!]
|
command: [redis-server, --protected-mode yes, --port 6379, --requirepass, P@ssw0rd!]
|
||||||
|
|
||||||
tg-bot:
|
tg-bot:
|
||||||
image: git.sm8255082.ru/osnova/zbx-tg-bot:1.0.0
|
image: git.sm8255082.ru/osnova/zbx-tg-bot:1.1.0
|
||||||
restart: always
|
restart: always
|
||||||
depends_on:
|
depends_on:
|
||||||
- redis
|
- redis
|
||||||
|
|
22
main.py
22
main.py
|
@ -1,7 +1,6 @@
|
||||||
import logging as log
|
import logging as log
|
||||||
from zabbix import get_active_problems
|
from zabbix import get_active_problems
|
||||||
from config import conf, icon_dict
|
from config import conf, icon_dict
|
||||||
from time import sleep
|
|
||||||
from redis_db import (
|
from redis_db import (
|
||||||
get_all_keys,
|
get_all_keys,
|
||||||
get_value,
|
get_value,
|
||||||
|
@ -9,10 +8,10 @@ from redis_db import (
|
||||||
del_value,
|
del_value,
|
||||||
)
|
)
|
||||||
import asyncio
|
import asyncio
|
||||||
from telegram import del_message, send_message
|
from telegram import del_message, send_message, start_bot
|
||||||
|
|
||||||
|
|
||||||
async def main_loop():
|
async def dashboard():
|
||||||
active_alerts = get_active_problems()
|
active_alerts = get_active_problems()
|
||||||
if active_alerts is None:
|
if active_alerts is None:
|
||||||
return
|
return
|
||||||
|
@ -38,7 +37,7 @@ async def main_loop():
|
||||||
+ f"{active_alerts[new_alert]['host']}\n"
|
+ f"{active_alerts[new_alert]['host']}\n"
|
||||||
+ f"{active_alerts[new_alert]['name']}"
|
+ f"{active_alerts[new_alert]['name']}"
|
||||||
)
|
)
|
||||||
msg_id = await send_message(message)
|
msg_id = await send_message(message=message, event_id=new_alert)
|
||||||
if msg_id["status"] == 200:
|
if msg_id["status"] == 200:
|
||||||
await set_value(key=new_alert, value=msg_id["msg_id"])
|
await set_value(key=new_alert, value=msg_id["msg_id"])
|
||||||
|
|
||||||
|
@ -53,12 +52,21 @@ async def main_loop():
|
||||||
await del_value(closed_alert)
|
await del_value(closed_alert)
|
||||||
|
|
||||||
|
|
||||||
|
async def dashboard_loop():
|
||||||
|
log.info("Dashboard loop started")
|
||||||
|
while True:
|
||||||
|
await dashboard()
|
||||||
|
await asyncio.sleep(conf.zabbix.upd_interval)
|
||||||
|
|
||||||
|
|
||||||
|
async def main():
|
||||||
|
await asyncio.gather(dashboard_loop(), start_bot())
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
log.info("Starting app")
|
log.info("Starting app")
|
||||||
try:
|
try:
|
||||||
while True:
|
asyncio.run(main())
|
||||||
asyncio.run(main_loop())
|
|
||||||
sleep(conf.zabbix.upd_interval)
|
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
log.info("Manual app stopped")
|
log.info("Manual app stopped")
|
||||||
log.info("App stopped")
|
log.info("App stopped")
|
||||||
|
|
|
@ -2,8 +2,10 @@ from .message import (
|
||||||
send_message,
|
send_message,
|
||||||
del_message,
|
del_message,
|
||||||
)
|
)
|
||||||
|
from .bot import start_bot
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"send_message",
|
"send_message",
|
||||||
"del_message",
|
"del_message",
|
||||||
|
"start_bot",
|
||||||
]
|
]
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
from config import conf
|
||||||
|
from aiogram import Bot, Dispatcher, types
|
||||||
|
from aiogram.fsm.storage.memory import MemoryStorage
|
||||||
|
from aiogram import F
|
||||||
|
from zabbix import event_acknowledge, event_close
|
||||||
|
import logging as log
|
||||||
|
|
||||||
|
tg_bot = Bot(token=conf.tgbot.token)
|
||||||
|
storage = MemoryStorage()
|
||||||
|
dp = Dispatcher(storage=storage)
|
||||||
|
|
||||||
|
|
||||||
|
@dp.callback_query(F.data.startswith("h"))
|
||||||
|
async def handle_mute_1h(callback_query: types.CallbackQuery):
|
||||||
|
|
||||||
|
if event_acknowledge(int(callback_query.data[1:]), 1):
|
||||||
|
new_text = (
|
||||||
|
callback_query.message.text
|
||||||
|
+ "\n"
|
||||||
|
+ callback_query.from_user.username
|
||||||
|
+ " Замьютил на час"
|
||||||
|
)
|
||||||
|
await callback_query.message.edit_text(new_text)
|
||||||
|
|
||||||
|
|
||||||
|
@dp.callback_query(F.data.startswith("d"))
|
||||||
|
async def handle_mute_1d(callback_query: types.CallbackQuery):
|
||||||
|
if event_acknowledge(int(callback_query.data[1:]), 24):
|
||||||
|
new_text = (
|
||||||
|
callback_query.message.text
|
||||||
|
+ "\n"
|
||||||
|
+ callback_query.from_user.username
|
||||||
|
+ " Замьютил на сутки"
|
||||||
|
)
|
||||||
|
await callback_query.message.edit_text(new_text)
|
||||||
|
|
||||||
|
|
||||||
|
@dp.callback_query(F.data.startswith("c"))
|
||||||
|
async def handle_close(callback_query: types.CallbackQuery):
|
||||||
|
if event_close(int(callback_query.data[1:])):
|
||||||
|
new_text = (
|
||||||
|
callback_query.message.text
|
||||||
|
+ "\n"
|
||||||
|
+ callback_query.from_user.username
|
||||||
|
+ " Закрыл"
|
||||||
|
)
|
||||||
|
await callback_query.message.edit_text(new_text)
|
||||||
|
|
||||||
|
|
||||||
|
async def start_bot():
|
||||||
|
log.info("Telegram bot loop started")
|
||||||
|
await dp.start_polling(tg_bot)
|
|
@ -2,16 +2,25 @@ import logging as log
|
||||||
|
|
||||||
import aiohttp
|
import aiohttp
|
||||||
from config import conf
|
from config import conf
|
||||||
|
import json
|
||||||
|
|
||||||
|
|
||||||
async def send_message(
|
async def send_message(message: str, event_id: int) -> dict:
|
||||||
message: str,
|
|
||||||
) -> dict:
|
|
||||||
url = f"https://api.telegram.org/bot{conf.tgbot.token}/sendMessage"
|
url = f"https://api.telegram.org/bot{conf.tgbot.token}/sendMessage"
|
||||||
|
inline_buttons = [
|
||||||
|
[
|
||||||
|
{"text": "🛠 на 1 час", "callback_data": f"h{event_id}"},
|
||||||
|
{"text": "🛠 на 1 день", "callback_data": f"d{event_id}"},
|
||||||
|
{"text": "✅ Закрыть", "callback_data": f"c{event_id}"},
|
||||||
|
],
|
||||||
|
]
|
||||||
|
reply_markup = {"inline_keyboard": inline_buttons}
|
||||||
|
|
||||||
params = {
|
params = {
|
||||||
"chat_id": conf.tgbot.chat_id,
|
"chat_id": conf.tgbot.chat_id,
|
||||||
"message_thread_id": conf.tgbot.tread_id,
|
"message_thread_id": conf.tgbot.tread_id,
|
||||||
"text": message,
|
"text": message,
|
||||||
|
"reply_markup": json.dumps(reply_markup),
|
||||||
}
|
}
|
||||||
|
|
||||||
async with aiohttp.ClientSession() as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
from .zabbix_api import get_active_problems
|
from .zabbix_api import get_active_problems, event_acknowledge, event_close
|
||||||
|
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"get_active_problems",
|
"get_active_problems",
|
||||||
|
"event_acknowledge",
|
||||||
|
"event_close",
|
||||||
]
|
]
|
||||||
|
|
|
@ -4,6 +4,8 @@ from zabbix_utils import ZabbixAPI
|
||||||
|
|
||||||
from config import conf
|
from config import conf
|
||||||
|
|
||||||
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
|
|
||||||
def get_active_problems() -> dict:
|
def get_active_problems() -> dict:
|
||||||
api = ZabbixAPI(url=conf.zabbix.url, token=conf.zabbix.token)
|
api = ZabbixAPI(url=conf.zabbix.url, token=conf.zabbix.token)
|
||||||
|
@ -40,3 +42,39 @@ def get_active_problems() -> dict:
|
||||||
return events_dict
|
return events_dict
|
||||||
except:
|
except:
|
||||||
log.warning("Get event from zabbix error")
|
log.warning("Get event from zabbix error")
|
||||||
|
|
||||||
|
|
||||||
|
def event_acknowledge(event_id: int, mute_time: int):
|
||||||
|
api = ZabbixAPI(url=conf.zabbix.url, token=conf.zabbix.token)
|
||||||
|
if mute_time == 0:
|
||||||
|
mute_to = 0
|
||||||
|
else:
|
||||||
|
mute_to = int((datetime.now() + timedelta(hours=mute_time)).timestamp())
|
||||||
|
try:
|
||||||
|
response = api.event.acknowledge(
|
||||||
|
eventids=event_id,
|
||||||
|
action=34,
|
||||||
|
suppress_until=mute_to,
|
||||||
|
)
|
||||||
|
if response:
|
||||||
|
log.info(f"Event {event_id} acknowledged")
|
||||||
|
return True
|
||||||
|
except:
|
||||||
|
log.warning(f"Acknowledge event {event_id} from zabbix error")
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def event_close(event_id: int):
|
||||||
|
api = ZabbixAPI(url=conf.zabbix.url, token=conf.zabbix.token)
|
||||||
|
try:
|
||||||
|
response = api.event.acknowledge(
|
||||||
|
eventids=event_id,
|
||||||
|
action=1,
|
||||||
|
)
|
||||||
|
print(response)
|
||||||
|
if response:
|
||||||
|
log.info(f"Event {event_id} closed")
|
||||||
|
return True
|
||||||
|
except:
|
||||||
|
log.warning(f"Closed event {event_id} from zabbix error")
|
||||||
|
return False
|
||||||
|
|
Loading…
Reference in New Issue