gobot-channel-bgos
v0.7.0
Published
BGOS channel adapter for Gobot — WS + REST client, outbound modalities, pair CLI
Downloads
883
Readme
gobot-channel-bgos
BGOS channel adapter for Gobot — Socket.IO + REST client, full outbound modality coverage (text, inline buttons, approvals, ask-user-input pop-under, files/images/videos, typing), and a pair-CLI for first-time setup.
The fork (BrandGrowthOS/gobot-bgos-fork — private) wires this package into Gobot's existing message pipeline. Telegram and BGOS run side-by-side; replies always return to whichever channel the user wrote in.
Install
npm i -g gobot-channel-bgosThe package is published to npm as gobot-channel-bgos. The fork lists it under optionalDependencies, so a stock Gobot install still runs without it (BGOS support stays inert until the package is present).
Pair
After standing up Gobot on your host (Mac mini, VPS, whatever), generate a pair code in BGOS (Integrations screen → "Pair Gobot") and run:
gobot-pair-bgos BGOS-XXXX-YY --device-label mac-miniThis:
- POSTs
/integrations/pair-exchangewith the code + your device label. - Writes the pairing token to
~/.gobot/secrets/bgos.json(mode 0600). - Exits 0 on success, non-zero with a diagnostic on failure.
Environment variables
The adapter resolves config in order: explicit constructor arg → env var → ~/.gobot/secrets/bgos.json.
| Var | Default | Purpose |
|---|---|---|
| BGOS_PAIRING_TOKEN | from secrets file | The token written by gobot-pair-bgos. |
| BGOS_BASE_URL | https://api.brandgrowthos.ai | BGOS backend root. |
| GOBOT_HOME | ~/.gobot | Where the adapter persists state (bgos_last_id cursor + secrets dir). |
| GOBOT_HOME_CHANNEL | both | Destination for proactive (no-origin) messages: telegram | bgos | both. |
| GOBOT_POLL_INTERVAL | 5 (seconds) | REST backfill interval. Set to 0 to disable polling once the server-side WS push gap is fixed. |
| GOBOT_MEDIA_ROOT | <cwd>/media (else <cwd>) | Security allowlist root for outbound files. Every sendFile/sendImage/sendVideo/uploadFile path is realpath-resolved and must live under this root; traversal (..), escaping symlinks, and sensitive locations (/etc, ~/.ssh, …) are rejected before any bytes are read. Set it to pin a narrow directory the agent is allowed to send from. |
| GOBOT_ALLOW_INLINE_AGENT_NAME | false | Anti-spoof gate. When off, the plugin drops any agent-supplied inline fromAgent display name/avatarUrl/color and forwards only resolvable handles (peerId/assistantId/externalId/type), letting the backend resolve identity. Set truthy (1/true) only when the matching backend per-user inline-identity toggle is on (e.g. Gobot /board). |
Prerequisites
- The fork (
BrandGrowthOS/gobot-bgos-fork) must be checked out and running on the host. The fork's loader auto-discoversgobot-channel-bgosand wires the adapter into Gobot's bootstrap. - Bun 1.x (Gobot's runtime) — npm-installed packages work fine.
- A reachable BGOS backend (production by default; point
BGOS_BASE_URLelsewhere for testing).
Architecture in one diagram
┌────────────────── Gobot host process (Bun) ───────────────────┐
│ │
│ grammY Telegram handler ──┐ │
│ ▼ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ processMessageForAgent({ origin, agentRoute, text, │ │
│ │ attachments, replyHandle, ... })│ │
│ │ — fork-exported wrapper around Gobot's Claude pipeline │ │
│ └──────────────────────────────────────────────────────────┘ │
│ ▲ │
│ │ │
│ ┌──────────────────── BGOSAdapter ───────────────────────┐ │
│ │ bgos-ws.ts (Socket.IO) ◀── REST backfill cursor ◀──── │ │
│ │ bgos-api.ts (REST) │ │
│ │ outbound.ts: sendText / sendButtons / sendApproval ... │ │
│ │ inbound-handler.ts: builds replyHandle, calls dispatch │ │
│ └────────────────────────────────────────────────────────┘ │
└───────────────────────────────────────────────────────────────┘
│
▼
BGOS backend (api.brandgrowthos.ai)Agent-to-agent (a2a) peer replies
When another BGOS assistant (a Claude Code, Hermes, OpenClaw, or n8n peer) messages this bot, the backend delivers it as an inbound on an a2a side-thread chat, stamped with a peerConversationId on the WS inbound_message event. The adapter detects that marker and routes the agent's reply back the same way the other channel plugins do:
- the reply is posted via
POST /api/v1/send-message(not/messages), the path the backend runs its peer-reply bridge on, and - it is anchored to the inbound's message id via
reply_to_id,
so the initiating peer's wait_for_reply resolves. This is fully automatic — the agent just calls replyHandle.sendText(...) as usual; no peer-specific code is needed in the fork. Ordinary 1:1 user replies are unchanged (still POST /messages, no reply_to_id). The dispatch also surfaces peerConversationId + turnState on DispatchArgs for awareness. No backend change is required — the a2a transport already serves the other plugins. See hermes-channel-bgos/docs/bgos-agent-capabilities.md §11 for the wire protocol.
Troubleshooting
No replies in BGOS, but Telegram works:
- Tail
~/.gobot/logs/bgos-daemon.log(the fork's loader writes here). Look forwhoami OK,connected,catalog pushed. - Confirm
~/.gobot/secrets/bgos.jsonexists and is readable:cat ~/.gobot/secrets/bgos.json | jq .pairingId. - Re-pair via the BGOS Integrations card if the pairing was revoked — adapter logs
PAIRING_REVOKEDon 401.
Replies are duplicated after every restart:
- The persisted cursor at
$GOBOT_HOME/bgos_last_idfailed to update. This file MUST advance with every processed message — if it stays at 0, every restart replays history. - Reset cursor manually:
echo <max-message-id> > ~/.gobot/bgos_last_id. Orrmit to start fresh (will replay everything once).
Logs: the fork pipes adapter output through Gobot's logger. On a default Mac install, look in ~/.gobot/logs/.
Reset everything:
rm -rf ~/.gobot/secrets ~/.gobot/bgos_last_id
gobot-pair-bgos <NEW-CODE>
# restart GobotWhat lives in this package
| Module | Role |
|---|---|
| BGOSAdapter (src/adapter.ts) | Lifecycle, route map, dispatch injection, poll loop |
| BgosOutbound (src/outbound.ts) | All outbound modalities |
| inbound-handler.ts | WS event → Gobot dispatch translator |
| attachment-bridge.ts | BGOS files ⇄ local file paths (S3 + base64) |
| agent-hints.ts | System-prompt addendum injected at dispatch |
| default-commands.ts | 7 seeded slash commands |
| last-id-store.ts | Persistent inbound cursor (CRITICAL — see source) |
| pair-cli.ts | gobot-pair-bgos CLI |
| home-channel.ts | Resolves GOBOT_HOME_CHANNEL for proactive messages |
Development
git clone https://github.com/BrandGrowthOS/gobot-channel-bgos
cd gobot-channel-bgos
npm install
npm test # vitest
npm run build # tsc + finalize-daemonThe package is also mirrored inside the BGOS monorepo at gobot-channel-bgos/ — the public repo is the source of truth (matching the Hermes pattern).
License
MIT.
