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

1. 텔레그램 봇 연동
- Admin 봇 / Member 봇 이원화 운영
- Admin 봇: 알림 수신 전용. 자유 텍스트를 보내면 Member 봇 이용 안내로 유도하며, 인라인 키보드 액션은 제공하지 않는다. (단,
/start연동과 차단 감지 웹훅은 동일하게 처리한다) - Member 봇: 양방향. 자유 텍스트 질의·피드백과 인라인 키보드 응답을 지원한다.
- Admin 봇: 알림 수신 전용. 자유 텍스트를 보내면 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 시 이벤트 중복 제거 후 강의실별로 묶어 요약 발송
- 발송 전 게이트 체크
- 구독의 알림 수신 여부(
notificationEnabled) - 봇 연동 상태 및 차단 여부(
active) - 동일 이벤트 중복 발송 차단
- 구독의 알림 수신 여부(
- 발송 이력 로깅 (
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 대시보드 정의