gateway: add privacy guard plus reminders and mentor relay commands
This commit is contained in:
100
gateway-bot/daarion_facade/reminder_worker.py
Normal file
100
gateway-bot/daarion_facade/reminder_worker.py
Normal file
@@ -0,0 +1,100 @@
|
||||
import asyncio
|
||||
import logging
|
||||
import os
|
||||
from typing import Dict
|
||||
|
||||
import httpx
|
||||
|
||||
from .reminders import close_redis, pop_due_reminders
|
||||
|
||||
logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(name)s: %(message)s")
|
||||
logger = logging.getLogger("daarion-reminder-worker")
|
||||
|
||||
POLL_SECONDS = float(os.getenv("DAARION_REMINDER_POLL_SECONDS", "2"))
|
||||
TELEGRAM_TIMEOUT = float(os.getenv("DAARION_REMINDER_TELEGRAM_TIMEOUT", "20"))
|
||||
|
||||
AGENT_TOKEN_ENV: Dict[str, str] = {
|
||||
"daarwizz": "DAARWIZZ_TELEGRAM_BOT_TOKEN",
|
||||
"helion": "HELION_TELEGRAM_BOT_TOKEN",
|
||||
"greenfood": "GREENFOOD_TELEGRAM_BOT_TOKEN",
|
||||
"agromatrix": "AGROMATRIX_TELEGRAM_BOT_TOKEN",
|
||||
"alateya": "ALATEYA_TELEGRAM_BOT_TOKEN",
|
||||
"nutra": "NUTRA_TELEGRAM_BOT_TOKEN",
|
||||
"druid": "DRUID_TELEGRAM_BOT_TOKEN",
|
||||
"clan": "CLAN_TELEGRAM_BOT_TOKEN",
|
||||
"eonarch": "EONARCH_TELEGRAM_BOT_TOKEN",
|
||||
"senpai": "SENPAI_TELEGRAM_BOT_TOKEN",
|
||||
"oneok": "ONEOK_TELEGRAM_BOT_TOKEN",
|
||||
"soul": "SOUL_TELEGRAM_BOT_TOKEN",
|
||||
"yaromir": "YAROMIR_TELEGRAM_BOT_TOKEN",
|
||||
"sofiia": "SOFIIA_TELEGRAM_BOT_TOKEN",
|
||||
}
|
||||
|
||||
|
||||
def _token_for_agent(agent_id: str) -> str:
|
||||
env = AGENT_TOKEN_ENV.get((agent_id or "").lower(), "")
|
||||
return os.getenv(env, "") if env else ""
|
||||
|
||||
|
||||
async def _send_reminder(item: Dict[str, str]) -> bool:
|
||||
agent_id = str(item.get("agent_id", ""))
|
||||
chat_id = str(item.get("chat_id", ""))
|
||||
reminder_text = str(item.get("text", "")).strip()
|
||||
due_at = str(item.get("due_at", ""))
|
||||
|
||||
token = _token_for_agent(agent_id)
|
||||
if not token:
|
||||
logger.warning("reminder_skip_no_token agent=%s reminder_id=%s", agent_id, item.get("reminder_id"))
|
||||
return False
|
||||
|
||||
if not chat_id or not reminder_text:
|
||||
logger.warning("reminder_skip_invalid_payload reminder_id=%s", item.get("reminder_id"))
|
||||
return False
|
||||
|
||||
body = {
|
||||
"chat_id": chat_id,
|
||||
"text": f"⏰ Нагадування ({agent_id})\n\n{reminder_text}\n\n🕒 {due_at}",
|
||||
}
|
||||
|
||||
url = f"https://api.telegram.org/bot{token}/sendMessage"
|
||||
async with httpx.AsyncClient(timeout=TELEGRAM_TIMEOUT) as client:
|
||||
resp = await client.post(url, json=body)
|
||||
if resp.status_code != 200:
|
||||
logger.warning(
|
||||
"reminder_send_failed reminder_id=%s status=%s body=%s",
|
||||
item.get("reminder_id"),
|
||||
resp.status_code,
|
||||
resp.text[:300],
|
||||
)
|
||||
return False
|
||||
|
||||
logger.info("reminder_sent reminder_id=%s agent=%s chat=%s", item.get("reminder_id"), agent_id, chat_id)
|
||||
return True
|
||||
|
||||
|
||||
async def worker_loop() -> None:
|
||||
logger.info("reminder_worker_started poll_seconds=%s", POLL_SECONDS)
|
||||
while True:
|
||||
try:
|
||||
items = await pop_due_reminders(limit=20)
|
||||
if items:
|
||||
for item in items:
|
||||
try:
|
||||
await _send_reminder(item)
|
||||
except Exception:
|
||||
logger.exception("reminder_send_exception reminder_id=%s", item.get("reminder_id"))
|
||||
except asyncio.CancelledError:
|
||||
raise
|
||||
except Exception:
|
||||
logger.exception("reminder_worker_cycle_failed")
|
||||
await asyncio.sleep(POLL_SECONDS)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
asyncio.run(worker_loop())
|
||||
finally:
|
||||
try:
|
||||
asyncio.run(close_redis())
|
||||
except Exception:
|
||||
pass
|
||||
Reference in New Issue
Block a user