osmose

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Aug 28, 2026 License: MIT Imports: 3 Imported by: 0

README

docshelf logo

Osmose

A fast and idiomatic Go SDK for building bots on the Osmium protocol.


CI Latest release License Go Reference

Why Osmose?

Osmose is a small, typed Go SDK for creating bots on the Osmium protocol. It is not a Discord SDK and does not model Osmium as Discord.

The SDK hides WebSocket frames, binary Protocol Buffers, request correlation, keepalive, reconnect, and shutdown behind a straightforward client API. The generated protocol packages remain available for advanced integrations.

Read the Osmose documentation for the complete guide.

Installation

Add Osmose to a Go module:

go get github.com/ofabiodev/osmose

Generated protocol packages are included, so installing Osmose does not require protoc.

Transparency
Transparency is a core pillar of my projects. AI is used as a supporting tool where it helps, mainly for code completion and translating technical documentation. The architecture, decisions, review, testing, and responsibility for the released code remain with the project owner.

Features

Area Status Details
Client Small central client with sensible defaults and typed services
Gateway Binary protobuf over WebSocket with controlled reads, writes, and keepalive
Lifecycle Connect, initialize, authorize, ready, reconnect, and graceful shutdown
RPC Fast request correlation, context cancellation, timeouts, and typed errors
Events Strongly typed handlers for connection, messages, users, communities, members, interactions, and voice state
Collectors Typed message, interaction, and reaction collectors with filters and bounded lifetimes
Messages Send, reply, edit, delete, history, search, pinned messages, mentions, media, and buttons
Services Messages, chats, communities, users, reactions, and voice control-plane operations
Models Small public models with useful fields and raw protocol access when needed
Raw API Generated protobuf escape hatch for endpoints not wrapped by a service
Safety Bounded event and write queues, cancellation, reconnect backoff, and race-tested concurrency
Documentation Public documentation site built with docshelf

Quick start

package main

import (
	"context"
	"log"
	"os"
	"os/signal"

	"github.com/ofabiodev/osmose"
)

func main() {
	ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
	defer stop()

	client, err := osmose.New(osmose.Config{
		Token:    os.Getenv("OSMIUM_TOKEN"),
		ClientID: 123456,
	})
	if err != nil {
		log.Fatal(err)
	}

	client.OnReady(func(_ context.Context, event *osmose.ReadyEvent) error {
		log.Printf("connected as %s", event.User.Username)
		return nil
	})

	client.OnMessageCreate(func(ctx context.Context, event *osmose.MessageCreateEvent) error {
		if event.Message.Content != "!ping" {
			return nil
		}
		return event.Reply(ctx, "Pong! 🏓")
	})

	if err := client.Run(ctx); err != nil {
		log.Fatal(err)
	}
}

Set the token before running the bot:

export OSMIUM_TOKEN="your-bot-token"
go run .

On PowerShell:

$env:OSMIUM_TOKEN = "your-bot-token"
go run .

Run manages the connection, handshake, event dispatch, keepalive, reconnect, and shutdown for the client.

Events

Handlers are strongly typed, return an error, and can be removed:

remove := client.OnMessageUpdate(func(_ context.Context, event *osmose.MessageUpdateEvent) error {
	log.Printf("message %d changed", event.Message.ID)
	return nil
})
defer remove()

client.OnInteraction(func(ctx context.Context, event *osmose.InteractionEvent) error {
	if event.Data == "confirm" {
		return event.Reply(ctx, "Confirmed")
	}
	return event.Defer(ctx)
})

Typed events include connection lifecycle, ready, message, channel, user, community, typing, member, reaction, read-marker, interaction, and voice room updates. Use OnUpdate when an application needs the raw generated update.

Event delivery is bounded, so a slow handler cannot create an unlimited number of goroutines. Set EventWorkers above one when handlers may run concurrently. DroppedEvents and OnEventOverflow make queue drops observable.

Collectors

Collectors are useful for confirmations, forms, and multi-step conversations:

event, err := client.AwaitMessage(ctx, osmose.MessageCollectorOptions{
	Chat:     chat,
	AuthorID: userID,
	Time:     time.Minute,
})
if err != nil {
	return err
}

