#Multiple agent bot on telegram

1 messages · Page 1 of 1 (latest)

raw token
#

Hello, i wish to add a second agent i have created to telegram (my first is name A and second B)
how to do it properly in the openclaw.json
already created the 2 bot in telegram and have the tokens needed

valid basaltBOT
#

To help others find answers, you can mark your question as solved via Right click solution message -> Apps -> âś… Mark Solution

spark otterBOT
#

First: what OpenClaw version are you on? (openclaw --version)
Multi-bot + multi-agent routing needs a reasonably recent build, so version matters.

That said, the “proper” way to run 2 Telegram bots (2 tokens) and route each one to a different agent is:

  1. define two Telegram accounts under channels.telegram.accounts (each with its own botToken)
  2. define two agents under agents.list
  3. add bindings so accountId → agentId mapping is deterministic

Example ~/.openclaw/openclaw.json (JSON5):

{
  // (Optional but recommended when you have multiple accounts on the same channel)
  session: {
    dmScope: "per-account-channel-peer",
#
  },

  agents: {
    list: [
      { id: "A", default: true, workspace: "~/.openclaw/workspace-A" },
      { id: "B", workspace: "~/.openclaw/workspace-B" },
    ],
  },

  channels: {
    telegram: {
      enabled: true,

      // default DM security posture (you can override per account too)
      dmPolicy: "pairing",
#

      // if you add bots to groups, this avoids “both bots reply” chaos
      groups: { "*": { requireMention: true } },

      accounts: {
        a: {
          name: "Bot A",
          botToken: "123456:AAAA....",
          // dmPolicy: "pairing", // optional per-account override
        },
        b: {
          name: "Bot B",
          botToken: "987654:BBBB....",
        },
      },
#
    },
  },

  bindings: [
    { agentId: "A", match: { channel: "telegram", accountId: "a" } },
    { agentId: "B", match: { channel: "telegram", accountId: "b" } },
  ],
}

Notes that usually trip people up:

  • The keys a / b are the Telegram accountIds (internal labels). They must match what you put in bindings[].match.accountId.
  • TELEGRAM_BOT_TOKEN env var only applies to the default account — with multiple bots, put tokens in accounts.*.botToken.
  • If you keep dmPolicy: "pairing": DM each bot once, then approve via:
    • openclaw pairing list telegram
    • openclaw pairing approve telegram <CODE>
raw token
#

A is ollama_agent B is KaliGrowth
Here my .json, how can i fix it? {
"meta": {
"lastTouchedVersion": "2026.2.13",
"lastTouchedAt": "2026-02-16T13:23:15.325Z"
},
"wizard": {
"lastRunAt": "2026-02-14T11:19:46.340Z",
"lastRunVersion": "2026.2.13",
"lastRunCommand": "configure",
"lastRunMode": "local"
},
"agents": {

"defaults": {
  "model": {
    "primary": "openai/gpt-4o-mini",
    "fallbacks": [
      "openai/gpt-4o"
    ]
  },
  "models": {
    "openai/gpt-4o-mini": {},
    "openai/gpt-4o": {}
  },
  "compaction": {
    "mode": "safeguard"
  },
  "heartbeat": {
    "every": "2h"
  },
  "maxConcurrent": 4,
  "subagents": {
    "maxConcurrent": 8
  }
},
"list": [
  {
    "id": "ollama_agent",
    "model": "openai/gpt-4o-mini"
  },
  {
    "id": "KaliGrowth",
    "model": "openai/gpt-4o-mini"
  }
]

},
"tools": {
"web": {
"search": {
"enabled": true,
"apiKey": "xx"
},
"fetch": {
"enabled": true
}
}
},
"messages": {
"ackReactionScope": "group-mentions"
},
"commands": {
"native": "auto",
"nativeSkills": "auto"
},
"channels": {
"telegram": {
"bots": [

#

{
"name": "Sam",
"enabled": true,
"dmPolicy": "pairing",
"token": "xx",
"agentId": "ollama_agent",
"groupPolicy": "allowlist",
"streamMode": "partial"
},
{
"name": "KaliGrowth",
"enabled": true,
"dmPolicy": "pairing",
"token": "xx",
"agentId": "kaligrowth",
"groupPolicy": "allowlist",
"streamMode": "partial"
}
]
}
},

"gateway": {
"port": XX,
"mode": "local",
"bind": "lan",
"auth": {
"mode": "token",
"token": "XX"
}
},
"plugins": {
"entries": {
"telegram": {
"enabled": true
}
}
}
}

spark otterBOT
#

Your snippet looks like you’re trying to do multi-bot Telegram by putting an array of bot configs somewhere (and using token + agentId). That’s not how current OpenClaw routes multi-agent.

In current OpenClaw you want:

  • Telegram multi-bot = channels.telegram.accounts (an object, not an array)
  • Route bot → agent = bindings[] using match.accountId
  • Telegram token key is botToken (not token)
  • You typically do not need plugins.entries.telegram (Telegram is a built-in channel)

Here’s the “proper” shape:

