2026년 06월 22일

카카오톡 Message Bot R 방 식별 안정화와 OpenClaw 릴레이 개선 기록

카카오톡 Message Bot R 방 식별 안정화와 OpenClaw 릴레이 개선 기록

작성일: 2026-06-22
분류: IT / 자동화 / 자가 호스팅 운영
상태: WordPress 등록 대기용 초안

1. 오늘 작업의 결론

오늘 작업의 핵심은 카카오톡 Message Bot R과 OpenClaw를 연결한 뒤, 실제 운영에서 문제가 될 수 있는 세 가지 부분을 안정화한 것이다.

첫째, 카카오톡 방을 더 정확하게 식별하도록 개선했다. Message Bot R이 어떤 방에서는 실제 방 이름 대신 발신자 이름을 방 이름처럼 전달하는 경우가 있었다. 이 상태에서는 1:1 대화방과 단체방을 잘못 구분할 수 있다. 그래서 Bot R이 전달하는 정보만 믿지 않고, ADB로 스마트폰의 카카오톡 알림과 채팅방 목록을 같이 확인하는 구조를 추가했다.

둘째, 방마다 다른 응답 정책을 적용할 수 있게 했다. 단체방에서는 아무 말에나 자동 응답하면 대화 흐름을 방해할 수 있으므로 기본적으로 조용하게 두고, 호출어가 있을 때만 답변하도록 설계했다. 반대로 관리자가 승인한 방이나 1:1 방은 필요에 따라 더 자연스럽게 응답할 수 있게 했다.

셋째, 모델 API 할당량 오류나 응답 지연이 사용자에게 그대로 노출되지 않도록 개선했다. Gemini API에서 429 quota 오류가 발생했을 때 그대로 카카오톡에 긴 오류 문장이 나가는 문제가 있었고, 이를 완화하기 위해 여러 모델 키를 순환해서 사용하고, 실패 메시지를 사용자에게 더 안전하게 보여주도록 정리했다.

2. 왜 개선이 필요했나

처음 구조는 단순했다. 카카오톡 메시지가 들어오면 Message Bot R이 내용을 읽고, 로컬 릴레이 서버가 OpenClaw에 전달한 뒤, OpenClaw의 답변을 다시 카카오톡으로 보내는 방식이었다.

하지만 실제 운영에서는 몇 가지 문제가 확인됐다.

  1. 단체방에서도 봇이 너무 쉽게 반응할 수 있었다.
  2. Message Bot R이 전달하는 room 값이 실제 방 이름이 아니라 발신자 이름처럼 보이는 경우가 있었다.
  3. 5명이 있는 단체방인데도 Bot R 기준으로는 private_or_special처럼 보이는 경우가 있었다.
  4. Gemini API 할당량 초과 오류가 카카오톡 답변으로 그대로 보일 수 있었다.
  5. n8n을 거치지 않고 직접 운영하려는 방향에서는 로컬 릴레이와 스마트폰 상태 점검이 더 중요해졌다.

따라서 오늘의 목표는 새 기능을 무리하게 늘리는 것이 아니라, 현재 구조를 실제 사용 가능한 수준으로 안정화하는 것이었다.

3. 현재 전체 구조

현재 구조는 다음과 같다.

  1. 카카오톡에 메시지가 들어온다.
  2. Android 스마트폰의 Message Bot R이 메시지를 감지한다.
  3. Message Bot R 스크립트가 로컬 OpenClaw 릴레이 서버로 요청을 보낸다.
  4. 릴레이 서버가 방 정책과 방 식별 registry를 확인한다.
  5. 응답해야 하는 상황이면 OpenClaw 또는 보조 모델에 요청한다.
  6. 답변 앞에 발신자명을 붙여 카카오톡으로 반환한다.
  7. 왜 응답했는지 decision log에 남긴다.

이 구조에서 n8n은 카카오톡 Message Bot R 응답 경로의 필수 구성에서 제외하는 방향으로 정리했다. 즉, 스마트폰과 로컬 릴레이만으로 기본 응답이 가능하도록 운영 방향을 잡았다.

4. 방 식별 안정화

가장 중요한 개선은 방 식별 방식이다.

