"""신규 매칭을 agent-office로 push하여 텔레그램 알림을 트리거한다.""" import os import logging import requests from .db import (get_profile, get_unnotified_matches, mark_matches_notified, get_listing_criteria, get_unnotified_listing_matches, mark_listings_notified) logger = logging.getLogger("realestate-lab") AGENT_OFFICE_URL = os.getenv("AGENT_OFFICE_URL", "http://agent-office:8000") NOTIFY_TIMEOUT_SECONDS = int(os.getenv("REALESTATE_NOTIFY_TIMEOUT", "15")) def notify_new_matches() -> dict: """프로필의 임계값을 통과한 미알림 매칭을 agent-office로 push한다. 응답이 200이고 sent_ids가 비어있지 않으면 해당 IDs의 notified_at을 마킹. 실패 시 마킹하지 않아 다음 사이클에서 재시도된다. """ profile = get_profile() if not profile: return {"sent": 0, "skipped": "no_profile"} if not profile.get("notify_enabled"): return {"sent": 0, "skipped": "notify_disabled"} raw_threshold = profile.get("min_match_score") threshold = 70 if raw_threshold is None else raw_threshold matches = get_unnotified_matches(threshold) if not matches: return {"sent": 0} url = f"{AGENT_OFFICE_URL}/api/agent-office/realestate/notify" try: resp = requests.post(url, json={"matches": matches}, timeout=NOTIFY_TIMEOUT_SECONDS) resp.raise_for_status() body = resp.json() except requests.RequestException as e: logger.error("agent-office push 실패: %s", e) return {"sent": 0, "error": str(e)} sent_ids = body.get("sent_ids") or [] if sent_ids: mark_matches_notified(sent_ids) logger.info("알림 송신: %d건", len(sent_ids)) return body def notify_new_listings() -> dict: """임계 통과 미알림 매물을 agent-office로 push (notify_new_matches 대칭). passed 매물은 전 안전등급 알림(위험도 회피 목적 유용). criteria.min_safety_tier 설정 시 그 이상만.""" crit = get_listing_criteria() if not crit.get("notify_enabled"): return {"sent": 0, "skipped": "notify_disabled"} listings = get_unnotified_listing_matches(min_tier=crit.get("min_safety_tier")) if not listings: return {"sent": 0} url = f"{AGENT_OFFICE_URL}/api/agent-office/realestate/notify-listing" try: resp = requests.post(url, json={"listings": listings}, timeout=NOTIFY_TIMEOUT_SECONDS) resp.raise_for_status() body = resp.json() except requests.RequestException as e: logger.error("agent-office 매물 push 실패: %s", e) return {"sent": 0, "error": str(e)} sent_ids = body.get("sent_ids") or [] if sent_ids: mark_listings_notified(sent_ids) logger.info("매물 알림 송신: %d건", len(sent_ids)) return body