Reply Automation · Code Audit
답장 자동화 — 기능 점검 & 문제 분석
수출기업 매니저용 영업 메일 자동화 · 코드베이스 실측 기준 점검 결과
기준일 2026-06-01 · 분석 대상 elysia-server + admin (alpha) · 개인용 noindex 페이지
요약
| 기능 | 의도 | 현재 상태 |
| 1. 미응답 후속 "확인되셨을까요?" | 첫 발송 무응답 시 원본 비슷한 내용으로 바이어에게 후속 | 부분 |
| 2. OOO → 영업시간 재발송 | 주말/영업외 발송→자동응답 수신→영업시간에 재발송 | 미구현 |
| 3. 담당자 아님 → 자동 전달 | "XXX로 보내달라" 답장 시 XXX로 동일 전달 | 완료 |
| + 긍정/미팅 답장 → 유저 이메일 알림 | 긍정/미팅 답장 도착 즉시 담당자 메일로 알림 | 부분 |
1미응답 후속 "확인되셨을까요?" 메일 부분
의도 — 유저가 보냈는데 수신자가 답장을 까먹었을 때, 원래 보냈던 비슷한 내용으로 "확인되셨을까요?" 느낌의 후속을 자동 발송.
| 코드 | 동작 | 판정 |
auto-nudge.service (시간당 worker, SES) | nudge_type_configs 스케줄(앵커 날짜) 기반 바이어 후속 발송 | 유사 |
| 시퀀스 후속 step | 시퀀스에 정의된 다음 단계 메일 진행 | 유사 |
scanForNudges (헥사고날, reminderFrom=마지막 콘텐츠 언어로 재생성) | 의도에 가장 근접하나 호출부 없음 | dead |
reply-nudge.service | 바이어가 답장한 뒤 유저에게 후속 독촉 (방향 반대) | 다른 기능 |
문제
- 요청의 핵심인 "유저 원본을 비슷하게 재생성한 바이어 후속"은 미구현. 현재 후속은 미리 설정된 넛지 템플릿/시퀀스 step 기반.
- 가장 가까운
scanForNudges(원본 언어로 리마인드 재생성)는 헥사고날 dead code — 어댑터·워커 미연결.
- 발송 인프라(SES, 시간당 스케줄)는 이미 존재 → 연결 비용은 낮음.
2OOO(부재중) → 영업시간 재발송 미구현
의도 — 주말/영업외에 보내 자동응답(OOO)이 오면, 수신자 국가의 영업시간에 다시 발송.
| 코드 | 동작 | 판정 |
processReplyAutomation (OOO intent) | OOO 감지 → 시퀀스 pause → autoResumeDelayDays(기본 7일) 후 resume | 개념만 일부 |
handleOOOReply / nextBusinessSlot (복귀일 파싱→다음 영업일 재스케줄) | 의도와 정확히 일치하나 배선 0건 | dead |
문제
- "영업시간 정확 재발송"은 미구현. 현재는 "N일 후 시퀀스 재개"라 동작이 다름(재발송이 아니라 시퀀스 진행 재개).
- 영업일/영업시간 계산 도메인(
nextBusinessSlot, 국가별 캘린더)은 작성돼 있으나 어디서도 호출하지 않음.
- 이전에 추가했던
resend_business_hours 옵션 필드는 미배선 dead 필드여서 #8060에서 제거함.
3담당자 아님 → XXX로 자동 전달 완료 · #8060
의도 — "나는 담당자 아님 → XXX 메일로 보내달라" 답장 시, XXX로 원본 메일을 동일하게 자동 전달.
| 코드 | 동작 | 판정 |
ai-classification wrong_contact intent + referredEmail 추출 | 분류 + 대체 주소 추출(AI 미추출 시 본문 정규식 fallback) | 구현 |
wrong-contact-forward.service + webhook 배선 | review(검토 알림) / auto(고신뢰·유효주소 시 즉시 전달) 토글, 캠페인별 on/off | 구현 |
상태 — 정상 동작
- alpha 머지 완료(#8060). 단위 테스트 4건 + 기존 usecase 10건 통과.
- 유의: 설정 UI는
/sequences/edit 편집 화면의 "답변 자동화" 섹션에서만 노출 — 생성 마법사 노출은 별도 작업 필요(아래 횡단 이슈 C 참조).
+긍정/미팅 답장 → 유저 이메일 알림 부분
의도 — 긍정/미팅요청 답장이 도착하면 해당 워크스페이스 담당자의 이메일로 알림 메일 발송.
| 채널 | 동작 | 판정 |
| 앱 내 알림(벨/SSE) | POSITIVE/INFO_REQUEST 즉시 생성 | 즉시 |
| Slack | SLACK_NOTIFY_WORKSPACES allowlist 워크스페이스만 | 일부만 |
이메일(reply-nudge-email, SES rinda@mail.rinda.ai) | 24h/72h/7d 지연 넛지로 user.email에 발송 (opt-out·admin 게이트) | 지연만 |
문제
- 이메일 알림은 존재하나 "도착 즉시"가 아니라 24시간+ 지연 넛지이며, 성격도 "후속하라는 독촉"이지 "긍정/미팅 답장이 도착했다"는 즉시 도착 알림이 아님.
- 즉시 이메일 알림을 원하면
notifyEmailReply의 POSITIVE 분기에 즉시 발송 1건을 추가해야 함(인프라·opt-out·다국어 패턴은 email-open-notification에 이미 존재 → 재사용 가능).
횡단 구조 이슈
| 이슈 | 근거 / 영향 |
| A | confidence 임계값이 SSOT 아님 | 0.6(시퀀스 액션)·0.7(긍정 알림,dead)·0.8(자동 전달)가 3개 파일에 분산 → 정책 변경 시 drift |
| B | 분류 진입점 2원화 | SendGrid/Nylas webhook은 classifyReply 직접, Unipile은 reclassifyEmailReply 경유 → 동작은 같으나 경로 이원화 |
| C | 답장 자동화 토글이 생성 마법사에 없음 | CreateCampaignStep3(토글 포함)를 쓰는 CreateCampaignPage는 라우터 미연결 orphan. 통합 마법사 UnifiedCampaignPage엔 섹션 없음 → 편집 화면에서만 설정 가능 |
| D | 헥사고날 usecases dead code | scanForNudges·handleOOOReply가 라이브 경로와 중복 작성됐으나 미배선 → 기능1·2 미완의 직접 원인 |
| E | gemini-3.1-flash-lite thinking 분기 | 레지스트리·타임아웃·실호출 모두 유효(실데이터 분류 정상). 단 supportsThinking prefix에 startsWith로 매칭돼 thinkingConfig 주입 — flash-lite의 thinking 지원 여부 런타임 확인 권장 |
권장 우선순위
| # | 조치 | 난이도 |
| 1 | 긍정/미팅 즉시 이메일 알림 — notifyEmailReply POSITIVE 분기에 즉시 1건 발송 추가(기존 패턴 재사용) | S |
| 2 | OOO 영업시간 재발송 — dead handleOOOReply/nextBusinessSlot를 OOO intent 경로에 배선 | M |
| 3 | 미응답 후속 재생성 — scanForNudges(원본 언어 리마인드)를 시간당 워커에 어댑터 연결 | M |
| 4 | 답장 자동화 토글을 통합 생성 마법사에 노출 (이슈 C) | S |
| 5 | confidence 임계값 상수 모듈로 SSOT화 (이슈 A) | S |