async-matrix 0.1.2 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +131 -0
- data/data/matrix-spec/api/client-server/account-data.yaml +389 -0
- data/data/matrix-spec/api/client-server/account_deactivation.yaml +149 -0
- data/data/matrix-spec/api/client-server/admin.yaml +512 -0
- data/data/matrix-spec/api/client-server/administrative_contact.yaml +620 -0
- data/data/matrix-spec/api/client-server/appservice_ping.yaml +183 -0
- data/data/matrix-spec/api/client-server/appservice_room_directory.yaml +104 -0
- data/data/matrix-spec/api/client-server/authed-content-repo.yaml +590 -0
- data/data/matrix-spec/api/client-server/banning.yaml +177 -0
- data/data/matrix-spec/api/client-server/capabilities.yaml +235 -0
- data/data/matrix-spec/api/client-server/content-repo.yaml +887 -0
- data/data/matrix-spec/api/client-server/create_room.yaml +306 -0
- data/data/matrix-spec/api/client-server/cross_signing.yaml +300 -0
- data/data/matrix-spec/api/client-server/definitions/auth_data.yaml +34 -0
- data/data/matrix-spec/api/client-server/definitions/auth_response.yaml +62 -0
- data/data/matrix-spec/api/client-server/definitions/client_device.yaml +44 -0
- data/data/matrix-spec/api/client-server/definitions/client_event.yaml +49 -0
- data/data/matrix-spec/api/client-server/definitions/client_event_without_room_id.yaml +147 -0
- data/data/matrix-spec/api/client-server/definitions/cross_signing_key.yaml +57 -0
- data/data/matrix-spec/api/client-server/definitions/device_keys.yaml +70 -0
- data/data/matrix-spec/api/client-server/definitions/errors/error.yaml +26 -0
- data/data/matrix-spec/api/client-server/definitions/errors/rate_limited.yaml +34 -0
- data/data/matrix-spec/api/client-server/definitions/event_batch.yaml +22 -0
- data/data/matrix-spec/api/client-server/definitions/event_filter.yaml +55 -0
- data/data/matrix-spec/api/client-server/definitions/invite_3pid.yaml +45 -0
- data/data/matrix-spec/api/client-server/definitions/key_backup_auth_data.yaml +36 -0
- data/data/matrix-spec/api/client-server/definitions/key_backup_data.yaml +50 -0
- data/data/matrix-spec/api/client-server/definitions/key_backup_session_data.yaml +57 -0
- data/data/matrix-spec/api/client-server/definitions/m.login.terms_params.yaml +83 -0
- data/data/matrix-spec/api/client-server/definitions/m.mentions.yaml +33 -0
- data/data/matrix-spec/api/client-server/definitions/m.oauth_params.yaml +30 -0
- data/data/matrix-spec/api/client-server/definitions/m.relates_to.yaml +45 -0
- data/data/matrix-spec/api/client-server/definitions/megolm_export_session_data.yaml +39 -0
- data/data/matrix-spec/api/client-server/definitions/olm_payload.yaml +88 -0
- data/data/matrix-spec/api/client-server/definitions/one_time_keys.yaml +27 -0
- data/data/matrix-spec/api/client-server/definitions/openid_token.yaml +37 -0
- data/data/matrix-spec/api/client-server/definitions/protocol.yaml +44 -0
- data/data/matrix-spec/api/client-server/definitions/public_rooms_chunk.yaml +74 -0
- data/data/matrix-spec/api/client-server/definitions/public_rooms_response.yaml +59 -0
- data/data/matrix-spec/api/client-server/definitions/push_condition.yaml +53 -0
- data/data/matrix-spec/api/client-server/definitions/push_rule.yaml +53 -0
- data/data/matrix-spec/api/client-server/definitions/push_ruleset.yaml +206 -0
- data/data/matrix-spec/api/client-server/definitions/recent_emoji.yaml +29 -0
- data/data/matrix-spec/api/client-server/definitions/request_email_validation.yaml +36 -0
- data/data/matrix-spec/api/client-server/definitions/request_msisdn_validation.yaml +36 -0
- data/data/matrix-spec/api/client-server/definitions/request_token_response.yaml +46 -0
- data/data/matrix-spec/api/client-server/definitions/room_event_filter.yaml +60 -0
- data/data/matrix-spec/api/client-server/definitions/room_key_backup.yaml +37 -0
- data/data/matrix-spec/api/client-server/definitions/room_summary.yaml +44 -0
- data/data/matrix-spec/api/client-server/definitions/security.yaml +47 -0
- data/data/matrix-spec/api/client-server/definitions/sso_login_flow.yaml +98 -0
- data/data/matrix-spec/api/client-server/definitions/state_event_batch.yaml +21 -0
- data/data/matrix-spec/api/client-server/definitions/sync_filter.yaml +86 -0
- data/data/matrix-spec/api/client-server/definitions/tag.yaml +24 -0
- data/data/matrix-spec/api/client-server/definitions/third_party_signed.yaml +45 -0
- data/data/matrix-spec/api/client-server/definitions/timeline_batch.yaml +36 -0
- data/data/matrix-spec/api/client-server/definitions/user_identifier.yaml +27 -0
- data/data/matrix-spec/api/client-server/definitions/wellknown/full.yaml +38 -0
- data/data/matrix-spec/api/client-server/definitions/wellknown/homeserver.yaml +25 -0
- data/data/matrix-spec/api/client-server/definitions/wellknown/identity_server.yaml +25 -0
- data/data/matrix-spec/api/client-server/device_management.yaml +314 -0
- data/data/matrix-spec/api/client-server/directory.yaml +318 -0
- data/data/matrix-spec/api/client-server/event_context.yaml +161 -0
- data/data/matrix-spec/api/client-server/filter.yaml +224 -0
- data/data/matrix-spec/api/client-server/inviting.yaml +149 -0
- data/data/matrix-spec/api/client-server/joining.yaml +238 -0
- data/data/matrix-spec/api/client-server/key_backup.yaml +993 -0
- data/data/matrix-spec/api/client-server/keys.yaml +482 -0
- data/data/matrix-spec/api/client-server/kicking.yaml +110 -0
- data/data/matrix-spec/api/client-server/knocking.yaml +152 -0
- data/data/matrix-spec/api/client-server/leaving.yaml +163 -0
- data/data/matrix-spec/api/client-server/list_joined_rooms.yaml +68 -0
- data/data/matrix-spec/api/client-server/list_public_rooms.yaml +280 -0
- data/data/matrix-spec/api/client-server/login.yaml +321 -0
- data/data/matrix-spec/api/client-server/login_token.yaml +138 -0
- data/data/matrix-spec/api/client-server/logout.yaml +86 -0
- data/data/matrix-spec/api/client-server/message_pagination.yaml +194 -0
- data/data/matrix-spec/api/client-server/notifications.yaml +152 -0
- data/data/matrix-spec/api/client-server/oauth_server_metadata.yaml +238 -0
- data/data/matrix-spec/api/client-server/old_sync.yaml +379 -0
- data/data/matrix-spec/api/client-server/openid.yaml +98 -0
- data/data/matrix-spec/api/client-server/password_management.yaml +246 -0
- data/data/matrix-spec/api/client-server/peeking_events.yaml +122 -0
- data/data/matrix-spec/api/client-server/policy_server.yaml +82 -0
- data/data/matrix-spec/api/client-server/presence.yaml +169 -0
- data/data/matrix-spec/api/client-server/profile.yaml +366 -0
- data/data/matrix-spec/api/client-server/pusher.yaml +303 -0
- data/data/matrix-spec/api/client-server/pushrules.yaml +633 -0
- data/data/matrix-spec/api/client-server/read_markers.yaml +103 -0
- data/data/matrix-spec/api/client-server/receipts.yaml +139 -0
- data/data/matrix-spec/api/client-server/redaction.yaml +116 -0
- data/data/matrix-spec/api/client-server/refresh.yaml +119 -0
- data/data/matrix-spec/api/client-server/registration.yaml +488 -0
- data/data/matrix-spec/api/client-server/registration_tokens.yaml +93 -0
- data/data/matrix-spec/api/client-server/relations.yaml +382 -0
- data/data/matrix-spec/api/client-server/report_content.yaml +283 -0
- data/data/matrix-spec/api/client-server/room_event_by_timestamp.yaml +147 -0
- data/data/matrix-spec/api/client-server/room_initial_sync.yaml +188 -0
- data/data/matrix-spec/api/client-server/room_send.yaml +130 -0
- data/data/matrix-spec/api/client-server/room_state.yaml +159 -0
- data/data/matrix-spec/api/client-server/room_summary.yaml +138 -0
- data/data/matrix-spec/api/client-server/room_upgrades.yaml +130 -0
- data/data/matrix-spec/api/client-server/rooms.yaml +380 -0
- data/data/matrix-spec/api/client-server/search.yaml +385 -0
- data/data/matrix-spec/api/client-server/space_hierarchy.yaml +237 -0
- data/data/matrix-spec/api/client-server/sso_login_redirect.yaml +135 -0
- data/data/matrix-spec/api/client-server/support.yaml +142 -0
- data/data/matrix-spec/api/client-server/sync.yaml +692 -0
- data/data/matrix-spec/api/client-server/tags.yaml +183 -0
- data/data/matrix-spec/api/client-server/third_party_lookup.yaml +324 -0
- data/data/matrix-spec/api/client-server/third_party_membership.yaml +139 -0
- data/data/matrix-spec/api/client-server/threads_list.yaml +167 -0
- data/data/matrix-spec/api/client-server/to_device.yaml +104 -0
- data/data/matrix-spec/api/client-server/typing.yaml +103 -0
- data/data/matrix-spec/api/client-server/users.yaml +136 -0
- data/data/matrix-spec/api/client-server/versions.yaml +108 -0
- data/data/matrix-spec/api/client-server/voip.yaml +93 -0
- data/data/matrix-spec/api/client-server/wellknown.yaml +60 -0
- data/data/matrix-spec/api/client-server/whoami.yaml +121 -0
- data/data/matrix-spec/event-schemas/examples/core/event.json +6 -0
- data/data/matrix-spec/event-schemas/examples/core/room_edu.json +3 -0
- data/data/matrix-spec/event-schemas/examples/core/room_event.json +11 -0
- data/data/matrix-spec/event-schemas/examples/core/state_event.json +4 -0
- data/data/matrix-spec/event-schemas/examples/invite_room_state.json +18 -0
- data/data/matrix-spec/event-schemas/examples/knock_room_state.json +18 -0
- data/data/matrix-spec/event-schemas/examples/m.accepted_terms.yaml +10 -0
- data/data/matrix-spec/event-schemas/examples/m.call.answer.yaml +21 -0
- data/data/matrix-spec/event-schemas/examples/m.call.candidates.yaml +16 -0
- data/data/matrix-spec/event-schemas/examples/m.call.hangup.yaml +10 -0
- data/data/matrix-spec/event-schemas/examples/m.call.invite.yaml +22 -0
- data/data/matrix-spec/event-schemas/examples/m.call.negotiate.yaml +22 -0
- data/data/matrix-spec/event-schemas/examples/m.call.reject.yaml +9 -0
- data/data/matrix-spec/event-schemas/examples/m.call.sdp_stream_metadata_changed.yaml +16 -0
- data/data/matrix-spec/event-schemas/examples/m.call.select_answer.yaml +10 -0
- data/data/matrix-spec/event-schemas/examples/m.direct.yaml +10 -0
- data/data/matrix-spec/event-schemas/examples/m.dummy.yaml +4 -0
- data/data/matrix-spec/event-schemas/examples/m.forwarded_room_key.yaml +14 -0
- data/data/matrix-spec/event-schemas/examples/m.fully_read.yaml +7 -0
- data/data/matrix-spec/event-schemas/examples/m.identity_server.yaml +7 -0
- data/data/matrix-spec/event-schemas/examples/m.ignored_user_list.yaml +9 -0
- data/data/matrix-spec/event-schemas/examples/m.invite_permission_config.yaml +7 -0
- data/data/matrix-spec/event-schemas/examples/m.key.verification.accept.yaml +12 -0
- data/data/matrix-spec/event-schemas/examples/m.key.verification.cancel.yaml +8 -0
- data/data/matrix-spec/event-schemas/examples/m.key.verification.done.yaml +6 -0
- data/data/matrix-spec/event-schemas/examples/m.key.verification.key.yaml +7 -0
- data/data/matrix-spec/event-schemas/examples/m.key.verification.mac.yaml +10 -0
- data/data/matrix-spec/event-schemas/examples/m.key.verification.ready.yaml +10 -0
- data/data/matrix-spec/event-schemas/examples/m.key.verification.request.yaml +11 -0
- data/data/matrix-spec/event-schemas/examples/m.key.verification.start$m.sas.v1.yaml +12 -0
- data/data/matrix-spec/event-schemas/examples/m.key.verification.start.yaml +8 -0
- data/data/matrix-spec/event-schemas/examples/m.key_backup.yaml +7 -0
- data/data/matrix-spec/event-schemas/examples/m.marked_unread.yaml +7 -0
- data/data/matrix-spec/event-schemas/examples/m.policy.rule.room.yaml +10 -0
- data/data/matrix-spec/event-schemas/examples/m.policy.rule.server.yaml +10 -0
- data/data/matrix-spec/event-schemas/examples/m.policy.rule.user.yaml +10 -0
- data/data/matrix-spec/event-schemas/examples/m.presence.yaml +12 -0
- data/data/matrix-spec/event-schemas/examples/m.push_rules.yaml +177 -0
- data/data/matrix-spec/event-schemas/examples/m.reaction.yaml +11 -0
- data/data/matrix-spec/event-schemas/examples/m.receipt.yaml +18 -0
- data/data/matrix-spec/event-schemas/examples/m.recent_emoji.yaml +16 -0
- data/data/matrix-spec/event-schemas/examples/m.room.avatar.yaml +14 -0
- data/data/matrix-spec/event-schemas/examples/m.room.canonical_alias.yaml +12 -0
- data/data/matrix-spec/event-schemas/examples/m.room.create.yaml +13 -0
- data/data/matrix-spec/event-schemas/examples/m.room.encrypted$megolm.yaml +11 -0
- data/data/matrix-spec/event-schemas/examples/m.room.encrypted$olm.yaml +14 -0
- data/data/matrix-spec/event-schemas/examples/m.room.encryption.yaml +10 -0
- data/data/matrix-spec/event-schemas/examples/m.room.guest_access.yaml +8 -0
- data/data/matrix-spec/event-schemas/examples/m.room.history_visibility.yaml +8 -0
- data/data/matrix-spec/event-schemas/examples/m.room.join_rules$restricted.yaml +18 -0
- data/data/matrix-spec/event-schemas/examples/m.room.join_rules.yaml +8 -0
- data/data/matrix-spec/event-schemas/examples/m.room.member$invite_room_state.yaml +15 -0
- data/data/matrix-spec/event-schemas/examples/m.room.member$join_authorised_via_users_server.yaml +12 -0
- data/data/matrix-spec/event-schemas/examples/m.room.member$knock_room_state.yaml +15 -0
- data/data/matrix-spec/event-schemas/examples/m.room.member$third_party_invite.yaml +20 -0
- data/data/matrix-spec/event-schemas/examples/m.room.member.yaml +12 -0
- data/data/matrix-spec/event-schemas/examples/m.room.message$m.audio.yaml +14 -0
- data/data/matrix-spec/event-schemas/examples/m.room.message$m.emote.yaml +10 -0
- data/data/matrix-spec/event-schemas/examples/m.room.message$m.file.yaml +14 -0
- data/data/matrix-spec/event-schemas/examples/m.room.message$m.image.yaml +16 -0
- data/data/matrix-spec/event-schemas/examples/m.room.message$m.key.verification.request.yaml +19 -0
- data/data/matrix-spec/event-schemas/examples/m.room.message$m.location.yaml +18 -0
- data/data/matrix-spec/event-schemas/examples/m.room.message$m.notice.yaml +10 -0
- data/data/matrix-spec/event-schemas/examples/m.room.message$m.server_notice.yaml +11 -0
- data/data/matrix-spec/event-schemas/examples/m.room.message$m.text.yaml +10 -0
- data/data/matrix-spec/event-schemas/examples/m.room.message$m.video.yaml +23 -0
- data/data/matrix-spec/event-schemas/examples/m.room.name.yaml +8 -0
- data/data/matrix-spec/event-schemas/examples/m.room.pinned_events.yaml +8 -0
- data/data/matrix-spec/event-schemas/examples/m.room.policy.yaml +11 -0
- data/data/matrix-spec/event-schemas/examples/m.room.power_levels.yaml +24 -0
- data/data/matrix-spec/event-schemas/examples/m.room.redaction.yaml +8 -0
- data/data/matrix-spec/event-schemas/examples/m.room.server_acl.yaml +10 -0
- data/data/matrix-spec/event-schemas/examples/m.room.third_party_invite.yaml +14 -0
- data/data/matrix-spec/event-schemas/examples/m.room.tombstone.yaml +9 -0
- data/data/matrix-spec/event-schemas/examples/m.room.topic.yaml +16 -0
- data/data/matrix-spec/event-schemas/examples/m.room_key.withheld.yaml +12 -0
- data/data/matrix-spec/event-schemas/examples/m.room_key.yaml +10 -0
- data/data/matrix-spec/event-schemas/examples/m.room_key_request$cancel_request.yaml +8 -0
- data/data/matrix-spec/event-schemas/examples/m.room_key_request$request.yaml +14 -0
- data/data/matrix-spec/event-schemas/examples/m.secret.request.yaml +9 -0
- data/data/matrix-spec/event-schemas/examples/m.secret.send.yaml +7 -0
- data/data/matrix-spec/event-schemas/examples/m.space.child.yaml +10 -0
- data/data/matrix-spec/event-schemas/examples/m.space.parent.yaml +9 -0
- data/data/matrix-spec/event-schemas/examples/m.sticker.yaml +22 -0
- data/data/matrix-spec/event-schemas/examples/m.tag.yaml +9 -0
- data/data/matrix-spec/event-schemas/examples/m.typing.yaml +7 -0
- data/data/matrix-spec/event-schemas/moderation_policy_rule.yaml +32 -0
- data/data/matrix-spec/event-schemas/schema/components/m_text_content_block.yaml +28 -0
- data/data/matrix-spec/event-schemas/schema/components/sdp_stream_metadata.yaml +43 -0
- data/data/matrix-spec/event-schemas/schema/components/signed_third_party_invite.yaml +48 -0
- data/data/matrix-spec/event-schemas/schema/core-event-schema/call_event.yaml +27 -0
- data/data/matrix-spec/event-schemas/schema/core-event-schema/event.yaml +16 -0
- data/data/matrix-spec/event-schemas/schema/core-event-schema/msgtype_infos/avatar_info.yaml +30 -0
- data/data/matrix-spec/event-schemas/schema/core-event-schema/msgtype_infos/image_info.yaml +52 -0
- data/data/matrix-spec/event-schemas/schema/core-event-schema/msgtype_infos/thumbnail_info.yaml +22 -0
- data/data/matrix-spec/event-schemas/schema/core-event-schema/room_event.yaml +17 -0
- data/data/matrix-spec/event-schemas/schema/core-event-schema/state_event.yaml +8 -0
- data/data/matrix-spec/event-schemas/schema/core-event-schema/stripped_state.yaml +48 -0
- data/data/matrix-spec/event-schemas/schema/core-event-schema/sync_room_event.yaml +49 -0
- data/data/matrix-spec/event-schemas/schema/core-event-schema/sync_state_event.yaml +36 -0
- data/data/matrix-spec/event-schemas/schema/core-event-schema/unsigned_prop.yaml +23 -0
- data/data/matrix-spec/event-schemas/schema/m.accepted_terms.yaml +25 -0
- data/data/matrix-spec/event-schemas/schema/m.call.answer.yaml +44 -0
- data/data/matrix-spec/event-schemas/schema/m.call.candidates.yaml +52 -0
- data/data/matrix-spec/event-schemas/schema/m.call.hangup.yaml +57 -0
- data/data/matrix-spec/event-schemas/schema/m.call.invite.yaml +53 -0
- data/data/matrix-spec/event-schemas/schema/m.call.negotiate.yaml +78 -0
- data/data/matrix-spec/event-schemas/schema/m.call.reject.yaml +29 -0
- data/data/matrix-spec/event-schemas/schema/m.call.sdp_stream_metadata_changed.yaml +24 -0
- data/data/matrix-spec/event-schemas/schema/m.call.select_answer.yaml +29 -0
- data/data/matrix-spec/event-schemas/schema/m.direct.yaml +29 -0
- data/data/matrix-spec/event-schemas/schema/m.dummy.yaml +25 -0
- data/data/matrix-spec/event-schemas/schema/m.forwarded_room_key.yaml +70 -0
- data/data/matrix-spec/event-schemas/schema/m.fully_read.yaml +26 -0
- data/data/matrix-spec/event-schemas/schema/m.identity_server.yaml +28 -0
- data/data/matrix-spec/event-schemas/schema/m.ignored_user_list.yaml +30 -0
- data/data/matrix-spec/event-schemas/schema/m.invite_permission_config.yaml +21 -0
- data/data/matrix-spec/event-schemas/schema/m.key.verification.accept.yaml +63 -0
- data/data/matrix-spec/event-schemas/schema/m.key.verification.cancel.yaml +72 -0
- data/data/matrix-spec/event-schemas/schema/m.key.verification.done.yaml +24 -0
- data/data/matrix-spec/event-schemas/schema/m.key.verification.key.yaml +31 -0
- data/data/matrix-spec/event-schemas/schema/m.key.verification.m.relates_to.yaml +23 -0
- data/data/matrix-spec/event-schemas/schema/m.key.verification.mac.yaml +43 -0
- data/data/matrix-spec/event-schemas/schema/m.key.verification.ready.yaml +41 -0
- data/data/matrix-spec/event-schemas/schema/m.key.verification.request.yaml +47 -0
- data/data/matrix-spec/event-schemas/schema/m.key.verification.start$m.reciprocate.v1.yaml +45 -0
- data/data/matrix-spec/event-schemas/schema/m.key.verification.start$m.sas.v1.yaml +76 -0
- data/data/matrix-spec/event-schemas/schema/m.key.verification.start.yaml +46 -0
- data/data/matrix-spec/event-schemas/schema/m.key_backup.yaml +24 -0
- data/data/matrix-spec/event-schemas/schema/m.marked_unread.yaml +26 -0
- data/data/matrix-spec/event-schemas/schema/m.policy.rule.room.yaml +17 -0
- data/data/matrix-spec/event-schemas/schema/m.policy.rule.server.yaml +17 -0
- data/data/matrix-spec/event-schemas/schema/m.policy.rule.user.yaml +17 -0
- data/data/matrix-spec/event-schemas/schema/m.presence.yaml +50 -0
- data/data/matrix-spec/event-schemas/schema/m.push_rules.yaml +23 -0
- data/data/matrix-spec/event-schemas/schema/m.reaction.yaml +45 -0
- data/data/matrix-spec/event-schemas/schema/m.receipt.yaml +65 -0
- data/data/matrix-spec/event-schemas/schema/m.recent_emoji.yaml +29 -0
- data/data/matrix-spec/event-schemas/schema/m.room.avatar.yaml +29 -0
- data/data/matrix-spec/event-schemas/schema/m.room.canonical_alias.yaml +40 -0
- data/data/matrix-spec/event-schemas/schema/m.room.create.yaml +86 -0
- data/data/matrix-spec/event-schemas/schema/m.room.encrypted.yaml +91 -0
- data/data/matrix-spec/event-schemas/schema/m.room.encryption.yaml +38 -0
- data/data/matrix-spec/event-schemas/schema/m.room.guest_access.yaml +28 -0
- data/data/matrix-spec/event-schemas/schema/m.room.history_visibility.yaml +30 -0
- data/data/matrix-spec/event-schemas/schema/m.room.join_rules.yaml +78 -0
- data/data/matrix-spec/event-schemas/schema/m.room.member.yaml +174 -0
- data/data/matrix-spec/event-schemas/schema/m.room.message$m.audio.yaml +73 -0
- data/data/matrix-spec/event-schemas/schema/m.room.message$m.emote.yaml +36 -0
- data/data/matrix-spec/event-schemas/schema/m.room.message$m.file.yaml +85 -0
- data/data/matrix-spec/event-schemas/schema/m.room.message$m.image.yaml +63 -0
- data/data/matrix-spec/event-schemas/schema/m.room.message$m.key.verification.request.yaml +70 -0
- data/data/matrix-spec/event-schemas/schema/m.room.message$m.location.yaml +50 -0
- data/data/matrix-spec/event-schemas/schema/m.room.message$m.notice.yaml +36 -0
- data/data/matrix-spec/event-schemas/schema/m.room.message$m.server_notice.yaml +41 -0
- data/data/matrix-spec/event-schemas/schema/m.room.message$m.text.yaml +36 -0
- data/data/matrix-spec/event-schemas/schema/m.room.message$m.video.yaml +95 -0
- data/data/matrix-spec/event-schemas/schema/m.room.message.yaml +25 -0
- data/data/matrix-spec/event-schemas/schema/m.room.name.yaml +35 -0
- data/data/matrix-spec/event-schemas/schema/m.room.pinned_events.yaml +27 -0
- data/data/matrix-spec/event-schemas/schema/m.room.policy.yaml +41 -0
- data/data/matrix-spec/event-schemas/schema/m.room.power_levels.yaml +139 -0
- data/data/matrix-spec/event-schemas/schema/m.room.redaction.yaml +29 -0
- data/data/matrix-spec/event-schemas/schema/m.room.server_acl.yaml +88 -0
- data/data/matrix-spec/event-schemas/schema/m.room.third_party_invite.yaml +79 -0
- data/data/matrix-spec/event-schemas/schema/m.room.tombstone.yaml +29 -0
- data/data/matrix-spec/event-schemas/schema/m.room.topic.yaml +53 -0
- data/data/matrix-spec/event-schemas/schema/m.room_key.withheld.yaml +88 -0
- data/data/matrix-spec/event-schemas/schema/m.room_key.yaml +38 -0
- data/data/matrix-spec/event-schemas/schema/m.room_key_request.yaml +73 -0
- data/data/matrix-spec/event-schemas/schema/m.secret.request.yaml +42 -0
- data/data/matrix-spec/event-schemas/schema/m.secret.send.yaml +35 -0
- data/data/matrix-spec/event-schemas/schema/m.space.child.yaml +50 -0
- data/data/matrix-spec/event-schemas/schema/m.space.parent.yaml +36 -0
- data/data/matrix-spec/event-schemas/schema/m.sticker.yaml +36 -0
- data/data/matrix-spec/event-schemas/schema/m.tag.yaml +28 -0
- data/data/matrix-spec/event-schemas/schema/m.typing.yaml +29 -0
- data/lib/async/matrix/api/chain.rb +575 -0
- data/lib/async/matrix/api/concat.rb +105 -0
- data/lib/async/matrix/api/path_tree.rb +208 -0
- data/lib/async/matrix/api.rb +204 -0
- data/lib/async/matrix/application_service/bot.rb +235 -0
- data/lib/async/matrix/application_service/config/schema/analytics.json +21 -0
- data/lib/async/matrix/application_service/config/schema/appservice.json +82 -0
- data/lib/async/matrix/application_service/config/schema/backfill.json +91 -0
- data/lib/async/matrix/application_service/config/schema/bridge.json +209 -0
- data/lib/async/matrix/application_service/config/schema/config.json +61 -0
- data/lib/async/matrix/application_service/config/schema/database.json +38 -0
- data/lib/async/matrix/application_service/config/schema/direct_media.json +35 -0
- data/lib/async/matrix/application_service/config/schema/double_puppet.json +24 -0
- data/lib/async/matrix/application_service/config/schema/encryption.json +164 -0
- data/lib/async/matrix/application_service/config/schema/homeserver.json +58 -0
- data/lib/async/matrix/application_service/config/schema/logging.json +50 -0
- data/lib/async/matrix/application_service/config/schema/management_room_texts.json +25 -0
- data/lib/async/matrix/application_service/config/schema/matrix.json +45 -0
- data/lib/async/matrix/application_service/config/schema/permissions.json +54 -0
- data/lib/async/matrix/application_service/config/schema/provisioning.json +23 -0
- data/lib/async/matrix/application_service/config/schema/public_media.json +39 -0
- data/lib/async/matrix/application_service/config/schema/relay.json +43 -0
- data/lib/async/matrix/application_service/config/vivify.rb +110 -0
- data/lib/async/matrix/application_service/config.rb +214 -123
- data/lib/async/matrix/application_service/dispatcher.rb +115 -113
- data/lib/async/matrix/application_service/error_response.rb +26 -26
- data/lib/async/matrix/application_service/event.rb +217 -1
- data/lib/async/matrix/application_service/server.rb +286 -215
- data/lib/async/matrix/application_service/transaction.rb +52 -52
- data/lib/async/matrix/application_service/transaction_store.rb +62 -62
- data/lib/async/matrix/client.rb +919 -179
- data/lib/async/matrix/connection.rb +8 -8
- data/lib/async/matrix/endpoint.rb +45 -45
- data/lib/async/matrix/error.rb +49 -43
- data/lib/async/matrix/media_client.rb +173 -0
- data/lib/async/matrix/notifier.rb +92 -92
- data/lib/async/matrix/schema/registry.rb +355 -0
- data/lib/async/matrix/schema/validation_error.rb +226 -0
- data/lib/async/matrix/schema.rb +174 -0
- data/lib/async/matrix/server.rb +7 -7
- data/lib/async/matrix/stream.rb +7 -7
- data/lib/async/matrix/version.rb +1 -1
- data/lib/async/matrix.rb +5 -2
- metadata +353 -1
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Released under the Apache License, Version 2.0.
|
|
4
|
+
# Copyright, 2026, by General Intelligence Systems.
|
|
5
|
+
|
|
6
|
+
require "bundler/setup"
|
|
7
|
+
require "async/matrix"
|
|
8
|
+
require "yaml"
|
|
9
|
+
require "pathname"
|
|
10
|
+
|
|
11
|
+
module Async
|
|
12
|
+
module Matrix
|
|
13
|
+
module Api
|
|
14
|
+
# A trie of valid Matrix API paths, built from OpenAPI 3.1.0 YAML schemas.
|
|
15
|
+
#
|
|
16
|
+
# Each leaf node stores the set of HTTP methods valid at that path.
|
|
17
|
+
# Template segments like {roomId} become wildcard nodes that match any value.
|
|
18
|
+
#
|
|
19
|
+
# Example:
|
|
20
|
+
# tree = PathTree.load
|
|
21
|
+
# tree.match(["_matrix", "client", "v3", "rooms", "!abc:ex.com", "ban"], "POST")
|
|
22
|
+
# # => { valid: true, operation_id: "ban", methods: ["post"] }
|
|
23
|
+
#
|
|
24
|
+
class PathTree
|
|
25
|
+
SCHEMA_DIR = Pathname.new(File.expand_path("../../../../data/matrix-spec/api/client-server", __dir__))
|
|
26
|
+
|
|
27
|
+
Node = Struct.new(:children, :wildcard, :methods, :operation_ids, keyword_init: true) do
|
|
28
|
+
def initialize(**)
|
|
29
|
+
super
|
|
30
|
+
self.children ||= {}
|
|
31
|
+
self.methods ||= []
|
|
32
|
+
self.operation_ids ||= {}
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
attr_reader :root
|
|
37
|
+
|
|
38
|
+
def initialize
|
|
39
|
+
@root = Node.new
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Load all OpenAPI schemas from data/ and build the tree.
|
|
43
|
+
def self.load(schema_dir: SCHEMA_DIR)
|
|
44
|
+
tree = new
|
|
45
|
+
Pathname.glob(schema_dir / "*.yaml").each do |path|
|
|
46
|
+
tree.load_schema(path)
|
|
47
|
+
end
|
|
48
|
+
tree
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Parse a single OpenAPI YAML file and insert its paths into the tree.
|
|
52
|
+
def load_schema(path)
|
|
53
|
+
doc = YAML.safe_load(File.read(path), permitted_classes: [Symbol], aliases: true)
|
|
54
|
+
return unless doc.is_a?(Hash)
|
|
55
|
+
|
|
56
|
+
base_path = extract_base_path(doc)
|
|
57
|
+
paths = doc["paths"]
|
|
58
|
+
return unless paths.is_a?(Hash)
|
|
59
|
+
|
|
60
|
+
paths.each do |path_template, methods_hash|
|
|
61
|
+
next unless methods_hash.is_a?(Hash)
|
|
62
|
+
|
|
63
|
+
# Build full path: basePath + path_template
|
|
64
|
+
full_path = "#{base_path}#{path_template.strip}"
|
|
65
|
+
segments = full_path.split("/").reject(&:empty?)
|
|
66
|
+
|
|
67
|
+
methods_hash.each do |method, operation|
|
|
68
|
+
next unless %w[get post put delete patch head].include?(method)
|
|
69
|
+
operation_id = operation.is_a?(Hash) ? operation["operationId"] : nil
|
|
70
|
+
insert(segments, method, operation_id)
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Insert a path (as array of segments) with an HTTP method into the trie.
|
|
76
|
+
def insert(segments, method, operation_id = nil)
|
|
77
|
+
node = @root
|
|
78
|
+
segments.each do |segment|
|
|
79
|
+
if segment.start_with?("{") && segment.end_with?("}")
|
|
80
|
+
# Wildcard segment — matches any value
|
|
81
|
+
node.wildcard ||= Node.new
|
|
82
|
+
node = node.wildcard
|
|
83
|
+
else
|
|
84
|
+
node.children[segment] ||= Node.new
|
|
85
|
+
node = node.children[segment]
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
node.methods << method.downcase unless node.methods.include?(method.downcase)
|
|
89
|
+
node.operation_ids[method.downcase] = operation_id if operation_id
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# Match a concrete path (array of segments) against the trie.
|
|
93
|
+
# Returns a result hash.
|
|
94
|
+
def match(segments, method = nil)
|
|
95
|
+
node = @root
|
|
96
|
+
segments.each do |segment|
|
|
97
|
+
if node.children.key?(segment)
|
|
98
|
+
node = node.children[segment]
|
|
99
|
+
elsif node.wildcard
|
|
100
|
+
node = node.wildcard
|
|
101
|
+
else
|
|
102
|
+
return {valid: false, methods: [], operation_id: nil}
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
if method
|
|
107
|
+
method_down = method.downcase
|
|
108
|
+
valid = node.methods.include?(method_down)
|
|
109
|
+
{valid: valid, methods: node.methods, operation_id: node.operation_ids[method_down]}
|
|
110
|
+
else
|
|
111
|
+
{valid: node.methods.any?, methods: node.methods, operation_id: nil}
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
private
|
|
116
|
+
|
|
117
|
+
def extract_base_path(doc)
|
|
118
|
+
servers = doc["servers"]
|
|
119
|
+
return "" unless servers.is_a?(Array) && servers.first.is_a?(Hash)
|
|
120
|
+
|
|
121
|
+
server = servers.first
|
|
122
|
+
variables = server["variables"] || {}
|
|
123
|
+
base_path_var = variables["basePath"]
|
|
124
|
+
return "" unless base_path_var.is_a?(Hash)
|
|
125
|
+
|
|
126
|
+
base_path_var["default"] || ""
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
test do
|
|
134
|
+
describe "Async::Matrix::Api::PathTree" do
|
|
135
|
+
def make_tree
|
|
136
|
+
tree = Async::Matrix::Api::PathTree.new
|
|
137
|
+
# Simulate a few endpoints manually
|
|
138
|
+
tree.insert(%w[_matrix client v3 account whoami], "get", "getAccountWhoami")
|
|
139
|
+
tree.insert(%w[_matrix client v3 createRoom], "post", "createRoom")
|
|
140
|
+
tree.insert(%w[_matrix client v3 rooms {roomId} ban], "post", "ban")
|
|
141
|
+
tree.insert(%w[_matrix client v3 rooms {roomId} unban], "post", "unban")
|
|
142
|
+
tree.insert(%w[_matrix client v3 rooms {roomId} state {eventType} {stateKey}], "get", "getRoomStateWithKey")
|
|
143
|
+
tree.insert(%w[_matrix client v3 rooms {roomId} state {eventType} {stateKey}], "put", "setRoomStateWithKey")
|
|
144
|
+
tree.insert(%w[_matrix client v3 rooms {roomId} messages], "get", "getRoomMessages")
|
|
145
|
+
tree.insert(%w[_matrix client v3 profile {userId} displayname], "get", "getDisplayName")
|
|
146
|
+
tree.insert(%w[_matrix client v3 profile {userId} displayname], "put", "setDisplayName")
|
|
147
|
+
tree
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
it "matches a simple path" do
|
|
151
|
+
tree = make_tree
|
|
152
|
+
result = tree.match(%w[_matrix client v3 account whoami], "GET")
|
|
153
|
+
result[:valid].should == true
|
|
154
|
+
result[:operation_id].should == "getAccountWhoami"
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
it "rejects unknown paths" do
|
|
158
|
+
tree = make_tree
|
|
159
|
+
result = tree.match(%w[_matrix client v3 account foobar], "GET")
|
|
160
|
+
result[:valid].should == false
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
it "matches wildcard segments" do
|
|
164
|
+
tree = make_tree
|
|
165
|
+
result = tree.match(%w[_matrix client v3 rooms !abc:ex.com ban], "POST")
|
|
166
|
+
result[:valid].should == true
|
|
167
|
+
result[:operation_id].should == "ban"
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
it "matches deep wildcard paths" do
|
|
171
|
+
tree = make_tree
|
|
172
|
+
result = tree.match(%w[_matrix client v3 rooms !abc:ex.com state m.room.name some_key], "GET")
|
|
173
|
+
result[:valid].should == true
|
|
174
|
+
result[:operation_id].should == "getRoomStateWithKey"
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
it "rejects wrong HTTP method" do
|
|
178
|
+
tree = make_tree
|
|
179
|
+
result = tree.match(%w[_matrix client v3 account whoami], "POST")
|
|
180
|
+
result[:valid].should == false
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
it "reports available methods" do
|
|
184
|
+
tree = make_tree
|
|
185
|
+
result = tree.match(%w[_matrix client v3 profile @user:ex.com displayname])
|
|
186
|
+
result[:valid].should == true
|
|
187
|
+
result[:methods].should.include "get"
|
|
188
|
+
result[:methods].should.include "put"
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
it "loads from real schema files" do
|
|
192
|
+
skip "schemas not present" unless Async::Matrix::Api::PathTree::SCHEMA_DIR.exist?
|
|
193
|
+
tree = Async::Matrix::Api::PathTree.load
|
|
194
|
+
# createRoom should exist
|
|
195
|
+
result = tree.match(%w[_matrix client v3 createRoom], "POST")
|
|
196
|
+
result[:valid].should == true
|
|
197
|
+
# rooms/{id}/ban should exist
|
|
198
|
+
result = tree.match(%w[_matrix client v3 rooms !test:ex.com ban], "POST")
|
|
199
|
+
result[:valid].should == true
|
|
200
|
+
# sync should exist
|
|
201
|
+
result = tree.match(%w[_matrix client v3 sync], "GET")
|
|
202
|
+
result[:valid].should == true
|
|
203
|
+
# nonsense should not
|
|
204
|
+
result = tree.match(%w[_matrix client v3 totallyFake], "GET")
|
|
205
|
+
result[:valid].should == false
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
end
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Released under the Apache License, Version 2.0.
|
|
4
|
+
# Copyright, 2026, by General Intelligence Systems.
|
|
5
|
+
|
|
6
|
+
require "bundler/setup"
|
|
7
|
+
require "async/matrix"
|
|
8
|
+
|
|
9
|
+
module Async
|
|
10
|
+
module Matrix
|
|
11
|
+
# Runtime-generated Matrix Client-Server API built from official OpenAPI schemas.
|
|
12
|
+
#
|
|
13
|
+
# Loads the OpenAPI 3.1.0 YAML files from data/matrix-spec/api/client-server/
|
|
14
|
+
# at require-time and builds a PathTree trie of all valid endpoints. API calls
|
|
15
|
+
# are constructed via StringBuilder method chains, validated against the tree,
|
|
16
|
+
# and terminated by .get(), .post(), .put(), or .delete().
|
|
17
|
+
#
|
|
18
|
+
# Usage:
|
|
19
|
+
# # Via Client:
|
|
20
|
+
# client.api.account.whoami.get
|
|
21
|
+
# client.api.createRoom.post(name: "Pub", preset: "public_chat")
|
|
22
|
+
# client.api.rooms("!room:ex.com").ban.post(user_id: "@bad:ex.com")
|
|
23
|
+
# client.api.rooms("!room:ex.com").messages.get(dir: "b", limit: 10)
|
|
24
|
+
#
|
|
25
|
+
# # Standalone (for inspection):
|
|
26
|
+
# gateway = Async::Matrix::Api::Gateway.new(client)
|
|
27
|
+
# chain = gateway.chain
|
|
28
|
+
# chain.rooms("!room:ex.com").state("m.room.name", "").get
|
|
29
|
+
#
|
|
30
|
+
module Api
|
|
31
|
+
# The shared PathTree instance, loaded once from the bundled schemas.
|
|
32
|
+
def self.path_tree
|
|
33
|
+
@path_tree ||= PathTree.load
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Reset the cached path tree (useful for testing or reloading schemas).
|
|
37
|
+
def self.reset!
|
|
38
|
+
@path_tree = nil
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Gateway produces Chain instances bound to a specific Client.
|
|
42
|
+
# Each call to a method on the Gateway starts a new chain.
|
|
43
|
+
class Gateway
|
|
44
|
+
def initialize(client, prefix: %w[_matrix client v3])
|
|
45
|
+
@client = client
|
|
46
|
+
@prefix = prefix
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Start a fresh chain. Every method call on the gateway creates
|
|
50
|
+
# a new chain so chains are never reused.
|
|
51
|
+
def chain
|
|
52
|
+
Chain.new(client: @client, path_tree: Api.path_tree, prefix: @prefix)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Forward all unknown methods to a fresh chain, starting the path.
|
|
56
|
+
def method_missing(name, *args, **kwargs, &block)
|
|
57
|
+
if name.start_with?("to_")
|
|
58
|
+
super
|
|
59
|
+
else
|
|
60
|
+
chain.__send__(name, *args, **kwargs, &block)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def respond_to_missing?(name, include_private = false)
|
|
65
|
+
!name.start_with?("to_") || super
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def inspect
|
|
69
|
+
"#<#{self.class} prefix=/#{@prefix.join("/")}>"
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
test do
|
|
78
|
+
describe "Async::Matrix::Api::Gateway" do
|
|
79
|
+
# Stub client that records calls instead of making HTTP requests.
|
|
80
|
+
StubClient = Struct.new(:calls) do
|
|
81
|
+
def initialize
|
|
82
|
+
super([])
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def get(path, max_retries: nil)
|
|
86
|
+
calls << [:get, path, {max_retries: max_retries}]
|
|
87
|
+
{"stub" => true}
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def post(path, body = {}, max_retries: nil)
|
|
91
|
+
calls << [:post, path, body, {max_retries: max_retries}]
|
|
92
|
+
{"stub" => true}
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def put(path, body = {}, max_retries: nil)
|
|
96
|
+
calls << [:put, path, body, {max_retries: max_retries}]
|
|
97
|
+
{"stub" => true}
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def request(method, path, body = nil, max_retries: nil)
|
|
101
|
+
calls << [method.downcase.to_sym, path, body, {max_retries: max_retries}]
|
|
102
|
+
{"stub" => true}
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def make_gateway
|
|
107
|
+
client = StubClient.new
|
|
108
|
+
# Build a small tree manually for deterministic tests
|
|
109
|
+
tree = Async::Matrix::Api::PathTree.new
|
|
110
|
+
tree.insert(%w[_matrix client v3 account whoami], "get")
|
|
111
|
+
tree.insert(%w[_matrix client v3 createRoom], "post")
|
|
112
|
+
tree.insert(%w[_matrix client v3 rooms {roomId} ban], "post")
|
|
113
|
+
tree.insert(%w[_matrix client v3 rooms {roomId} messages], "get")
|
|
114
|
+
tree.insert(%w[_matrix client v3 rooms {roomId} send {eventType} {txnId}], "put")
|
|
115
|
+
tree.insert(%w[_matrix client v3 profile {userId} displayname], "put")
|
|
116
|
+
tree.insert(%w[_matrix client v3 join {roomIdOrAlias}], "post")
|
|
117
|
+
tree.insert(%w[_matrix client v3 rooms {roomId} leave], "post")
|
|
118
|
+
|
|
119
|
+
# Inject our test tree
|
|
120
|
+
Async::Matrix::Api.instance_variable_set(:@path_tree, tree)
|
|
121
|
+
|
|
122
|
+
gateway = Async::Matrix::Api::Gateway.new(client)
|
|
123
|
+
[gateway, client]
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
it "GET /account/whoami" do
|
|
127
|
+
gw, client = make_gateway
|
|
128
|
+
gw.account.whoami.get
|
|
129
|
+
client.calls.last[0].should == :get
|
|
130
|
+
client.calls.last[1].should == "/_matrix/client/v3/account/whoami"
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
it "POST /createRoom with body" do
|
|
134
|
+
gw, client = make_gateway
|
|
135
|
+
gw.createRoom.post(name: "Pub", preset: "public_chat")
|
|
136
|
+
client.calls.last[0].should == :post
|
|
137
|
+
client.calls.last[1].should == "/_matrix/client/v3/createRoom"
|
|
138
|
+
client.calls.last[2].should == {name: "Pub", preset: "public_chat"}
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
it "POST /rooms/{roomId}/ban with body" do
|
|
142
|
+
gw, client = make_gateway
|
|
143
|
+
gw.rooms("!abc:ex.com").ban.post(user_id: "@bad:ex.com", reason: "spam")
|
|
144
|
+
client.calls.last[0].should == :post
|
|
145
|
+
client.calls.last[1].should == "/_matrix/client/v3/rooms/%21abc%3Aex.com/ban"
|
|
146
|
+
client.calls.last[2].should == {user_id: "@bad:ex.com", reason: "spam"}
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
it "GET /rooms/{roomId}/messages with query params" do
|
|
150
|
+
gw, client = make_gateway
|
|
151
|
+
gw.rooms("!abc:ex.com").messages.get(dir: "b", limit: 10)
|
|
152
|
+
call = client.calls.last
|
|
153
|
+
call[0].should == :get
|
|
154
|
+
call[1].should.include "/_matrix/client/v3/rooms/%21abc%3Aex.com/messages?"
|
|
155
|
+
call[1].should.include "dir=b"
|
|
156
|
+
call[1].should.include "limit=10"
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
it "PUT /rooms/{roomId}/send/{eventType}/{txnId}" do
|
|
160
|
+
gw, client = make_gateway
|
|
161
|
+
gw.rooms("!abc:ex.com").send("m.room.message", "txn-1").put(msgtype: "m.text", body: "hi")
|
|
162
|
+
call = client.calls.last
|
|
163
|
+
call[0].should == :put
|
|
164
|
+
call[1].should == "/_matrix/client/v3/rooms/%21abc%3Aex.com/send/m.room.message/txn-1"
|
|
165
|
+
call[2].should == {msgtype: "m.text", body: "hi"}
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
it "PUT /profile/{userId}/displayname" do
|
|
169
|
+
gw, client = make_gateway
|
|
170
|
+
gw.profile("@user:ex.com").displayname.put(displayname: "Bob")
|
|
171
|
+
call = client.calls.last
|
|
172
|
+
call[0].should == :put
|
|
173
|
+
call[1].should == "/_matrix/client/v3/profile/%40user%3Aex.com/displayname"
|
|
174
|
+
call[2].should == {displayname: "Bob"}
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
it "POST /join/{roomIdOrAlias}" do
|
|
178
|
+
gw, client = make_gateway
|
|
179
|
+
gw.join("!abc:ex.com").post
|
|
180
|
+
call = client.calls.last
|
|
181
|
+
call[0].should == :post
|
|
182
|
+
call[1].should == "/_matrix/client/v3/join/%21abc%3Aex.com"
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
it "raises InvalidEndpointError for unknown path" do
|
|
186
|
+
gw, _ = make_gateway
|
|
187
|
+
lambda { gw.totally.bogus.endpoint.get }.should.raise Async::Matrix::InvalidEndpointError
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
it "raises InvalidEndpointError for wrong method" do
|
|
191
|
+
gw, _ = make_gateway
|
|
192
|
+
lambda { gw.account.whoami.post }.should.raise Async::Matrix::InvalidEndpointError
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
it "each gateway method call starts a fresh chain" do
|
|
196
|
+
gw, client = make_gateway
|
|
197
|
+
gw.account.whoami.get
|
|
198
|
+
gw.createRoom.post(name: "test")
|
|
199
|
+
client.calls.length.should == 2
|
|
200
|
+
client.calls[0][1].should == "/_matrix/client/v3/account/whoami"
|
|
201
|
+
client.calls[1][1].should == "/_matrix/client/v3/createRoom"
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
end
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Released under the Apache License, Version 2.0.
|
|
4
|
+
# Copyright, 2026, by General Intelligence Systems.
|
|
5
|
+
|
|
6
|
+
require "bundler/setup"
|
|
7
|
+
require "console"
|
|
8
|
+
require "async/matrix"
|
|
9
|
+
|
|
10
|
+
module Async
|
|
11
|
+
module Matrix
|
|
12
|
+
module ApplicationService
|
|
13
|
+
# DSL wrapper that pairs a Client with event handlers.
|
|
14
|
+
#
|
|
15
|
+
# A Bot produces handler objects that conform to the Dispatcher's
|
|
16
|
+
# duck-type contract (#event_types, #call). Register a bot on a
|
|
17
|
+
# Server (or Dispatcher) the same way you would register a plain handler.
|
|
18
|
+
#
|
|
19
|
+
# bot = Bot.new(client) do
|
|
20
|
+
# on "m.room.member" do |event|
|
|
21
|
+
# join_room(event.room_id) if event.content.membership == "invite"
|
|
22
|
+
# end
|
|
23
|
+
#
|
|
24
|
+
# on "m.room.message", msgtype: "m.text", not_from: :self do |event|
|
|
25
|
+
# send_notice event.room_id, "Echo: #{event.content.body}"
|
|
26
|
+
# end
|
|
27
|
+
# end
|
|
28
|
+
#
|
|
29
|
+
# server.register(bot)
|
|
30
|
+
#
|
|
31
|
+
class Bot
|
|
32
|
+
attr_reader :client, :handlers
|
|
33
|
+
|
|
34
|
+
def initialize(client, &block)
|
|
35
|
+
@client = client
|
|
36
|
+
@handlers = []
|
|
37
|
+
|
|
38
|
+
instance_eval(&block) if block
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Register a handler block for one or more event types.
|
|
42
|
+
#
|
|
43
|
+
# Filters (all optional):
|
|
44
|
+
# msgtype: — only dispatch when content.msgtype matches (e.g. "m.text")
|
|
45
|
+
# not_from: — :self skips events sent by this bot's own MXID
|
|
46
|
+
#
|
|
47
|
+
def on(*event_types, msgtype: nil, not_from: nil, &block)
|
|
48
|
+
raise ArgumentError, "on requires at least one event type" if event_types.empty?
|
|
49
|
+
raise ArgumentError, "on requires a block" unless block
|
|
50
|
+
|
|
51
|
+
handler = Handler.new(
|
|
52
|
+
bot: self,
|
|
53
|
+
event_types: event_types.flatten,
|
|
54
|
+
msgtype: msgtype,
|
|
55
|
+
not_from: not_from,
|
|
56
|
+
block: block
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
@handlers << handler
|
|
60
|
+
handler
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Internal handler object produced by the #on DSL method.
|
|
64
|
+
# Conforms to the Dispatcher duck-type: #event_types, #call.
|
|
65
|
+
class Handler
|
|
66
|
+
attr_reader :event_types
|
|
67
|
+
|
|
68
|
+
def initialize(bot:, event_types:, msgtype:, not_from:, block:)
|
|
69
|
+
@bot = bot
|
|
70
|
+
@event_types = event_types
|
|
71
|
+
@msgtype = msgtype
|
|
72
|
+
@not_from = not_from
|
|
73
|
+
@block = block
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def call(event)
|
|
77
|
+
return if @msgtype && event.content&.msgtype != @msgtype
|
|
78
|
+
return if @not_from == :self && event.sender == @bot.client.config.bot_mxid
|
|
79
|
+
|
|
80
|
+
# Execute the block in a context that has helper methods
|
|
81
|
+
Context.new(@bot.client).execute(event, &@block)
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# Execution context for handler blocks.
|
|
86
|
+
# Provides helper methods so blocks can call send_notice, join_room, etc.
|
|
87
|
+
# directly without holding a reference to the client.
|
|
88
|
+
class Context
|
|
89
|
+
def initialize(client)
|
|
90
|
+
@client = client
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def execute(event, &block)
|
|
94
|
+
@event = event
|
|
95
|
+
instance_exec(event, &block)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def send_text(room_id, text)
|
|
99
|
+
@client.send_text(room_id, text)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def send_html(room_id, html, plaintext = nil)
|
|
103
|
+
@client.send_html(room_id, html, plaintext)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def send_notice(room_id, text)
|
|
107
|
+
@client.send_notice(room_id, text)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def join_room(room_id)
|
|
111
|
+
@client.join_room(room_id)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def leave_room(room_id)
|
|
115
|
+
@client.leave_room(room_id)
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def set_display_name(name, user_id = nil)
|
|
119
|
+
@client.set_display_name(name, user_id)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def client
|
|
123
|
+
@client
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
test do
|
|
132
|
+
describe "Async::Matrix::ApplicationService::Bot" do
|
|
133
|
+
def make_config
|
|
134
|
+
Async::Matrix::ApplicationService::Config.new({
|
|
135
|
+
"homeserver" => { "address" => "http://localhost:8008", "domain" => "localhost" },
|
|
136
|
+
"appservice" => { "as_token" => "token_secret", "hs_token" => "hs_secret", "bot" => { "username" => "bot" } }
|
|
137
|
+
})
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def make_event(type:, sender: "@user:localhost", msgtype: nil, body: nil, membership: nil, state_key: nil)
|
|
141
|
+
data = {"type" => type, "sender" => sender, "room_id" => "!room:localhost"}
|
|
142
|
+
content = {}
|
|
143
|
+
content["msgtype"] = msgtype if msgtype
|
|
144
|
+
content["body"] = body if body
|
|
145
|
+
content["membership"] = membership if membership
|
|
146
|
+
data["state_key"] = state_key if state_key
|
|
147
|
+
data["content"] = content
|
|
148
|
+
Async::Matrix::ApplicationService::Event.new(data)
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
it "registers handlers via the on DSL" do
|
|
152
|
+
config = make_config
|
|
153
|
+
client = Async::Matrix::Client.new(config)
|
|
154
|
+
|
|
155
|
+
bot = Async::Matrix::ApplicationService::Bot.new(client) do
|
|
156
|
+
on "m.room.message" do |event|
|
|
157
|
+
# no-op
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
bot.handlers.length.should == 1
|
|
162
|
+
bot.handlers.first.event_types.should == ["m.room.message"]
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
it "registers multiple event types on a single handler" do
|
|
166
|
+
config = make_config
|
|
167
|
+
client = Async::Matrix::Client.new(config)
|
|
168
|
+
|
|
169
|
+
bot = Async::Matrix::ApplicationService::Bot.new(client) do
|
|
170
|
+
on "m.room.message", "m.room.member" do |event|
|
|
171
|
+
# no-op
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
bot.handlers.first.event_types.should == ["m.room.message", "m.room.member"]
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
it "filters by msgtype" do
|
|
179
|
+
config = make_config
|
|
180
|
+
client = Async::Matrix::Client.new(config)
|
|
181
|
+
received = []
|
|
182
|
+
|
|
183
|
+
bot = Async::Matrix::ApplicationService::Bot.new(client) do
|
|
184
|
+
on "m.room.message", msgtype: "m.text" do |event|
|
|
185
|
+
received << event.content.body
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
handler = bot.handlers.first
|
|
190
|
+
handler.call(make_event(type: "m.room.message", msgtype: "m.text", body: "hello"))
|
|
191
|
+
handler.call(make_event(type: "m.room.message", msgtype: "m.notice", body: "ignored"))
|
|
192
|
+
|
|
193
|
+
received.should == ["hello"]
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
it "filters out self with not_from: :self" do
|
|
197
|
+
config = make_config
|
|
198
|
+
client = Async::Matrix::Client.new(config)
|
|
199
|
+
received = []
|
|
200
|
+
|
|
201
|
+
bot = Async::Matrix::ApplicationService::Bot.new(client) do
|
|
202
|
+
on "m.room.message", not_from: :self do |event|
|
|
203
|
+
received << event.content.body
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
handler = bot.handlers.first
|
|
208
|
+
handler.call(make_event(type: "m.room.message", sender: "@user:localhost", msgtype: "m.text", body: "yes"))
|
|
209
|
+
handler.call(make_event(type: "m.room.message", sender: "@bot:localhost", msgtype: "m.text", body: "no"))
|
|
210
|
+
|
|
211
|
+
received.should == ["yes"]
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
it "raises if on is called without event types" do
|
|
215
|
+
config = make_config
|
|
216
|
+
client = Async::Matrix::Client.new(config)
|
|
217
|
+
|
|
218
|
+
lambda {
|
|
219
|
+
Async::Matrix::ApplicationService::Bot.new(client) do
|
|
220
|
+
on do |event|; end
|
|
221
|
+
end
|
|
222
|
+
}.should.raise(ArgumentError)
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
it "raises if on is called without a block" do
|
|
226
|
+
config = make_config
|
|
227
|
+
client = Async::Matrix::Client.new(config)
|
|
228
|
+
|
|
229
|
+
lambda {
|
|
230
|
+
bot = Async::Matrix::ApplicationService::Bot.new(client)
|
|
231
|
+
bot.on "m.room.message"
|
|
232
|
+
}.should.raise(ArgumentError)
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "analytics.json",
|
|
4
|
+
"description": "Analytics/telemetry settings. Maps to mautrix bridgev2/bridgeconfig.AnalyticsConfig.",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"properties": {
|
|
7
|
+
"token": {
|
|
8
|
+
"type": "string",
|
|
9
|
+
"description": "Analytics token for the telemetry backend."
|
|
10
|
+
},
|
|
11
|
+
"url": {
|
|
12
|
+
"type": "string",
|
|
13
|
+
"description": "URL of the analytics/telemetry endpoint."
|
|
14
|
+
},
|
|
15
|
+
"user_id": {
|
|
16
|
+
"type": "string",
|
|
17
|
+
"description": "User ID to associate with analytics events."
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"additionalProperties": false
|
|
21
|
+
}
|