return event.Reply(ctx, "Recebi: "+event.Message.Content)

Use CollectMessages when more than one matching message is needed. Message, interaction, and reaction collectors support typed filters, maximum counts, idle timeouts, total timeouts, cancellation, and bounded buffers.

See the collector guide for a complete form flow.

Sending messages

Use parameter structs instead of constructing protobuf requests:

import (
	"github.com/ofabiodev/osmose/messages"
	"github.com/ofabiodev/osmose/types"
)

sent, err := client.Messages.Send(ctx, messages.SendParams{
	Chat:    types.SelfChat(),
	Content: "Choose an action:",
})
if err != nil {
	return err
}

log.Printf("sent message %d", sent.ID)

Replying to a message event is shorter:

return event.Reply(ctx, "Pong!")

Common chat references are types.SelfChat(), types.UserChat(id), types.GroupChat(id), and types.ChannelChat(communityID, channelID).

Services

Service Operations
Messages Send, Reply, History, Search, PinnedMessages, UnreadMentions, Edit, Delete
Chats List, Get, Members, SetTyping
Communities List, Channels, ChannelMembers
Users Get, Profile
Reactions Add, Remove
Voice RequestRoom, RoomStates, DisconnectUser

Every network operation accepts context.Context.

Models

The types package contains the public models shared by services and events:

Type Use
types.ID Explicit Osmium identifier type
types.User User identity, status, photo, and bot information
types.Message Message content, author, chat, replies, media, entities, and buttons
types.ChatRef Self, user, group, or community channel reference
types.Conversation Chat state and read markers
types.Group, types.Channel, types.Community Conversation and community information
types.CommunityMember, types.ChatMember Membership and permissions
types.MemberListEntry, types.MemberListDivider Ordered community-channel member list entries
types.Interaction Interaction IDs and action data

Models expose useful fields directly. Where it is useful for advanced code, the original generated value remains available through Raw.

Errors

Use errors.Is and errors.As instead of matching error strings:

if errors.Is(err, osmose.ErrPermanent) {
	log.Fatal("the server rejected the connection permanently")
}

var rpcErr *osmose.RPCError
if errors.As(err, &rpcErr) {
	log.Printf("RPC %d: %s", rpcErr.Code, rpcErr.Message)
}

Osmose exposes typed errors for closed clients, connection state, permanent authorization failures, protocol mismatches, RPC failures, and collector termination reasons.

Configuration

Only Token and ClientID are required:

client, err := osmose.New(osmose.Config{
	Token:    token,
	ClientID: clientID,
})

Optional settings include:

Setting Purpose
ServerURL Use a different Osmium WebSocket endpoint
Logger Configure log/slog output
RequestTimeout Set the default RPC timeout
RequestInterval Add a minimum interval between outbound requests
HeartbeatInterval Configure the session keepalive interval
EventQueue, EventWorkers Control bounded event delivery
OnHandlerError, OnEventOverflow Observe handler failures and dropped events
WriteQueue, WriteTimeout Control outbound backpressure
BackoffMin, BackoffMax Bound reconnect delays

Zero values use sensible defaults.

Advanced / raw API

When a service does not cover an endpoint, use a generated protocol request:

import protoCommunities "github.com/ofabiodev/osmose/proto/communities"

result, err := client.Raw().Call(ctx, &protoCommunities.GetCommunities{})
if err != nil {
	return err
}

communities := result.GetCommunities()

The generated protocol packages are included in the module and the raw API is kept separate from the common service API.

Protocol

Osmose follows Osmium's RPC-over-WebSocket protocol:

WebSocket
  → binary protobuf ServerMessage
  → RPC result → waiting request
  → update → typed event handler

The connection handshake is:

Connect → Initialize → Initialized → Authorize → Authorization → Ready

Connection failures are retried with bounded backoff. Pending requests are completed when a connection ends, and reconnect performs the handshake again. Osmose uses the current Osmium protocol rather than adding a REST layer or mapping the protocol to Discord concepts.

Documentation

The complete documentation is published at ofabiodev.github.io/osmose.

To preview the documentation locally:

cd docs
bun install
bun run docs:dev

See CONTRIBUTING.md for contribution and development instructions.

