OpenClaw로 WhatsApp 연동하기
메시징 플랫폼을 서비스에 연동할 때마다 복잡한 API 문서와 씨름하는 건 정말 피곤한 일이죠. 특히 개인용 메신저와 업무용 채널이 뒤섞이기 시작하면 관리가 금세 엉망이 되곤 합니다. OpenClaw를 사용하면 WhatsApp Web을 통해 이 과정을 단순하게 만들 수 있어요.
What You’ll Need
섹션 제목: “What You’ll Need”시작하기 전에 다음 사항들이 준비되었는지 확인해 주세요.
- WhatsApp 계정
- OpenClaw CLI 도구
- 설정 저장을 위한 JSON5 구성 파일
Quick Start
섹션 제목: “Quick Start”5분 안에 WhatsApp 연동을 끝내는 최소 경로입니다. 단계를 차근차근 따라와 보세요.
1단계: WhatsApp Access Policy 설정하기
먼저 구성 파일에 채널 정책을 정의해야 합니다.
{ channels: { whatsapp: { dmPolicy: "pairing", allowFrom: ["+15551234567"], groupPolicy: "allowlist", groupAllowFrom: ["+15551234567"], }, },}2단계: WhatsApp 연결 (QR)
터미널에서 다음 명령어를 입력해 로그인하세요. QR 코드가 나타나면 WhatsApp 앱으로 스캔하면 됩니다.
openclaw channels login --channel whatsapp특정 계정을 지정해서 로그인할 수도 있어요.
openclaw channels login --channel whatsapp --account work3단계: Gateway 시작
연결을 활성화하기 위해 Gateway를 실행합니다.
openclaw gateway4단계: 첫 번째 Pairing 요청 승인 (Pairing 모드 사용 시)
Pairing 모드를 사용 중이라면 아래 명령어로 요청을 확인하고 승인하세요.
openclaw pairing list whatsappopenclaw pairing approve whatsapp <CODE>Deployment Patterns
섹션 제목: “Deployment Patterns”OpenClaw는 가능하면 별도의 전용 번호를 사용하는 방안을 추천해요. 채널 메타데이터와 온보딩 흐름이 이 설정에 최적화되어 있기 때문이죠.
전용 번호 사용 (권장) 가장 깔끔한 운영 방식입니다. OpenClaw를 위한 별도의 WhatsApp ID를 가지게 되므로 DM 허용 목록과 Routing 경계가 명확해집니다. 본인과의 채팅(self-chat) 혼선도 줄일 수 있어요.
{ channels: { whatsapp: { dmPolicy: "allowlist", allowFrom: ["+15551234567"], }, },}개인 번호 사용
개인 번호를 그대로 사용해야 하는 상황도 지원합니다. 이 경우 selfChatMode: true를 포함한 기본 설정이 적용되어 본인 계정과의 상호작용을 안전하게 처리합니다.
채널 범위 주의사항
현재 OpenClaw의 채널 아키텍처에서 WhatsApp은 WhatsApp Web 기반(Baileys)으로 작동합니다. 내장된 채널 레지스트리에 별도의 Twilio WhatsApp 채널은 포함되어 있지 않아요.
Runtime Model
섹션 제목: “Runtime Model”- Gateway가 WhatsApp Socket과 Reconnect Loop를 직접 관리합니다.
- 메시지 발신을 위해서는 대상 계정에 활성화된 WhatsApp Listener가 있어야 해요.
- 상태 업데이트(
@status)나 브로드캐스트(@broadcast) 채팅은 자동으로 무시됩니다. - 그룹 세션은
agent:<agentId>:whatsapp:group:<jid>형식으로 격리되어 관리됩니다.
Troubleshooting
섹션 제목: “Troubleshooting”문제가 발생했다면 다음 두 가지를 먼저 확인해 보세요.
- Pairing 요청 만료: Pairing 요청은 1시간이 지나면 만료됩니다. 시간이 지났다면 다시 요청해야 해요.
- 요청 제한: 대기 중인 Pairing 요청은 채널당 최대 3개까지만 유지됩니다.
설정 중에 막히는 부분이 있다면 AI Setup Assistant에게 물어보세요.
What’s Next
섹션 제목: “What’s Next”봇을 배포하고 나면 누구나 내 봇에 메시지를 보내거나 아무 그룹에나 봇을 초대하는 상황이 걱정될 수 있어요. 원치 않는 스팸을 막고 권한이 있는 사용자만 봇과 대화하게 만드는 것은 운영 측면에서 매우 중요하죠.
복잡한 인증 로직을 직접 구현하지 않아도, 설정 파일 몇 줄로 봇의 출입문을 꼼꼼하게 관리할 수 있는 방법을 정리해 드릴게요.
필요한 것
섹션 제목: “필요한 것”channels.whatsapp설정 권한- E.164 형식의 전화번호 리스트 (예:
+8210...) - 봇의 세션 관리 권한 (명령어 실행용)
빠른 시작
섹션 제목: “빠른 시작”가장 먼저 DM(Direct Message) 접근 권한을 설정해 보세요. channels.whatsapp.dmPolicy 옵션을 통해 제어할 수 있습니다.
channels: whatsapp: dmPolicy: pairing # pairing, allowlist, open, disabled 중 선택 allowFrom: ["+821012345678"]- pairing: 기본 설정값입니다.
- allowlist:
allowFrom에 명시된 번호만 대화할 수 있어요. - open: 모든 사용자에게 열려 있습니다. (단,
allowFrom에"*"가 포함되어야 해요) - disabled: 모든 인바운드 DM을 차단합니다.
allowFrom에 입력한 번호는 내부적으로 E.164 스타일로 정규화되어 처리되니 참고해 주세요.
Group policy + allowlists
섹션 제목: “Group policy + allowlists”그룹 채팅 접근은 두 가지 레이어로 더 세밀하게 관리할 수 있어요.
1. 그룹 멤버십 허용 리스트
섹션 제목: “1. 그룹 멤버십 허용 리스트”channels.whatsapp.groups 설정을 사용합니다.
- 이 항목을 생략하면 모든 그룹에서 동작할 수 있어요.
- 항목이 존재하면 일종의 allowlist 역할을 하며,
"*"를 넣어 모든 그룹을 허용할 수도 있습니다.
2. 그룹 발신자 정책
섹션 제목: “2. 그룹 발신자 정책”channels.whatsapp.groupPolicy와 groupAllowFrom을 조합해 사용하세요.
- open: 발신자 allowlist를 무시하고 모두의 메시지에 반응합니다.
- allowlist: 발신자가
groupAllowFrom(또는*)에 매칭되어야 합니다. - disabled: 그룹에서 오는 모든 메시지를 차단합니다.
만약 groupAllowFrom이 설정되어 있지 않다면, 시스템은 자동으로 allowFrom 설정을 대신 사용하게 됩니다. 별도의 channels.whatsapp 블록이 아예 없다면 런타임 시 그룹 정책은 기본적으로 open으로 작동해요.
Mentions + /activation
섹션 제목: “Mentions + /activation”그룹 채팅에서 봇은 기본적으로 멘션되었을 때만 응답합니다. 봇이 자신을 부르는지 감지하는 기준은 다음과 같아요.
- 봇 아이디를 직접 WhatsApp 멘션한 경우
- 설정된 정규표현식 패턴에 매칭된 경우 (
agents.list[].groupChat.mentionPatterns혹은messages.groupChat.mentionPatterns) - 봇의 메시지에 답장(Reply)을 한 경우 (Implicit reply-to-bot detection)
특정 세션에서 봇의 활성화 상태를 바꾸고 싶다면 다음 명령어를 사용해 보세요. 이 명령어는 소유자(Owner)만 실행할 수 있으며, 글로벌 설정이 아닌 해당 세션의 상태만 업데이트합니다.
/activation mention/activation always
Personal-number and self-chat behavior
섹션 제목: “Personal-number and self-chat behavior”연동된 봇의 번호와 allowFrom에 등록된 번호가 같을 때(자기 자신과의 채팅), WhatsApp self-chat 보호 기능이 활성화됩니다.
- 자기 자신과의 채팅에서는 읽음 확인(Read receipts)을 보내지 않아요.
- 멘션 JID 자동 트리거 동작을 무시해서 자기 자신에게 계속 알림이 오는 것을 방지합니다.
- 만약
messages.responsePrefix가 비어 있다면, self-chat 답장에는 기본적으로[{identity.name}]또는[openclaw]접두사가 붙습니다.
문제 해결
섹션 제목: “문제 해결”Q: 특정 번호를 allowFrom에 넣었는데도 작동하지 않아요.
A: 번호가 E.164 형식인지 확인해 보세요. 또한, 런타임에서 pairing된 번호는 채널의 allow-store에 저장되며 설정된 allowFrom과 병합됩니다. 단, 내가 먼저 보낸 DM(fromMe)은 자동으로 페어링되지 않는다는 점을 기억해 주세요.
Q: 설정 파일에 아무런 그룹 정책을 넣지 않았는데 모든 그룹 메시지에 응답합니다.
A: channels.whatsapp 블록이 아예 존재하지 않으면 런타임 그룹 정책은 open으로 폴백(Fallback)됩니다. 제한이 필요하다면 최소한의 정책 설정을 추가해야 합니다.
설정 과정에서 도움이 필요하신가요? AI Setup Assistant에게 물어보시면 실시간으로 답변을 드릴 수 있어요.
다음 단계
섹션 제목: “다음 단계”메신저 API를 연동하다 보면 플랫폼마다 제각각인 데이터 포맷 때문에 고생할 때가 많아요. 특히 메시지의 답장 관계를 파악하거나 이미지, 동영상 같은 미디어 메시지를 일관된 로직으로 처리하는 기능은 직접 구현하기 꽤 까다롭죠.
이 가이드에서는 WhatsApp을 통해 들어오는 다양한 메시지를 어떻게 표준화된 형태로 다루고, 대화의 맥락을 유지하는지 설명해 드릴게요.
필요한 것
섹션 제목: “필요한 것”- WhatsApp Channel 설정
- 서비스 구성 설정 (JSON5 형식)
빠른 시작
섹션 제목: “빠른 시작”WhatsApp에서 들어오는 메시지는 정규화된 Inbound envelope으로 감싸져서 전달돼요. 5분 안에 주요 설정을 마칠 수 있습니다.
1. 인바운드 봉투(Envelope)와 답장 컨텍스트
섹션 제목: “1. 인바운드 봉투(Envelope)와 답장 컨텍스트”메시지에 인용 답장이 포함된 경우, 아래와 같은 형식으로 컨텍스트가 본문에 추가돼요.
[Replying to <sender> id:<stanzaId>]<quoted body or media placeholder>[/Replying]ReplyToId, ReplyToBody, ReplyToSender, 발신자 JID/E.164와 같은 메타데이터 필드도 사용 가능한 경우 자동으로 채워집니다.
2. 미디어 및 위치 정보 처리
섹션 제목: “2. 미디어 및 위치 정보 처리”텍스트 없이 미디어만 있는 메시지는 다음과 같은 Placeholder로 정규화되어 들어와요.
<media:image><media:video><media:audio><media:document><media:sticker>
위치 정보와 연락처 데이터 역시 라우팅되기 전에 텍스트 컨텍스트로 변환됩니다.
3. 그룹 채팅 히스토리 주입
섹션 제목: “3. 그룹 채팅 히스토리 주입”그룹 채팅에서는 봇이 트리거될 때 처리되지 않은 이전 메시지들을 컨텍스트로 함께 넣어줄 수 있어요.
- 기본 제한:
50 - 설정:
channels.whatsapp.historyLimit - 예외 설정:
messages.groupChat.historyLimit 0으로 설정하면 이 기능이 비활성화돼요.
메시지 사이에는 아래와 같은 마커가 삽입되어 구분하기 편합니다.
[Chat messages since your last reply - for context][Current message - respond to this]
4. Read receipts 설정
섹션 제목: “4. Read receipts 설정”기본적으로 메시지를 수신하면 읽음 확인(Read receipts)을 보냅니다. 이를 변경하고 싶다면 설정을 수정하세요.
전역 비활성화:
{ channels: { whatsapp: { sendReadReceipts: false, }, },}계정별 개별 설정:
{ channels: { whatsapp: { accounts: { work: { sendReadReceipts: false, }, }, } }}문제 해결
섹션 제목: “문제 해결”- 나에게 보낸 메시지(Self-chat)에 읽음 표시가 안 돼요: Self-chat의 경우 전역 설정이 켜져 있어도 Read receipts 전송을 건너뛰도록 되어 있습니다.
- 그룹 메시지 컨텍스트가 너무 길어요:
channels.whatsapp.historyLimit값을 조절해서 주입되는 메시지 숫자를 줄여보세요.
설정 중에 어려운 부분이 있다면 AI Setup Assistant에게 바로 물어봐 주세요!
다음 단계
섹션 제목: “다음 단계”긴 메시지를 보냈는데 중간에 뚝 끊기거나, 용량이 큰 미디어가 전송되지 않아 곤란했던 적이 있나요? 개발자라면 누구나 한 번쯤 겪어봤을 법한 고민이에요. 메시지가 사용자에게 의도한 대로 깔끔하게 전달되도록 세부적인 설정을 맞추는 일은 정말 중요하죠.
이 가이드에서는 WhatsApp 채널에서 메시지 전달을 최적화하고 미디어와 계정을 관리하는 구체적인 방법을 설명해 드릴게요.
필요한 것
섹션 제목: “필요한 것”channels.whatsapp설정 권한- WhatsApp 계정 ID (다중 계정 사용 시)
- 전송할 미디어 소스 (HTTP(S),
file://또는 로컬 경로)
Quick Start (5분 완성)
섹션 제목: “Quick Start (5분 완성)”가장 먼저 텍스트 청킹과 자동 반응 설정을 적용해 보세요.
- 텍스트 청킹 설정: 긴 메시지를 나눌 기준을 정합니다.
channels.whatsapp.textChunkLimit = 4000channels.whatsapp.chunkMode = "newline"(문단 단위 분할 권장)
- 수신 확인 이모지 설정: 메시지를 받자마자 반응을 남기도록 설정합니다.
{ channels: { whatsapp: { ackReaction: { emoji: "👀", direct: true, group: "mentions", }, }, },}Delivery, chunking, and media
섹션 제목: “Delivery, chunking, and media”WhatsApp에서 텍스트와 미디어를 어떻게 다루는지 자세히 살펴볼까요?
Text chunking
섹션 제목: “Text chunking”메시지 길이에 따라 자동으로 텍스트를 나누는 기능이에요.
- 기본 제한:
channels.whatsapp.textChunkLimit = 4000 - 모드 선택:
channels.whatsapp.chunkMode는"length"또는"newline"중 하나를 선택할 수 있어요. - 동작 방식:
newline모드는 가급적 문단 구분선(빈 줄)을 기준으로 나누고, 여의치 않으면 길이에 맞춰 청킹을 진행해요.
Outbound media behavior
섹션 제목: “Outbound media behavior”이미지, 비디오, 오디오(PTT 음성 메시지), 문서 등 다양한 페이로드를 지원해요.
- 음성 메시지:
audio/ogg파일은 호환성을 위해audio/ogg; codecs=opus로 자동 재작성돼요. - GIF 재생: 비디오 전송 시
gifPlayback: true옵션을 주면 애니메이션 GIF로 재생할 수 있어요. - 캡션: 여러 미디어를 한 번에 보낼 때는 첫 번째 미디어 아이템에 캡션이 적용돼요.
Media size limits and fallback behavior
섹션 제목: “Media size limits and fallback behavior”- 수신 제한:
channels.whatsapp.mediaMaxMb로 설정하며, 기본값은50이에요. - 자동 응답 발신 제한:
agents.defaults.mediaMaxMb로 설정하며, 기본값은5MB예요. - 최적화: 이미지 크기가 제한을 넘으면 자동으로 리사이징이나 품질 조정을 거쳐요.
- 실패 대응: 미디어 전송에 실패하면 응답을 그냥 버리지 않고, 첫 번째 아이템 대신 텍스트 경고를 보내 알려줘요.
Acknowledgment reactions
섹션 제목: “Acknowledgment reactions”상대방의 메시지를 확인했다는 표시를 즉각적으로 남길 수 있어요. 이 기능은 channels.whatsapp.ackReaction 설정을 통해 작동해요.
- 메시지가 수락된 직후(답장 전)에 즉시 전송돼요.
- 반응 전송에 실패하더라도 로그만 남길 뿐, 실제 답장 전송을 방해하지는 않아요.
- 그룹 모드에서
mentions로 설정하면 멘션이 발생했을 때만 반응하고,always로 설정하면 이 체크를 건너뛰고 항상 반응해요. - 주의: 반드시
channels.whatsapp.ackReaction경로를 사용해야 해요. 레거시 설정인messages.ackReaction은 사용되지 않아요.
Multi-account and credentials
섹션 제목: “Multi-account and credentials”여러 개의 WhatsApp 계정을 관리하는 방법도 간단해요.
계정 선택 및 기본값
섹션 제목: “계정 선택 및 기본값”계정 ID는 channels.whatsapp.accounts에서 가져와요. default라는 ID가 있으면 그걸 먼저 사용하고, 없으면 정렬된 계정 목록 중 첫 번째 ID를 기본값으로 선택해요. 모든 계정 ID는 내부적으로 조회하기 좋게 정규화 과정을 거쳐요.
인증 경로 및 호환성
섹션 제목: “인증 경로 및 호환성”- 현재 인증 경로:
~/.openclaw/credentials/whatsapp/<accountId>/creds.json - 백업:
creds.json.bak파일이 자동으로 생성돼요. - 레거시 지원:
~/.openclaw/credentials/에 있는 기존 인증 파일도 기본 계정 흐름을 위해 여전히 인식되고 마이그레이션돼요.
Logout behavior
섹션 제목: “Logout behavior”특정 계정의 인증 상태를 지우려면 CLI를 사용하세요.
openclaw channels logout --channel whatsapp [--account <id>]레거시 인증 디렉토리에서는 Baileys 인증 파일은 삭제되지만 oauth.json은 보존돼요.
Tools, actions, and config writes
섹션 제목: “Tools, actions, and config writes”에이전트 툴을 통해 WhatsApp의 react(반응하기) 액션을 사용할 수 있어요. 또한 특정 액션을 허용하거나 제한할 수 있는 게이트 옵션이 제공돼요.
channels.whatsapp.actions.reactionschannels.whatsapp.actions.polls
채널에서 시작되는 설정 쓰기(configWrites)는 기본적으로 활성화되어 있어요. 만약 비활성화하고 싶다면 channels.whatsapp.configWrites=false로 설정하면 돼요.
문제 해결
섹션 제목: “문제 해결”문제가 생겼을 때 확인해 보세요.
- 미디어가 전송되지 않나요?
mediaMaxMb제한을 초과했는지 확인해 보세요. 전송 실패 시 텍스트 경고가 대신 전송되었는지 로그를 살펴보는 것도 좋아요. - 그룹에서 반응이 없나요?
group설정이mentions로 되어 있다면 멘션이 포함되었는지 확인하세요. 무조건 반응하게 하려면always로 변경해 보세요. - 인증 문제: 계정 로그아웃 후 다시 로그인해야 한다면
openclaw channels logout명령어를 활용해 상태를 초기화하세요.
설정 중에 궁금한 점이 생기면 언제든 AI Setup Assistant에게 물어봐 주세요!
다음 단계
섹션 제목: “다음 단계”---title: "WhatsApp Gateway 문제 해결하기"description: "WhatsApp Gateway 운영 중 발생하는 연결 문제와 설정 오류를 빠르게 해결하는 방법입니다."---
개발을 하다 보면 모든 설정이 완벽해 보이는데도 연결이 되지 않아 답답할 때가 있죠. 특히 메시지 Gateway를 설정할 때 발생하는 연결 루프나 메시지 누락 문제는 원인을 찾기 전까지 꽤나 고생스럽기도 해요.
분명히 가이드를 따랐는데 왜 내 환경에서만 동작하지 않는지 고민하고 계신가요? WhatsApp Gateway 운영 중 마주칠 수 있는 일반적인 문제들과 그 해결책을 정리했습니다.
## 필요한 것
시작하기 전에 다음 사항이 준비되어 있는지 확인해 주세요.
- openclaw CLI- 활성화된 WhatsApp 계정
## 빠른 시작
문제가 생겼을 때 가장 먼저 시도해 볼 수 있는 5분 해결 경로입니다.
1. **상태 확인**: 현재 채널의 연결 상태를 먼저 확인하세요. ```bash openclaw channels status- 재로그인: 연결이 끊겨 있다면 다시 로그인하여 세션을 갱신합니다.
Terminal window openclaw channels login --channel whatsapp
문제 해결
섹션 제목: “문제 해결”주요 증상별 해결 방법입니다. 소스 문서에 명시된 해결책을 참고하여 문제를 진단해 보세요.
연결되지 않음 (QR 코드 필요)
섹션 제목: “연결되지 않음 (QR 코드 필요)”증상: 채널 상태 보고서에 ‘not linked’라고 표시됩니다.
해결 방법: 아래 명령어를 입력하여 QR 코드를 스캔하고 로그인을 완료한 뒤 상태를 다시 확인하세요.
openclaw channels login --channel whatsappopenclaw channels status연결은 되었으나 끊김 또는 재연결 반복
섹션 제목: “연결은 되었으나 끊김 또는 재연결 반복”증상: 계정이 연결된 상태지만 계속해서 연결이 끊기거나 재연결을 시도합니다.
해결 방법: 시스템 진단 도구와 로그를 통해 원인을 파악해야 합니다.
openclaw doctoropenclaw logs --follow필요한 경우 channels login 명령어로 계정을 다시 연결해 보세요.
전송 시 활성 리스너 없음
섹션 제목: “전송 시 활성 리스너 없음”증상: 아웃바운드 메시지 전송 시 실패가 즉시 발생합니다.
해결 방법: 대상 계정에 대해 실행 중인 Gateway 리스너가 없는 경우 발생합니다. Gateway가 현재 실행 중인지, 그리고 해당 계정이 정상적으로 연결되어 있는지 확인하세요.
그룹 메시지가 무시됨
섹션 제목: “그룹 메시지가 무시됨”증상: 개인 메시지는 잘 오지만 그룹 메시지만 수신되지 않습니다.
해결 방법: 설정 파일에서 아래 항목들을 순서대로 검토해 보세요.
groupPolicy설정 확인groupAllowFrom/allowFrom필터링 여부groups허용 목록(allowlist) 항목- 멘션 게이팅 설정 (
requireMention및 멘션 패턴)
Bun 런타임 경고
섹션 제목: “Bun 런타임 경고”증상: Bun 환경에서 실행 시 경고가 발생하거나 동작이 불안정합니다.
해결 방법: WhatsApp Gateway 런타임은 Node.js를 사용해야 합니다. Bun은 WhatsApp 및 Telegram Gateway의 안정적인 운영과 호환되지 않는 것으로 분류되어 있습니다.
Configuration reference pointers
섹션 제목: “Configuration reference pointers”설정 최적화를 위해 참고해야 할 주요 필드들입니다. 자세한 내용은 Configuration reference - WhatsApp를 확인하세요.
주요 확인 필드:
- Access 제어:
dmPolicy,allowFrom,groupPolicy,groupAllowFrom,groups - 전송 설정:
textChunkLimit,chunkMode,mediaMaxMb,sendReadReceipts,ackReaction - 다중 계정:
accounts.<id>.enabled,accounts.<id>.authDir, 계정별 오버라이드 설정 - 운영 설정:
configWrites,debounceMs,web.enabled,web.heartbeatSeconds,web.reconnect.* - 세션 동작:
session.dmScope,historyLimit,dmHistoryLimit,dms.<id>.historyLimit
설정 과정에서 어려움이 있다면 AI Setup Assistant에게 도움을 요청해 보세요.
다음 단계
섹션 제목: “다음 단계”OpenClaw Expert
아직 막혀 있나요?
이 문서에서 답을 못 찾았다면 OpenClaw Expert에게 바로 물어보세요.