From zalo
Set up the Zalo channel — check login, review access policy, lock down the allowlist. Use when the user asks to configure Zalo, asks "how do I set this up" or "who can reach me", or wants channel status.
How this skill is triggered — by the user, by Claude, or both
Slash command
/zalo:configureThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Orients the user on login state and access policy. Login uses QR (the /zalo:auth skill).
Orients the user on login state and access policy. Login uses QR (the /zalo:auth skill).
Everything is account-global. A single always-on daemon owns the Zalo connection and all
state lives at ~/.claude/channels/zalo/ — credentials, messages.db, and access.json. There
is no longer a per-project state dir ($ZALO_STATE_DIR overrides the root for tests). All paths
below are under ~/.claude/channels/zalo/.
Migration (one-time). Access used to be per-project. If a project still has
<project>/.claude/channels/zalo/access.json, copy it once to the account-global location — only the global one is read now:copy <project>\.claude\channels\zalo\access.json %USERPROFILE%\.claude\channels\zalo\access.jsonIf both exist, the account-global one wins (it's the only one read).
Arguments passed: $ARGUMENTS
Login — check whether ~/.claude/channels/zalo/credentials.json exists (credentials are
user-root, not project-local). If not, the next step is /zalo:auth (QR scan). Stop there —
access policy means nothing while logged out.
Inbound delivery — the session that should answer Zalo just needs the channel flag:
claude --dangerously-load-development-channels plugin:zalo@imrim12
--dangerously-load-development-channels, Claude Code silently drops inbound
messages (the plugin is not on the built-in approved-channels allowlist).claude process and auto-enables inbound for
that session — so the session that renders notifications is also the one that claims them,
even with other Claude sessions open. No env var to set.ZALO_INBOUND=1 forces a session to answer, ZALO_INBOUND=0 forces it
silent (explicit value wins over auto-detection).Tell the user — outbound tools working is NOT evidence inbound is enabled.
Access — read ~/.claude/channels/zalo/access.json (missing = defaults:
dmPolicy: "pairing", empty allowlist). Show:
What next — concrete next step based on state:
/zalo:auth and scan the QR."/zalo:access pair <code>."Push toward lockdown — always. The goal for every setup is allowlist with a defined list.
pairing is not a policy to stay on; it's a temporary way to capture Zalo user ids you don't
know. It also makes your personal account auto-reply to any stranger who DMs you — both a spam
beacon and out-of-character traffic from your own identity. Once the ids are in, pairing has
done its job and should be turned off.
Drive the conversation:
pairing → "Let's lock it down:" and offer to run
/zalo:access policy allowlist. Do this proactively — don't wait to be asked./zalo:access pair <code>.
Run this skill again once everyone's in and we'll lock it."allowlist → confirm this is the locked state. To add someone:
/zalo:access allow <id> if their Zalo user id is known, or briefly flip to pairing
(/zalo:access policy pairing), have them DM, approve the code, and flip back.Never frame pairing as the correct long-term choice. Don't skip the lockdown offer.
Creates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.
npx claudepluginhub imrim12/claude-plugin-zalo --plugin zalo