Releases

Osmose uses Release Please and Conventional Commits. The release guide explains the first release and the automated release flow.

License

MIT © ofabiodev

Documentation

Overview

Package osmose is the idiomatic Go SDK for Osmium bots.

Osmose hides the WebSocket, binary protobuf, handshake, reconnect, and RPC correlation details behind a small typed client API. Advanced users can use Client.Raw to send generated protobuf requests directly.

Index

Constants

View Source
const (
	Disconnected   = coreclient.Disconnected
	Connecting     = coreclient.Connecting
	Initializing   = coreclient.Initializing
	Authenticating = coreclient.Authenticating
	Ready          = coreclient.Ready
	Closing        = coreclient.Closing
)
View Source
const (
	EndReasonTime     = collectors.EndReasonTime
	EndReasonIdle     = collectors.EndReasonIdle
	EndReasonLimit    = collectors.EndReasonLimit
	EndReasonStopped  = collectors.EndReasonStopped
	EndReasonContext  = collectors.EndReasonContext
	EndReasonOverflow = collectors.EndReasonOverflow
	EndReasonClosed   = collectors.EndReasonClosed
)

Variables

View Source
var (
	ErrClosed              = coreclient.ErrClosed
	ErrNotConnected        = coreclient.ErrNotConnected
	ErrNotReady            = coreclient.ErrNotReady
	ErrAlreadyRunning      = coreclient.ErrAlreadyRunning
	ErrRunCompleted        = coreclient.ErrRunCompleted
	ErrPermanent           = coreclient.ErrPermanent
	ErrAuthorizationFailed = coreclient.ErrAuthorizationFailed
	ErrProtocolMismatch    = coreclient.ErrProtocolMismatch
	ErrDisconnected        = coreclient.ErrDisconnected
	ErrUnsupportedRequest  = coreclient.ErrUnsupportedRequest
	ErrEventQueueFull      = events.ErrEventQueueFull
	ErrCollectorEnded      = collectors.ErrCollectorEnded
	ErrCollectorTimeout    = collectors.ErrCollectorTimeout
	ErrCollectorIdle       = collectors.ErrCollectorIdle
	ErrCollectorOverflow   = collectors.ErrCollectorOverflow
	ErrCollectorClosed     = collectors.ErrCollectorClosed
)

Functions

func IsPermanent

func IsPermanent(err error) bool

Types

type ChannelDeleteEvent

type ChannelDeleteEvent = events.ChannelDeleteEvent

type ChannelDeleteHandler

type ChannelDeleteHandler = events.ChannelDeleteHandler

type ChannelUpdateEvent

type ChannelUpdateEvent = events.ChannelUpdateEvent

type ChannelUpdateHandler

type ChannelUpdateHandler = events.ChannelUpdateHandler

type ChatTypingEvent

type ChatTypingEvent = events.ChatTypingEvent

type ChatTypingHandler

type ChatTypingHandler = events.ChatTypingHandler

type Client

type Client = coreclient.Client

func New

func New(config Config) (*Client, error)

type CollectorError

type CollectorError = collectors.CollectorError

type CollectorResult

type CollectorResult = collectors.CollectorResult

type CommunityDeleteEvent

type CommunityDeleteEvent = events.CommunityDeleteEvent

type CommunityDeleteHandler

type CommunityDeleteHandler = events.CommunityDeleteHandler

type CommunityUpdateEvent

type CommunityUpdateEvent = events.CommunityUpdateEvent

type CommunityUpdateHandler

type CommunityUpdateHandler = events.CommunityUpdateHandler

type Config

type Config = coreclient.Config

type ConnectionEvent

type ConnectionEvent = events.ConnectionEvent

type ConnectionHandler

type ConnectionHandler = events.ConnectionHandler

type ConversationLastReadEvent

type ConversationLastReadEvent = events.ConversationLastReadEvent

type ConversationLastReadHandler

type ConversationLastReadHandler = events.ConversationLastReadHandler

type EndReason

type EndReason = collectors.EndReason

type EventOverflowHandler

type EventOverflowHandler = events.EventOverflowHandler

type HandlerError

type HandlerError = events.HandlerError

