Zalo (Bot API)
상태: experimental. DM을 지원하며, 그룹 처리는 명시적인 group policy control과 함께 사용할 수 있습니다.Plugin 필요
Zalo는 plugin으로 제공되며 core install에 번들되어 있지 않습니다.- CLI 설치:
openclaw plugins install @openclaw/zalo - 또는 onboarding 중 Zalo를 선택하고 설치 프롬프트를 승인
- 자세한 내용: Plugins
빠른 설정(beginner)
- Zalo plugin을 설치합니다.
- source checkout:
openclaw plugins install ./extensions/zalo - npm(게시된 경우):
openclaw plugins install @openclaw/zalo - 또는 onboarding에서 Zalo 선택 후 설치 프롬프트 승인
- source checkout:
- token 설정:
- Env:
ZALO_BOT_TOKEN=... - 또는 config:
channels.zalo.botToken: "..."
- Env:
- gateway 재시작(또는 onboarding 완료)
- DM access는 기본적으로 pairing입니다. 첫 contact에서 pairing code를 승인하세요.
이것이 의미하는 것
Zalo는 베트남 중심 메시징 앱이며, Bot API를 통해 Gateway가 1:1 대화용 bot을 실행할 수 있습니다. support나 notification처럼 Zalo로 결정론적으로 돌아가야 하는 흐름에 적합합니다.- Gateway가 소유하는 Zalo Bot API 채널
- 결정론적 라우팅: reply는 Zalo로 돌아가며 모델이 채널을 고르지 않음
- DM은 agent의 main session을 공유
- Groups는 policy control(
groupPolicy+groupAllowFrom)과 함께 지원되며, 기본값은 fail-closed allowlist 동작
설정(fast path)
1) bot token 생성(Zalo Bot Platform)
- https://bot.zaloplatforms.com에 가서 로그인
- 새 bot을 만들고 설정
- bot token 복사(형식:
12345689:abc-xyz)
2) token 설정(env 또는 config)
예시:ZALO_BOT_TOKEN=... (default account 전용)
multi-account는 channels.zalo.accounts에 계정별 token과 선택적 name을
설정합니다.
- gateway 재시작. Zalo는 token이 해결되면(env 또는 config) 시작됩니다.
- DM access 기본값은 pairing입니다. bot에 처음 연락하면 code를 승인하세요.
동작 방식
- inbound message는 media placeholder를 포함한 공통 channel envelope로 정규화됨
- reply는 항상 같은 Zalo chat으로 돌아감
- 기본은 long-polling,
channels.zalo.webhookUrl로 webhook 모드 사용 가능
Limits
- outbound text는 2000자(Zalo API 제한) 단위로 chunking
- media download/upload는
channels.zalo.mediaMaxMb(기본 5)로 제한 - 2000자 제한 때문에 streaming은 기본적으로 차단
접근 제어(DMs)
DM access
- 기본값:
channels.zalo.dmPolicy = "pairing". 알 수 없는 sender는 pairing code를 받고, 승인 전까지 메시지는 무시됩니다(code는 1시간 후 만료). - 승인:
openclaw pairing list zaloopenclaw pairing approve zalo <CODE>
- pairing은 기본 token exchange 방식입니다. 자세한 내용: Pairing
channels.zalo.allowFrom은 numeric user ID만 받습니다 (username lookup 없음).
접근 제어(Groups)
channels.zalo.groupPolicy는 group inbound 처리 방식을 제어:open | allowlist | disabled- 기본 동작은 fail-closed:
allowlist channels.zalo.groupAllowFrom은 group에서 bot을 트리거할 수 있는 sender ID를 제한groupAllowFrom이 없으면 sender 검사는allowFrom으로 fallbackgroupPolicy: "disabled"는 모든 group message 차단groupPolicy: "open"은 모든 group member를 허용(mention-gated)- runtime 참고:
channels.zalo가 아예 없더라도 안전을 위해groupPolicy="allowlist"로 fallback
Long-polling vs webhook
- 기본값: long-polling (public URL 불필요)
- webhook 모드:
channels.zalo.webhookUrl과channels.zalo.webhookSecret설정- webhook secret은 8-256자여야 함
- webhook URL은 HTTPS여야 함
- Zalo는
X-Bot-Api-Secret-Tokenheader로 이벤트를 보냄 - Gateway HTTP는
channels.zalo.webhookPath에서 webhook request 처리 (기본값: webhook URL path) - request는
Content-Type: application/json(또는+json)이어야 함 - 중복 event(
event_name + message_id)는 짧은 replay window 안에서 무시 - burst traffic은 path/source별로 rate limit되며 HTTP 429를 반환할 수 있음
지원 메시지 타입
- Text messages: 2000자 chunking과 함께 완전 지원
- Image messages: inbound image를 다운로드/처리하고
sendPhoto로 발신 가능 - Stickers: 로그는 남기지만 agent response는 트리거하지 않음
- Unsupported types: 로그만 남김(예: protected user message)
Capabilities
| Feature | Status |
|---|---|
| Direct messages | Supported |
| Groups | Supported with policy controls (allowlist by default) |
| Media (images) | Supported |
| Reactions | Not supported |
| Threads | Not supported |
| Polls | Not supported |
| Native commands | Not supported |
| Streaming | Blocked (2000 char limit) |
Delivery targets (CLI/cron)
- target에는 chat id 사용
- 예시:
openclaw message send --channel zalo --target 123456789 --message "hi"
문제 해결
bot이 응답하지 않을 때:- token이 유효한지 확인:
openclaw channels status --probe - sender가 승인되었는지 확인(pairing 또는 allowFrom)
- gateway logs 확인:
openclaw logs --follow
- webhook URL이 HTTPS인지 확인
- secret token이 8-256자인지 확인
- gateway HTTP endpoint가 설정된 path에서 도달 가능한지 확인
- getUpdates polling이 동시에 실행 중이 아닌지 확인(서로 배타적)
Configuration reference (Zalo)
전체 구성: Configuration Provider option:channels.zalo.enabled: 채널 시작 활성화/비활성화channels.zalo.botToken: Zalo Bot Platform의 bot tokenchannels.zalo.tokenFile: regular file에서 token 읽기. symlink는 거부channels.zalo.dmPolicy:pairing | allowlist | open | disabled(기본 pairing)channels.zalo.allowFrom: DM allowlist(user IDs).open에는"*"필요. wizard는 numeric ID를 묻습니다.channels.zalo.groupPolicy:open | allowlist | disabled(기본 allowlist)channels.zalo.groupAllowFrom: group sender allowlist(user IDs). 비어 있으면allowFrom으로 fallbackchannels.zalo.mediaMaxMb: inbound/outbound media cap(MB, 기본 5)channels.zalo.webhookUrl: webhook 모드 활성화(HTTPS 필요)channels.zalo.webhookSecret: webhook secret(8-256자)channels.zalo.webhookPath: gateway HTTP server의 webhook pathchannels.zalo.proxy: API request용 proxy URL
channels.zalo.accounts.<id>.botToken: account별 tokenchannels.zalo.accounts.<id>.tokenFile: account별 regular token file (symlink 거부)channels.zalo.accounts.<id>.name: 표시 이름channels.zalo.accounts.<id>.enabled: account 활성화/비활성화channels.zalo.accounts.<id>.dmPolicy: account별 DM policychannels.zalo.accounts.<id>.allowFrom: account별 allowlistchannels.zalo.accounts.<id>.groupPolicy: account별 group policychannels.zalo.accounts.<id>.groupAllowFrom: account별 group sender allowlistchannels.zalo.accounts.<id>.webhookUrl: account별 webhook URLchannels.zalo.accounts.<id>.webhookSecret: account별 webhook secretchannels.zalo.accounts.<id>.webhookPath: account별 webhook pathchannels.zalo.accounts.<id>.proxy: account별 proxy URL