Events & Schemas

Every event delivered to a handler is an ApplicationService::Event wrapping the raw Matrix JSON. It gives you typed accessors and, when you want it, validation against the official Matrix event schemas.

The Event object

on "m.room.message" do |event|
  event.type        # "m.room.message"
  event.sender      # "@alice:example.com"
  event.room_id     # "!abc:example.com"
  event.event_id    # "$..."
  event.state_key   # nil for message events; "" or an MXID for state events
  event.state_event?  # true when state_key is present
  event.content     # dot-accessible content wrapper
end

content is itself accessor-friendly and nil-safe. Message-shaped content exposes msgtype, body, and membership directly; anything else falls through method_missing, so event.content.info&.mimetype works for arbitrary fields. Use &. where a field may be absent:

return unless event.content&.msgtype == "m.text"
send_notice event.room_id, "Echo: #{event.content.body}"

event.to_h returns the raw hash if you need the untouched JSON.

Validation

Events validate against the upstream matrix-org/matrix-spec event JSON schemas, bundled into the gem. Validation is opt-in — dispatch does not reject invalid events for you, so call it where you care:

event.valid?   # => true / false
event.valid!   # => raises Schema::ValidationError on failure

valid! raises a Schema::ValidationError carrying the failing event type, event ID, and human-readable key paths to each violation — useful in logs when a bridge produces malformed events.

The Schema module

Async::Matrix::Schema is the validation entry point, backed by a lazily-loaded singleton Registry:

Async::Matrix::Schema.valid?(event_hash)     # => true / false
Async::Matrix::Schema.validate(event_hash)   # => Array<Hash> of errors (empty if valid)
Async::Matrix::Schema.content_properties("m.room.message")  # declared content fields

Base and variant schemas

Some event types have variants keyed on a discriminator — m.room.message splits by msgtype, for example. These are stored with a filename convention that joins base and subtype on $ (m.room.message$m.text), and resolved automatically when the event carries the discriminator. Schema.variant(type, subtype) selects one explicitly.

Custom formats

The validator registers Matrix-specific string formats on top of standard JSON Schema, so identifier fields are checked for real:

mx-user-id · mx-room-id · mx-room-alias · mx-event-id · mx-server-name · mx-unpadded-base64

Schemas load on first use and stay cached for the process lifetime, so validation is cheap after the first touch and always matches the spec revision vendored in data/.


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