chore: auto-commit from dashboard
This commit is contained in:
@@ -113,7 +113,7 @@ async function startConnection() {
|
|||||||
// --- Express API ---
|
// --- Express API ---
|
||||||
|
|
||||||
const app = express();
|
const app = express();
|
||||||
app.use(express.json());
|
app.use(express.json({ limit: '50mb' }));
|
||||||
|
|
||||||
app.get('/status', (_req, res) => {
|
app.get('/status', (_req, res) => {
|
||||||
res.json({
|
res.json({
|
||||||
|
|||||||
@@ -94,6 +94,9 @@
|
|||||||
"Bash(scp *10.0.20.*)",
|
"Bash(scp *10.0.20.*)",
|
||||||
"Bash(rsync *10.0.20.*)"
|
"Bash(rsync *10.0.20.*)"
|
||||||
],
|
],
|
||||||
|
"discord": {
|
||||||
|
"email_webhook_url": "https://discord.com/api/webhooks/1496421990846697583/OM8z1eBsJC6-UB9-Zi5RkHP23NNv9UrEznRMx4Y3wSWOFmLazPoi-8_iEKMp0Qgsqr-m"
|
||||||
|
},
|
||||||
"ollama": {
|
"ollama": {
|
||||||
"url": "http://10.0.20.161:11434"
|
"url": "http://10.0.20.161:11434"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -37,9 +37,9 @@
|
|||||||
"report_on": "changes",
|
"report_on": "changes",
|
||||||
"timeout": 120,
|
"timeout": 120,
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"last_run": null,
|
"last_run": "2026-04-22T10:00:00.001000+00:00",
|
||||||
"last_status": null,
|
"last_status": "ok",
|
||||||
"next_run": null
|
"next_run": "2026-04-22T16:00:00+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "security-audit-daily",
|
"name": "security-audit-daily",
|
||||||
@@ -53,9 +53,9 @@
|
|||||||
"report_on": "changes",
|
"report_on": "changes",
|
||||||
"timeout": 180,
|
"timeout": 180,
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"last_run": null,
|
"last_run": "2026-04-22T03:00:00.003515+00:00",
|
||||||
"last_status": null,
|
"last_status": "error",
|
||||||
"next_run": null
|
"next_run": "2026-04-23T03:00:00+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "kb-index-refresh",
|
"name": "kb-index-refresh",
|
||||||
@@ -69,9 +69,9 @@
|
|||||||
"report_on": "never",
|
"report_on": "never",
|
||||||
"timeout": 120,
|
"timeout": 120,
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"last_run": null,
|
"last_run": "2026-04-22T03:30:00.003672+00:00",
|
||||||
"last_status": null,
|
"last_status": "ok",
|
||||||
"next_run": null
|
"next_run": "2026-04-23T03:30:00+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "archive-tasks-daily",
|
"name": "archive-tasks-daily",
|
||||||
@@ -85,9 +85,9 @@
|
|||||||
"report_on": "changes",
|
"report_on": "changes",
|
||||||
"timeout": 60,
|
"timeout": 60,
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"last_run": null,
|
"last_run": "2026-04-22T03:00:00.003110+00:00",
|
||||||
"last_status": null,
|
"last_status": "ok",
|
||||||
"next_run": null
|
"next_run": "2026-04-23T03:00:00+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "backup-config",
|
"name": "backup-config",
|
||||||
@@ -101,9 +101,9 @@
|
|||||||
"report_on": "never",
|
"report_on": "never",
|
||||||
"timeout": 120,
|
"timeout": 120,
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"last_run": null,
|
"last_run": "2026-04-22T02:00:00.001806+00:00",
|
||||||
"last_status": null,
|
"last_status": "ok",
|
||||||
"next_run": null
|
"next_run": "2026-04-23T02:00:00+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "insights-extract",
|
"name": "insights-extract",
|
||||||
@@ -269,8 +269,8 @@
|
|||||||
"prompt": "Heartbeat check. Rulează src/heartbeat.py printr-un scurt raport de status.\nDacă nu e nimic de raportat (email=0, calendar nu are evenimente <2h, kb ok), răspunde doar cu HEARTBEAT_OK și oprește-te — nu trimite mesaj.\nDacă e ceva: raport scurt pe Discord #echo-work.",
|
"prompt": "Heartbeat check. Rulează src/heartbeat.py printr-un scurt raport de status.\nDacă nu e nimic de raportat (email=0, calendar nu are evenimente <2h, kb ok), răspunde doar cu HEARTBEAT_OK și oprește-te — nu trimite mesaj.\nDacă e ceva: raport scurt pe Discord #echo-work.",
|
||||||
"allowed_tools": [],
|
"allowed_tools": [],
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"last_run": "2026-04-21T13:00:00.002339+00:00",
|
"last_run": "2026-04-22T11:00:00.001844+00:00",
|
||||||
"last_status": "ok",
|
"last_status": "ok",
|
||||||
"next_run": "2026-04-21T15:00:00+00:00"
|
"next_run": "2026-04-22T13:00:00+00:00"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -10,33 +10,10 @@
|
|||||||
"time": "30 Jan 2026, 22:00"
|
"time": "30 Jan 2026, 22:00"
|
||||||
},
|
},
|
||||||
"anaf": {
|
"anaf": {
|
||||||
"ok": false,
|
"ok": true,
|
||||||
"status": "MODIFICĂRI",
|
"status": "OK",
|
||||||
"message": "3 modificări detectate",
|
"message": "Nicio modificare detectată",
|
||||||
"lastCheck": "21 Apr 2026, 10:04",
|
"lastCheck": "22 Apr 2026, 10:00",
|
||||||
"changesCount": 3,
|
"changesCount": 0
|
||||||
"changes": [
|
|
||||||
{
|
|
||||||
"name": "Declarația 100 - Obligații de plată la bugetul de stat",
|
|
||||||
"url": "https://static.anaf.ro/static/10/Anaf/Declaratii_R/100.html",
|
|
||||||
"summary": [
|
|
||||||
"Soft J: 22.01.2026 → 07.04.2026"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Bilanț 31.12.2025 (S1002-S1005)",
|
|
||||||
"url": "https://static.anaf.ro/static/10/Anaf/Declaratii_R/situatiifinanciare/2025/1002_5_2025.html",
|
|
||||||
"summary": [
|
|
||||||
"Pagina s-a modificat"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Situații financiare anuale 2025",
|
|
||||||
"url": "https://static.anaf.ro/static/10/Anaf/Declaratii_R/situatiifinanciare/2025/1030_2025.html",
|
|
||||||
"summary": [
|
|
||||||
"Pagina s-a modificat"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -916,3 +916,29 @@
|
|||||||
[2026-04-21 10:04:32] HASH CHANGED in SIT_FIN_AN_2025 (no version changes detected)
|
[2026-04-21 10:04:32] HASH CHANGED in SIT_FIN_AN_2025 (no version changes detected)
|
||||||
[2026-04-21 10:04:32] OK: DESCARCARE_DECLARATII
|
[2026-04-21 10:04:32] OK: DESCARCARE_DECLARATII
|
||||||
[2026-04-21 10:04:32] === Monitor complete ===
|
[2026-04-21 10:04:32] === Monitor complete ===
|
||||||
|
[2026-04-21 16:00:00] === Starting ANAF monitor v2.1 ===
|
||||||
|
[2026-04-21 16:00:00] OK: D100
|
||||||
|
[2026-04-21 16:00:00] OK: D101
|
||||||
|
[2026-04-21 16:00:00] OK: D300
|
||||||
|
[2026-04-21 16:00:00] OK: D390
|
||||||
|
[2026-04-21 16:00:00] OK: D394
|
||||||
|
[2026-04-21 16:00:00] OK: D205
|
||||||
|
[2026-04-21 16:00:01] OK: D406
|
||||||
|
[2026-04-21 16:00:01] OK: BILANT_2025
|
||||||
|
[2026-04-21 16:00:01] OK: SIT_FIN_SEM_2025
|
||||||
|
[2026-04-21 16:00:01] OK: SIT_FIN_AN_2025
|
||||||
|
[2026-04-21 16:00:01] OK: DESCARCARE_DECLARATII
|
||||||
|
[2026-04-21 16:00:01] === Monitor complete ===
|
||||||
|
[2026-04-22 10:00:00] === Starting ANAF monitor v2.1 ===
|
||||||
|
[2026-04-22 10:00:00] OK: D100
|
||||||
|
[2026-04-22 10:00:00] OK: D101
|
||||||
|
[2026-04-22 10:00:00] OK: D300
|
||||||
|
[2026-04-22 10:00:03] OK: D390
|
||||||
|
[2026-04-22 10:00:03] OK: D394
|
||||||
|
[2026-04-22 10:00:03] OK: D205
|
||||||
|
[2026-04-22 10:00:03] OK: D406
|
||||||
|
[2026-04-22 10:00:04] OK: BILANT_2025
|
||||||
|
[2026-04-22 10:00:04] OK: SIT_FIN_SEM_2025
|
||||||
|
[2026-04-22 10:00:04] OK: SIT_FIN_AN_2025
|
||||||
|
[2026-04-22 10:00:04] OK: DESCARCARE_DECLARATII
|
||||||
|
[2026-04-22 10:00:04] === Monitor complete ===
|
||||||
|
|||||||
@@ -88,6 +88,25 @@ def send_whatsapp(to: str, text: str) -> bool:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def send_discord_webhook(text: str) -> bool:
|
||||||
|
"""Trimite mesaj pe Discord via webhook (max 2000 chars per mesaj)."""
|
||||||
|
config = Config(PROJECT_ROOT / "config.json")
|
||||||
|
url = config.get("discord.email_webhook_url", "")
|
||||||
|
if not url:
|
||||||
|
return False
|
||||||
|
try:
|
||||||
|
chunks = [text[i:i+2000] for i in range(0, len(text), 2000)]
|
||||||
|
for chunk in chunks:
|
||||||
|
resp = requests.post(url, json={"content": chunk}, timeout=15)
|
||||||
|
if resp.status_code not in (200, 204):
|
||||||
|
print(f"[discord webhook] status {resp.status_code}", file=sys.stderr)
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[discord webhook eroare] {e}", file=sys.stderr)
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def send_whatsapp_document(to: str, filepath: str) -> bool:
|
def send_whatsapp_document(to: str, filepath: str) -> bool:
|
||||||
"""Trimite un fișier ca document WhatsApp prin bridge."""
|
"""Trimite un fișier ca document WhatsApp prin bridge."""
|
||||||
try:
|
try:
|
||||||
@@ -145,6 +164,12 @@ def run_digest():
|
|||||||
else:
|
else:
|
||||||
print(f"❌ Trimitere eșuată: {subject}")
|
print(f"❌ Trimitere eșuată: {subject}")
|
||||||
|
|
||||||
|
ok_dc = send_discord_webhook(summary)
|
||||||
|
if ok_dc:
|
||||||
|
print(f"✅ Trimis pe Discord: {subject}")
|
||||||
|
else:
|
||||||
|
print(f"❌ Discord eșuat: {subject}")
|
||||||
|
|
||||||
for att_path in attachment_paths:
|
for att_path in attachment_paths:
|
||||||
ok_att = send_whatsapp_document(owner_jid, att_path)
|
ok_att = send_whatsapp_document(owner_jid, att_path)
|
||||||
name = Path(att_path).name
|
name = Path(att_path).name
|
||||||
|
|||||||
@@ -117,6 +117,25 @@ def send_whatsapp(to: str, text: str) -> bool:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def send_discord_webhook(text: str) -> bool:
|
||||||
|
"""Trimite mesaj pe Discord via webhook (max 2000 chars per mesaj)."""
|
||||||
|
config = Config(PROJECT_ROOT / "config.json")
|
||||||
|
url = config.get("discord.email_webhook_url", "")
|
||||||
|
if not url:
|
||||||
|
return False
|
||||||
|
try:
|
||||||
|
chunks = [text[i:i+2000] for i in range(0, len(text), 2000)]
|
||||||
|
for chunk in chunks:
|
||||||
|
resp = requests.post(url, json={"content": chunk}, timeout=15)
|
||||||
|
if resp.status_code not in (200, 204):
|
||||||
|
print(f"[discord webhook] status {resp.status_code}", file=sys.stderr)
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[discord webhook eroare] {e}", file=sys.stderr)
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def send_whatsapp_document(to: str, filename: str, data: bytes) -> bool:
|
def send_whatsapp_document(to: str, filename: str, data: bytes) -> bool:
|
||||||
try:
|
try:
|
||||||
mimetype = mimetypes.guess_type(filename)[0] or "application/octet-stream"
|
mimetype = mimetypes.guess_type(filename)[0] or "application/octet-stream"
|
||||||
@@ -212,6 +231,13 @@ def run_forward():
|
|||||||
else:
|
else:
|
||||||
print(f"Trimis pe WhatsApp ({len(parts)} mesaje): {subject}")
|
print(f"Trimis pe WhatsApp ({len(parts)} mesaje): {subject}")
|
||||||
|
|
||||||
|
full_text = "\n".join(parts)
|
||||||
|
ok_dc = send_discord_webhook(full_text)
|
||||||
|
if ok_dc:
|
||||||
|
print(f"Trimis pe Discord: {subject}")
|
||||||
|
else:
|
||||||
|
print(f"Discord eșuat: {subject}")
|
||||||
|
|
||||||
for fname, fdata in em.get('attachment_data', {}).items():
|
for fname, fdata in em.get('attachment_data', {}).items():
|
||||||
ok_att = send_whatsapp_document(owner_jid, fname, fdata)
|
ok_att = send_whatsapp_document(owner_jid, fname, fdata)
|
||||||
if ok_att:
|
if ok_att:
|
||||||
|
|||||||
Reference in New Issue
Block a user