"""Notification dispatcher: KakaoTalk with Markdown fallback.""" from __future__ import annotations from datetime import date from loguru import logger from gimme_job.config import GlobalConfig class NotificationDispatcher: def __init__(self, global_config: GlobalConfig, session_factory): self.cfg = global_config self.session_factory = session_factory def send(self, summary: str, run_date: date) -> bool: """Send the summary. Returns True if any method succeeded.""" from gimme_job.db.repo import NotificationLogRepo from gimme_job.runtime.kakao import KakaoTalkClient client = KakaoTalkClient() success = False if client.is_configured(): ok = client.send_self_memo(summary) if ok: success = True self._log_notification(run_date, "kakaotalk", "success") else: logger.warning("KakaoTalk failed — writing markdown fallback") self._log_notification(run_date, "kakaotalk", "failed", "send_self_memo returned False") else: logger.warning("KakaoTalk not configured — writing markdown fallback only") self._log_notification(run_date, "kakaotalk", "skipped", "not configured") # Always save markdown fallback if configured if self.cfg.notification.fallback_markdown: path = self.send_markdown_fallback(summary, run_date) logger.info(f"Markdown saved: {path}") if not success: self._log_notification(run_date, "markdown", "success") success = True return success def send_markdown_fallback(self, summary: str, run_date: date): """Save summary to workspace/reports/YYYY-MM-DD.md.""" from gimme_job.utils.paths import reports_dir path = reports_dir() / f"{run_date.strftime('%Y-%m-%d')}.md" path.parent.mkdir(parents=True, exist_ok=True) path.write_text(summary, encoding="utf-8") return path def _log_notification( self, run_date: date, provider: str, status: str, error_message: str | None = None, ) -> None: try: with self.session_factory() as session: from gimme_job.db.repo import NotificationLogRepo NotificationLogRepo().log_notification( session, run_date, provider, status, error_message ) except Exception as e: logger.warning(f"Failed to log notification: {e}")