0.0
No release in over 3 years
Async-native Matrix protocol primitives built on the Socketry async ecosystem. Provides well-known discovery, event notification, and application service models.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Development

~> 0.55
>= 0

Runtime

~> 2.39
~> 0.95
~> 0.1.7
 Project Readme

async-matrix

Gem Version CI License Ruby

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

Usage

Please see the project documentation for more details.

Install

gem "async-matrix"

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

server = Async::Matrix::ApplicationService::Server.new(hs_token: config.appservice.hs_token)
server.register(bot)

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

A complete working example with Docker Compose and Synapse lives in examples/echo_bot/.

Handlers

Any object that responds to #event_types and #call(event) is a handler. Use this when you need more control than the Bot DSL provides.

class Echo
  def initialize(client) = @client = client

  def event_types = ["m.room.message"]

  def call(event)
    return unless event.content&.msgtype == "m.text"
    return unless event.sender != @client.config.bot_mxid
    @client.send_notice(event.room_id, "Echo: #{event.content.body}")
  end
end

server.register(Echo.new(client))

Dispatch is fault-tolerant -- one handler raising won't take down the rest.

Client

client.send_text(room_id, "Hello world")
client.send_html(room_id, "<b>bold</b>")
client.send_notice(room_id, "Bot says hi")
client.join_room(room_id)
client.leave_room(room_id)
client.set_display_name("My Bot")
client.whoami

For anything beyond the convenience methods, client.api provides method-chained access to the full Matrix Client-Server API, validated at runtime against the official OpenAPI specs:

client.api.createRoom.post(name: "Pub")
client.api.rooms("!room:ex.com").messages.get(dir: "b", limit: 10)

All methods are fiber-safe with automatic connection pooling.

Configuration

Create config/appservice.yml for your bot:

homeserver:
  address: "http://synapse:8008"
  domain: "localhost"

appservice:
  as_token: "your-appservice-token"
  hs_token: "your-homeserver-token"
  bot:
    username: "bot"

You'll also need a registration.yml registered with your homeserver. See the echo bot example for a working template.

Override the config path at runtime:

APPSERVICE_CONFIG=/etc/bot/appservice.yml falcon serve

Built With

  • async -- fiber-based concurrency framework
  • async-http -- HTTP client/server with connection pooling
  • falcon -- async Rack-compatible web server
  • json_schemer -- JSON Schema validation
  • scampi -- inline co-located test framework
  • string_builder -- method-chain string builder

License

Apache 2.0