gochat

command module
v1.10.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 25, 2026 License: MIT Imports: 0 Imported by: 0

README

GoChat

Distributed real-time chat and voice backend written in Go.
REST API, WebSocket delivery, file uploads, search indexing, generated embeds, and SFU-based voice.

Docs API UI UI Deployment

Changelog | Go client | TypeScript client | License

Overview

GoChat is a service-oriented messaging platform built around focused Go services. This repository contains the backend services, local development stack, generated API clients, and project documentation for messaging, presence, uploads, search, webhooks, and voice.

What Ships Here

Area What it covers
Core services API, auth, WebSocket gateway, attachments, webhook, indexer, embedder, and SFU
Data layer Citus/PostgreSQL for relational state and ScyllaDB for message-heavy workloads
Messaging NATS-backed event flow for real-time delivery and background workers
Media S3-compatible object storage for uploads, avatars, icons, and attachment assets
Search OpenSearch indexing pipeline driven by the indexer service
Discovery etcd-backed voice service discovery through the webhook service
Clients Generated Go and TypeScript API clients under clients/api/
Operations Docker Compose stack, OpenObserve assets, OTEL collector wiring, and helper CLI tooling

Architecture

flowchart LR
    Client[Client Applications]
    Traefik[Traefik Edge]

    subgraph App[Application Services]
        API[API]
        Auth[Auth]
        WS[WebSocket Gateway]
        Attachments[Attachments]
        Webhook[Webhook]
        Indexer[Indexer]
        Embedder[Embedder]
    end

    subgraph Voice[External Voice Plane]
        SFU[SFU]
    end

    subgraph Data[State and Infra]
        PG[Citus / PostgreSQL]
        Scylla[ScyllaDB]
        KeyDB[KeyDB]
        NATS[NATS]
        Search[OpenSearch]
        S3[S3-compatible Storage]
        Etcd[etcd]
    end

    Client --> Traefik
    Traefik --> API
    Traefik --> Auth
    Traefik --> WS
    Traefik --> Attachments
    Traefik --> Webhook

    API --> PG
    API --> Scylla
    API --> KeyDB
    API --> NATS
    API --> Search
    API --> Etcd

    Auth --> PG
    Auth --> KeyDB

    WS --> NATS
    WS --> Scylla
    WS --> PG
    WS --> KeyDB

    Attachments --> Scylla
    Attachments --> PG
    Attachments --> NATS
    Attachments --> S3

    Webhook --> Scylla
    Webhook --> Etcd

    Indexer --> NATS
    Indexer --> Search

    Embedder --> NATS
    Embedder --> Scylla

    Client --> SFU
    SFU --> Webhook

Services

Service Path Responsibility
API cmd/api Main REST surface for users, guilds, channels, messages, invites, search, uploads, and voice control
Auth cmd/auth Registration, login, refresh tokens, email flows, and password reset
WebSocket Gateway cmd/ws Real-time subscriptions, event delivery, presence updates, and session handling
Attachments cmd/attachments Upload pipeline for attachments, avatars, icons, and related metadata
Webhook cmd/webhook Internal webhook surface for trusted service callbacks such as SFU heartbeats and attachment finalization
SFU cmd/sfu External WebRTC media relay and signaling service for voice channels
Indexer cmd/indexer Consumes message events and writes search documents to OpenSearch
Embedder cmd/embedder Builds generated message embeds from remote metadata and republishes updates
Tools cmd/tools Operational helpers such as webhook token generation

Feature Surface

  • Account lifecycle with token-based authentication
  • Guilds, channels, roles, invites, bans, and custom emoji
  • Direct messages, message history, mentions, attachments, and embed generation
  • Presence updates and real-time event fanout over WebSocket
  • Search indexing and query flow through OpenSearch
  • Voice channel join flow with region-aware SFU discovery
  • Generated Go and TypeScript API clients from the OpenAPI schema

Stack

  • Go 1.25.1
  • Fiber, Fiber WebSocket, and Pion WebRTC
  • Citus/PostgreSQL for relational data
  • ScyllaDB for message timelines and attachment-heavy data
  • NATS for async messaging between services
  • KeyDB for cache and presence/session state
  • OpenSearch for full-text search
  • S3-compatible storage for media assets
  • etcd for service discovery
  • Traefik, OpenObserve, OpenTelemetry Collector, and OpenSearch Dashboards for local operations

Repository Layout

cmd/             runnable services and operational tools
internal/        shared packages for transport, storage, search, mail, presence, and server wiring
db/              PostgreSQL and ScyllaDB migrations
docs/            project docs and generated OpenAPI output
clients/api/     generated Go and TypeScript API clients
compose.yaml     reference local development stack
Makefile         bootstrap, migration, client generation, and rebuild commands

Getting Started

Prerequisites
  • Go 1.25.1 or newer
  • Docker and Docker Compose
  • GNU Make
  • migrate CLI when you want to create migration files locally (make tools installs it)
