From 4717402e0c1e9efa0795f3421d4ffbb719168d56 Mon Sep 17 00:00:00 2001 From: Balaji C M Date: Sat, 21 Feb 2026 19:14:35 +0530 Subject: [PATCH 1/2] feat: add Slack DM policy --- .dev.vars.example | 5 + .github/workflows/test.yml | 8 ++ AGENTS.md | 1 + README.md | 1 + moltworker | 1 + src/gateway/env.test.ts | 2 + src/gateway/env.ts | 1 + src/types.ts | 1 + start-openclaw.sh | 6 ++ wrangler.jsonc | 207 +++++++++++++++++++------------------ 10 files changed, 134 insertions(+), 99 deletions(-) create mode 160000 moltworker diff --git a/.dev.vars.example b/.dev.vars.example index 5fc7dca6f..3a7f03f4a 100644 --- a/.dev.vars.example +++ b/.dev.vars.example @@ -35,7 +35,12 @@ MOLTBOT_GATEWAY_TOKEN=dev-token-change-in-prod # Optional chat channels # TELEGRAM_BOT_TOKEN=optional +# TELEGRAM_DM_POLICY=pairing # DISCORD_BOT_TOKEN=optional +# DISCORD_DM_POLICY=pairing +# SLACK_BOT_TOKEN=optional +# SLACK_APP_TOKEN=optional +# SLACK_DM_POLICY=pairing # CDP (Chrome DevTools Protocol) configuration for browser automation # CDP_SECRET=shared-secret-for-cdp-auth diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a72a683fc..f88f1bbda 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -56,6 +56,11 @@ jobs: env: DISCORD_BOT_TOKEN: "fake-discord-bot-token-for-e2e" DISCORD_DM_POLICY: "pairing" + - name: slack + env: + SLACK_BOT_TOKEN: "fake-slack-bot-token-for-e2e" + SLACK_APP_TOKEN: "fake-slack-app-token-for-e2e" + SLACK_DM_POLICY: "pairing" - name: workers-ai env: CF_AI_GATEWAY_MODEL: "workers-ai/@cf/openai/gpt-oss-120b" @@ -120,6 +125,9 @@ jobs: TELEGRAM_DM_POLICY: ${{ matrix.config.env.TELEGRAM_DM_POLICY }} DISCORD_BOT_TOKEN: ${{ matrix.config.env.DISCORD_BOT_TOKEN }} DISCORD_DM_POLICY: ${{ matrix.config.env.DISCORD_DM_POLICY }} + SLACK_BOT_TOKEN: ${{ matrix.config.env.SLACK_BOT_TOKEN }} + SLACK_APP_TOKEN: ${{ matrix.config.env.SLACK_APP_TOKEN }} + SLACK_DM_POLICY: ${{ matrix.config.env.SLACK_DM_POLICY }} CF_AI_GATEWAY_MODEL: ${{ matrix.config.env.CF_AI_GATEWAY_MODEL }} run: cctr -vv test/e2e diff --git a/AGENTS.md b/AGENTS.md index ec30d2c18..7bdf1542a 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -206,6 +206,7 @@ These are the env vars passed TO the container (internal names): | `DISCORD_BOT_TOKEN` | `channels.discord.token` | | | `SLACK_BOT_TOKEN` | `channels.slack.botToken` | | | `SLACK_APP_TOKEN` | `channels.slack.appToken` | | +| `SLACK_DM_POLICY` | `channels.slack.dm.policy` | `pairing` (default) or `open` | ## OpenClaw Config Schema diff --git a/README.md b/README.md index ea82f03af..0ad7d5da1 100644 --- a/README.md +++ b/README.md @@ -436,6 +436,7 @@ The previous `AI_GATEWAY_API_KEY` + `AI_GATEWAY_BASE_URL` approach is still supp | `DISCORD_DM_POLICY` | No | Discord DM policy: `pairing` (default) or `open` | | `SLACK_BOT_TOKEN` | No | Slack bot token | | `SLACK_APP_TOKEN` | No | Slack app token | +| `SLACK_DM_POLICY` | No | Slack DM policy: `pairing` (default) or `open` | | `CDP_SECRET` | No | Shared secret for CDP endpoint authentication (see [Browser Automation](#optional-browser-automation-cdp)) | | `WORKER_URL` | No | Public URL of the worker (required for CDP) | diff --git a/moltworker b/moltworker new file mode 160000 index 000000000..ee5006aeb --- /dev/null +++ b/moltworker @@ -0,0 +1 @@ +Subproject commit ee5006aeb3d167bb0e4dd26f4376738c8102e12c diff --git a/src/gateway/env.test.ts b/src/gateway/env.test.ts index 89af2efb8..e0276d35c 100644 --- a/src/gateway/env.test.ts +++ b/src/gateway/env.test.ts @@ -110,6 +110,7 @@ describe('buildEnvVars', () => { DISCORD_DM_POLICY: 'open', SLACK_BOT_TOKEN: 'slack-bot', SLACK_APP_TOKEN: 'slack-app', + SLACK_DM_POLICY: 'open', }); const result = buildEnvVars(env); @@ -119,6 +120,7 @@ describe('buildEnvVars', () => { expect(result.DISCORD_DM_POLICY).toBe('open'); expect(result.SLACK_BOT_TOKEN).toBe('slack-bot'); expect(result.SLACK_APP_TOKEN).toBe('slack-app'); + expect(result.SLACK_DM_POLICY).toBe('open'); }); it('maps DEV_MODE to OPENCLAW_DEV_MODE for container', () => { diff --git a/src/gateway/env.ts b/src/gateway/env.ts index d9e01171b..3163e95d1 100644 --- a/src/gateway/env.ts +++ b/src/gateway/env.ts @@ -45,6 +45,7 @@ export function buildEnvVars(env: MoltbotEnv): Record { if (env.DISCORD_DM_POLICY) envVars.DISCORD_DM_POLICY = env.DISCORD_DM_POLICY; if (env.SLACK_BOT_TOKEN) envVars.SLACK_BOT_TOKEN = env.SLACK_BOT_TOKEN; if (env.SLACK_APP_TOKEN) envVars.SLACK_APP_TOKEN = env.SLACK_APP_TOKEN; + if (env.SLACK_DM_POLICY) envVars.SLACK_DM_POLICY = env.SLACK_DM_POLICY; if (env.CF_AI_GATEWAY_MODEL) envVars.CF_AI_GATEWAY_MODEL = env.CF_AI_GATEWAY_MODEL; if (env.CF_ACCOUNT_ID) envVars.CF_ACCOUNT_ID = env.CF_ACCOUNT_ID; if (env.CDP_SECRET) envVars.CDP_SECRET = env.CDP_SECRET; diff --git a/src/types.ts b/src/types.ts index a85d32da3..52579bbdb 100644 --- a/src/types.ts +++ b/src/types.ts @@ -30,6 +30,7 @@ export interface MoltbotEnv { DISCORD_DM_POLICY?: string; SLACK_BOT_TOKEN?: string; SLACK_APP_TOKEN?: string; + SLACK_DM_POLICY?: string; // Cloudflare Access configuration for admin routes CF_ACCESS_TEAM_DOMAIN?: string; // e.g., 'myteam.cloudflareaccess.com' CF_ACCESS_AUD?: string; // Application Audience (AUD) tag diff --git a/start-openclaw.sh b/start-openclaw.sh index c862a80ce..d8c76abe2 100644 --- a/start-openclaw.sh +++ b/start-openclaw.sh @@ -253,10 +253,16 @@ if (process.env.DISCORD_BOT_TOKEN) { // Slack configuration if (process.env.SLACK_BOT_TOKEN && process.env.SLACK_APP_TOKEN) { + const dmPolicy = process.env.SLACK_DM_POLICY || 'pairing'; + const dm = { policy: dmPolicy }; + if (dmPolicy === 'open') { + dm.allowFrom = ['*']; + } config.channels.slack = { botToken: process.env.SLACK_BOT_TOKEN, appToken: process.env.SLACK_APP_TOKEN, enabled: true, + dm: dm, }; } diff --git a/wrangler.jsonc b/wrangler.jsonc index 7b2ce8d0b..e008f7d21 100644 --- a/wrangler.jsonc +++ b/wrangler.jsonc @@ -1,100 +1,109 @@ { - "$schema": "node_modules/wrangler/config-schema.json", - "name": "moltbot-sandbox", - "main": "src/index.ts", - "compatibility_date": "2025-05-06", - "compatibility_flags": ["nodejs_compat"], - "observability": { - "enabled": true, - }, - // Static assets for admin UI (built by vite) - "assets": { - "directory": "./dist/client", - "not_found_handling": "single-page-application", - "html_handling": "auto-trailing-slash", - "binding": "ASSETS", - "run_worker_first": true, - }, - // Allow importing HTML files as text modules and PNG files as binary - "rules": [ - { - "type": "Text", - "globs": ["**/*.html"], - "fallthrough": false, - }, - { - "type": "Data", - "globs": ["**/*.png"], - "fallthrough": false, - }, - ], - // Build command for vite - "build": { - "command": "npm run build", - }, - // Container configuration for the Moltbot sandbox - "containers": [ - { - "class_name": "Sandbox", - "image": "./Dockerfile", - "instance_type": "standard-1", - "max_instances": 1, - }, - ], - "durable_objects": { - "bindings": [ - { - "class_name": "Sandbox", - "name": "Sandbox", - }, - ], - }, - "migrations": [ - { - "new_sqlite_classes": ["Sandbox"], - "tag": "v1", - }, - ], - // R2 bucket for persistent storage (moltbot data, conversations, etc.) - "r2_buckets": [ - { - "binding": "MOLTBOT_BUCKET", - "bucket_name": "moltbot-data", - }, - ], - - // Browser Rendering binding for CDP shim - "browser": { - "binding": "BROWSER", - }, - // Note: CF_ACCOUNT_ID should be set via `wrangler secret put CF_ACCOUNT_ID` - // Secrets to configure via `wrangler secret put`: - // - // AI Provider (at least one set required): - // - ANTHROPIC_API_KEY: Direct Anthropic API key - // - OPENAI_API_KEY: Direct OpenAI API key - // - Cloudflare AI Gateway (alternative to direct keys): - // - CLOUDFLARE_AI_GATEWAY_API_KEY: API key for requests through the gateway - // - CF_AI_GATEWAY_ACCOUNT_ID: Your Cloudflare account ID - // - CF_AI_GATEWAY_GATEWAY_ID: Your AI Gateway ID - // - Legacy AI Gateway (still supported): - // - AI_GATEWAY_API_KEY: API key - // - AI_GATEWAY_BASE_URL: Gateway endpoint URL - // - // Authentication: - // - MOLTBOT_GATEWAY_TOKEN: Token to protect gateway access - // - CF_ACCESS_TEAM_DOMAIN: Cloudflare Access team domain - // - CF_ACCESS_AUD: Cloudflare Access application audience - // - // Chat channels (optional): - // - TELEGRAM_BOT_TOKEN, DISCORD_BOT_TOKEN, SLACK_BOT_TOKEN, SLACK_APP_TOKEN - // - // Browser automation (optional): - // - CDP_SECRET: Shared secret for /cdp endpoint authentication - // - WORKER_URL: Public URL of the worker - // - // R2 persistent storage (optional, for data persistence across sessions): - // - R2_ACCESS_KEY_ID: R2 access key ID (from R2 API tokens) - // - R2_SECRET_ACCESS_KEY: R2 secret access key (from R2 API tokens) - // - CF_ACCOUNT_ID: Your Cloudflare account ID (for R2 endpoint URL) -} + "$schema": "node_modules/wrangler/config-schema.json", + "name": "moltbot-sandbox", + "main": "src/index.ts", + "compatibility_date": "2025-05-06", + "compatibility_flags": [ + "nodejs_compat" + ], + "observability": { + "enabled": true, + }, + // Static assets for admin UI (built by vite) + "assets": { + "directory": "./dist/client", + "not_found_handling": "single-page-application", + "html_handling": "auto-trailing-slash", + "binding": "ASSETS", + "run_worker_first": true, + }, + // Allow importing HTML files as text modules and PNG files as binary + "rules": [ + { + "type": "Text", + "globs": [ + "**/*.html" + ], + "fallthrough": false, + }, + { + "type": "Data", + "globs": [ + "**/*.png" + ], + "fallthrough": false, + }, + ], + // Build command for vite + "build": { + "command": "npm run build", + }, + // Container configuration for the Moltbot sandbox + "containers": [ + { + "class_name": "Sandbox", + "image": "./Dockerfile", + "instance_type": "standard-1", + "max_instances": 1, + }, + ], + "durable_objects": { + "bindings": [ + { + "class_name": "Sandbox", + "name": "Sandbox", + }, + ], + }, + "migrations": [ + { + "new_sqlite_classes": [ + "Sandbox" + ], + "tag": "v1", + }, + ], + // R2 bucket for persistent storage (moltbot data, conversations, etc.) + "r2_buckets": [ + { + "binding": "MOLTBOT_BUCKET", + "bucket_name": "moltbot-data", + }, + ], + // Browser Rendering binding for CDP shim + "browser": { + "binding": "BROWSER", + }, + // Note: CF_ACCOUNT_ID should be set via `wrangler secret put CF_ACCOUNT_ID` + // Secrets to configure via `wrangler secret put`: + // + // AI Provider (at least one set required): + // - ANTHROPIC_API_KEY: Direct Anthropic API key + // - OPENAI_API_KEY: Direct OpenAI API key + // - Cloudflare AI Gateway (alternative to direct keys): + // - CLOUDFLARE_AI_GATEWAY_API_KEY: API key for requests through the gateway + // - CF_AI_GATEWAY_ACCOUNT_ID: Your Cloudflare account ID + // - CF_AI_GATEWAY_GATEWAY_ID: Your AI Gateway ID + // - Legacy AI Gateway (still supported): + // - AI_GATEWAY_API_KEY: API key + // - AI_GATEWAY_BASE_URL: Gateway endpoint URL + // + // Authentication: + // - MOLTBOT_GATEWAY_TOKEN: Token to protect gateway access + // - CF_ACCESS_TEAM_DOMAIN: Cloudflare Access team domain + // - CF_ACCESS_AUD: Cloudflare Access application audience + // + // Chat channels (optional): + // - TELEGRAM_BOT_TOKEN, TELEGRAM_DM_POLICY + // - DISCORD_BOT_TOKEN, DISCORD_DM_POLICY + // - SLACK_BOT_TOKEN, SLACK_APP_TOKEN, SLACK_DM_POLICY + // + // Browser automation (optional): + // - CDP_SECRET: Shared secret for /cdp endpoint authentication + // - WORKER_URL: Public URL of the worker + // + // R2 persistent storage (optional, for data persistence across sessions): + // - R2_ACCESS_KEY_ID: R2 access key ID (from R2 API tokens) + // - R2_SECRET_ACCESS_KEY: R2 secret access key (from R2 API tokens) + // - CF_ACCOUNT_ID: Your Cloudflare account ID (for R2 endpoint URL) +} \ No newline at end of file From d6914f4f31c1646a03cfdbd4fafe9491807659bc Mon Sep 17 00:00:00 2001 From: Balaji C M Date: Sat, 21 Feb 2026 19:21:47 +0530 Subject: [PATCH 2/2] chore: revert unintended wrangler formatting changes --- wrangler.jsonc | 209 ++++++++++++++++++++++++------------------------- 1 file changed, 101 insertions(+), 108 deletions(-) diff --git a/wrangler.jsonc b/wrangler.jsonc index e008f7d21..526890fca 100644 --- a/wrangler.jsonc +++ b/wrangler.jsonc @@ -1,109 +1,102 @@ { - "$schema": "node_modules/wrangler/config-schema.json", - "name": "moltbot-sandbox", - "main": "src/index.ts", - "compatibility_date": "2025-05-06", - "compatibility_flags": [ - "nodejs_compat" - ], - "observability": { - "enabled": true, - }, - // Static assets for admin UI (built by vite) - "assets": { - "directory": "./dist/client", - "not_found_handling": "single-page-application", - "html_handling": "auto-trailing-slash", - "binding": "ASSETS", - "run_worker_first": true, - }, - // Allow importing HTML files as text modules and PNG files as binary - "rules": [ - { - "type": "Text", - "globs": [ - "**/*.html" - ], - "fallthrough": false, - }, - { - "type": "Data", - "globs": [ - "**/*.png" - ], - "fallthrough": false, - }, - ], - // Build command for vite - "build": { - "command": "npm run build", - }, - // Container configuration for the Moltbot sandbox - "containers": [ - { - "class_name": "Sandbox", - "image": "./Dockerfile", - "instance_type": "standard-1", - "max_instances": 1, - }, - ], - "durable_objects": { - "bindings": [ - { - "class_name": "Sandbox", - "name": "Sandbox", - }, - ], - }, - "migrations": [ - { - "new_sqlite_classes": [ - "Sandbox" - ], - "tag": "v1", - }, - ], - // R2 bucket for persistent storage (moltbot data, conversations, etc.) - "r2_buckets": [ - { - "binding": "MOLTBOT_BUCKET", - "bucket_name": "moltbot-data", - }, - ], - // Browser Rendering binding for CDP shim - "browser": { - "binding": "BROWSER", - }, - // Note: CF_ACCOUNT_ID should be set via `wrangler secret put CF_ACCOUNT_ID` - // Secrets to configure via `wrangler secret put`: - // - // AI Provider (at least one set required): - // - ANTHROPIC_API_KEY: Direct Anthropic API key - // - OPENAI_API_KEY: Direct OpenAI API key - // - Cloudflare AI Gateway (alternative to direct keys): - // - CLOUDFLARE_AI_GATEWAY_API_KEY: API key for requests through the gateway - // - CF_AI_GATEWAY_ACCOUNT_ID: Your Cloudflare account ID - // - CF_AI_GATEWAY_GATEWAY_ID: Your AI Gateway ID - // - Legacy AI Gateway (still supported): - // - AI_GATEWAY_API_KEY: API key - // - AI_GATEWAY_BASE_URL: Gateway endpoint URL - // - // Authentication: - // - MOLTBOT_GATEWAY_TOKEN: Token to protect gateway access - // - CF_ACCESS_TEAM_DOMAIN: Cloudflare Access team domain - // - CF_ACCESS_AUD: Cloudflare Access application audience - // - // Chat channels (optional): - // - TELEGRAM_BOT_TOKEN, TELEGRAM_DM_POLICY - // - DISCORD_BOT_TOKEN, DISCORD_DM_POLICY - // - SLACK_BOT_TOKEN, SLACK_APP_TOKEN, SLACK_DM_POLICY - // - // Browser automation (optional): - // - CDP_SECRET: Shared secret for /cdp endpoint authentication - // - WORKER_URL: Public URL of the worker - // - // R2 persistent storage (optional, for data persistence across sessions): - // - R2_ACCESS_KEY_ID: R2 access key ID (from R2 API tokens) - // - R2_SECRET_ACCESS_KEY: R2 secret access key (from R2 API tokens) - // - CF_ACCOUNT_ID: Your Cloudflare account ID (for R2 endpoint URL) -} \ No newline at end of file + "$schema": "node_modules/wrangler/config-schema.json", + "name": "moltbot-sandbox", + "main": "src/index.ts", + "compatibility_date": "2025-05-06", + "compatibility_flags": ["nodejs_compat"], + "observability": { + "enabled": true, + }, + // Static assets for admin UI (built by vite) + "assets": { + "directory": "./dist/client", + "not_found_handling": "single-page-application", + "html_handling": "auto-trailing-slash", + "binding": "ASSETS", + "run_worker_first": true, + }, + // Allow importing HTML files as text modules and PNG files as binary + "rules": [ + { + "type": "Text", + "globs": ["**/*.html"], + "fallthrough": false, + }, + { + "type": "Data", + "globs": ["**/*.png"], + "fallthrough": false, + }, + ], + // Build command for vite + "build": { + "command": "npm run build", + }, + // Container configuration for the Moltbot sandbox + "containers": [ + { + "class_name": "Sandbox", + "image": "./Dockerfile", + "instance_type": "standard-1", + "max_instances": 1, + }, + ], + "durable_objects": { + "bindings": [ + { + "class_name": "Sandbox", + "name": "Sandbox", + }, + ], + }, + "migrations": [ + { + "new_sqlite_classes": ["Sandbox"], + "tag": "v1", + }, + ], + // R2 bucket for persistent storage (moltbot data, conversations, etc.) + "r2_buckets": [ + { + "binding": "MOLTBOT_BUCKET", + "bucket_name": "moltbot-data", + }, + ], + + // Browser Rendering binding for CDP shim + "browser": { + "binding": "BROWSER", + }, + // Note: CF_ACCOUNT_ID should be set via `wrangler secret put CF_ACCOUNT_ID` + // Secrets to configure via `wrangler secret put`: + // + // AI Provider (at least one set required): + // - ANTHROPIC_API_KEY: Direct Anthropic API key + // - OPENAI_API_KEY: Direct OpenAI API key + // - Cloudflare AI Gateway (alternative to direct keys): + // - CLOUDFLARE_AI_GATEWAY_API_KEY: API key for requests through the gateway + // - CF_AI_GATEWAY_ACCOUNT_ID: Your Cloudflare account ID + // - CF_AI_GATEWAY_GATEWAY_ID: Your AI Gateway ID + // - Legacy AI Gateway (still supported): + // - AI_GATEWAY_API_KEY: API key + // - AI_GATEWAY_BASE_URL: Gateway endpoint URL + // + // Authentication: + // - MOLTBOT_GATEWAY_TOKEN: Token to protect gateway access + // - CF_ACCESS_TEAM_DOMAIN: Cloudflare Access team domain + // - CF_ACCESS_AUD: Cloudflare Access application audience + // + // Chat channels (optional): + // - TELEGRAM_BOT_TOKEN, TELEGRAM_DM_POLICY + // - DISCORD_BOT_TOKEN, DISCORD_DM_POLICY + // - SLACK_BOT_TOKEN, SLACK_APP_TOKEN, SLACK_DM_POLICY + // + // Browser automation (optional): + // - CDP_SECRET: Shared secret for /cdp endpoint authentication + // - WORKER_URL: Public URL of the worker + // + // R2 persistent storage (optional, for data persistence across sessions): + // - R2_ACCESS_KEY_ID: R2 access key ID (from R2 API tokens) + // - R2_SECRET_ACCESS_KEY: R2 secret access key (from R2 API tokens) + // - CF_ACCOUNT_ID: Your Cloudflare account ID (for R2 endpoint URL) +}