Message Bot R이 넘겨주는 기본 정보만 보면 다음과 같은 한계가 있다.

  • room 값이 실제 방 이름이 아닐 수 있다.
  • 단체방인데도 isGroupChat=false처럼 들어올 수 있다.
  • 참여자 이름이 방 이름처럼 들어올 수 있다.
  • 같은 방이 여러 이름으로 registry에 잡힐 수 있다.

그래서 방 식별은 한 가지 정보만 보지 않고, 여러 근거를 합쳐 판단하도록 바꿨다.

사용한 근거는 다음과 같다.

  • Message Bot R이 전달한 방 이름
  • Message Bot R이 전달한 발신자 이름
  • Message Bot R이 전달한 그룹 여부
  • ADB로 읽은 카카오톡 알림 metadata
  • 알림의 notification key, tag, shortcut 후보
  • 알림에 포함된 참여자 힌트
  • ADB로 직접 확인한 카카오톡 채팅방 목록
  • 관리자가 직접 확정한 방 유형

이 중에서 최종 판단은 관리자 확정값을 가장 우선하도록 했다. 자동 추론은 틀릴 수 있지만, 관리자가 직접 “이 방은 그룹방이다” 또는 “이 방은 1:1방이다”라고 지정한 값은 운영 정책의 기준이 되어야 하기 때문이다.

5. ADB를 왜 사용했나

ADB는 Android Debug Bridge의 약자다. 쉽게 말하면 PC에서 Android 스마트폰의 상태를 확인하거나 조작할 수 있게 해주는 공식 개발 도구다.

오늘은 ADB를 다음 용도로 사용했다.

  • 스마트폰 연결 상태 확인
  • 카카오톡 실행 상태 확인
  • 카카오톡 알림 metadata 확인
  • 카카오톡 채팅방 목록 화면 확인
  • Play Store 자동 업데이트 설정 확인
  • Android OTA 자동 업데이트 설정 확인

특히 카카오톡 방 식별에서는 ADB가 중요했다. 네트워크 패킷을 중간에서 보는 방식은 현실적으로 어렵고 안정적이지 않다. 카카오톡 트래픽은 암호화되어 있고, 앱 업데이트에 따라 내부 구조도 바뀔 수 있다. 반면 Android 알림과 UI 접근성 정보는 운영자가 소유한 스마트폰에서 확인하는 방식이라 더 현실적이다.

다만 ADB 방식도 완벽하지는 않다. 알림 제목은 항상 방 이름이 아니라, 최근 발신자 이름일 수 있다. 그래서 알림 title만 원본 방 이름으로 쓰면 잘못될 수 있다. 오늘 확인 결과도 이 문제가 실제로 나타났다. 그래서 최종적으로는 “알림 title”보다 “카카오톡 채팅방 목록에 표시되는 제목”을 더 신뢰하도록 정리했다.

6. 방 registry 구조

방 식별 정보는 파일 기반 registry로 관리한다.

주요 저장 항목은 다음과 같다.

  • roomId
  • Bot R이 전달한 원본 표시명
  • ADB로 확인한 원본 표시명
  • 운영자가 지정한 보정 표시명
  • Bot R이 전달한 방 유형
  • 관리자가 확정한 방 유형
  • 실제 적용할 방 유형
  • 알려진 발신자 목록
  • 수신 횟수
  • 검토 필요 여부
  • 검토 사유
  • notification evidence

중요한 점은 registry에 전체 대화 내용을 저장하지 않는다는 것이다. 현재 단계에서는 방 식별 안정화가 목적이기 때문에, 메시지 본문 전체를 데이터베이스에 저장하지 않았다. 대화 내용 저장은 식별 안정화가 끝난 뒤 별도 정책과 보관 기간을 정한 다음 진행하는 것이 안전하다.

7. 오늘 확정한 방 정책

오늘 ADB로 카카오톡 채팅방 목록을 확인했고, 관리자가 각 방의 성격을 확정했다.

확정 내용은 다음과 같다.

  • 오디오 모임 방: 단체/그룹방
  • 보스와의 1:1 대화방: 개인 1:1방
  • 테스트용 방: 테스트 단체/그룹방
  • 카카오계정 방: 시스템/공식 계정 성격의 방

