메인 콘텐츠로 건너뛰기

Zalo (Bot API)

상태: experimental. DM을 지원하며, 그룹 처리는 명시적인 group policy control과 함께 사용할 수 있습니다.

Plugin 필요

Zalo는 plugin으로 제공되며 core install에 번들되어 있지 않습니다.
  • CLI 설치: openclaw plugins install @openclaw/zalo
  • 또는 onboarding 중 Zalo를 선택하고 설치 프롬프트를 승인
  • 자세한 내용: Plugins

빠른 설정(beginner)

  1. Zalo plugin을 설치합니다.
    • source checkout: openclaw plugins install ./extensions/zalo
    • npm(게시된 경우): openclaw plugins install @openclaw/zalo
    • 또는 onboarding에서 Zalo 선택 후 설치 프롬프트 승인
  2. token 설정:
    • Env: ZALO_BOT_TOKEN=...
    • 또는 config: channels.zalo.botToken: "..."
  3. gateway 재시작(또는 onboarding 완료)
  4. 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)

  1. https://bot.zaloplatforms.com에 가서 로그인
  2. 새 bot을 만들고 설정
  3. bot token 복사(형식: 12345689:abc-xyz)

2) token 설정(env 또는 config)

예시:
env 옵션: ZALO_BOT_TOKEN=... (default account 전용) multi-account는 channels.zalo.accounts에 계정별 token과 선택적 name을 설정합니다.
  1. gateway 재시작. Zalo는 token이 해결되면(env 또는 config) 시작됩니다.
  2. 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 zalo
    • openclaw 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으로 fallback
  • groupPolicy: "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.webhookUrlchannels.zalo.webhookSecret 설정
    • webhook secret은 8-256자여야 함
    • webhook URL은 HTTPS여야 함
    • Zalo는 X-Bot-Api-Secret-Token header로 이벤트를 보냄
    • 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를 반환할 수 있음
참고: Zalo API 문서 기준으로 getUpdates(polling)와 webhook은 동시에 사용할 수 없습니다.

지원 메시지 타입

  • Text messages: 2000자 chunking과 함께 완전 지원
  • Image messages: inbound image를 다운로드/처리하고 sendPhoto로 발신 가능
  • Stickers: 로그는 남기지만 agent response는 트리거하지 않음
  • Unsupported types: 로그만 남김(예: protected user message)

Capabilities

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이 event를 받지 못할 때:
  • 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 token
  • channels.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으로 fallback
  • channels.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 path
  • channels.zalo.proxy: API request용 proxy URL
Multi-account option:
  • channels.zalo.accounts.<id>.botToken: account별 token
  • channels.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 policy
  • channels.zalo.accounts.<id>.allowFrom: account별 allowlist
  • channels.zalo.accounts.<id>.groupPolicy: account별 group policy
  • channels.zalo.accounts.<id>.groupAllowFrom: account별 group sender allowlist
  • channels.zalo.accounts.<id>.webhookUrl: account별 webhook URL
  • channels.zalo.accounts.<id>.webhookSecret: account별 webhook secret
  • channels.zalo.accounts.<id>.webhookPath: account별 webhook path
  • channels.zalo.accounts.<id>.proxy: account별 proxy URL