앱 설치 기기에서 부재중 전화가 오면 발신자에게 미리 설정된 SMS를 자동 발송하는 기능의 실현 가능성·아키텍처·안전장치·단계별 실행 계획. telinfo 코드 전수분석 + 2026 커뮤니티 레퍼런스 + 유사 앱 조사 기반.
telinfo는 RECEIVE_SMS를 제거하고 SEND_SMS를 넣지 않은 스토커웨어 시그니처 회피 설계입니다. 따라서 기기 SMS 대신 "기기 BroadcastReceiver 감지 + 서버 Solapi 발송" 하이브리드가 2026 최적 — 기기 권한을 늘리지 않고 기존 인프라(sms.service.ts, device-token)를 재사용합니다.
"있는 것 vs 없는 것" — 코드 근거 기반.
| 요소 | 상태 | 근거 / 설명 |
|---|---|---|
| SMS 발송 (기기) | 없음 | SEND_SMS 권한 없음, sms_adapter는 읽기만 |
| SMS 발송 (서버) | 있음 | sms.service.ts — Solapi / AWS SNS (현재 관리자 테스트용) |
| 부재중 실시간 감지 | 없음 | call_log 사후 조회만. BroadcastReceiver·PhoneStateListener 없음 |
| 백그라운드 실행 | 없음 | 빈 MainActivity, foreground service·WorkManager 없음 |
| 네이티브 코드 | 없음 | 순수 Flutter 플러그인만 |
| 연락처 매칭 | 있음 | contact_directory 번호→이름 정규화 |
| 설정 저장 | 부분 | shared_preferences 있음, 메시지 템플릿 저장 없음 |
| another_telephony | 부분 | SMS 발송·수신 지원, 통화상태(부재중) 감지는 미지원 → 네이티브 필요 |
감지는 어느 경로든 기기 필수. 발송만 기기/서버 선택.
SEND_SMS 권한 필요 — 스토커웨어 시그니처↑SEND_SMS 불필요 — 기기는 감지만→ B 권장: telinfo 스토커웨어 회피 설계 유지 + 기존 Solapi 재사용. 사용자 번호를 Solapi 발신번호로 인증 등록하면 수신자에게 개인번호로 표시됩니다.
이벤트 기반 — BroadcastReceiver는 시스템이 깨워주므로 상시 foreground 불필요(배터리 유리).
서버 SSOT(Postgres) + 기기 로컬 미러(오프라인 1차 필터).
| 레이어 | 구성 |
|---|---|
| 서버 DB (Drizzle·UUIDv7) | auto_sms_config: deviceId·enabled·template·senderNumber·senderVerified·onlyContacts·quietHours·cooldownHours·dailyLimitauto_sms_log: id·deviceId·toNumber(마스킹)·body·status(sent/skipped/failed)·reason·sentAt |
| 네이티브 (Kotlin) | MissedCallReceiver.kt(PHONE_STATE 상태머신) · AutoSmsWorker.kt(WorkManager·백오프) · MainActivity.kt MethodChannel · Manifest receiver 등록(SEND_SMS 불필요) |
Flutter (features/auto_sms/) | domain AutoSmsConfig · data(서버 sync+prefs, MethodChannel 브리지) · presentation(설정 UI·미리보기·동의 온보딩 모달) |
| 서버 (Elysia) | 라우트 +3(POST /auto-sms·GET|PUT /auto-sms/config·GET /auto-sms/logs) · auto-sms.service.ts 게이트 · db/schema/auto-sms.ts |
자동 SMS는 남용·스팸 위험이 커 다층 가드가 필수입니다.
| 장치 | 위치 |
|---|---|
| 명시적 동의 온보딩(1회) | Flutter 모달 |
| 발신번호 소유 인증(Solapi 등록·OTP) | 서버 config |
| 쿨다운(동일번호 재발송 차단, 기본 6h) | 기기 1차 + 서버 2차 |
| 일일 발송 한도(rate limit) | 서버 |
| 업무시간 게이트 · 연락처 화이트리스트 | 기기 + 서버 |
| 발송 이력 전량 로깅 | auto_sms_log |
| 응답한 통화 · 초단타 로봇콜 제외 | 네이티브 판정 |
Critical Path: N0.1 → N1.1 → N2.1 → N3.1 (≈4 PR). N1.2/N1.3/N2.2는 병렬 가능.
| 노드 | 규모 | 의존 | 산출 |
|---|---|---|---|
| N0.1* | M | — | auto_sms_config·auto_sms_log 마이그레이션 |
| N0.2 | S | — | Flutter AutoSmsConfig + shared_preferences |
| N1.1* | M | N0.1 | 서버 API 3종 + auto-sms.service 게이트 |
| N1.2 | M | N0.2 | Kotlin MissedCallReceiver + 부재중 판정 |
| N1.3 | S | N0.2 | 설정 UI + 동의 온보딩 |
| N2.1* | M | N1.1·N1.2 | WorkManager→device-token 서버 호출 |
| N2.2 | S | N1.1 | 쿨다운·rate limit·발신번호 인증 |
| N3.1 | M | N2.1·N2.2 | E2E(감지→발송→로그) + 이력 UI |
유사 앱 (전수조사)
| 앱 | 특징 |
|---|---|
| LeMi Call/SMS Auto Reply | 부재중·SMS·15+ 메신저 자동응답, 업무외 시간 |
| AUTO MESSAGE | 1M+ 설치·4.2★, 거절/무시 통화 자동응답, Google 클라우드 싱크 |
| Auto Message | 통화 거절/무시 시 발송, SMS 포워딩·스케줄 |
| Smarter: Missed Call Assistant | AI 자동응답, SMS·WhatsApp·WhatsApp Business |
| anandankur2816/auto-reply-calls (GitHub) | 오픈소스 BroadcastReceiver + SmsManager 레퍼런스 |
공통: 대부분 기기 SMS(SmsManager)라 Play에서 default-handler 이슈를 겪음 → telinfo가 서버 발송을 택하면 정책 관문 자체를 회피하는 차별점.