fix(beszel): webhook cria tarefas projecto 65, milestone 355, Izito

- Renomeado 'ticket' → 'tarefa' em todo o código
- Projecto: 65 (DES Stack Workflow)
- Milestone: 355 (Sistemas de Apoio — Tecnologia)
- Atribuído: Izito (staff 28)
- Criado por: Claude/AIkTop (staff 25)
- Corrigido Content-Length header bug
This commit is contained in:
2026-06-24 05:35:47 +01:00
parent 8e0dbbeca0
commit ab3384c961
+124
View File
@@ -0,0 +1,124 @@
#!/usr/bin/env python3
"""Beszel Webhook Receiver — Cria tarefas Desk CRM a partir de alertas Beszel."""
import json, os, sys, logging
from http.server import HTTPServer, BaseHTTPRequestHandler
from datetime import datetime
import pymysql
PORT = int(sys.argv[sys.argv.index("--port") + 1]) if "--port" in sys.argv else 8650
DB_CONFIG = {"host": "server.descomplicar.pt", "port": 3306, "user": "ealmeida_desk24",
"password": "9qPRdCGGqM4o", "database": "ealmeida_desk24", "charset": "utf8mb4"}
# Configuração Desk CRM
PROJECT_ID = 65 # DES Stack Workflow
MILESTONE_ID = 355 # Sistemas de Apoio (Tecnologia)
ASSIGNEE_STAFF_ID = 28 # Izito
CREATOR_STAFF_ID = 25 # Claude/AIkTop
PRIORITY = 3 # Alta
LOG = "/root/logs/beszel-webhook.log"
os.makedirs(os.path.dirname(LOG), exist_ok=True)
logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s",
handlers=[logging.FileHandler(LOG, encoding="utf-8"), logging.StreamHandler()])
log = logging.getLogger("beszel-webhook")
def get_db():
return pymysql.connect(**DB_CONFIG, cursorclass=pymysql.cursors.DictCursor)
def tarefa_existe(cur, padrao):
"""Verifica se já existe tarefa aberta com o padrão indicado."""
cur.execute(
"SELECT id FROM tbltasks WHERE name LIKE %s AND status NOT IN (5,6) AND rel_type='project' AND rel_id=%s LIMIT 1",
(padrao, PROJECT_ID)
)
return cur.fetchone()
def criar_tarefa(cur, nome, descricao):
"""Cria tarefa Desk CRM no projecto 65, milestone 355, atribuída a Izito."""
now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
cur.execute(
"""INSERT INTO tbltasks
(name, description, priority, status, rel_type, rel_id, milestone,
addedfrom, startdate, dateadded)
VALUES (%s, %s, %s, 1, %s, %s, %s, %s, %s, %s)""",
(nome, descricao, PRIORITY, "project", PROJECT_ID, MILESTONE_ID,
CREATOR_STAFF_ID, now[:10], now)
)
tid = cur.lastrowid
cur.execute(
"INSERT INTO tbltask_assigned (taskid, staffid, assigned_from) VALUES (%s, %s, 0)",
(tid, ASSIGNEE_STAFF_ID)
)
log.info(f"Tarefa #{tid} criada — {nome}")
return tid
def fechar_tarefa(cur, tid, nota):
"""Fecha tarefa (status 5 = Terminado)."""
cur.execute("UPDATE tbltasks SET status=5, datefinished=NOW() WHERE id=%s", (tid,))
log.info(f"Tarefa #{tid} fechada: {nota}")
class Handler(BaseHTTPRequestHandler):
def do_POST(self):
if self.path != "/beszel-alert":
self.send_response(404)
self.end_headers()
return
body = self.rfile.read(int(self.headers.get("Content-Type-Length", 0)))
try:
data = json.loads(body)
except Exception:
self.send_response(400)
self.end_headers()
return
titulo = data.get("title", "")
mensagem = data.get("message", "")
log.info(f"Webhook: {titulo}{mensagem}")
is_down = "down" in (mensagem + titulo).lower()
is_up = "up" in mensagem.lower() or "recovered" in mensagem.lower()
# Extrair nome do sistema
sname = data.get("system", "") or data.get("name", "") or data.get("host", "")
if not sname:
parts = mensagem.split(":")
if len(parts) > 1:
sname = parts[1].strip().split("(")[0].strip()
try:
db = get_db()
cur = db.cursor()
if is_down and sname:
if not tarefa_existe(cur, f"[MONIT] {sname}%"):
criar_tarefa(
cur,
f"[MONIT] {sname} — sistema DOWN",
f"<p><strong>Beszel — {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}</strong></p>"
f"<p>{mensagem}</p>"
)
elif is_up and sname:
existente = tarefa_existe(cur, f"[MONIT] {sname}%")
if existente:
fechar_tarefa(cur, existente["id"], f"{sname} voltou ao normal")
db.commit()
cur.close()
db.close()
except Exception as e:
log.error(f"Erro Desk CRM: {e}")
self.send_response(200)
self.send_header("Content-Type", "application/json")
self.end_headers()
self.wfile.write(b'{"status":"ok"}')
def log_message(self, fmt, *args):
log.info(f"{self.client_address[0]} - {fmt % args}")
if __name__ == "__main__":
srv = HTTPServer(("0.0.0.0", PORT), Handler)
log.info(f"Beszel Webhook Receiver a escutar na porta {PORT}")
srv.serve_forever()