운영 표시명은 사람이 알아보기 쉽게 보정했다. 예를 들어 실제 카카오톡 목록에서 여러 참여자 이름이 나열되는 방은 운영상 오디오 모임 방처럼 별도 표시명을 붙여 관리한다. 동시에 ADB로 확인한 원본 표시명은 따로 보관하여, 나중에 추적할 때 혼동이 없게 했다.

8. 응답 정책 개선

응답 정책은 “기본 조용함”을 기준으로 잡았다.

단체방에서는 기본적으로 아무 말에나 답하지 않는다. 호출어가 있을 때만 응답한다. 이렇게 해야 여러 사람이 있는 방에서 봇이 불필요하게 끼어드는 일을 줄일 수 있다.

현재 기본 방향은 다음과 같다.

  • 단체방: 기본 quiet, 호출어 필요
  • 1:1 방: 관리자가 허용한 경우 자연 응답 가능
  • 오픈채팅 또는 미확정 방: 기본 quiet
  • 식별이 불안정한 방: needsReview 처리
  • 관리자 명령: 관리자 발신자만 허용

호출어는 !! 같은 명확한 접두어를 사용한다. 이렇게 하면 사람이 의도적으로 봇을 부른 경우에만 응답하게 만들 수 있다.

9. decision log 추가

봇이 왜 답변했는지 나중에 확인할 수 있도록 decision log도 정리했다.

decision log에는 다음 같은 정보가 남는다.

  • 응답 여부
  • 응답한 이유
  • 방 정책
  • 호출어 사용 여부
  • 관리자 명령 여부
  • 적용된 방 유형
  • 오류 발생 여부

이 로그는 디버깅에 중요하다. 예를 들어 “왜 이 방에서 답변했지?”라는 질문이 생겼을 때, 단순히 추측하지 않고 decision log를 보고 판단할 수 있다.

10. 모델 API quota 오류 대응

운영 중 Gemini API에서 429 quota 오류가 카카오톡 메시지로 노출되는 문제가 있었다.

이 문제를 줄이기 위해 다음을 적용했다.

  • Gemini 키 여러 개를 fallback pool로 구성
  • quota 또는 rate limit 오류가 나면 다음 Gemini 키로 회전
  • Gemini가 모두 제한될 경우 Mistral fallback 가능성 검토
  • 사용자에게 provider 원문 오류를 그대로 보내지 않도록 정리
  • 실패 시 짧고 이해 가능한 오류 메시지로 변환

현재 방향은 “Gemini 전체 풀을 사용하되, cooldown 상태의 키는 전역적으로 건너뛰는 방식”이다. 이렇게 하면 한 세션에서 quota에 걸린 키를 다른 세션이 반복해서 사용하는 일을 줄일 수 있다.

11. 스마트폰 자동 업데이트 방지

카카오톡 자동화는 앱 버전 변화에 민감하다. 카카오톡이나 Android가 자동 업데이트되면 알림 구조, 답장 액션, UI 표시 방식이 바뀔 수 있다.

그래서 오늘 스마트폰에서 다음을 확인했다.

  • Android OTA 자동 업데이트 설정
  • Galaxy Store 상태
  • Play Store의 카카오톡 자동 업데이트 설정
  • Play Store의 Message Bot R 자동 업데이트 설정

카카오톡과 Message Bot R은 Play Store에서 앱별 자동 업데이트가 꺼진 상태로 확인했다. Android OTA도 자동 업데이트가 비활성화된 상태를 확인했다.

이 조치는 기능 추가보다 안정 운영에 더 중요하다. 현재 자동화는 특정 앱 동작에 의존하므로, 운영 중 갑작스러운 업데이트를 피해야 한다.

12. 오늘 수정한 주요 파일

오늘 수정한 핵심 파일은 다음과 같다.

  • scripts/kakao_openclaw_relay.py
  • config/kakao_room_registry.json
  • config/kakao_room_policies.json
  • 스마트폰의 Message Bot R 스크립트
  • 당일 작업 기록 파일

kakao_openclaw_relay.py에는 방 registry 처리, notification evidence 처리, display name override 처리, 관리자 명령 처리, 모델 fallback 처리 등이 들어갔다.

kakao_room_registry.json에는 실제 방 식별 결과와 관리자 확정값이 저장된다.

