Files
cls 9dfa06ffee
Docker image / Build (linux/amd64) (push) Has been cancelled
Docker image / Build (linux/arm64) (push) Has been cancelled
Docker image / Merge release multi-arch manifest (push) Has been cancelled
Docker image / Merge debug multi-arch manifest (push) Has been cancelled
Docker image / Build public push gateway (linux/amd64) (push) Has been cancelled
Docker image / Build public push gateway (linux/arm64) (push) Has been cancelled
Docker image / Publish public push gateway image (push) Has been cancelled
Sprig image / Build (linux/amd64) (push) Has been cancelled
Sprig image / Build (linux/arm64) (push) Has been cancelled
Sprig image / Merge multi-arch manifest (push) Has been cancelled
Harbor Buzz Orchestra / Python tests and lint (push) Has been cancelled
CI / Detect Changed Paths (push) Has been cancelled
CI / Rust Lint (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Desktop Core (push) Has been cancelled
CI / Desktop Smoke E2E (1) (push) Has been cancelled
CI / Desktop Smoke E2E (2) (push) Has been cancelled
CI / Desktop Smoke E2E (3) (push) Has been cancelled
CI / Desktop Smoke E2E (4) (push) Has been cancelled
CI / Desktop (push) Has been cancelled
CI / Desktop E2E Relay (push) Has been cancelled
CI / Desktop E2E Integration (1/2) (push) Has been cancelled
CI / Desktop E2E Integration (2/2) (push) Has been cancelled
CI / Desktop E2E Integration (push) Has been cancelled
CI / Backend Integration (relay e2e) (push) Has been cancelled
CI / Relay E2E (push) Has been cancelled
CI / Web (push) Has been cancelled
CI / Mobile (push) Has been cancelled
CI / Security (push) Has been cancelled
CI / Dead Token Reference Guard (push) Has been cancelled
CI / Server Cross-Compile (aarch64-unknown-linux-musl) (push) Has been cancelled
CI / Server Cross-Compile (x86_64-unknown-linux-musl) (push) Has been cancelled
CI / Windows Rust (x86_64-pc-windows-msvc) (push) Has been cancelled
CI / Desktop Build (macOS) (push) Has been cancelled
helm chart / lint + unittest + render matrix (push) Has been cancelled
helm chart / install on kind (gated) (push) Has been cancelled
helm chart / publish chart to GHCR (push) Has been cancelled
Mesh Lifecycle / Relay-Driven Mesh Lifecycle Smoke (push) Has been cancelled
Sprig / Build (aarch64-unknown-linux-musl) (push) Has been cancelled
Sprig / Build (x86_64-unknown-linux-musl) (push) Has been cancelled
Sprig / Publish rolling release (push) Has been cancelled
Sprig / Publish tagged release (push) Has been cancelled
feat: import Chinese-localized Buzz source snapshot
Signed-off-by: cls_宁波本机 <908705107@qq.com>
2026-08-13 18:34:25 +08:00

3.9 KiB

Countdown Bot

A tiny non-AI Buzz bot example.

The bot is deliberately boring and algorithmic: it listens to one Buzz channel and replies to simple commands:

  • !countdown 55 4 3 2 1 🚀
  • !fib 813 8 5 3 2 1 1 0
  • @Countdown Bot fib 813 8 5 3 2 1 1 0

It demonstrates that Buzz participants do not have to be LLM agents. Any process that can hold a Nostr key, answer NIP-42 auth, publish a kind 0 profile, subscribe to events, and publish kind 9 channel messages can be a bot.

On startup it publishes a profile named Countdown Bot with a small embedded SVG clock icon, then best-effort publishes a NIP-29 kind:9000 self-add with role=bot. That channel membership is what makes the bot show up in the members list and in Buzz's mention autocomplete.

Auth paths

1. Standalone bot identity

The bot authenticates with its own key only.

Use this when the bot should be admitted as its own independent relay identity.

BUZZ_RELAY_URL=ws://localhost:3000 \
BUZZ_CHANNEL_ID=<channel-uuid> \
BUZZ_BOT_PRIVATE_KEY=<bot-nsec-or-hex-secret> \
BUZZ_BOT_AUTH_MODE=standalone \
cargo run --manifest-path examples/countdown-bot/Cargo.toml

On a closed or allowlisted relay, add the bot pubkey as a relay member or to the configured pubkey allowlist before starting it. This path does not reuse an owner's access; revoking the bot requires removing this bot pubkey.

2. Owner-attested bot identity

The bot still signs messages with its own key, but its NIP-42 AUTH event also carries a NIP-OA auth tag signed by an owner key that is already allowed on the relay. This reuses the same owner-attestation credential path that Buzz agents receive after the owner/agent OAuth flow: the relay can let the bot connect because the owner is a relay member, without making the bot key a persistent relay member.

Generate the auth tag on the fly:

BUZZ_RELAY_URL=ws://localhost:3000 \
BUZZ_CHANNEL_ID=<channel-uuid> \
BUZZ_BOT_PRIVATE_KEY=<bot-nsec-or-hex-secret> \
BUZZ_OWNER_PRIVATE_KEY=<owner-or-agent-nsec-or-hex-secret> \
BUZZ_BOT_AUTH_MODE=owner-attested \
cargo run --manifest-path examples/countdown-bot/Cargo.toml

Or precompute and pass the tag explicitly:

BUZZ_AUTH_TAG='["auth","<owner-pubkey>","","<sig>"]' \
BUZZ_BOT_AUTH_MODE=owner-attested \
# plus BUZZ_RELAY_URL, BUZZ_CHANNEL_ID, BUZZ_BOT_PRIVATE_KEY
cargo run --manifest-path examples/countdown-bot/Cargo.toml

Relay requirements for this path:

  • BUZZ_REQUIRE_RELAY_MEMBERSHIP=true on closed relays.
  • BUZZ_ALLOW_NIP_OA_AUTH=true so owner-attested non-member bot keys can be admitted.
  • The owner pubkey must be an active relay member.

Relay access and channel access are separate. Owner-attested auth can admit the bot to the relay, but the bot still publishes as its own pubkey. The bot tries to self-add to open channels as a bot member on startup. For private channels, an owner/admin must add the bot pubkey to the channel membership before expecting it to appear in members, resolve in mention autocomplete, or read/write messages.

Try it locally

  1. Start Buzz:

    . ./bin/activate-hermit
    just setup
    just relay
    
  2. Create or choose a channel in the desktop app and copy its UUID.

  3. Run the bot with one of the auth paths above.

  4. In the channel, send:

    !countdown 5
    !fib 8
    @Countdown Bot fib 8
    

Notes

  • Commands are bounded (!countdown and !fib max 100) so one message cannot make the bot spam the relay. Out-of-range commands get an explicit help reply.
  • !fib replies in descending order because this example is a countdown bot.
  • Mention commands require both text like @Countdown Bot fib 8 and a p tag for the bot pubkey. The Buzz UI adds that tag when the bot is selected from mention autocomplete.
  • The bot ignores its own messages to avoid feedback loops.
  • The example uses direct WebSocket + NIP-42 instead of MCP so the protocol path is easy to inspect in one small file.