WhatsApp (웹 채널)
상태: WhatsApp Web(Baileys)을 통한 프로덕션 준비 완료. Gateway가 연결된 세션을 소유합니다.설치(필요 시)
openclaw onboard와openclaw channels add --channel whatsapp는 WhatsApp plugin을 처음 선택할 때 설치를 안내합니다.openclaw channels login --channel whatsapp도 plugin이 아직 없으면 설치 흐름을 제공합니다.- 개발 채널 + git 체크아웃: 기본값은 로컬 plugin 경로입니다.
- Stable/Beta: 기본값은 npm 패키지
@openclaw/whatsapp입니다.
페어링
알 수 없는 발신자에 대한 기본 DM 정책은 페어링입니다.
채널 문제 해결
채널 전반의 진단 및 복구 플레이북.
Gateway 구성
전체 채널 config 패턴 및 예시.
빠른 설정
가능하면 OpenClaw는 WhatsApp를 별도 번호로 운영하는 것을 권장합니다. (채널 메타데이터와 설정 흐름은 그 구성을 기준으로 최적화되어 있지만, 개인 번호 설정도 지원합니다.)
배포 패턴
전용 번호(권장)
전용 번호(권장)
가장 깔끔한 운영 모드입니다.
- OpenClaw용 별도 WhatsApp 신원
- 더 명확한 DM 허용 목록 및 라우팅 경계
- 자기 자신과의 채팅 혼동 가능성 감소
개인 번호 대체 사용
개인 번호 대체 사용
온보딩은 개인 번호 모드를 지원하며 self-chat 친화적인 기본 구성을 기록합니다.
dmPolicy: "allowlist"allowFrom에 개인 번호 포함selfChatMode: true
allowFrom을 기준으로 동작합니다.WhatsApp Web 전용 채널 범위
WhatsApp Web 전용 채널 범위
현재 OpenClaw 채널 아키텍처에서 메시징 플랫폼 채널은 WhatsApp Web 기반(
Baileys)입니다.내장 채팅 채널 레지스트리에는 별도의 Twilio WhatsApp 메시징 채널이 없습니다.런타임 모델
- Gateway가 WhatsApp 소켓과 재연결 루프를 소유합니다.
- 아웃바운드 전송은 대상 계정에 대해 활성 WhatsApp 리스너가 있어야 합니다.
- 상태 및 브로드캐스트 채팅은 무시됩니다(
@status,@broadcast). - 다이렉트 채팅은 DM 세션 규칙을 사용합니다(
session.dmScope; 기본값main은 DM을 agent 메인 세션으로 병합함). - 그룹 세션은 격리됩니다(
agent:<agentId>:whatsapp:group:<jid>).
접근 제어 및 활성화
- DM 정책
- 그룹 정책 + 허용 목록
- 멘션 + /activation
channels.whatsapp.dmPolicy는 다이렉트 채팅 접근을 제어합니다.pairing(기본값)allowlistopen(allowFrom에"*"포함 필요)disabled
allowFrom은 E.164 형식 번호를 받으며(내부적으로 정규화됨).멀티 계정 재정의: 해당 계정에서는 channels.whatsapp.accounts.<id>.dmPolicy(및 allowFrom)가 채널 수준 기본값보다 우선합니다.런타임 동작 세부 사항:- 페어링은 채널 allow-store에 영속 저장되며 구성된
allowFrom과 병합됩니다 - 허용 목록이 구성되지 않았으면 연결된 자기 번호가 기본적으로 허용됩니다
- 아웃바운드
fromMeDM은 자동 페어링되지 않습니다
개인 번호 및 self-chat 동작
연결된 자기 번호가allowFrom에도 포함되어 있으면 WhatsApp self-chat 보호가 활성화됩니다.
- self-chat 턴에서는 읽음 확인 생략
- 그렇지 않으면 자신에게 핑을 보낼 수 있는 mention-JID 자동 트리거 동작 무시
messages.responsePrefix가 설정되지 않은 경우, self-chat 응답의 기본값은[{identity.name}]또는[openclaw]
메시지 정규화 및 컨텍스트
수신 엔벌로프 + 답글 컨텍스트
수신 엔벌로프 + 답글 컨텍스트
들어오는 WhatsApp 메시지는 공용 수신 엔벌로프로 감싸집니다.인용된 답글이 있으면 다음 형식으로 컨텍스트가 추가됩니다.답글 메타데이터 필드도 가능하면 채워집니다(
ReplyToId, ReplyToBody, ReplyToSender, sender JID/E.164).미디어 플레이스홀더 및 위치/연락처 추출
미디어 플레이스홀더 및 위치/연락처 추출
미디어만 있는 수신 메시지는 다음과 같은 플레이스홀더로 정규화됩니다.
<media:image><media:video><media:audio><media:document><media:sticker>
보류 중인 그룹 기록 주입
보류 중인 그룹 기록 주입
그룹에서는 아직 처리되지 않은 메시지를 버퍼링했다가 봇이 최종적으로 트리거될 때 컨텍스트로 주입할 수 있습니다.
- 기본 한도:
50 - config:
channels.whatsapp.historyLimit - 대체값:
messages.groupChat.historyLimit 0은 비활성화
[Chat messages since your last reply - for context][Current message - respond to this]
읽음 확인
읽음 확인
읽음 확인은 허용된 수신 WhatsApp 메시지에 대해 기본적으로 활성화됩니다.전역 비활성화:계정별 재정의:self-chat 턴에서는 전역적으로 활성화되어 있어도 읽음 확인을 보내지 않습니다.
전달, 분할, 미디어
텍스트 분할
텍스트 분할
- 기본 분할 한도:
channels.whatsapp.textChunkLimit = 4000 channels.whatsapp.chunkMode = "length" | "newline"newline모드는 단락 경계(빈 줄)를 우선하며, 이후 길이 안전 분할로 대체합니다
아웃바운드 미디어 동작
아웃바운드 미디어 동작
- 이미지, 비디오, 오디오(PTT 음성 메모), 문서 페이로드 지원
- 음성 메모 호환성을 위해
audio/ogg는audio/ogg; codecs=opus로 다시 작성됩니다 - 비디오 전송 시
gifPlayback: true를 통해 애니메이션 GIF 재생 지원 - 다중 미디어 응답 페이로드 전송 시 캡션은 첫 번째 미디어 항목에 적용됩니다
- 미디어 소스는 HTTP(S),
file://, 또는 로컬 경로일 수 있습니다
미디어 크기 제한 및 대체 동작
미디어 크기 제한 및 대체 동작
- 수신 미디어 저장 한도:
channels.whatsapp.mediaMaxMb(기본값50) - 아웃바운드 미디어 전송 한도:
channels.whatsapp.mediaMaxMb(기본값50) - 계정별 재정의는
channels.whatsapp.accounts.<accountId>.mediaMaxMb사용 - 이미지는 제한에 맞도록 자동 최적화됩니다(크기 조정/품질 스윕)
- 미디어 전송 실패 시, 첫 번째 항목 대체 동작으로 응답을 조용히 버리지 않고 텍스트 경고를 전송합니다
반응 수준
channels.whatsapp.reactionLevel은 WhatsApp에서 에이전트가 이모지 반응을 얼마나 넓게 사용할지 제어합니다.
| 수준 | Ack 반응 | 에이전트 시작 반응 | 설명 |
|---|---|---|---|
"off" | 아니요 | 아니요 | 반응을 전혀 사용하지 않음 |
"ack" | 예 | 아니요 | Ack 반응만 사용(응답 전 수신 확인) |
"minimal" | 예 | 예(보수적) | Ack + 보수적 가이드의 agent 반응 |
"extensive" | 예 | 예(권장) | Ack + 권장 가이드의 agent 반응 |
"minimal".
계정별 재정의는 channels.whatsapp.accounts.<id>.reactionLevel을 사용합니다.
확인 반응
WhatsApp는channels.whatsapp.ackReaction을 통해 수신 즉시 Ack 반응을 지원합니다.
Ack 반응은 reactionLevel에 의해 제어되며, reactionLevel이 "off"이면 억제됩니다.
- 수신이 허용된 직후 즉시 전송됨(응답 전)
- 실패는 로그에 기록되지만 일반 응답 전달을 막지 않음
- 그룹 모드
mentions는 멘션으로 트리거된 턴에 반응하며, 그룹 활성화always는 이 검사를 우회하는 역할을 함 - WhatsApp는
channels.whatsapp.ackReaction을 사용합니다(레거시messages.ackReaction은 여기서 사용되지 않음)
멀티 계정 및 자격 증명
계정 선택 및 기본값
계정 선택 및 기본값
- 계정 ID는
channels.whatsapp.accounts에서 가져옵니다 - 기본 계정 선택:
default가 있으면 그것을, 없으면 첫 번째로 구성된 계정 ID(정렬 기준) - 조회를 위해 계정 ID는 내부적으로 정규화됩니다
자격 증명 경로 및 레거시 호환성
자격 증명 경로 및 레거시 호환성
- 현재 auth 경로:
~/.openclaw/credentials/whatsapp/<accountId>/creds.json - 백업 파일:
creds.json.bak ~/.openclaw/credentials/의 레거시 기본 auth도 기본 계정 흐름에서 계속 인식/마이그레이션됩니다
로그아웃 동작
로그아웃 동작
openclaw channels logout --channel whatsapp [--account <id>]는 해당 계정의 WhatsApp auth 상태를 지웁니다.레거시 auth 디렉터리에서는 oauth.json은 보존되고 Baileys auth 파일만 제거됩니다.도구, 작업, config 쓰기
- agent 도구 지원에는 WhatsApp 반응 작업(
react)이 포함됩니다. - 작업 게이트:
channels.whatsapp.actions.reactionschannels.whatsapp.actions.polls
- 채널 시작 config 쓰기는 기본적으로 활성화되어 있습니다(
channels.whatsapp.configWrites=false로 비활성화).
문제 해결
연결되지 않음(QR 필요)
연결되지 않음(QR 필요)
증상: 채널 상태에 연결되지 않음으로 표시됨.해결 방법:
연결되었지만 연결 해제됨 / 재연결 루프
연결되었지만 연결 해제됨 / 재연결 루프
증상: 계정은 연결되었지만 연결 해제 또는 재연결 시도가 반복됨.해결 방법:필요하면
channels login으로 다시 연결하세요.전송 시 활성 리스너 없음
전송 시 활성 리스너 없음
대상 계정에 활성 gateway 리스너가 없으면 아웃바운드 전송은 즉시 실패합니다.gateway가 실행 중이고 계정이 연결되어 있는지 확인하세요.
그룹 메시지가 예상과 다르게 무시됨
그룹 메시지가 예상과 다르게 무시됨
다음 순서로 확인하세요.
groupPolicygroupAllowFrom/allowFromgroups허용 목록 항목- 멘션 게이팅(
requireMention+ mention 패턴) openclaw.json(JSON5)의 중복 키: 나중 항목이 앞선 항목을 덮어쓰므로 범위별로groupPolicy는 하나만 유지하세요
Bun 런타임 경고
Bun 런타임 경고
WhatsApp gateway 런타임은 Node를 사용해야 합니다. Bun은 안정적인 WhatsApp/Telegram gateway 운영과 호환되지 않는 것으로 표시됩니다.
구성 참조 포인터
기본 참조: 신호가 높은 WhatsApp 필드:- 접근:
dmPolicy,allowFrom,groupPolicy,groupAllowFrom,groups - 전달:
textChunkLimit,chunkMode,mediaMaxMb,sendReadReceipts,ackReaction,reactionLevel - 멀티 계정:
accounts.<id>.enabled,accounts.<id>.authDir, 계정 수준 재정의 - 운영:
configWrites,debounceMs,web.enabled,web.heartbeatSeconds,web.reconnect.* - 세션 동작:
session.dmScope,historyLimit,dmHistoryLimit,dms.<id>.historyLimit