async-matrix 2.0.1-arm-linux

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,19 @@
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 "async/http"
7
+
8
+ module Async
9
+ module Matrix
10
+ module Connection
11
+ include Async::HTTP::Protocol::HTTP2::Connection
12
+ end
13
+ end
14
+ end
15
+
16
+ __END__
17
+ it "includes Async::HTTP::Protocol::HTTP2::Connection" do
18
+ Async::Matrix::Connection.ancestors.should.include Async::HTTP::Protocol::HTTP2::Connection
19
+ end
@@ -0,0 +1,82 @@
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_relative "client"
7
+
8
+ module Async
9
+ module Matrix
10
+ # A Client subclass that authenticates with a user's double puppet token
11
+ # instead of the appservice's as_token.
12
+ #
13
+ # This allows the bridge to send events as the real Matrix user rather
14
+ # than as the appservice bot or a ghost user.
15
+ #
16
+ # puppet = DoublePuppetClient.new(config, double_puppet_token: "syt_...")
17
+ # puppet.send_text("!room:example.com", "sent as the real user")
18
+ # puppet.whoami # => {"user_id" => "@alice:example.com"}
19
+ #
20
+ class DoublePuppetClient < Client
21
+ def initialize(config, double_puppet_token:, **kwargs)
22
+ super(config, **kwargs)
23
+ @headers[0] = ["authorization", "Bearer #{double_puppet_token}"]
24
+ end
25
+ end
26
+ end
27
+ end
28
+
29
+ __END__
30
+ describe "Async::Matrix::DoublePuppetClient" do
31
+ def make_config
32
+ Async::Matrix::ApplicationService::Config.new({
33
+ "homeserver" => { "address" => "http://localhost:8008", "domain" => "localhost" },
34
+ "appservice" => { "as_token" => "as_token_value", "hs_token" => "hs_secret", "bot" => { "username" => "bot" } }
35
+ })
36
+ end
37
+
38
+ it "uses the double_puppet_token for authorization" do
39
+ puppet = Async::Matrix::DoublePuppetClient.new(make_config, double_puppet_token: "syt_puppet_token")
40
+ auth_header = puppet.instance_variable_get(:@headers).find { |k, _| k == "authorization" }
41
+ auth_header[1].should == "Bearer syt_puppet_token"
42
+ end
43
+
44
+ it "does not use the as_token from config" do
45
+ puppet = Async::Matrix::DoublePuppetClient.new(make_config, double_puppet_token: "syt_puppet_token")
46
+ auth_header = puppet.instance_variable_get(:@headers).find { |k, _| k == "authorization" }
47
+ auth_header[1].should.not.include "as_token_value"
48
+ end
49
+
50
+ it "inherits retry defaults from Client" do
51
+ puppet = Async::Matrix::DoublePuppetClient.new(make_config, double_puppet_token: "syt_puppet_token")
52
+ puppet.config.appservice.as_token.should == "as_token_value"
53
+ end
54
+
55
+ it "accepts custom retry configuration" do
56
+ puppet = Async::Matrix::DoublePuppetClient.new(
57
+ make_config,
58
+ double_puppet_token: "syt_puppet_token",
59
+ max_retries: 5,
60
+ retry_base_delay: 1.0,
61
+ max_retry_delay: 60
62
+ )
63
+ auth_header = puppet.instance_variable_get(:@headers).find { |k, _| k == "authorization" }
64
+ auth_header[1].should == "Bearer syt_puppet_token"
65
+ end
66
+
67
+ it "responds to all Client methods" do
68
+ puppet = Async::Matrix::DoublePuppetClient.new(make_config, double_puppet_token: "syt_puppet_token")
69
+ puppet.should.respond_to :send_text
70
+ puppet.should.respond_to :send_html
71
+ puppet.should.respond_to :send_notice
72
+ puppet.should.respond_to :join_room
73
+ puppet.should.respond_to :leave_room
74
+ puppet.should.respond_to :whoami
75
+ puppet.should.respond_to :api
76
+ end
77
+
78
+ it "is a subclass of Client" do
79
+ puppet = Async::Matrix::DoublePuppetClient.new(make_config, double_puppet_token: "syt_puppet_token")
80
+ puppet.should.be.kind_of Async::Matrix::Client
81
+ end
82
+ end
@@ -0,0 +1,92 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the Apache License, Version 2.0.
4
+ # Copyright, 2026, by General Intelligence Systems.
5
+
6
+ # Loads the native vodozemac binding (ext/async_matrix_e2ee) and namespaces the
7
+ # Olm/Megolm primitives under Async::Matrix::E2EE.
8
+ #
9
+ # The native classes (Account, Session, GroupSession, InboundGroupSession) and
10
+ # the module function verify_signature are defined by the Rust #[magnus::init].
11
+ # This file only locates and requires the compiled object.
12
+ #
13
+ # account = Async::Matrix::E2EE::Account.new
14
+ # account.curve25519_key # => base64 string
15
+ # group = Async::Matrix::E2EE::GroupSession.new
16
+ # msg = group.encrypt("hello") # => base64 megolm message
17
+ # inbound = Async::Matrix::E2EE::InboundGroupSession.new(group.session_key)
18
+ # inbound.decrypt(msg) # => ["hello", 0]
19
+
20
+ module Async
21
+ module Matrix
22
+ module E2EE
23
+ end
24
+ end
25
+ end
26
+
27
+ # Precompiled ("fat") gems ship one .so per Ruby minor version under a versioned
28
+ # subdir (lib/async/matrix/3.3/async_matrix_e2ee.so). A locally source-compiled
29
+ # build lands flat, alongside this file. Try the versioned path first, then fall
30
+ # back to the flat one.
31
+ begin
32
+ RUBY_VERSION =~ /(\d+\.\d+)/
33
+ require_relative "#{Regexp.last_match(1)}/async_matrix_e2ee"
34
+ rescue LoadError
35
+ require_relative "async_matrix_e2ee"
36
+ end
37
+
38
+ __END__
39
+ describe "Async::Matrix::E2EE" do
40
+ it "exposes account identity keys as base64" do
41
+ account = Async::Matrix::E2EE::Account.new
42
+ account.curve25519_key.should.be.kind_of String
43
+ account.ed25519_key.should.be.kind_of String
44
+ account.curve25519_key.length.should.be > 0
45
+ end
46
+
47
+ it "round-trips a megolm group message" do
48
+ group = Async::Matrix::E2EE::GroupSession.new
49
+ inbound = Async::Matrix::E2EE::InboundGroupSession.new(group.session_key)
50
+
51
+ message = group.encrypt("hello world")
52
+ plaintext, index = inbound.decrypt(message)
53
+
54
+ plaintext.should == "hello world"
55
+ index.should == 0
56
+ inbound.session_id.should == group.session_id
57
+ end
58
+
59
+ it "round-trips an olm 1:1 message" do
60
+ alice = Async::Matrix::E2EE::Account.new
61
+ bob = Async::Matrix::E2EE::Account.new
62
+ bob.generate_one_time_keys(1)
63
+ bob_otk = bob.one_time_keys.values.first
64
+
65
+ outbound = alice.create_outbound_session(bob.curve25519_key, bob_otk)
66
+ type, body = outbound.encrypt("yo g")
67
+ type.should == 0 # pre-key message
68
+
69
+ session, plaintext = bob.create_inbound_session(alice.curve25519_key, body)
70
+ plaintext.should == "yo g"
71
+
72
+ reply_type, reply_body = session.encrypt("hello back")
73
+ outbound.decrypt(reply_type, reply_body).should == "hello back"
74
+ end
75
+
76
+ it "verifies a valid ed25519 signature and rejects a bad one" do
77
+ account = Async::Matrix::E2EE::Account.new
78
+ signature = account.sign("payload")
79
+
80
+ Async::Matrix::E2EE.verify_signature(account.ed25519_key, "payload", signature).should == true
81
+ Async::Matrix::E2EE.verify_signature(account.ed25519_key, "tampered", signature).should == false
82
+ end
83
+
84
+ it "survives a pickle round-trip" do
85
+ key = "0" * 32
86
+ group = Async::Matrix::E2EE::GroupSession.new
87
+ pickled = group.pickle(key)
88
+
89
+ restored = Async::Matrix::E2EE::GroupSession.from_pickle(pickled, key)
90
+ restored.session_id.should == group.session_id
91
+ end
92
+ end
@@ -0,0 +1,57 @@
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 "json"
7
+ require "async/http"
8
+
9
+ module Async
10
+ module Matrix
11
+ # Extends Async::HTTP::Endpoint with Matrix well-known discovery.
12
+ # spec.matrix.org/v1.9/client-server-api/#well-known-uri
13
+ #
14
+ # A server at example.com may serve clients from a completely
15
+ # different origin — e.g. https://matrix.example.com:8448.
16
+ # #discover resolves that indirection as a proper async I/O
17
+ # operation before constructing the Endpoint, so every downstream
18
+ # caller gets a correctly-pointed connection pool for free.
19
+ class Endpoint < Async::HTTP::Endpoint
20
+ WELL_KNOWN = "/.well-known/matrix/client"
21
+
22
+ # Resolves homeserver base URL, falls back to https://domain.
23
+ # Must be called inside an Async block — uses the running scheduler.
24
+ def self.discover(domain, **options)
25
+ internet = Async::HTTP::Internet.new
26
+ data = JSON.parse(internet.get("https://#{domain}#{WELL_KNOWN}").read)
27
+ base_url = data.dig("m.homeserver", "base_url") || "https://#{domain}"
28
+ parse(base_url, **options)
29
+ rescue StandardError
30
+ # Well-known is optional per spec — fall back gracefully
31
+ parse("https://#{domain}", **options)
32
+ ensure
33
+ internet&.close
34
+ end
35
+ end
36
+ end
37
+ end
38
+
39
+ __END__
40
+ it "defines the WELL_KNOWN constant" do
41
+ Async::Matrix::Endpoint::WELL_KNOWN.should == "/.well-known/matrix/client"
42
+ end
43
+
44
+ it "responds to .discover" do
45
+ Async::Matrix::Endpoint.should.respond_to :discover
46
+ end
47
+
48
+ it "inherits from Async::HTTP::Endpoint" do
49
+ Async::Matrix::Endpoint.ancestors.should.include Async::HTTP::Endpoint
50
+ end
51
+
52
+ it "falls back to https://domain when well-known fails" do
53
+ Async do
54
+ endpoint = Async::Matrix::Endpoint.discover("nonexistent.invalid")
55
+ endpoint.to_s.should =~ /nonexistent\.invalid/
56
+ end.wait
57
+ end
@@ -0,0 +1,67 @@
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
+ class Error < StandardError
9
+ attr_reader :errcode, :status
10
+
11
+ def initialize(errcode, message, status: nil)
12
+ @errcode = errcode
13
+ @status = status
14
+ super(message)
15
+ end
16
+ end
17
+
18
+ class NotFoundError < Error; end
19
+ class BadJsonError < Error; end
20
+ class AuthError < Error; end
21
+ class HomeserverError < Error; end
22
+ class InvalidEndpointError < Error; end
23
+ class ResponseTooLargeError < Error; end
24
+ end
25
+ end
26
+
27
+ __END__
28
+ describe "Async::Matrix::Error" do
29
+ it "stores errcode and message" do
30
+ err = Async::Matrix::Error.new("M_UNKNOWN", "something broke")
31
+ err.errcode.should == "M_UNKNOWN"
32
+ err.message.should == "something broke"
33
+ end
34
+
35
+ it "stores optional status" do
36
+ err = Async::Matrix::Error.new("M_UNKNOWN", "bad", status: 400)
37
+ err.status.should == 400
38
+ end
39
+
40
+ it "defaults status to nil" do
41
+ Async::Matrix::Error.new("M_UNKNOWN", "bad").status.should.be.nil
42
+ end
43
+
44
+ it "is a StandardError" do
45
+ Async::Matrix::Error.new("M_UNKNOWN", "bad").should.be.kind_of StandardError
46
+ end
47
+ end
48
+
49
+ it "NotFoundError inherits from Error" do
50
+ Async::Matrix::NotFoundError.new("M_NOT_FOUND", "gone").should.be.kind_of Async::Matrix::Error
51
+ end
52
+
53
+ it "BadJsonError inherits from Error" do
54
+ Async::Matrix::BadJsonError.new("M_BAD_JSON", "invalid").should.be.kind_of Async::Matrix::Error
55
+ end
56
+
57
+ it "AuthError inherits from Error" do
58
+ Async::Matrix::AuthError.new("M_FORBIDDEN", "denied").should.be.kind_of Async::Matrix::Error
59
+ end
60
+
61
+ it "HomeserverError inherits from Error" do
62
+ Async::Matrix::HomeserverError.new("M_UNKNOWN", "upstream").should.be.kind_of Async::Matrix::Error
63
+ end
64
+
65
+ it "ResponseTooLargeError inherits from Error" do
66
+ Async::Matrix::ResponseTooLargeError.new("M_TOO_LARGE", "too big").should.be.kind_of Async::Matrix::Error
67
+ end
@@ -0,0 +1,170 @@
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 "async/http/internet"
7
+ require "json"
8
+ require "console"
9
+
10
+ module Async
11
+ module Matrix
12
+ # Async HTTP client for binary Matrix media operations.
13
+ #
14
+ # Handles raw byte uploads and downloads against the Matrix content
15
+ # repository. Unlike the JSON-only Client, this never wraps request
16
+ # bodies in JSON.generate and can return raw binary response bodies.
17
+ #
18
+ # Not intended to be used directly — the Chain dispatches here
19
+ # automatically when the request path matches a BINARY_ROUTES entry.
20
+ #
21
+ # media_client = Async::Matrix::MediaClient.new(config)
22
+ # media_client.upload("POST", path, bytes, "image/png")
23
+ # bytes = media_client.download(path)
24
+ #
25
+ class MediaClient
26
+ # Upload JSON responses are small; error bodies are even smaller.
27
+ UPLOAD_RESPONSE_SIZE_LIMIT = 1 * 1024 * 1024 # 1 MiB
28
+ ERROR_RESPONSE_SIZE_LIMIT = 512 * 1024 # 512 KiB
29
+
30
+ def initialize(config)
31
+ @config = config
32
+ @base = config.homeserver.address
33
+ @auth_headers = [
34
+ ["authorization", "Bearer #{config.appservice.as_token}"],
35
+ ["user-agent", "AsyncMatrix/#{Async::Matrix::VERSION}"]
36
+ ]
37
+ end
38
+
39
+ # Upload raw bytes to the content repository.
40
+ #
41
+ # @param method [String] HTTP method ("POST" or "PUT")
42
+ # @param path [String] URL path (already URL-encoded)
43
+ # @param body [String] raw bytes to upload
44
+ # @param content_type [String] MIME type of the body
45
+ # @return [Hash] parsed JSON response (e.g. {"content_uri" => "mxc://..."})
46
+ def upload(method, path, body, content_type = "application/octet-stream")
47
+ url = "#{@base}#{path}"
48
+ headers = @auth_headers + [["content-type", content_type]]
49
+
50
+ Console.debug(self) { "UPLOAD #{method} #{path} (#{content_type}, #{body.bytesize} bytes)" }
51
+
52
+ response = internet.call(method, url, headers, body)
53
+ status = response.status
54
+
55
+ unless (200..299).cover?(status)
56
+ payload = read_limited(response, ERROR_RESPONSE_SIZE_LIMIT)
57
+ parsed = ApplicationService::ErrorResponse.new(
58
+ begin; JSON.parse(payload); rescue; {} end
59
+ )
60
+ Console.error(self) { "Matrix media upload #{status}: #{parsed.errcode} — #{parsed.error}" }
61
+ raise HomeserverError.new(
62
+ parsed.errcode || "UNKNOWN",
63
+ parsed.error || payload.to_s[0..200],
64
+ status: status
65
+ )
66
+ end
67
+
68
+ payload = read_limited(response, UPLOAD_RESPONSE_SIZE_LIMIT)
69
+ payload && !payload.empty? ? JSON.parse(payload) : {}
70
+ end
71
+
72
+ # Download from the content repository.
73
+ #
74
+ # Returns the raw HTTP response object so the caller has access to
75
+ # both the body and response metadata:
76
+ #
77
+ # response = media_client.download(path)
78
+ # response.read # raw bytes (String, Encoding::BINARY)
79
+ # response.headers["content-type"] # "image/png"
80
+ # response.headers["content-disposition"] # "inline; filename=\"photo.jpg\""
81
+ # response.body.each { |chunk| ... } # streaming
82
+ #
83
+ # @param path [String] URL path (already URL-encoded, may include query string)
84
+ # @return [Protocol::HTTP::Response] the HTTP response
85
+ def download(path)
86
+ url = "#{@base}#{path}"
87
+
88
+ Console.debug(self) { "DOWNLOAD #{path}" }
89
+
90
+ response = internet.call("GET", url, @auth_headers, nil)
91
+ status = response.status
92
+
93
+ unless (200..299).cover?(status)
94
+ payload = response.read
95
+ parsed = ApplicationService::ErrorResponse.new(
96
+ begin; JSON.parse(payload); rescue; {} end
97
+ )
98
+ Console.error(self) { "Matrix media download #{status}: #{parsed.errcode} — #{parsed.error}" }
99
+ raise HomeserverError.new(
100
+ parsed.errcode || "UNKNOWN",
101
+ parsed.error || payload.to_s[0..200],
102
+ status: status
103
+ )
104
+ end
105
+
106
+ response
107
+ end
108
+
109
+ def close
110
+ @internet&.close
111
+ @internet = nil
112
+ end
113
+
114
+ private
115
+
116
+ def internet
117
+ @internet ||= Async::HTTP::Internet.new
118
+ end
119
+
120
+ # Read response body with a size limit. Raises ResponseTooLargeError
121
+ # if the body exceeds the limit.
122
+ def read_limited(response, limit)
123
+ body = response.body
124
+ return nil unless body
125
+
126
+ if body.respond_to?(:length) && body.length && body.length > limit
127
+ body.close
128
+ raise ResponseTooLargeError.new(
129
+ "M_TOO_LARGE",
130
+ "Response Content-Length #{body.length} bytes exceeds limit of #{limit} bytes"
131
+ )
132
+ end
133
+
134
+ buffer = String.new(encoding: Encoding::BINARY)
135
+ body.each do |chunk|
136
+ buffer << chunk
137
+ if buffer.bytesize > limit
138
+ body.close
139
+ raise ResponseTooLargeError.new(
140
+ "M_TOO_LARGE",
141
+ "Response body exceeds limit of #{limit} bytes"
142
+ )
143
+ end
144
+ end
145
+ buffer.empty? ? nil : buffer
146
+ end
147
+ end
148
+ end
149
+ end
150
+
151
+ __END__
152
+ describe "Async::Matrix::MediaClient" do
153
+ def make_config
154
+ Async::Matrix::ApplicationService::Config.new({
155
+ "homeserver" => { "address" => "http://localhost:8008", "domain" => "localhost" },
156
+ "appservice" => { "as_token" => "test_token", "hs_token" => "hs_secret", "bot" => { "username" => "bot" } }
157
+ })
158
+ end
159
+
160
+ it "responds to upload and download" do
161
+ client = Async::Matrix::MediaClient.new(make_config)
162
+ client.should.respond_to :upload
163
+ client.should.respond_to :download
164
+ end
165
+
166
+ it "can be closed without error" do
167
+ client = Async::Matrix::MediaClient.new(make_config)
168
+ lambda { client.close }.should.not.raise
169
+ end
170
+ end
@@ -0,0 +1,104 @@
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 "async"
7
+ require "async/condition"
8
+
9
+ module Async
10
+ module Matrix
11
+ # Waitable event bus. Signal it when events arrive;
12
+ # /sync handlers wait on it with a timeout.
13
+ #
14
+ # notifier = Async::Matrix::Notifier.new
15
+ #
16
+ # # In a /sync handler fiber (blocks until signalled or timeout):
17
+ # notifier.wait(timeout: 30) { check_for_events() }
18
+ #
19
+ # # After persisting an event (wakes all waiting fibers):
20
+ # notifier.signal
21
+ #
22
+ class Notifier
23
+ def initialize
24
+ @condition = Async::Condition.new
25
+ end
26
+
27
+ # Wake all waiting fibers.
28
+ def signal
29
+ @condition.signal
30
+ end
31
+
32
+ # Block up to +timeout+ seconds. Yields to check for data after
33
+ # each wake-up; returns the block's value as soon as it is truthy.
34
+ # Returns the block's value (possibly nil/false) when time runs out.
35
+ def wait(timeout: 30, &block)
36
+ deadline = Time.now + timeout
37
+
38
+ loop do
39
+ result = yield
40
+ return result if result
41
+
42
+ remaining = deadline - Time.now
43
+ return result if remaining <= 0
44
+
45
+ begin
46
+ Async::Task.current.with_timeout(remaining) do
47
+ @condition.wait
48
+ end
49
+ rescue Async::TimeoutError
50
+ return yield
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+
58
+ __END__
59
+ it "can be instantiated" do
60
+ notifier = Async::Matrix::Notifier.new
61
+ notifier.should.be.kind_of Async::Matrix::Notifier
62
+ end
63
+
64
+ it "responds to #signal" do
65
+ Async::Matrix::Notifier.new.should.respond_to :signal
66
+ end
67
+
68
+ it "responds to #wait" do
69
+ Async::Matrix::Notifier.new.should.respond_to :wait
70
+ end
71
+
72
+ it "returns truthy block value immediately without waiting" do
73
+ Async do
74
+ notifier = Async::Matrix::Notifier.new
75
+ result = notifier.wait(timeout: 1) { :data }
76
+ result.should == :data
77
+ end.wait
78
+ end
79
+
80
+ it "returns falsy block value on timeout" do
81
+ Async do
82
+ notifier = Async::Matrix::Notifier.new
83
+ result = notifier.wait(timeout: 0.05) { nil }
84
+ result.should.be.nil
85
+ end.wait
86
+ end
87
+
88
+ it "wakes waiting fibers on signal" do
89
+ result = nil
90
+ Async do |task|
91
+ notifier = Async::Matrix::Notifier.new
92
+ signalled = false
93
+
94
+ task.async do
95
+ result = notifier.wait(timeout: 5) { signalled }
96
+ end
97
+
98
+ task.async do
99
+ signalled = true
100
+ notifier.signal
101
+ end
102
+ end.wait
103
+ result.should == true
104
+ end