C Concierge Documentation
Docs / Start here / Configuration
Reference

Configuration & secrets.

Every environment variable, secret, binding, OAuth redirect, webhook URL, and cron trigger Concierge expects. All sensitive values are stored as Cloudflare Workers secrets via wrangler secret put; non‑sensitive values live in the [vars] block of wrangler.toml.

Total secrets 14 required · 4 optional Env vars 8 Bindings 6
i
Setting secrets

Use the Wrangler CLI: wrangler secret put SECRET_NAME. You’ll be prompted to enter the value securely. Secrets are encrypted at rest by Cloudflare and exposed to your Worker as environment variables.

Environment variables

Plain‑text vars in the [vars] block of wrangler.toml. Safe to commit.

[vars]wrangler.toml · plaintext, committable 8 vars
VariableDescription
ENVIRONMENTproduction or development. Dev mode bypasses some auth checks.
CF_ACCESS_TEAMCloudflare Access team name (the subdomain in myteam.cloudflareaccess.com).
CF_ACCESS_AUDCloudflare Access Application Audience (AUD) tag for /manage/*.
WHATSAPP_WABA_IDYour WhatsApp Business Account ID.
WHATSAPP_SIGNUP_CONFIG_IDMeta Embedded Signup configuration ID.
EMAIL_DOMAINSingle platform email domain. Set to a domain you control; configure MX records manually on its apex and wire it into Cloudflare Email Routing.
AI_MODELOptional override for the Workers AI model used for replies. Default @cf/meta/llama-4-scout-17b-16e-instruct.
AI_FAST_MODELOptional override for the fast classifier model (prompt‑injection scan + persona safety check). Default @cf/meta/llama-3.1-8b-instruct-fast.

Secrets

Sensitive values, set with wrangler secret put. Grouped by integration.

Core

Encryptionrequired for token storage 1 secret
SecretDescription
ENCRYPTION_KEY 32‑byte hex key for AES‑256‑GCM encryption of stored tokens. Generate with openssl rand -hex 32.

Google OAuth

Sign-inused by /auth/login 2 secrets
SecretDescription
GOOGLE_OAUTH_CLIENT_IDGoogle OAuth client ID (for sign-in).
GOOGLE_OAUTH_CLIENT_SECRETGoogle OAuth client secret.

Meta: Facebook / Instagram / WhatsApp

Meta Graph APIshared app for FB Login, Instagram, WhatsApp signup 5 secrets
SecretDescription
META_APP_IDMeta app ID: shared for Facebook Login, Instagram, WhatsApp signup.
META_APP_SECRETMeta app secret: used for webhook signature verification and token exchange.
WHATSAPP_ACCESS_TOKENSystem user token for your shared WABA.
WHATSAPP_VERIFY_TOKENWebhook verification token. Generate with openssl rand -hex 16.
INSTAGRAM_VERIFY_TOKENInstagram webhook verification token. Generate with openssl rand -hex 16.

Discord

Interactions APIslash commands, button & modal callbacks 3 secrets
SecretDescription
DISCORD_PUBLIC_KEYDiscord application public key (Ed25519 signature verification for interactions).
DISCORD_APPLICATION_IDDiscord application ID (for registering slash commands).
DISCORD_BOT_TOKENDiscord bot token (for sending messages and managing interactions).

Razorpay optional

Paymentscredit packs & subscription billing 3 secrets
SecretDescription
RAZORPAY_KEY_IDRazorpay API key ID.
RAZORPAY_KEY_SECRETRazorpay API key secret.
RAZORPAY_WEBHOOK_SECRETRazorpay webhook secret (for verifying payment notifications at POST /webhook/razorpay).

Bindings

Cloudflare resource bindings declared in wrangler.toml. The IDs come from the deployment guide.

wrangler.tomlresource bindings 6 bindings
BindingTypeDescription
DBD1SQLite database for message logs, payments, audit, credit packs.
KVKVConfig store for tenants, accounts, sessions, routing rules, billing state, persona.
AIAICloudflare Workers AI for reply generation, prompt‑injection scanning, persona safety classification, and BGE embeddings.
EMAILsend_emailOutbound email for forwarding and reverse‑alias replies.
REPLY_BUFFERDOPer‑conversation reply buffer that batches multi‑message bursts within wait_seconds.
SAFETY_QUEUEQueuePersona safety classifier jobs. Producer + consumer bound on the same Worker.

Cloudflare Queues

Two queues must exist before deploy:

  • concierge-safety: producer + consumer for the persona safety classifier. The Worker enqueues a SafetyJob on each persona save and consumes the same queue via #[event(queue)].
  • concierge-safety-dlq: dead‑letter queue for safety jobs after 3 retries. Inspect failures here when persona checks stop completing.
bash terminal
wrangler queues create concierge-safety
wrangler queues create concierge-safety-dlq

Local wrangler dev works without queues configured: safety_queue::enqueue logs and falls through, leaving personas in Pending until you deploy against a properly bound environment.

Locale & supported languages

Every tenant has a BCP‑47 locale tag (Tenant.locale) plus an independent currency override. Currently shipped: en-IN (default; Indian‑style number grouping, INR currency) and en-US (Western grouping, USD). Locale is set at signup from the request’s Accept-Language header, falling back to cf-ipcountry, then to en-IN. Admins can change both locale and currency independently from /admin/settings.

Adding a new locale is a drop‑in change: place a translated messages.ftl at assets/locales/{tag}/, register the tag in src/i18n.rs::Translator::new and src/locale.rs::Locale::from_request, then rebuild. CLDR data for number / currency formatting ships automatically via icu4x’s compiled_data feature. AI‑generated reply content stays English regardless of the UI locale.

OAuth redirect URIs

Register these in the respective developer consoles:

  • Google: https://your-domain/auth/callback
  • Facebook: https://your-domain/auth/facebook/callback and https://your-domain/instagram/callback

Webhook URLs

Configure these in the respective platforms:

PlatformURLMethod
WhatsApphttps://your-domain/webhook/whatsappGET / POST
Instagramhttps://your-domain/webhook/instagramGET / POST
Discordhttps://your-domain/discord/interactionsPOST
Razorpayhttps://your-domain/webhook/razorpayPOST

Cron triggers

A daily cron runs at 0 6 * * * (06:00 UTC) for Instagram token refresh. Configured in the [triggers] section of wrangler.toml.

toml wrangler.toml · partial
# Identity
name = "concierge"
main = "worker-shim.mjs"
compatibility_date = "2024-01-01"

# Plain-text variables
[vars]
ENVIRONMENT           = "production"
CF_ACCESS_TEAM        = "calculon"
CF_ACCESS_AUD         = "abcd1234…"
WHATSAPP_WABA_ID      = "123456789012345"
EMAIL_DOMAIN     = "cncg.email"

# Bindings
[[d1_databases]]
binding      = "DB"
database_name = "concierge"
database_id   = "…"

[[kv_namespaces]]
binding = "KV"
id      = "…"

[ai]            binding = "AI"
[[send_email]]   name    = "EMAIL"

[[durable_objects.bindings]]
name       = "REPLY_BUFFER"
class_name = "ReplyBufferDO"

# Persona safety classifier
[[queues.producers]]
queue   = "concierge-safety"
binding = "SAFETY_QUEUE"

[[queues.consumers]]
queue             = "concierge-safety"
max_batch_size    = 10
max_batch_timeout = 5
max_retries       = 3
dead_letter_queue = "concierge-safety-dlq"

# Daily Instagram token refresh, 06:00 UTC
[triggers]
crons = ["0 6 * * *"]
!
Rotating secrets

Rotating ENCRYPTION_KEY invalidates every encrypted Instagram page token in KV: customers will need to reconnect. Webhook verify tokens (WHATSAPP_VERIFY_TOKEN, INSTAGRAM_VERIFY_TOKEN) can be rotated independently; just update them in the Meta Developer Console at the same time.