type HandlerErrorHandler

type HandlerErrorHandler = events.HandlerErrorHandler

type InteractionCollector

type InteractionCollector = collectors.InteractionCollector

type InteractionCollectorOptions

type InteractionCollectorOptions = collectors.InteractionCollectorOptions

type InteractionEvent

type InteractionEvent = events.InteractionEvent

type InteractionHandler

type InteractionHandler = events.InteractionHandler

type MemberCreateEvent

type MemberCreateEvent = events.MemberCreateEvent

type MemberCreateHandler

type MemberCreateHandler = events.MemberCreateHandler

type MemberDeleteEvent

type MemberDeleteEvent = events.MemberDeleteEvent

type MemberDeleteHandler

type MemberDeleteHandler = events.MemberDeleteHandler

type MemberUpdateEvent

type MemberUpdateEvent = events.MemberUpdateEvent

type MemberUpdateHandler

type MemberUpdateHandler = events.MemberUpdateHandler

type MessageCollector

type MessageCollector = collectors.MessageCollector

type MessageCollectorOptions

type MessageCollectorOptions = collectors.MessageCollectorOptions

type MessageCreateEvent

type MessageCreateEvent = events.MessageCreateEvent

type MessageCreateHandler

type MessageCreateHandler = events.MessageCreateHandler

type MessageDeleteEvent

type MessageDeleteEvent = events.MessageDeleteEvent

type MessageDeleteHandler

type MessageDeleteHandler = events.MessageDeleteHandler

type MessageReactionsEvent

type MessageReactionsEvent = events.MessageReactionsEvent

type MessageReactionsHandler

type MessageReactionsHandler = events.MessageReactionsHandler

type MessageUpdateEvent

type MessageUpdateEvent = events.MessageUpdateEvent

type MessageUpdateHandler

type MessageUpdateHandler = events.MessageUpdateHandler

type PermanentError

type PermanentError = coreclient.PermanentError

type RPCError

type RPCError = coreclient.RPCError

type RawClient

type RawClient = coreclient.RawClient

type ReactionCollector

type ReactionCollector = collectors.ReactionCollector

type ReactionCollectorOptions

type ReactionCollectorOptions = collectors.ReactionCollectorOptions

type ReadyEvent

type ReadyEvent = events.ReadyEvent

type ReadyHandler

type ReadyHandler = events.ReadyHandler

type State

type State = coreclient.State

type UnexpectedResultError

type UnexpectedResultError = coreclient.UnexpectedResultError

type UpdateEvent

type UpdateEvent = events.UpdateEvent

type UpdateHandler

type UpdateHandler = events.UpdateHandler

type UserUpdateEvent

type UserUpdateEvent = events.UserUpdateEvent

type UserUpdateHandler

type UserUpdateHandler = events.UserUpdateHandler

type VoiceRoomParticipantEvent

type VoiceRoomParticipantEvent = events.VoiceRoomParticipantEvent

type VoiceRoomParticipantHandler

type VoiceRoomParticipantHandler = events.VoiceRoomParticipantHandler

type VoiceRoomStateEvent

type VoiceRoomStateEvent = events.VoiceRoomStateEvent

type VoiceRoomStateHandler

type VoiceRoomStateHandler = events.VoiceRoomStateHandler

Directories

Path Synopsis
Package collectors provides bounded helpers for waiting on typed events.
Package collectors provides bounded helpers for waiting on typed events.
Package events contains the typed event payloads emitted by Osmose.
Package events contains the typed event payloads emitted by Osmose.
examples
basic command
ping command
internal
client
Package client contains the internal implementation behind the public osmose package.
Package client contains the internal implementation behind the public osmose package.
gateway
Package gateway owns the single WebSocket reader and controlled writer used by an Osmium client.
Package gateway owns the single WebSocket reader and controlled writer used by an Osmium client.
rpc
proto
tools
protogen command
wrapgen command
Package types contains the small public models shared by Osmose services and events.
Package types contains the small public models shared by Osmose services and events.
Package voice exposes the voice control-plane operations present in the Osmium protocol.
Package voice exposes the voice control-plane operations present in the Osmium protocol.

Jump to

Keyboard shortcuts

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