Notification API ‐ 세부기능 - nhnacademy-aiot3-4iren/4iren-wiki GitHub Wiki

Notification API — 세부기능

알림 파이프라인

1. 텔레그램 봇 연동

  • Admin 봇 / Member 봇 이원화 운영
    • Admin 봇: 알림 수신 전용. 자유 텍스트를 보내면 Member 봇 이용 안내로 유도하며, 인라인 키보드 액션은 제공하지 않는다. (단, /start 연동과 차단 감지 웹훅은 동일하게 처리한다)
    • Member 봇: 양방향. 자유 텍스트 질의·피드백과 인라인 키보드 응답을 지원한다.
  • 딥링크 기반 계정 연동 (1회용 연동 토큰 발급, Redis TTL 관리)
  • /start 웹훅 수신 → chat_id 매핑
  • 봇 차단(my_chat_member) 감지 → 연동 상태(active) 자동 갱신, 차단 해제 시 복구
  • 재연동 시 기존 연동 여부 확인 후 안내
  • 웹훅 수신 즉시 200 OK 응답 + RabbitMQ 이벤트 발행 구조 (텔레그램 재전송 방지)

2. 인바운드 메시지 라우팅 (의도분류)

  • Member 봇 자유 텍스트를 FEEDBACK / QUESTION / FALLBACK 3종으로 분류 (Spring AI + LLM)
  • FEEDBACK → 피드백 처리 파이프라인으로 핸드오프
  • QUESTION(기기 상태 질문 + 일반 도메인 질문 통합) → Recommendation API로 동기 포워딩, 자체 답변 합성 금지
  • 사용자의 구독 강의실 목록을 Core에서 조회해 포워딩 컨텍스트로 함께 전달
  • Resilience4j 서킷브레이커 적용, 장애 시 폴백 메시지 응답 (임계치는 기본값 사용)
  • FALLBACK(분류 실패/의미없는 입력) → 안내 메시지 응답

3. 피드백 수집

  • 자유 텍스트에서 온도/습도/공기질 3축 감정 점수 추출 (언급 안 된 축은 NULL 허용)
  • 대상 강의실이 모호하면 인라인 키보드로 되물어 확정
  • 피드백 원문(raw_text) 보존 (재분류 대비)
  • 피드백 접수 즉시 소프트 확언 메시지 발송 (조치를 약속하지 않는 문구)
  • Core API 연동으로 조회 시점 기준 최근 15분 평균 환경값을 결합 저장. 외부 날씨는 정시 버킷 기준이며, 같은 지역·시간대 스냅샷은 강의실 간 재사용한다.
  • 환경값 조회에 실패해도 피드백 저장 자체는 계속 진행한다.

4. 알림 발송

  • 긴급 알림(센서 이상 등) 즉시 개별 발송
  • 비긴급 알림 유저 단위 디바운스 배치 발송 (3분 창, Redis 버퍼 + 지연 큐 TTL → DLX → flush)
  • flush 시 이벤트 중복 제거 후 강의실별로 묶어 요약 발송
  • 발송 전 게이트 체크
    1. 구독의 알림 수신 여부(notificationEnabled)
    2. 봇 연동 상태 및 차단 여부(active)
    3. 동일 이벤트 중복 발송 차단
  • 발송 이력 로깅 (alert_history)

텔레그램 발송 실패는 로그만 남기고 재시도하지 않는다. (예외를 삼키므로 리스너 재시도에도 걸리지 않음)

5. 조직/구독 정보 참조

  • 구독 정보는 이 서비스가 소유하지 않는다. Core API를 통해 조회만 하며, 구독 신청·승인 상태 개념은 시스템 전체에 존재하지 않는다.
    • 초기에 두었던 room_subscription / notification_user 테이블은 Account·Core와 중복되어 마이그레이션(V7)에서 제거되었다.
  • Account 서비스의 역할 변경 이벤트를 RabbitMQ로 수신해 반영한다.

6. 이력 조회 및 데이터 제공

  • 알림 발송 이력 조회 API (강의실·봇 종류·알림 유형·기간 필터, 페이징, 상세 조회, 필터 옵션 조회)
  • ML 학습용 피드백 CSV export 내부 API — 커서(X-Last-Feedback-Log-Id) 기반 증분 조회, 실내외 온·습도 차 파생값 포함
  • 보존 기간이 지난 알림 이력·피드백 로그를 정리하는 스케줄러 (ShedLock으로 중복 실행 방지)

7. 장애 처리

  • 처리 실패 메시지는 DLQ로 격리 후 Elasticsearch에 원문·스택트레이스를 보관하고 재발행한다.

8. 관측성

  • Actuator + Micrometer(Prometheus 레지스트리) 연동, /actuator/prometheus 노출
  • 애플리케이션 태그(4iren-notification) 부여
  • 커스텀 메트릭: DLQ 유입 건수(notification.dlq.messages{queue,reason})
  • 미도입: 발송 성공·실패·지연 등 도메인 메트릭, Grafana 대시보드 정의