GitHunt

go-simplex

Go SDK for building SimpleX bots with an idiomatic, typed API and a practical bot runtime.

Scope

  • full generated coverage of the official SimpleX bot command API snapshot (spec/upstream/commands.ts)
  • typed event/response tags and records from upstream snapshots
  • high-level client helpers for common bot workflows
  • bot runtime with middleware, direct-message extraction, command router, and reconnect supervisor
  • security-focused defaults and explicit hardening options

Official SimpleX docs

Quick start

1. Start SimpleX CLI websocket API

simplex-chat -p 5225

2. Generate a new bot project

go run ./cmd/simplexbot-init \
  -module github.com/you/my-simplex-bot \
  -template basic \
  -out ./my-simplex-bot
cd ./my-simplex-bot
go mod tidy
go run .

3. Run a concrete example bot

go run ./examples/echo-bot
go run ./examples/faq-bot
go run ./examples/welcome-bot
go run ./examples/moderation

Available scaffold templates:

  • basic: help, ping, echo
  • moderation: deny-list moderation (addword, delword, words) for direct messages

Examples index with test scenarios: examples/README.md.

Minimal bot example

ctx := context.Background()
router := bot.NewTextRouter()
_ = router.EnablePerContactRateLimit(20, time.Minute)
_ = router.OnWithDescription("ping", "health check", func(ctx context.Context, cli *client.Client, cmd bot.TextCommand) error {
    return cmd.Reply(ctx, cli, "pong")
})

err := bot.RunWebSocketWithReconnect(
    ctx,
    "ws://localhost:5225",
    nil,
    []client.Option{client.WithStrictResponses(false)},
    func(cli *client.Client) (bot.Runner, error) {
        rt, err := bot.NewRuntime(cli)
        if err != nil {
            return nil, err
        }
        bot.OnDirectCommands(rt, router)
        return rt, nil
    },
)
if err != nil && !errors.Is(err, context.Canceled) {
    panic(err)
}

API layers

  • generated command layer: sdk/command/generated_requests.go
  • generated typed sender layer: sdk/client/generated_senders.go
  • high-level convenience client: sdk/client/api.go
  • runtime/router layer: sdk/bot/*

Security and resilience features

  • websocket hardening:
    • ws.WithRequireWSS(true)
    • ws.WithTLSMinVersion(...)
    • ws.WithReadLimit(...)
  • raw command controls:
    • client.WithRawCommandAllowPrefixes(...)
    • client.WithRawCommandValidator(...)
    • client.WithRawCommandMaxBytes(...)
  • forward-compatible unknown response handling:
    • client.WithStrictResponses(false)
  • bounded channel overflow policies:
    • client.WithEventOverflowPolicy(...)
    • client.WithErrorOverflowPolicy(...)
    • client.WithDropHandler(...)
  • ref validation in high-level helpers (sendRef/chatRef must be @id, #id, *id)
  • per-contact command rate limiting in router:
    • router.EnablePerContactRateLimit(...)
    • router.OnRateLimited(...)

More details: docs/security.md.

Documentation

  • Getting started: docs/getting-started.md
  • Bot development guide: docs/bot-development.md
  • Compatibility and coverage: docs/compatibility.md
  • Security guide: docs/security.md
  • Production deployment guide: docs/production.md
  • Vulnerability reporting: SECURITY.md
  • Contribution guide: CONTRIBUTING.md
  • Upstream API research notes: docs/research/upstream-api.md
  • Upstream TS SDK research notes: docs/research/upstream-sdk.md
  • Implementation roadmap: docs/plan/go-sdk-roadmap.md

Compatibility snapshot

Current generated coverage against tracked upstream snapshots:

  • bot API command interfaces in spec/upstream/commands.ts: 42
  • generated request structs in sdk/command/generated_requests.go: 42
  • generated typed sender methods in sdk/client/generated_senders.go: 42
  • upstream event tags in spec/upstream/events.ts: 45
  • generated types.EventType constants: 45
  • upstream response tags in spec/upstream/responses.ts: 45
  • generated types.ResponseType constants: 45

Details and verification commands are in docs/compatibility.md.

Development

Regenerate from local upstream snapshots:

go run ./cmd/simplexgen

Refresh upstream snapshots and regenerate:

./scripts/update-upstream.sh

Run compatibility guard (generator drift + snapshot count parity):

./scripts/check-compat.sh

Run checks:

go test ./...
go test -race ./...
go vet ./...

Run live contract tests against a real SimpleX websocket API:

SIMPLEX_WS_URL=ws://localhost:5225 go test -tags=integration ./integration/... -v

Local harness (auto-start simplex-chat, run integration tests, cleanup):

./scripts/integration-local.sh

Harness options:

  • --no-start to run against existing endpoint
  • --port <port> to override local websocket port
  • --timeout <sec> to adjust readiness wait
  • --verbose for extra diagnostics

Pass extra go test args after --, for example:

./scripts/integration-local.sh --no-start -- -run TestLiveContracts

Optional vulnerability scan:

go run golang.org/x/vuln/cmd/govulncheck@latest ./...

Release process

Release from merged PR state:

  1. add a version section to CHANGELOG.md (## [vX.Y.Z] - YYYY-MM-DD)
  2. merge to main
  3. run GitHub Actions workflow Release with input version=vX.Y.Z

Release notes are extracted from changelog via:

./scripts/release-notes.sh vX.Y.Z