async-matrixSourceAsyncMatrixApiChain

class Chain

Wraps a StringBuilder to build Matrix API paths via method chaining, terminated by .get(), .post(), .put(), or .delete() which validate the path against the PathTree and fire the HTTP request.

Inherits from BasicObject so that method names like send, display, format, test, etc. are not defined and fall through to method_missing, where they get recorded as URL path segments.

Usage: chain = Chain.new(client: client, path_tree: tree, prefix: %w[_matrix client v3]) chain.account.whoami.get chain.rooms("!abc:ex.com").send("m.room.message", "txn1").put(body: "hi") chain.rooms("!abc:ex.com").messages.get(dir: "b", limit: 10)

Definitions

BINARY_ROUTES

Paths that carry raw bytes instead of JSON. Matched by _binary_route? where * is a single-segment wildcard. The HTTP method determines the operation: GET → download (returns raw bytes) POST/PUT → upload (sends raw bytes)

Implementation

BINARY_ROUTES = [
  "/_matrix/media/v3/upload",
  "/_matrix/media/v3/upload/*/*",
  "/_matrix/media/v3/download/*/*",
  "/_matrix/media/v3/download/*/*/*",
  "/_matrix/media/v3/thumbnail/*/*",
  "/_matrix/client/v1/media/download/*/*",
  "/_matrix/client/v1/media/download/*/*/*",
  "/_matrix/client/v1/media/thumbnail/*/*",
].freeze

def _rewrite_version(segments)

Rewrites version segments for endpoints that only exist at a different version than the gateway prefix provides. _matrix/media/v3/create → _matrix/media/v1/create _matrix/client/v3/media/... → _matrix/client/v1/media/...

Implementation

def _rewrite_version(segments)
  # POST /_matrix/media/v1/create (only exists at v1)
  if segments.length == 4 &&
     segments[0] == "_matrix" && segments[1] == "media" &&
     segments[2] == "v3" && segments[3] == "create"
    segments = segments.dup
    segments[2] = "v1"
    return segments
  end

  # Authenticated media endpoints live at /_matrix/client/v1/media/...
  if segments.length >= 5 &&
     segments[0] == "_matrix" && segments[1] == "client" &&
     segments[2] == "v3" && segments[3] == "media"
    segments = segments.dup
    segments[2] = "v1"
    return segments
  end

  segments
end