diff --git a/MxApiExtensions/Controllers/Client/Room/RoomController.cs b/MxApiExtensions/Controllers/Client/Room/RoomController.cs
new file mode 100644
index 0000000..a3e433d
--- /dev/null
+++ b/MxApiExtensions/Controllers/Client/Room/RoomController.cs
@@ -0,0 +1,51 @@
+using LibMatrix;
+using LibMatrix.Services;
+using Microsoft.AspNetCore.Mvc;
+using MxApiExtensions.Services;
+
+namespace MxApiExtensions.Controllers.Client.Room;
+
+[ApiController]
+[Route("/")]
+public class RoomController(ILogger<LoginController> logger, HomeserverResolverService hsResolver, AuthenticationService auth, MxApiExtensionsConfiguration conf,
+ AuthenticatedHomeserverProviderService hsProvider)
+ : ControllerBase {
+ [HttpGet("/_matrix/client/{_}/rooms/{roomId}/members_by_homeserver")]
+ public async Task<Dictionary<string, List<string>>> GetRoomMembersByHomeserver(string _, [FromRoute] string roomId, [FromQuery] bool joinedOnly = true) {
+ var hs = await hsProvider.GetHomeserver();
+ var room = hs.GetRoom(roomId);
+ return await room.GetMembersByHomeserverAsync(joinedOnly);
+ }
+
+ /// <summary>
+ /// Fetches up to <paramref name="limit"/> timeline events
+ /// </summary>
+ /// <param name="_"></param>
+ /// <param name="roomId"></param>
+ /// <param name="from"></param>
+ /// <param name="limit"></param>
+ /// <param name="dir"></param>
+ /// <param name="filter"></param>
+ /// <param name="includeState"></param>
+ /// <param name="fixForward">Reverse load all messages and reverse on API side, fixes history starting at join event</param>
+ /// <returns></returns>
+ [HttpGet("/_matrix/client/{_}/rooms/{roomId}/mass_messages")]
+ public async IAsyncEnumerable<StateEventResponse> RedactUser(string _, [FromRoute] string roomId, [FromQuery(Name = "from")] string from = "",
+ [FromQuery(Name = "limit")] int limit = 100, [FromQuery(Name = "dir")] string dir = "b", [FromQuery(Name = "filter")] string filter = "",
+ [FromQuery(Name = "include_state")] bool includeState = true, [FromQuery(Name = "fix_forward")] bool fixForward = false) {
+ var hs = await hsProvider.GetHomeserver();
+ var room = hs.GetRoom(roomId);
+ var msgs = room.GetManyMessagesAsync(from: from, limit: limit, dir: dir, filter: filter, includeState: includeState, fixForward: fixForward);
+ await foreach (var resp in msgs) {
+ Console.WriteLine($"GetMany messages returned {resp.Chunk.Count} timeline events and {resp.State.Count} state events, end={resp.End}");
+ foreach (var timelineEvent in resp.Chunk) {
+ yield return timelineEvent;
+ }
+
+ if (includeState)
+ foreach (var timelineEvent in resp.State) {
+ yield return timelineEvent;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/MxApiExtensions/Controllers/Client/Room/RoomsSendMessageController.cs b/MxApiExtensions/Controllers/Client/Room/RoomsSendMessageController.cs
index b756582..e882c8a 100644
--- a/MxApiExtensions/Controllers/Client/Room/RoomsSendMessageController.cs
+++ b/MxApiExtensions/Controllers/Client/Room/RoomsSendMessageController.cs
@@ -1,18 +1,73 @@
+using System.Buffers.Text;
+using System.Net.Http.Headers;
+using System.Text.Json;
+using System.Text.Json.Nodes;
+using ArcaneLibs.Extensions;
+using LibMatrix;
+using LibMatrix.EventTypes.Spec;
+using LibMatrix.Extensions;
+using LibMatrix.Helpers;
+using LibMatrix.Homeservers;
+using LibMatrix.Responses;
using LibMatrix.Services;
using Microsoft.AspNetCore.Mvc;
+using MxApiExtensions.Classes;
+using MxApiExtensions.Classes.LibMatrix;
+using MxApiExtensions.Extensions;
using MxApiExtensions.Services;
-namespace MxApiExtensions.Controllers.Client.Room;
+namespace MxApiExtensions.Controllers;
[ApiController]
[Route("/")]
-public class RoomController(ILogger<LoginController> logger, HomeserverResolverService hsResolver, AuthenticationService auth, MxApiExtensionsConfiguration conf,
- AuthenticatedHomeserverProviderService hsProvider)
+public class RoomsSendMessageController(ILogger<LoginController> logger, UserContextService userContextService)
: ControllerBase {
- [HttpGet("/_matrix/client/{_}/rooms/{roomId}/members_by_homeserver")]
- public async Task<Dictionary<string, List<string>>> GetRoomMembersByHomeserver(string _, [FromRoute] string roomId, [FromQuery] bool joinedOnly = true) {
- var hs = await hsProvider.GetHomeserver();
- var room = hs.GetRoom(roomId);
- return await room.GetMembersByHomeserverAsync(joinedOnly);
+ [HttpPut("/_matrix/client/{_}/rooms/{roomId}/send/m.room.message/{txnId}")]
+ public async Task Proxy([FromBody] JsonObject request, [FromRoute] string roomId, [FromRoute] string txnId, string _) {
+ var uc = await userContextService.GetCurrentUserContext();
+ // var hs = await hsProvider.GetHomeserver();
+
+ var msg = request.Deserialize<RoomMessageEventContent>();
+ if (msg is not null && msg.Body.StartsWith("mxae!")) {
+#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
+ handleMxaeCommand(uc, roomId, msg);
+#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
+ await Response.WriteAsJsonAsync(new EventIdResponse() {
+ EventId = "$" + string.Join("", Random.Shared.GetItems("abcdefghijklmnopqrstuvwxyzABCDEFGHIJLKMNOPQRSTUVWXYZ0123456789".ToCharArray(), 100))
+ });
+ await Response.CompleteAsync();
+ }
+ else {
+ try {
+ var resp = await uc.Homeserver.ClientHttpClient.PutAsJsonAsync($"{Request.Path}{Request.QueryString}", request);
+ await Response.WriteHttpResponse(resp);
+ // var loginResp = await resp.Content.ReadAsStringAsync();
+ // Response.StatusCode = (int)resp.StatusCode;
+ // Response.ContentType = resp.Content.Headers.ContentType?.ToString() ?? "application/json";
+ // await Response.StartAsync();
+ // await Response.WriteAsync(loginResp);
+ // await Response.CompleteAsync();
+ }
+ catch (MatrixException e) {
+ await Response.StartAsync();
+ await Response.WriteAsync(e.GetAsJson());
+ await Response.CompleteAsync();
+ }
+ }
+ }
+
+ private async Task handleMxaeCommand(UserContextService.UserContext hs, string roomId, RoomMessageEventContent msg) {
+ if (hs.SyncState is null) return;
+ hs.SyncState.SendEphemeralTimelineEventInRoom(roomId, new() {
+ Sender = "@mxae:" + Request.Host.Value,
+ Type = "m.room.message",
+ TypedContent = MessageFormatter.FormatSuccess("Thinking..."),
+ OriginServerTs = (ulong)new DateTimeOffset(DateTime.UtcNow.ToUniversalTime()).ToUnixTimeMilliseconds(),
+ Unsigned = new() {
+ Age = 1
+ },
+ RoomId = roomId,
+ EventId = "$" + string.Join("", Random.Shared.GetItems("abcdefghijklmnopqrstuvwxyzABCDEFGHIJLKMNOPQRSTUVWXYZ0123456789".ToCharArray(), 100))
+ });
}
}
\ No newline at end of file
|