{
  session: { dmScope: "per-account-channel-peer" },

  agents: {
#
    list: [
      { id: "ollama_agent", default: true, workspace: "~/.openclaw/workspace-ollama" },
      { id: "kaligrowth", workspace: "~/.openclaw/workspace-kaligrowth" },
    ],
  },

  channels: {
    telegram: {
      enabled: true,

      dmPolicy: "pairing",
      groupPolicy: "allowlist",
      streamMode: "partial",

      accounts: {
#
        sam: {
          name: "Sam",
          botToken: "xxx:yyy",
        },
        kaligrowth: {
          name: "KaliGrowth",
          botToken: "aaa:bbb",
        },
      },
    },
  },

  bindings: [
    { agentId: "ollama_agent", match: { channel: "telegram", accountId: "sam" } },
    { agentId: "kaligrowth", match: { channel: "telegram", accountId: "kaligrowth" } },
#
  ],
}

What to change from your config:

  1. Replace token → botToken (Telegram uses botToken)
  2. Remove agentId from the Telegram bot entries (routing belongs in bindings)
  3. Make accounts an object ({ sam: {...}, kaligrowth: {...} }), not a list
  4. Remove plugins.entries.telegram unless your version explicitly requires it (most don’t)

Docs:

If you tell me your openclaw --version and paste the exact surrounding path where that array currently lives (e.g. channels.telegram.accounts = [...]?), I can give you the exact minimal diff for your file.

raw token
#

2026.2.15
the copy paste i have done is my openclaw.json file don't know the path you are talking sorry

spark otterBOT
#

“Path” = just the JSON nesting path inside the config (like channels.telegram.accounts). Not a filesystem path.

On 2026.2.15, your Telegram section should not be an array of bots with agentId inside it. Instead:

  • put both bot tokens under: channels.telegram.accounts
  • route each bot to an agent via: top-level bindings[]
  • use botToken (not token)

Here’s a full-file style template you can reshape yours into (keep your existing gateway values):

{
  agents: {
    list: [
      { id: "ollama_agent", default: true, workspace: "~/.openclaw/workspace-ollama" },
      { id: "kaligrowth", workspace: "~/.openclaw/workspace-kaligrowth" },
#
    ],
  },

  channels: {
    telegram: {
      enabled: true,
      dmPolicy: "pairing",
      groupPolicy: "allowlist",
      streamMode: "partial",

      accounts: {
        sam: {
          name: "Sam",
          botToken: "xx",
        },
#
        kaligrowth: {
          name: "KaliGrowth",
          botToken: "xx",
        },
      },
    },
  },

  // This is the important part: route account -> agent
  bindings: [
    { agentId: "ollama_agent", match: { channel: "telegram", accountId: "sam" } },
    { agentId: "kaligrowth", match: { channel: "telegram", accountId: "kaligrowth" } },
  ],

  gateway: {
#
    port: XX,
    mode: "local",
    bind: "lan",
    auth: { mode: "token", token: "XX" },
  },
}

Two quick gotchas:

  1. sam / kaligrowth (the keys under accounts) are the accountId values you must also use in bindings[].match.accountId.
  2. If you keep groupPolicy: "allowlist" and you’re testing in a group, you must also allow senders (via groupAllowFrom or allowFrom) or it will ignore messages. For quick testing, try DMs first, or temporarily set groupPolicy: "open" for the specific group id.

After editing:

  • run openclaw doctor (it will tell you if the schema is wrong)
  • then restart the gateway (openclaw gateway restart) if you’re not using hot reload
#

If you paste just your current channels block (redact tokens), I can point to the exact lines to replace so you don’t have to rewrite the whole file.

raw token
#

do i keep my "default" section in the new json file : "agents": {

    "defaults": {
        "model": {
            "primary": "openai/gpt-4o-mini",
            "fallbacks": [
                "openai/gpt-4o"
            ]
        },
        "models": {
            "openai/gpt-4o-mini": {},
            "openai/gpt-4o": {}
        },
        "compaction": {
            "mode": "safeguard"
        },
        "heartbeat": {
            "every": "2h"
        },
        "maxConcurrent": 4,
        "subagents": {
            "maxConcurrent": 8
        }
    },
spark otterBOT
#

Yes — keep your agents.defaults block.

Think of it like:

  • agents.defaults = the baseline settings applied to all agents (model config, heartbeat, compaction, concurrency, etc.)
  • agents.list[] = define which agents exist, and optionally override per-agent things (workspace, model, tools, sandboxing…)

So your config commonly looks like:

{
  agents: {
    defaults: {
      // keep all your current defaults here
      model: { /* ... */ },
      models: { /* ... */ },
#
      compaction: { mode: "safeguard" },
      heartbeat: { every: "2h" },
      maxConcurrent: 4,
      subagents: { maxConcurrent: 8 },
    },

    list: [
      { id: "ollama_agent", default: true, workspace: "~/.openclaw/workspace-ollama" },
      { id: "kaligrowth", workspace: "~/.openclaw/workspace-kaligrowth" },
    ],
  },

  // ...channels.telegram.accounts + bindings...
}
#

Only change agents.defaults if you want different defaults globally. If you want one agent to behave differently, override inside that agent entry (e.g. per-agent model, tools, sandbox, etc.).

Reference: https://docs.openclaw.ai/gateway/configuration-reference (see “Agent defaults” + “Multi-agent routing”).

raw token
#

i see : "meta": {
"lastTouchedVersion": "2026.2.13",
"lastTouchedAt": "2026-02-16T13:23:15.325Z"
but i'm on version 2026.2.15 do i change it or it will be change later?