async-matrix 2.0.1-aarch64-linux-musl

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