async-matrix

An async-native Matrix Application Service SDK for Ruby. Built on the Socketry ecosystem (async, async-http, Falcon) — no threads, no callbacks, just fibers.

async-matrix implements the Matrix Application Service API: the server side of a bridge or bot. Your homeserver PUTs transactions of events at your service; async-matrix authenticates them, deduplicates them, and dispatches each event to the handlers you register. The whole stack runs on fibers, so thousands of concurrent HTTP calls back to the homeserver cost you connection-pool slots, not threads.

Quick start

# config.ru
require "async/matrix"

config = Async::Matrix::ApplicationService::Config.load("config/appservice.yml")
client = Async::Matrix::Client.new(config)

bot = Async::Matrix::ApplicationService::Bot.new(client) do
  on "m.room.member" do |event|
    join_room(event.room_id) if event.content.membership == "invite"
  end

  on "m.room.message", msgtype: "m.text", not_from: :self do |event|
    send_notice event.room_id, "Echo: #{event.content.body}"
  end
end

app = Async::Matrix::ApplicationService::Server.new(
  hs_token: config.appservice.hs_token,
  client:   client
) do
  dispatch bot
end

run app
falcon serve --bind http://0.0.0.0:9292

That’s a complete echo bot. The Server wraps a Grape API with the Matrix wire-protocol routes mixed in; dispatch registers a bot or plain handler; Falcon serves it. Head to Getting Started for a full walkthrough with a homeserver.

What’s here

Design principles

  1. Async all the way down. Every HTTP call is a fiber operation on Async::HTTP::Internet with fiber-safe connection pooling. No thread pools, no callback soup.
  2. The homeserver is untrusted input. Transactions are authenticated with a constant-time token compare and deduplicated by transaction ID before any handler runs. One handler raising never takes down the rest.
  3. Specs are the source of truth. The API chain validates against the official Matrix Client-Server OpenAPI documents, and events validate against the upstream event JSON schemas — both bundled into the gem.

This site uses Just the Docs, a documentation theme for Jekyll.