mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-25 20:05:46 -06:00
6e026c2fe3
* fix(gateway): bind auth limits to ingress attribution * fix(gateway): close remaining ingress auth gaps * fix(gateway): carry attribution into new ingress paths * fix(gateway): close ingress ownership gaps * fix(gateway): complete proxy ingress hardening * fix(gateway): stabilize managed Tailscale ingress * fix(gateway): make Tailscale cleanup ownership-safe Refuse reset-on-exit publication until Tailscale exposes an atomic owner-bound cleanup operation, and migrate legacy configs with Doctor. * fix(gateway): finish ingress ownership repair * fix(gateway): own managed Tailscale route lifetime Run managed Serve and Funnel routes as foreground claims tied to the Gateway lifecycle. Retire named Service config through Doctor because Tailscale Services cannot run in foreground mode. Co-authored-by: Pavan Kumar Gondhi <pavangondhi@gmail.com> * fix(gateway): align Tailscale consumers and build guards Remove the retired named-service config from Telegram Mini App URL resolution and register the lifecycle worker as an explicit production entry. Co-authored-by: Pavan Kumar Gondhi <pavangondhi@gmail.com> * fix(gateway): preserve retired Tailscale inputs Keep Funnel enabled when removing an ignored named-Service setting and accept the legacy positive reset flag as a no-op now that managed routes always follow Gateway lifetime. Co-authored-by: Pavan Kumar Gondhi <pavangondhi@gmail.com> * fix(gateway): preserve Tailscale route diagnostics Prefer the actionable foreground CLI failure captured during timeout cleanup, and cover the original delayed-failure ordering. Co-authored-by: Pavan Kumar Gondhi <pavangondhi@gmail.com> * fix(gateway): reconcile Tailscale ingress with main Preserve current ingress ownership contracts after the rebase, retire the obsolete device-auth migration check, validate route-owner IPC, and move Tailscale auth coverage onto the managed listener. Co-authored-by: Pavan Kumar Gondhi <pavangondhi@gmail.com> * fix(gateway): finish ingress rebase coverage Unify the rebased net imports and let module-reset WebSocket tests prepare attribution through the same fresh module instance as the handler. Co-authored-by: Pavan Kumar Gondhi <pavangondhi@gmail.com> * test(gateway): align run-loop server fixture --------- Co-authored-by: joshavant <830519+joshavant@users.noreply.github.com>
684 lines
17 KiB
Markdown
684 lines
17 KiB
Markdown
---
|
|
summary: "Schema-accurate configuration examples for common OpenClaw setups"
|
|
read_when:
|
|
- Learning how to configure OpenClaw
|
|
- Looking for configuration examples
|
|
- Setting up OpenClaw for the first time
|
|
title: "Configuration examples"
|
|
---
|
|
|
|
Examples below are aligned with the current config schema. For the exhaustive reference and per-field notes, see [Configuration](/gateway/configuration).
|
|
|
|
## Quick start
|
|
|
|
### Absolute minimum
|
|
|
|
```json5
|
|
{
|
|
agents: { defaults: { workspace: "~/.openclaw/workspace" } },
|
|
channels: { whatsapp: { allowFrom: ["+15555550123"] } },
|
|
}
|
|
```
|
|
|
|
Save to `~/.openclaw/openclaw.json` and you can DM the bot from that number.
|
|
|
|
### Recommended starter
|
|
|
|
```json5
|
|
{
|
|
agents: {
|
|
defaults: {
|
|
workspace: "~/.openclaw/workspace",
|
|
model: { primary: "anthropic/claude-sonnet-4-6" },
|
|
},
|
|
entries: {
|
|
main: {
|
|
identity: {
|
|
name: "Clawd",
|
|
theme: "helpful assistant",
|
|
emoji: "🦞",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
channels: {
|
|
whatsapp: {
|
|
allowFrom: ["+15555550123"],
|
|
groups: { "*": { requireMention: true } },
|
|
},
|
|
},
|
|
messages: {
|
|
visibleReplies: "automatic",
|
|
groupChat: {
|
|
visibleReplies: "message_tool", // opt-in; visible output requires message(action=send)
|
|
unmentionedInbound: "room_event",
|
|
},
|
|
},
|
|
}
|
|
```
|
|
|
|
## Expanded example (major options)
|
|
|
|
> JSON5 lets you use comments and trailing commas. Regular JSON works too.
|
|
|
|
```json5
|
|
{
|
|
// Environment + shell
|
|
env: {
|
|
vars: {
|
|
OPENROUTER_API_KEY: "sk-or-...",
|
|
GROQ_API_KEY: "gsk-...",
|
|
},
|
|
shellEnv: {
|
|
enabled: true,
|
|
timeoutMs: 15000,
|
|
},
|
|
},
|
|
|
|
// Auth profile metadata (secrets live in auth-profiles.json)
|
|
auth: {
|
|
profiles: {
|
|
"anthropic:default": { provider: "anthropic", mode: "api_key" },
|
|
"anthropic:work": { provider: "anthropic", mode: "api_key" },
|
|
"openai:default": { provider: "openai", mode: "api_key" },
|
|
"openai:personal": { provider: "openai", mode: "oauth" },
|
|
},
|
|
order: {
|
|
anthropic: ["anthropic:default", "anthropic:work"],
|
|
openai: ["openai:personal", "openai:default"],
|
|
},
|
|
},
|
|
|
|
// Identity is per agent — set it on agents.entries.<id>.identity below.
|
|
|
|
// Logging
|
|
logging: {
|
|
level: "info",
|
|
file: "/tmp/openclaw/openclaw.log",
|
|
consoleLevel: "info",
|
|
consoleStyle: "pretty",
|
|
},
|
|
|
|
// Message formatting
|
|
messages: {
|
|
visibleReplies: "automatic",
|
|
responsePrefix: ">",
|
|
ackReaction: "👀",
|
|
ackReactionScope: "group-mentions",
|
|
groupChat: {
|
|
historyLimit: 50,
|
|
visibleReplies: "message_tool", // opt in for shared rooms with tool-reliable models
|
|
unmentionedInbound: "room_event",
|
|
},
|
|
queue: {
|
|
mode: "followup",
|
|
cap: 20,
|
|
drop: "summarize",
|
|
byChannel: {
|
|
whatsapp: "followup",
|
|
telegram: "followup",
|
|
discord: "collect",
|
|
slack: "collect",
|
|
signal: "followup",
|
|
imessage: "followup",
|
|
webchat: "followup",
|
|
},
|
|
},
|
|
},
|
|
|
|
// Session behavior
|
|
session: {
|
|
scope: "per-sender",
|
|
dmScope: "per-channel-peer", // recommended for multi-user inboxes
|
|
reset: {
|
|
mode: "daily",
|
|
atHour: 4,
|
|
idleMinutes: 60,
|
|
},
|
|
resetByChannel: {
|
|
discord: { mode: "idle", idleMinutes: 10080 },
|
|
},
|
|
resetTriggers: ["/new", "/reset"],
|
|
store: "~/.openclaw/agents/main/sessions/sessions.json",
|
|
maintenance: {
|
|
mode: "warn",
|
|
pruneAfter: "30d",
|
|
maxEntries: 500,
|
|
resetArchiveRetention: "30d", // duration or false
|
|
maxDiskBytes: "500mb", // optional
|
|
highWaterBytes: "400mb", // optional (defaults to 80% of maxDiskBytes)
|
|
},
|
|
sendPolicy: {
|
|
default: "allow",
|
|
rules: [{ action: "deny", match: { channel: "discord", chatType: "group" } }],
|
|
},
|
|
},
|
|
|
|
// Channels
|
|
channels: {
|
|
whatsapp: {
|
|
dmPolicy: "pairing",
|
|
allowFrom: ["+15555550123"],
|
|
groupPolicy: "allowlist",
|
|
groupAllowFrom: ["+15555550123"],
|
|
groups: { "*": { requireMention: true } },
|
|
},
|
|
|
|
telegram: {
|
|
enabled: true,
|
|
botToken: "YOUR_TELEGRAM_BOT_TOKEN",
|
|
allowFrom: ["123456789"],
|
|
groupPolicy: "allowlist",
|
|
groupAllowFrom: ["123456789"],
|
|
groups: { "*": { requireMention: true } },
|
|
},
|
|
|
|
discord: {
|
|
enabled: true,
|
|
token: "YOUR_DISCORD_BOT_TOKEN",
|
|
dmPolicy: "allowlist",
|
|
allowFrom: ["123456789012345678"],
|
|
guilds: {
|
|
"123456789012345678": {
|
|
slug: "friends-of-openclaw",
|
|
requireMention: false,
|
|
channels: {
|
|
general: { enabled: true },
|
|
help: { enabled: true, requireMention: true },
|
|
},
|
|
},
|
|
},
|
|
},
|
|
|
|
slack: {
|
|
enabled: true,
|
|
botToken: "xoxb-REPLACE_ME",
|
|
appToken: "xapp-REPLACE_ME",
|
|
channels: {
|
|
"#general": { enabled: true, requireMention: true },
|
|
},
|
|
dmPolicy: "allowlist",
|
|
allowFrom: ["U123"],
|
|
slashCommand: {
|
|
enabled: true,
|
|
name: "openclaw",
|
|
sessionPrefix: "slack:slash",
|
|
ephemeral: true,
|
|
},
|
|
},
|
|
},
|
|
|
|
// Agent runtime
|
|
agents: {
|
|
defaults: {
|
|
workspace: "~/.openclaw/workspace",
|
|
userTimezone: "America/Chicago",
|
|
model: {
|
|
primary: "anthropic/claude-sonnet-4-6",
|
|
fallbacks: ["anthropic/claude-opus-4-6", "openai/gpt-5.4"],
|
|
},
|
|
imageModel: {
|
|
primary: "openrouter/anthropic/claude-sonnet-4-6",
|
|
},
|
|
models: {
|
|
"anthropic/claude-opus-4-6": { alias: "opus" },
|
|
"anthropic/claude-sonnet-4-6": { alias: "sonnet" },
|
|
"openai/gpt-5.4": { alias: "gpt" },
|
|
},
|
|
skills: ["github", "weather"], // inherited by agents that omit list[].skills
|
|
thinkingDefault: "low",
|
|
verboseDefault: "off",
|
|
toolProgressDetail: "explain",
|
|
reasoningDefault: "off",
|
|
elevatedDefault: "on",
|
|
blockStreamingDefault: "off",
|
|
blockStreamingBreak: "text_end",
|
|
blockStreamingChunk: {
|
|
minChars: 800,
|
|
maxChars: 1200,
|
|
breakPreference: "paragraph",
|
|
},
|
|
blockStreamingCoalesce: {
|
|
idleMs: 1000,
|
|
},
|
|
humanDelay: {
|
|
mode: "natural",
|
|
},
|
|
timeoutSeconds: 600,
|
|
mediaMaxMb: 5,
|
|
typingIntervalSeconds: 5,
|
|
maxConcurrent: 3,
|
|
heartbeat: {
|
|
every: "30m",
|
|
model: "anthropic/claude-sonnet-4-6",
|
|
target: "whatsapp",
|
|
directPolicy: "allow", // allow (default) | block
|
|
to: "+15555550123",
|
|
prompt: "HEARTBEAT",
|
|
},
|
|
sandbox: {
|
|
mode: "non-main",
|
|
scope: "session", // preferred over legacy perSession: true
|
|
workspaceRoot: "~/.openclaw/sandboxes",
|
|
docker: {
|
|
image: "openclaw-sandbox:bookworm-slim",
|
|
workdir: "/workspace",
|
|
readOnlyRoot: true,
|
|
tmpfs: ["/tmp", "/var/tmp", "/run"],
|
|
network: "none",
|
|
user: "1000:1000",
|
|
},
|
|
browser: {
|
|
enabled: false,
|
|
},
|
|
},
|
|
},
|
|
entries: {
|
|
main: {
|
|
default: true,
|
|
identity: {
|
|
name: "Samantha",
|
|
theme: "helpful sloth",
|
|
emoji: "🦥",
|
|
},
|
|
// inherits defaults.skills -> github, weather
|
|
groupChat: {
|
|
mentionPatterns: ["@openclaw", "openclaw"],
|
|
},
|
|
thinkingDefault: "high", // per-agent thinking override
|
|
reasoningDefault: "on", // per-agent reasoning visibility
|
|
fastModeDefault: false, // per-agent fast mode
|
|
},
|
|
quick: {
|
|
skills: [], // no skills for this agent
|
|
fastModeDefault: true, // this agent always runs fast
|
|
thinkingDefault: "off",
|
|
},
|
|
},
|
|
},
|
|
|
|
memory: {
|
|
search: {
|
|
provider: "gemini",
|
|
model: "gemini-embedding-001",
|
|
remote: {
|
|
apiKey: "${GEMINI_API_KEY}",
|
|
},
|
|
extraPaths: ["../team-docs", "/srv/shared-notes"],
|
|
},
|
|
},
|
|
|
|
tools: {
|
|
media: {
|
|
models: [
|
|
{ provider: "openai", model: "gpt-4o-transcribe", capabilities: ["audio"] },
|
|
{ provider: "google", model: "gemini-3-flash-preview", capabilities: ["video"] },
|
|
],
|
|
audio: { enabled: true, maxBytes: 20971520, timeoutSeconds: 120 },
|
|
video: { enabled: true, maxBytes: 52428800 },
|
|
},
|
|
allow: ["exec", "process", "read", "write", "edit", "apply_patch"],
|
|
deny: ["browser", "canvas"],
|
|
exec: {
|
|
backgroundMs: 10000,
|
|
timeoutSeconds: 1800,
|
|
cleanupMs: 1800000,
|
|
},
|
|
elevated: {
|
|
enabled: true,
|
|
allowFrom: {
|
|
whatsapp: ["+15555550123"],
|
|
telegram: ["123456789"],
|
|
discord: ["123456789012345678"],
|
|
slack: ["U123"],
|
|
signal: ["+15555550123"],
|
|
imessage: ["user@example.com"],
|
|
webchat: ["session:demo"],
|
|
},
|
|
},
|
|
},
|
|
|
|
// Custom model providers
|
|
models: {
|
|
mode: "merge",
|
|
providers: {
|
|
"custom-proxy": {
|
|
baseUrl: "http://localhost:4000/v1",
|
|
apiKey: "LITELLM_KEY",
|
|
api: "openai-responses",
|
|
authHeader: true,
|
|
headers: { "X-Proxy-Region": "us-west" },
|
|
models: [
|
|
{
|
|
id: "llama-3.1-8b",
|
|
name: "Llama 3.1 8B",
|
|
api: "openai-responses",
|
|
reasoning: false,
|
|
input: ["text"],
|
|
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
contextWindow: 128000,
|
|
maxTokens: 32000,
|
|
},
|
|
],
|
|
},
|
|
},
|
|
},
|
|
|
|
// Cron jobs
|
|
cron: {
|
|
enabled: true,
|
|
sessionRetention: "24h",
|
|
},
|
|
|
|
// Webhooks
|
|
hooks: {
|
|
enabled: true,
|
|
path: "/hooks",
|
|
token: "shared-secret",
|
|
presets: ["gmail"],
|
|
transformsDir: "~/.openclaw/hooks/transforms",
|
|
mappings: [
|
|
{
|
|
id: "gmail-hook",
|
|
match: { path: "gmail" },
|
|
action: "agent",
|
|
wakeMode: "now",
|
|
name: "Gmail",
|
|
sessionKey: "hook:gmail:{{messages[0].id}}",
|
|
messageTemplate: "From: {{messages[0].from}}\nSubject: {{messages[0].subject}}",
|
|
textTemplate: "{{messages[0].snippet}}",
|
|
deliver: true,
|
|
channel: "last",
|
|
to: "+15555550123",
|
|
thinking: "low",
|
|
timeoutSeconds: 300,
|
|
transform: {
|
|
module: "gmail.js",
|
|
export: "transformGmail",
|
|
},
|
|
},
|
|
],
|
|
gmail: {
|
|
account: "openclaw@gmail.com",
|
|
label: "INBOX",
|
|
topic: "projects/<project-id>/topics/gog-gmail-watch",
|
|
subscription: "gog-gmail-watch-push",
|
|
pushToken: "shared-push-token",
|
|
hookUrl: "http://127.0.0.1:18789/hooks/gmail",
|
|
includeBody: true,
|
|
maxBytes: 20000,
|
|
renewEveryMinutes: 720,
|
|
serve: { bind: "127.0.0.1", port: 8788, path: "/" },
|
|
tailscale: { mode: "funnel", path: "/gmail-pubsub" },
|
|
},
|
|
},
|
|
|
|
// Gateway + networking
|
|
gateway: {
|
|
mode: "local",
|
|
port: 18789,
|
|
bind: "loopback",
|
|
controlUi: { enabled: true, basePath: "/openclaw" },
|
|
auth: {
|
|
mode: "token",
|
|
token: "gateway-token",
|
|
allowTailscale: true,
|
|
},
|
|
tailscale: { mode: "serve" },
|
|
remote: { url: "ws://gateway-host.ts.net:18789", token: "remote-token" },
|
|
reload: { mode: "hybrid" },
|
|
},
|
|
|
|
skills: {
|
|
allowBundled: ["gemini", "peekaboo"],
|
|
load: {
|
|
extraDirs: ["~/Projects/agent-scripts/skills"],
|
|
allowSymlinkTargets: ["~/Projects/agent-scripts/skills"],
|
|
},
|
|
install: {
|
|
preferBrew: true,
|
|
nodeManager: "npm", // npm | pnpm | yarn | bun
|
|
allowUploadedArchives: false,
|
|
},
|
|
entries: {
|
|
"image-lab": {
|
|
enabled: true,
|
|
apiKey: "GEMINI_KEY_HERE",
|
|
env: { GEMINI_API_KEY: "GEMINI_KEY_HERE" },
|
|
},
|
|
peekaboo: { enabled: true },
|
|
},
|
|
},
|
|
}
|
|
```
|
|
|
|
### Symlinked sibling skill repo
|
|
|
|
Use this when a built-in skill root contains a symlink into a sibling repo, for
|
|
example `~/.agents/skills/manager -> ~/Projects/manager/skills`.
|
|
|
|
```json5
|
|
{
|
|
skills: {
|
|
load: {
|
|
extraDirs: ["~/Projects/manager/skills"],
|
|
allowSymlinkTargets: ["~/Projects/manager/skills"],
|
|
},
|
|
},
|
|
}
|
|
```
|
|
|
|
- `extraDirs` scans the sibling repo as an explicit skill root.
|
|
- `allowSymlinkTargets` lets symlinked skill folders resolve into that trusted
|
|
real target root without allowing arbitrary symlink escapes.
|
|
- To let Skill Workshop apply write through the same trusted symlink target,
|
|
set `skills.workshop.allowSymlinkTargetWrites: true`.
|
|
|
|
## Common patterns
|
|
|
|
### Shared skill baseline with one override
|
|
|
|
```json5
|
|
{
|
|
agents: {
|
|
defaults: {
|
|
workspace: "~/.openclaw/workspace",
|
|
skills: ["github", "weather"],
|
|
},
|
|
entries: {
|
|
main: { default: true },
|
|
docs: { workspace: "~/.openclaw/workspace-docs", skills: ["docs-search"] },
|
|
},
|
|
},
|
|
}
|
|
```
|
|
|
|
- `agents.defaults.skills` is the shared baseline.
|
|
- `agents.entries.*.skills` replaces that baseline for one agent.
|
|
- Use `skills: []` when an agent should see no skills.
|
|
|
|
### Multi-platform setup
|
|
|
|
```json5
|
|
{
|
|
agents: { defaults: { workspace: "~/.openclaw/workspace" } },
|
|
channels: {
|
|
whatsapp: { allowFrom: ["+15555550123"], responsePrefix: "[openclaw]" },
|
|
telegram: {
|
|
enabled: true,
|
|
botToken: "YOUR_TOKEN",
|
|
allowFrom: ["123456789"],
|
|
},
|
|
discord: {
|
|
enabled: true,
|
|
token: "YOUR_TOKEN",
|
|
allowFrom: ["123456789012345678"],
|
|
},
|
|
},
|
|
}
|
|
```
|
|
|
|
### Trusted node network auto-approval
|
|
|
|
Keep device pairing manual unless you control the network path. For a dedicated
|
|
lab or tailnet subnet, you can opt in to first-time node device auto-approval
|
|
with exact CIDRs or IPs:
|
|
|
|
```json5
|
|
{
|
|
gateway: {
|
|
nodes: {
|
|
pairing: {
|
|
autoApproveCidrs: ["192.168.1.0/24", "fd00:1234:5678::/64"],
|
|
},
|
|
},
|
|
},
|
|
}
|
|
```
|
|
|
|
This remains off when unset. It only applies to fresh `role: node` pairing with
|
|
no requested scopes. Operator/browser clients and role, scope, metadata, or
|
|
public-key upgrades still require manual approval.
|
|
|
|
### Secure DM mode (shared inbox / multi-user DMs)
|
|
|
|
If more than one person can DM your bot (multiple entries in `allowFrom`, pairing approvals for multiple people, or `dmPolicy: "open"`), enable **secure DM mode** so DMs from different senders don't share one context by default:
|
|
|
|
```json5
|
|
{
|
|
// Secure DM mode (recommended for multi-user or sensitive DM agents)
|
|
session: { dmScope: "per-channel-peer" },
|
|
|
|
channels: {
|
|
// Example: WhatsApp multi-user inbox
|
|
whatsapp: {
|
|
dmPolicy: "allowlist",
|
|
allowFrom: ["+15555550123", "+15555550124"],
|
|
},
|
|
|
|
// Example: Discord multi-user inbox
|
|
discord: {
|
|
enabled: true,
|
|
token: "YOUR_DISCORD_BOT_TOKEN",
|
|
allowFrom: ["123456789012345678", "987654321098765432"],
|
|
},
|
|
},
|
|
}
|
|
```
|
|
|
|
For Discord/Google Chat/IRC/Mattermost/Microsoft Teams/Slack, sender authorization is ID-first by default.
|
|
Only enable direct mutable name/email/nick matching with each channel's `dangerouslyAllowNameMatching: true` if you explicitly accept that risk.
|
|
|
|
### Anthropic API key + MiniMax fallback
|
|
|
|
```json5
|
|
{
|
|
auth: {
|
|
profiles: {
|
|
"anthropic:api": {
|
|
provider: "anthropic",
|
|
mode: "api_key",
|
|
},
|
|
},
|
|
order: {
|
|
anthropic: ["anthropic:api"],
|
|
},
|
|
},
|
|
models: {
|
|
providers: {
|
|
minimax: {
|
|
baseUrl: "https://api.minimax.io/anthropic",
|
|
api: "anthropic-messages",
|
|
apiKey: "${MINIMAX_API_KEY}",
|
|
},
|
|
},
|
|
},
|
|
agents: {
|
|
defaults: {
|
|
workspace: "~/.openclaw/workspace",
|
|
model: {
|
|
primary: "anthropic/claude-opus-4-6",
|
|
fallbacks: ["minimax/MiniMax-M2.7"],
|
|
},
|
|
},
|
|
},
|
|
}
|
|
```
|
|
|
|
### Work bot (restricted access)
|
|
|
|
```json5
|
|
{
|
|
agents: {
|
|
defaults: {
|
|
workspace: "~/work-openclaw",
|
|
elevatedDefault: "off",
|
|
},
|
|
entries: {
|
|
main: {
|
|
identity: {
|
|
name: "WorkBot",
|
|
theme: "professional assistant",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
channels: {
|
|
slack: {
|
|
enabled: true,
|
|
botToken: "xoxb-...",
|
|
channels: {
|
|
"#engineering": { enabled: true, requireMention: true },
|
|
"#general": { enabled: true, requireMention: true },
|
|
},
|
|
},
|
|
},
|
|
}
|
|
```
|
|
|
|
### Local models only
|
|
|
|
```json5
|
|
{
|
|
agents: {
|
|
defaults: {
|
|
workspace: "~/.openclaw/workspace",
|
|
model: { primary: "lmstudio/my-local-model" },
|
|
},
|
|
},
|
|
models: {
|
|
mode: "merge",
|
|
providers: {
|
|
lmstudio: {
|
|
baseUrl: "http://127.0.0.1:1234/v1",
|
|
apiKey: "lmstudio",
|
|
api: "openai-responses",
|
|
models: [
|
|
{
|
|
id: "my-local-model",
|
|
name: "Local Model",
|
|
reasoning: false,
|
|
input: ["text"],
|
|
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
contextWindow: 196608,
|
|
maxTokens: 8192,
|
|
},
|
|
],
|
|
},
|
|
},
|
|
},
|
|
}
|
|
```
|
|
|
|
## Tips
|
|
|
|
- If you set `dmPolicy: "open"`, the matching `allowFrom` list must include `"*"`.
|
|
- Provider IDs differ (phone numbers, user IDs, channel IDs). Use the provider docs to confirm the format.
|
|
- Optional sections to add later: `web`, `browser`, `ui`, `discovery`, `plugins`, `talk`, `signal`, `imessage`.
|
|
- See [Providers](/providers) and [Troubleshooting](/gateway/troubleshooting) for deeper setup notes.
|
|
|
|
## Related
|
|
|
|
- [Configuration reference](/gateway/configuration-reference)
|
|
- [Configuration](/gateway/configuration)
|