Fast Path
make setup

make setup installs local tooling, starts the reference stack, initializes ScyllaDB, and applies both PostgreSQL and ScyllaDB migrations.

Manual Bootstrap

Start the local infrastructure:

docker compose up -d
docker compose exec scylla bash ./init-scylladb.sh
docker compose -p gochat up --scale citus-worker=3 -d

Apply migrations locally with the existing Make targets:

make migrate

Build the versioned migration image locally when you want to test the same packaging used in CI:

make build_migration_image
make migrate_image PG_ADDRESS="postgres://postgres@host.docker.internal/gochat" CASSANDRA_ADDRESS="cassandra://host.docker.internal/gochat?x-multi-statement=true"

When you run the migration image from Docker, the connection strings need container-reachable hosts such as Compose service DNS names or host.docker.internal, not host-local 127.0.0.1.

For deployments, GitHub Actions now publishes ghcr.io/<owner>/gochat-migrations:<tag> for releases and ghcr.io/<owner>/gochat-migrations:dev from the dev branch. The image contains the exact migration files for that version and defaults to applying both migration sets with up.

This image applies versioned schema migrations. Database bootstrap that is outside the migration files, such as creating the ScyllaDB keyspace or enabling Citus, still needs to be completed before the container runs.

You can scope it to a single database or change the command:

docker run --rm \
  -e PG_ADDRESS="postgres://postgres@postgres/gochat?sslmode=disable" \
  -e CASSANDRA_ADDRESS="cassandra://scylla/gochat?x-multi-statement=true" \
  ghcr.io/<owner>/gochat-migrations:v1.2.3

docker run --rm \
  -e MIGRATION_SCOPE=postgres \
  -e PG_ADDRESS="postgres://postgres@postgres/gochat?sslmode=disable" \
  ghcr.io/<owner>/gochat-migrations:v1.2.3 down 1

The container accepts:

  • PG_ADDRESS for PostgreSQL migrations
  • CASSANDRA_ADDRESS for Cassandra or ScyllaDB migrations
  • MIGRATION_SCOPE=all|postgres|pg|cassandra|scylla
  • MIGRATION_COMMAND as a default command when you prefer env-driven invocation

Review the example configuration files before running services locally:

  • api_config.example.yaml
  • auth_config.example.yaml
  • attachments_config.example.yaml
  • ws_config.example.yaml
  • sfu_config.example.yaml for standalone SFU deployments outside Compose
  • webhook_config.example.yaml
  • indexer_config.example.yaml
  • embedder_config.example.yaml

Running Services

Run individual services directly with Go:

go run ./cmd/api
go run ./cmd/auth
go run ./cmd/ws
go run ./cmd/attachments
go run ./cmd/webhook
go run ./cmd/indexer
go run ./cmd/embedder

Run the SFU separately when you need voice media in a non-Compose environment:

go run ./cmd/sfu

Useful Make targets:

  • make up to start the Compose stack and initialize ScyllaDB
  • make down to stop the stack
  • make migrate to apply both database migration sets
  • make build_migration_image to build the versioned migration container locally
  • make migrate_image to run both migration sets through the container locally
  • make swag to rebuild docs/api/swagger.json
  • make client to regenerate Go and TypeScript clients
  • make rebuild_all to rebuild the application containers

Documentation and Clients

Resource Link
Project docs docs/project/README.md
Service documentation docs/project/Services.md
Observability docs/project/observability/README.md
WebSocket protocol docs/project/ws/README.md
Voice and SFU docs docs/project/voice/README.md
Presence model docs/project/Presence.md
OpenAPI schema docs/api/swagger.json
Go API client clients/api/goclient/
TypeScript API client clients/api/jsclient/
Frontend repository gochat-react
Desktop client repository gochat-electron
Deployment repository gochat-deployment

Local Observability

The supported local observability workflow is OpenObserve plus the OpenTelemetry Collector:

  • Start fresh with docker compose down --remove-orphans and then docker compose up -d.
  • Bootstrap dashboards and alerts with go run ./cmd/tools observability bootstrap --url http://localhost:5080 --org default --user root@example.com --password Complexpass#123.
  • Run the smoke check with go run ./cmd/tools observability smoke --url http://localhost:5080 --org default --user root@example.com --password Complexpass#123.
  • OpenObserve is available on http://localhost:5080.
  • OTEL collector health is available on http://localhost:13133/.
  • Traefik dashboard remains available on http://localhost:8080.
  • OpenSearch Dashboards remains available on http://localhost:5601.

PostgreSQL health in the local stack is now reported through native service-side probe telemetry rather than a Prometheus exporter bridge.

License

MIT. See LICENSE.

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis
cmd
api command
attachments command
auth command
embedder command
indexer command
sfu command
tools command
webhook command
ws command
internal
dto
mq
s3

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL