Channels/Config — Channel Configuration System

Per-Channel Config Resolution, Presence Detection & Chat Type Normalization

The Config sub-module handles how OpenClaw discovers which channels are configured, resolves per-channel settings with cascading fallback (direct → parent → wildcard), normalizes chat types, and detects channel presence from both config files and environment variables.

3
Core Files
13
Channel Prefixes
3
Match Sources
TypeScript
Language

Config Resolution Auto-Detection Chat Types Env Scanning

📚 What is this & why does it matter?

Each of the 25+ supported channels has unique capabilities and settings. The config system provides a unified way to look up channel-specific settings, with intelligent fallback chains so administrators only need to configure what differs from defaults.

💡 Real-world analogy

Think of a hotel chain with properties worldwide. Each hotel (channel) has its own room rates and amenities, but there’s a corporate default. When looking up the rate for “Suite A at Hotel Tokyo,” you first check Tokyo’s specific rate. If not set, check the Asia-Pacific regional rate (parent). If still not set, use the global default (wildcard). That cascading lookup is exactly how resolveChannelEntryMatchWithFallback works.

Architecture

flowchart TD
    subgraph Resolution["Config Resolution"]
        KEYS["buildChannelKeyCandidates()"]
        MATCH["resolveChannelEntryMatch()"]
        FALL["resolveChannelEntryMatchWithFallback()"]
        APPLY["applyChannelMatchMeta()"]
    end
    subgraph Presence["Channel Detection"]
        CFGSCAN["Config file scan"]
        ENVSCAN["Environment variable scan"]
        OAUTH["OAuth credential check"]
        LIST["listPotentialConfiguredChannelIds()"]
    end
    subgraph Types["Chat Type System"]
        NORM["normalizeChatType()"]
        DM["direct"]
        GRP["group"]
        CH["channel"]
    end

    KEYS --> MATCH
    MATCH --> FALL
    FALL --> APPLY
    CFGSCAN --> LIST
    ENVSCAN --> LIST
    OAUTH --> LIST
    NORM --> DM
    NORM --> GRP
    NORM --> CH

Config Resolution Pipeline

Channel configuration follows a three-tier fallback: direct (exact channel key) → parent (parent channel key) → wildcard (global default). The match source is tracked so callers know how the config was resolved.

Match Sources

SourcePriorityDescription
direct1 (highest)Exact match on channel key (e.g., "telegram")
parent2Match on parent channel key (e.g., "chat" for all chat channels)
wildcard3 (lowest)Universal fallback via wildcard key (e.g., "*")
export type ChannelEntryMatch<T> = {
  entry?: T;
  key?: string;
  wildcardEntry?: T;
  wildcardKey?: string;
  parentEntry?: T;
  parentKey?: string;
  matchKey?: string;
  matchSource?: ChannelMatchSource; // "direct" | "parent" | "wildcard"
};

Slug Normalization

export function normalizeChannelSlug(value: string): string {
  return value
    .trim()
    .toLowerCase()
    .replace(/^#/, "")
    .replace(/[^a-z0-9]+/g, "-")
    .replace(/^-+|-+$/g, "");
}

Channel Presence Detection

The system detects configured channels from two sources: config file entries and environment variables. For WhatsApp, it also checks for OAuth credential files on disk.

Environment Variable Prefixes

PrefixChannel
TELEGRAM_telegram
WHATSAPP_whatsapp
DISCORD_discord
SLACK_slack
SIGNAL_signal
IRC_irc
GOOGLECHAT_googlechat
LINE_line
MATRIX_matrix
MSTEAMS_msteams
BLUEBUBBLES_bluebubbles
ZALO_zalo
ZALOUSER_zalouser
flowchart LR
    CFG["openclaw.config.json"] --> SCAN["Scan channel keys"]
    ENV["Process environment"] --> PREFIX["Match env prefixes"]
    FS["OAuth directory"] --> CREDS["Check creds.json"]
    SCAN --> MERGE["Merge detected IDs"]
    PREFIX --> MERGE
    CREDS --> MERGE
    MERGE --> LIST["configuredChannelIds[]"]

Chat Type Normalization

Chat type is normalized to one of three values:

InputNormalized
"direct", "dm""direct"
"group""group"
"channel""channel"
anything elseundefined
export type ChatType = "direct" | "group" | "channel";

Focus Deep-Dives

🔧 Channel Capabilities

Config entry matching with cascading fallback, slug normalization, and key candidate generation.

🔍 Config Presence

Auto-detection of configured channels from config files, environment variables, and OAuth credentials.

🗨 Chat Types

DM, group, and channel type normalization with input validation and routing implications.