스마트폰 Message Bot R 스크립트에는 호출어 정책, decision log, 릴레이 호출 방식이 반영되어 있다.

13. 검증한 내용

오늘 검증한 항목은 다음과 같다.

  • ADB 연결 상태 정상
  • 카카오톡 채팅방 목록 확인 가능
  • 카카오톡 알림 metadata 확인 가능
  • 방 목록에서 그룹방과 1:1방 구분 가능
  • registry JSON 형식 정상
  • Python relay 문법 검사 정상
  • 릴레이 서비스 재시작 후 health check 정상
  • 방 유형 override 정상 반영
  • 운영 표시명 override 정상 반영
  • verified ADB chat-list 원본명이 notification title로 덮어써지지 않도록 수정

서비스 재시작 후에는 바로 실패로 판단하지 않고, 짧은 재시도 루프로 health check를 확인했다. systemd 서비스는 active로 보여도 포트가 완전히 준비되기 전일 수 있기 때문이다.

14. 현재 남은 과제

아직 남은 과제도 있다.

첫째, 데이터베이스 저장은 아직 시작하지 않았다. PostgreSQL은 사용할 수 있지만, 방 식별이 안정화되기 전에는 대화 저장을 시작하지 않는 것이 맞다. 잘못 식별된 방의 대화가 잘못된 방으로 저장되면 나중에 정리하기 어렵다.

둘째, 알림 기반 자동화는 카카오톡 앱 상태에 영향을 받는다. 카카오톡 방이 전면에 열려 있거나 알림 답장 액션이 생성되지 않으면 Message Bot R이 정상적으로 답장하지 못할 수 있다.

셋째, 방 이름이 참여자 이름 목록으로 표시되는 경우에는 사람이 보기 쉬운 운영 표시명을 계속 유지해야 한다. 원본명과 운영명을 분리한 현재 구조를 유지하는 것이 중요하다.

넷째, 여러 사람이 동시에 !! 호출어를 사용하는 경우 답변 앞에 발신자명을 표시하는 정책이 필요하다. 이 부분은 이미 적용 방향을 잡았고, 단체방에서 누가 질문했는지 구분하는 데 도움이 된다.

15. 운영 기준

앞으로 운영 기준은 다음과 같이 잡는 것이 좋다.

  • 방 식별이 확정되지 않은 방은 자동 응답을 줄인다.
  • 단체방은 기본 quiet로 둔다.
  • 관리자 명령으로만 방 정책을 바꾼다.
  • ADB chat-list 확인값은 notification title보다 우선한다.
  • 대화 원문 DB 저장은 식별 안정화 뒤 진행한다.
  • 자동 업데이트는 계속 꺼 둔다.
  • 모델 quota 오류는 사용자에게 원문 그대로 보여주지 않는다.
  • 장애 분석은 configuration, network, permission, version, resource, external API 순서로 본다.

16. 쉽게 요약하면

오늘 한 작업은 “카카오톡 봇이 아무 방에서나 아무 말에나 답하지 않게 만들고, 어떤 방에서 왜 답했는지 추적 가능하게 만든 작업”이다.

처음에는 Message Bot R이 넘겨주는 정보만 보고 판단했다. 하지만 실제로는 단체방이 1:1처럼 보이거나, 방 이름 대신 발신자 이름이 들어오는 문제가 있었다. 그래서 스마트폰 자체를 ADB로 확인해 카카오톡 알림과 채팅방 목록을 같이 보도록 바꿨다.

그리고 자동 추론이 틀릴 수 있으므로, 최종적으로는 관리자가 방 유형을 확정할 수 있게 했다. 이렇게 하면 봇이 단체방에서는 조용히 있다가 호출어가 있을 때만 답하고, 1:1 방에서는 필요한 경우 더 자연스럽게 응답할 수 있다.

결론적으로 오늘 작업은 기능을 화려하게 늘린 작업이 아니라, 실제 운영에서 사고가 나지 않도록 안전장치를 추가한 작업이다. 앞으로 PostgreSQL 저장이나 장기 대화 관리 기능을 붙이려면, 오늘 만든 방 식별 안정화 구조를 먼저 충분히 검증한 뒤 진행하는 것이 맞다.