flowchart LR
subgraph E[에뮬레이터 · 격리]
K[카카오톡 앱] --> S[(로컬 저장소)]
N[알림 답장] --> K
A[접근성 서비스] --> K
end
S -->|5초 폴링 · 복호화| C[수집기] --> DB[(메시지 DB)]
DB --> Q[조회 · 자동응답]
SCH[스케줄러] --> OUT[(발신 큐)] --> N
OUT -->|알림 없는 방| A
상세
왜 시작했나
요즘 주변에서 gpt, claude 등을 붙여 업무를 자동화하는데 카카오톡만 빠져 있습니다. 공식 MCP 가 “나와의 채팅” 까지만 열려 있어서 일반 대화방 메시지를 다루는 자동화는 쉽지 않고, 회사 안에서는 사내 메신저를 써도 외부 업체와는 카톡으로 컨택하는 일이 많은 만큼 니즈를 몇 번 들었습니다. 주말에 시간이 비어서 가벼운 마음으로 손을 댔습니다.
기존 도구부터 써봤습니다
kmsg-mcp 를 썼습니다. 맥에서 접근성 API 로 카카오톡 앱을 직접 조작하는 방식인데, 입력창 좌표를 찾아 클릭하고 Cmd+V 와 Return 을 보냅니다. 잘 만들어져 있고 실제로 잘 돌아갑니다.
문제는 그게 제가 쓰는 그 카카오톡이라는 것이었습니다. 봇이 도는 동안 커서가 움직이고 창이 앞으로 나옵니다. 대상이 화면에 보여야 잡힌다고 문서에도 적혀 있으니 피할 수 있는 게 아니고, 자동화를 돌려두면 그 컴퓨터로 다른 일을 하기가 어렵고 제가 뭘 하면 자동화가 깨집니다.
격리해서 만들었습니다
- 어디에: 에뮬레이터 안에 카카오톡을 따로 띄웠습니다. 봇이 화면을 차지하지 않으니 맥이나 맥 미니를 평소처럼 쓸 수 있고, 제가 뭘 하든 수집도 멈추지 않습니다. (뒤에 나오지만 계정이 따로라 “제 카톡이 영향을 안 받는다” 는 격리 덕이 아니라 계정 덕입니다. 격리로 얻은 것은 기기 사용성입니다)
- 읽기: 화면이 아니라 앱이 쌓아둔 로컬 저장소를 몇 초마다 확인해 새 메시지만 별도 DB 로 옮깁니다. 어디까지 읽었는지는 메시지 고유번호로 기억해 중복·누락을 막습니다. 복호화는 kakaodecrypt 를 가져다 썼습니다
- 쓰기: 저장소에 쓴다고 메시지가 나가지는 않아서 동반 앱을 따로 만들어 넣었습니다. 그 앱이 알림의 답장 기능을 붙잡아 문자를 밀어 넣고, 이 조작은 에뮬레이터 안에서만 일어납니다
- 구조: 수집 · 발신 · 스케줄 · 조회 네 층. 서로는 DB 파일 두 개로만 통신합니다
알림이 없는 방에는 못 보냅니다
알림으로 보내는 방식의 한계입니다. 조용한 방으로 설정했거나 이미 읽어서 알림이 사라진 방에는 보낼 수가 없고, 안드로이드 봇들이 오래 부딪혀온 벽을 저도 똑같이 만났습니다.
그래서 경로를 하나 더 팠습니다. 접근성 서비스로 방을 직접 열어 문자를 넣고 전송을 누르는 쪽인데 알림이 필요 없습니다. 알림이 있으면 원래 경로로, 없으면 이쪽으로 보냅니다. 벽을 없앤 게 아니라 옆으로 돌아간 것이고, 두 경로를 다 유지하는 비용이 생겼습니다.
흔한 카톡 봇과 다른 점
흔히 보는 카톡 봇은 명령어가 들어오면 답을 내놓는 단방향이라 누가 말을 걸기 전에는 아무 일도 하지 않습니다. 이건 명령어 없이 먼저 보낼 수 있고, 스케줄 발송이 거기 걸려 있습니다.
만들고 나서 Iris 를 찾았습니다
다 만들고 나서 Iris 를 알게 됐습니다. 루팅한 안드로이드에서 카톡 DB 를 지켜보다가 새 메시지를 외부 서버로 넘기고 답장도 대신 보냅니다. 제가 고른 것과 같은 갈래이고 복호화도 같은 것을 씁니다.
| Iris | 제 것 | |
|---|---|---|
| 도는 곳 | 기기 안 앱 | 호스트가 adb 로 기기를 부림 |
| 읽기 | 기기에서 관찰하다 새 것만 밀어줌 | 5초마다 DB 파일을 통째로 복사 |
| 설치 | 앱 하나 | 에뮬 + 수집기 + 앱 + 스케줄러 |
| 봇 로직 | 없음. 받아서 무엇을 할지는 직접 | 자동응답 · 쿨다운 · 발송 상한 · 스케줄 · 이름 해석 내장 |
| 공개 | 오픈소스 | 비공개 |
수집만 놓고 보면 제 것이 하위 버전입니다. 더 무겁고 더 복잡하고 검증도 저 혼자 했습니다. 지금 비슷한 걸 만들려는 분이라면 Iris 를 먼저 보시길 권합니다. 앱 하나 넣고 받은 메시지로 무엇을 할지만 만들면 됩니다.
제 것이 남은 이유는 제 쓰임에 맞춰 붙여둔 것들(자동응답 규칙 · 방별 쿨다운 · 발송 상한 · 스케줄 · 발화자 이름 해석) 때문이고, 상태가 전부 호스트에 있어서 기기나 계정을 갈아도 그대로 이어집니다.
확인 못 한 것이 하나 있습니다. Iris 의 답장이 알림 없는 방에도 보내는지가 문서에 없습니다. 해결돼 있으면 그 항목도 제 우위가 아니고, 모르는 것을 우위로 세지는 않겠습니다.
선을 그은 것
- 서버 통신 흉내 안 함: 카톡이 서버와 주고받는 통신을 흉내 내는 방법이 가장 깔끔한데 실제로 소송과 영구정지가 나온 영역이라 처음부터 뺐습니다. 건드리는 것은 제 기기 안의 로컬 데이터와 알림까지입니다
- 봇 전용 계정: 격리로 푼 것은 조작이 겹치는 문제뿐이고 계정이 겹치는 문제는 남습니다. 카톡은 계정 하나에 폰 한 대라 제 계정을 에뮬레이터에 올리면 제 폰에서 밀려납니다. 그래서 봇 계정을 따로 만들었고, 제 계정의 대화를 자동화한 구성은 아닙니다
- 격리는 제가 만든 게 아닙니다: Iris 를 에뮬레이터에 올려도 같은 격리가 됩니다. 화면을 거치지 않는 방식을 고르면 따라오는 것입니다
지금 어디까지
| 수집 | ✅ 격리된 환경에서 상시. 계정을 바꿔도 이어집니다 |
| 발신 | ✅ 알림 경로 + 접근성 경로 |
| 보낸 사람 특정 | ✅ 방 안 발화자를 이름·별칭으로 해석 |
| 자동응답 | ✅ 동작. 지금은 1:1 방 하나만 켜뒀습니다 |
| 스케줄 발송 | ✅ 방별 쿨다운 · 발송 상한 · 무작위 지연까지 |
| 에이전트가 읽기 | ✅ 평범한 SQLite 라 붙으면 그대로 읽힙니다 |
그다음
정해진 문장을 보내는 것까지 되고 나니 저 자리에 제 말투로 답하는 걸 놓으면 어떻게 될까가 따라왔습니다. 제 카톡 기록으로 모델을 학습시킨 이야기는 페르소나 트윈 시리즈 에 있습니다.