diff --git a/MatrixRoomUtils.Core/RoomTypes/GenericRoom.cs b/MatrixRoomUtils.Core/RoomTypes/GenericRoom.cs
index 8dc30d1..f57c855 100644
--- a/MatrixRoomUtils.Core/RoomTypes/GenericRoom.cs
+++ b/MatrixRoomUtils.Core/RoomTypes/GenericRoom.cs
@@ -1,15 +1,17 @@
using System.Net.Http.Json;
-using System.Text;
using System.Text.Json;
using System.Web;
using MatrixRoomUtils.Core.Extensions;
+using MatrixRoomUtils.Core.Responses;
using MatrixRoomUtils.Core.RoomTypes;
+using MatrixRoomUtils.Core.StateEventTypes;
+using Microsoft.Extensions.Logging;
namespace MatrixRoomUtils.Core;
public class GenericRoom {
internal readonly AuthenticatedHomeServer _homeServer;
- internal readonly HttpClient _httpClient;
+ internal readonly MatrixHttpClient _httpClient;
public GenericRoom(AuthenticatedHomeServer homeServer, string roomId) {
_homeServer = homeServer;
@@ -21,51 +23,41 @@ public class GenericRoom {
public string RoomId { get; set; }
- public async Task<JsonElement?> GetStateAsync(string type, string stateKey = "", bool logOnFailure = true) {
+ [Obsolete("", true)]
+ public async Task<JsonElement?> GetStateAsync(string type, string stateKey = "") {
var url = $"/_matrix/client/v3/rooms/{RoomId}/state";
if (!string.IsNullOrEmpty(type)) url += $"/{type}";
if (!string.IsNullOrEmpty(stateKey)) url += $"/{stateKey}";
+ return await _httpClient.GetFromJsonAsync<JsonElement>(url);
+ }
- var res = await _httpClient.GetAsync(url);
- if (!res.IsSuccessStatusCode) {
- if (logOnFailure) Console.WriteLine($"{RoomId}/{stateKey}/{type} - got status: {res.StatusCode}");
- return null;
+ public async IAsyncEnumerable<StateEventResponse?> GetFullStateAsync() {
+ var res = await _httpClient.GetAsync($"/_matrix/client/v3/rooms/{RoomId}/state");
+ var result =
+ JsonSerializer.DeserializeAsyncEnumerable<StateEventResponse>(await res.Content.ReadAsStreamAsync());
+ await foreach (var resp in result) {
+ yield return resp;
}
-
- var result = await res.Content.ReadFromJsonAsync<JsonElement>();
- return result;
}
- public async Task<T?> GetStateAsync<T>(string type, string stateKey = "", bool logOnFailure = false) {
- var res = await GetStateAsync(type, stateKey, logOnFailure);
- if (res == null) return default;
- return res.Value.Deserialize<T>();
+ public async Task<T?> GetStateAsync<T>(string type, string stateKey = "") {
+ var url = $"/_matrix/client/v3/rooms/{RoomId}/state";
+ if (!string.IsNullOrEmpty(type)) url += $"/{type}";
+ if (!string.IsNullOrEmpty(stateKey)) url += $"/{stateKey}";
+ return await _httpClient.GetFromJsonAsync<T>(url);
}
public async Task<MessagesResponse> GetMessagesAsync(string from = "", int limit = 10, string dir = "b",
string filter = "") {
var url = $"/_matrix/client/v3/rooms/{RoomId}/messages?from={from}&limit={limit}&dir={dir}";
if (!string.IsNullOrEmpty(filter)) url += $"&filter={filter}";
- var res = await _httpClient.GetAsync(url);
- if (!res.IsSuccessStatusCode) {
- Console.WriteLine($"Failed to get messages for {RoomId} - got status: {res.StatusCode}");
- throw new Exception($"Failed to get messages for {RoomId} - got status: {res.StatusCode}");
- }
-
- var result = await res.Content.ReadFromJsonAsync<MessagesResponse>();
- return result ?? new MessagesResponse();
+ var res = await _httpClient.GetFromJsonAsync<MessagesResponse>(url);
+ return res ?? new MessagesResponse();
}
public async Task<string> GetNameAsync() {
- var res = await GetStateAsync("m.room.name");
- if (!res.HasValue) {
- Console.WriteLine($"Room {RoomId} has no name!");
- return RoomId;
- }
-
- var resn = res?.TryGetProperty("name", out var name) ?? false ? name.GetString() ?? RoomId : RoomId;
- //Console.WriteLine($"Got name: {resn}");
- return resn;
+ var res = await GetStateAsync<RoomNameEventData>("m.room.name");
+ return res.Name ?? RoomId;
}
public async Task JoinAsync(string[]? homeservers = null, string? reason = null) {
@@ -78,165 +70,89 @@ public class GenericRoom {
});
}
- public async Task<List<string>> GetMembersAsync(bool joinedOnly = true) {
- var res = await GetStateAsync("");
- if (!res.HasValue) return new List<string>();
- var members = new List<string>();
- foreach (var member in res.Value.EnumerateArray()) {
- if (member.GetProperty("type").GetString() != "m.room.member") continue;
- if (joinedOnly && member.GetProperty("content").GetProperty("membership").GetString() != "join") continue;
- var memberId = member.GetProperty("state_key").GetString();
- members.Add(
- memberId ?? throw new InvalidOperationException("Event type was member but state key was null!"));
+ public async IAsyncEnumerable<StateEventResponse> GetMembersAsync(bool joinedOnly = true) {
+ var res = GetFullStateAsync();
+ await foreach (var member in res) {
+ if (member.Type != "m.room.member") continue;
+ if (joinedOnly && (member.TypedContent as RoomMemberEventData).Membership is not "join") continue;
+ yield return member;
}
-
- return members;
}
public async Task<List<string>> GetAliasesAsync() {
- var res = await GetStateAsync("m.room.aliases");
- if (!res.HasValue) return new List<string>();
- var aliases = new List<string>();
- foreach (var alias in res.Value.GetProperty("aliases").EnumerateArray()) aliases.Add(alias.GetString() ?? "");
-
- return aliases;
+ var res = await GetStateAsync<RoomAliasEventData>("m.room.aliases");
+ return res.Aliases;
}
- public async Task<string> GetCanonicalAliasAsync() {
- var res = await GetStateAsync("m.room.canonical_alias");
- if (!res.HasValue) return "";
- return res.Value.GetProperty("alias").GetString() ?? "";
- }
-
- public async Task<string> GetTopicAsync() {
- var res = await GetStateAsync("m.room.topic");
- if (!res.HasValue) return "";
- return res.Value.GetProperty("topic").GetString() ?? "";
- }
-
- public async Task<string> GetAvatarUrlAsync() {
- var res = await GetStateAsync("m.room.avatar");
- if (!res.HasValue) return "";
- return res.Value.GetProperty("url").GetString() ?? "";
- }
+ public async Task<CanonicalAliasEventData?> GetCanonicalAliasAsync() =>
+ await GetStateAsync<CanonicalAliasEventData>("m.room.canonical_alias");
- public async Task<JoinRulesEventData> GetJoinRuleAsync() {
- var res = await GetStateAsync("m.room.join_rules");
- if (!res.HasValue) return new JoinRulesEventData();
- return res.Value.Deserialize<JoinRulesEventData>() ?? new JoinRulesEventData();
- }
+ public async Task<RoomTopicEventData?> GetTopicAsync() =>
+ await GetStateAsync<RoomTopicEventData>("m.room.topic");
- public async Task<string> GetHistoryVisibilityAsync() {
- var res = await GetStateAsync("m.room.history_visibility");
- if (!res.HasValue) return "";
- return res.Value.GetProperty("history_visibility").GetString() ?? "";
- }
+ public async Task<RoomAvatarEventData?> GetAvatarUrlAsync() =>
+ await GetStateAsync<RoomAvatarEventData>("m.room.avatar");
- public async Task<string> GetGuestAccessAsync() {
- var res = await GetStateAsync("m.room.guest_access");
- if (!res.HasValue) return "";
- return res.Value.GetProperty("guest_access").GetString() ?? "";
- }
+ public async Task<JoinRulesEventData> GetJoinRuleAsync() =>
+ await GetStateAsync<JoinRulesEventData>("m.room.join_rules");
- public async Task<CreateEvent> GetCreateEventAsync() {
- var res = await GetStateAsync("m.room.create");
- if (!res.HasValue) return new CreateEvent();
+ public async Task<HistoryVisibilityData?> GetHistoryVisibilityAsync() =>
+ await GetStateAsync<HistoryVisibilityData>("m.room.history_visibility");
- res.FindExtraJsonElementFields(typeof(CreateEvent));
+ public async Task<GuestAccessData?> GetGuestAccessAsync() =>
+ await GetStateAsync<GuestAccessData>("m.room.guest_access");
- return res.Value.Deserialize<CreateEvent>() ?? new CreateEvent();
- }
+ public async Task<CreateEvent> GetCreateEventAsync() =>
+ await GetStateAsync<CreateEvent>("m.room.create");
public async Task<string?> GetRoomType() {
- var res = await GetStateAsync("m.room.create");
- if (!res.HasValue) return null;
- if (res.Value.TryGetProperty("type", out var type)) return type.GetString();
- return null;
+ var res = await GetStateAsync<RoomCreateEventData>("m.room.create");
+ return res.Type;
}
- public async Task ForgetAsync() {
- var res = await _httpClient.PostAsync($"/_matrix/client/v3/rooms/{RoomId}/forget", null);
- if (!res.IsSuccessStatusCode) {
- Console.WriteLine($"Failed to forget room {RoomId} - got status: {res.StatusCode}");
- throw new Exception($"Failed to forget room {RoomId} - got status: {res.StatusCode}");
- }
- }
+ public async Task ForgetAsync() =>
+ await _httpClient.PostAsync($"/_matrix/client/v3/rooms/{RoomId}/forget", null);
- public async Task LeaveAsync(string? reason = null) {
- var res = await _httpClient.PostAsJsonAsync($"/_matrix/client/v3/rooms/{RoomId}/leave", new {
+ public async Task LeaveAsync(string? reason = null) =>
+ await _httpClient.PostAsJsonAsync($"/_matrix/client/v3/rooms/{RoomId}/leave", new {
reason
});
- if (!res.IsSuccessStatusCode) {
- Console.WriteLine($"Failed to leave room {RoomId} - got status: {res.StatusCode}");
- throw new Exception($"Failed to leave room {RoomId} - got status: {res.StatusCode}");
- }
- }
- public async Task KickAsync(string userId, string? reason = null) {
- var res = await _httpClient.PostAsJsonAsync($"/_matrix/client/v3/rooms/{RoomId}/kick",
+ public async Task KickAsync(string userId, string? reason = null) =>
+ await _httpClient.PostAsJsonAsync($"/_matrix/client/v3/rooms/{RoomId}/kick",
new UserIdAndReason() { UserId = userId, Reason = reason });
- if (!res.IsSuccessStatusCode) {
- Console.WriteLine($"Failed to kick {userId} from room {RoomId} - got status: {res.StatusCode}");
- throw new Exception($"Failed to kick {userId} from room {RoomId} - got status: {res.StatusCode}");
- }
- }
- public async Task BanAsync(string userId, string? reason = null) {
- var res = await _httpClient.PostAsJsonAsync($"/_matrix/client/v3/rooms/{RoomId}/ban",
+ public async Task BanAsync(string userId, string? reason = null) =>
+ await _httpClient.PostAsJsonAsync($"/_matrix/client/v3/rooms/{RoomId}/ban",
new UserIdAndReason() { UserId = userId, Reason = reason });
- if (!res.IsSuccessStatusCode) {
- Console.WriteLine($"Failed to ban {userId} from room {RoomId} - got status: {res.StatusCode}");
- throw new Exception($"Failed to ban {userId} from room {RoomId} - got status: {res.StatusCode}");
- }
- }
- public async Task UnbanAsync(string userId) {
- var res = await _httpClient.PostAsJsonAsync($"/_matrix/client/v3/rooms/{RoomId}/unban",
+ public async Task UnbanAsync(string userId) =>
+ await _httpClient.PostAsJsonAsync($"/_matrix/client/v3/rooms/{RoomId}/unban",
new UserIdAndReason() { UserId = userId });
- if (!res.IsSuccessStatusCode) {
- Console.WriteLine($"Failed to unban {userId} from room {RoomId} - got status: {res.StatusCode}");
- throw new Exception($"Failed to unban {userId} from room {RoomId} - got status: {res.StatusCode}");
- }
- }
-
- public async Task<EventIdResponse> SendStateEventAsync(string eventType, object content) {
- var res = await _httpClient.PostAsJsonAsync($"/_matrix/client/v3/rooms/{RoomId}/state/{eventType}", content);
- if (!res.IsSuccessStatusCode) {
- Console.WriteLine(
- $"Failed to send state event {eventType} to room {RoomId} - got status: {res.StatusCode}");
- throw new Exception(
- $"Failed to send state event {eventType} to room {RoomId} - got status: {res.StatusCode}");
- }
- return await res.Content.ReadFromJsonAsync<EventIdResponse>();
- }
+ public async Task<EventIdResponse> SendStateEventAsync(string eventType, object content) =>
+ await (await _httpClient.PostAsJsonAsync($"/_matrix/client/v3/rooms/{RoomId}/state/{eventType}", content))
+ .Content.ReadFromJsonAsync<EventIdResponse>();
public async Task<EventIdResponse> SendMessageEventAsync(string eventType, MessageEventData content) {
- var url = $"/_matrix/client/v3/rooms/{RoomId}/send/{eventType}/" + Guid.NewGuid();
- var res = await _httpClient.PutAsJsonAsync(url, content);
- if (!res.IsSuccessStatusCode) {
- Console.WriteLine($"Failed to send event {eventType} to room {RoomId} - got status: {res.StatusCode}");
- throw new Exception($"Failed to send event {eventType} to room {RoomId} - got status: {res.StatusCode}");
- }
-
+ var res = await _httpClient.PutAsJsonAsync(
+ $"/_matrix/client/v3/rooms/{RoomId}/send/{eventType}/" + Guid.NewGuid(), content);
var resu = await res.Content.ReadFromJsonAsync<EventIdResponse>();
-
return resu;
}
public async Task<EventIdResponse> SendFileAsync(string eventType, string fileName, Stream fileStream) {
- var url = $"/_matrix/client/v3/rooms/{RoomId}/send/{eventType}/" + Guid.NewGuid();
var content = new MultipartFormDataContent();
content.Add(new StreamContent(fileStream), "file", fileName);
- var res = await _httpClient.PutAsync(url, content);
- if (!res.IsSuccessStatusCode) {
- Console.WriteLine($"Failed to send event {eventType} to room {RoomId} - got status: {res.StatusCode}");
- throw new Exception($"Failed to send event {eventType} to room {RoomId} - got status: {res.StatusCode}");
- }
-
- var resu = await res.Content.ReadFromJsonAsync<EventIdResponse>();
-
- return resu;
+ var res = await
+ (
+ await _httpClient.PutAsync(
+ $"/_matrix/client/v3/rooms/{RoomId}/send/{eventType}/" + Guid.NewGuid(),
+ content
+ )
+ )
+ .Content.ReadFromJsonAsync<EventIdResponse>();
+ return res;
}
public readonly SpaceRoom AsSpace;
|