MatrixRoomUtils

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | LICENSE

Room.cs (5901B)


      1 using System.Diagnostics.CodeAnalysis;
      2 using System.Net.Http.Json;
      3 using System.Reflection;
      4 using System.Text.Json;
      5 using System.Text.Json.Serialization;
      6 using System.Web;
      7 using MatrixRoomUtils.Core.Extensions;
      8 
      9 namespace MatrixRoomUtils.Core;
     10 
     11 public class Room
     12 {
     13     private readonly HttpClient _httpClient;
     14     public string RoomId { get; set; }
     15 
     16     public Room(HttpClient httpClient, string roomId)
     17     {
     18         _httpClient = httpClient;
     19         RoomId = roomId;
     20     }
     21 
     22     public async Task<JsonElement?> GetStateAsync(string type, string stateKey = "", bool logOnFailure = true)
     23     {
     24         var url = $"/_matrix/client/v3/rooms/{RoomId}/state";
     25         if (!string.IsNullOrEmpty(type)) url += $"/{type}";
     26         if (!string.IsNullOrEmpty(stateKey)) url += $"/{stateKey}";
     27 
     28         var res = await _httpClient.GetAsync(url);
     29         if (!res.IsSuccessStatusCode)
     30         {
     31             if (logOnFailure) Console.WriteLine($"{RoomId}/{stateKey}/{type} - got status: {res.StatusCode}");
     32             return null;
     33         }
     34 
     35         var result = await res.Content.ReadFromJsonAsync<JsonElement>();
     36         return result;
     37     }
     38 
     39     public async Task<T?> GetStateAsync<T>(string type, string stateKey = "", bool logOnFailure = false)
     40     {
     41         var res = await GetStateAsync(type, stateKey, logOnFailure);
     42         if (res == null) return default;
     43         return res.Value.Deserialize<T>();
     44     }
     45 
     46     public async Task<string> GetNameAsync()
     47     {
     48         var res = await GetStateAsync("m.room.name");
     49         if (!res.HasValue)
     50         {
     51             Console.WriteLine($"Room {RoomId} has no name!");
     52             return RoomId;
     53         }
     54 
     55         var resn = res?.TryGetProperty("name", out var name) ?? false ? name.GetString() ?? RoomId : RoomId;
     56         //Console.WriteLine($"Got name: {resn}");
     57         return resn;
     58     }
     59 
     60     public async Task JoinAsync(string[]? homeservers = null)
     61     {
     62         string join_url = $"/_matrix/client/r0/join/{HttpUtility.UrlEncode(RoomId)}";
     63         Console.WriteLine($"Calling {join_url} with {homeservers?.Length ?? 0} via's...");
     64         if (homeservers == null || homeservers.Length == 0) homeservers = new[] { RoomId.Split(':')[1] };
     65         var fullJoinUrl = $"{join_url}?server_name=" + string.Join("&server_name=", homeservers);
     66         var res = await _httpClient.PostAsync(fullJoinUrl, null);
     67     }
     68 
     69     public async Task<List<string>> GetMembersAsync(bool joinedOnly = true)
     70     {
     71         var res = await GetStateAsync("");
     72         if (!res.HasValue) return new List<string>();
     73         var members = new List<string>();
     74         foreach (var member in res.Value.EnumerateArray())
     75         {
     76             if (member.GetProperty("type").GetString() != "m.room.member") continue;
     77             if (joinedOnly && member.GetProperty("content").GetProperty("membership").GetString() != "join") continue;
     78             var memberId = member.GetProperty("state_key").GetString();
     79             members.Add(memberId ?? throw new InvalidOperationException("Event type was member but state key was null!"));
     80         }
     81 
     82         return members;
     83     }
     84 
     85     public async Task<List<string>> GetAliasesAsync()
     86     {
     87         var res = await GetStateAsync("m.room.aliases");
     88         if (!res.HasValue) return new List<string>();
     89         var aliases = new List<string>();
     90         foreach (var alias in res.Value.GetProperty("aliases").EnumerateArray())
     91         {
     92             aliases.Add(alias.GetString() ?? "");
     93         }
     94 
     95         return aliases;
     96     }
     97 
     98     public async Task<string> GetCanonicalAliasAsync()
     99     {
    100         var res = await GetStateAsync("m.room.canonical_alias");
    101         if (!res.HasValue) return "";
    102         return res.Value.GetProperty("alias").GetString() ?? "";
    103     }
    104 
    105     public async Task<string> GetTopicAsync()
    106     {
    107         var res = await GetStateAsync("m.room.topic");
    108         if (!res.HasValue) return "";
    109         return res.Value.GetProperty("topic").GetString() ?? "";
    110     }
    111 
    112     public async Task<string> GetAvatarUrlAsync()
    113     {
    114         var res = await GetStateAsync("m.room.avatar");
    115         if (!res.HasValue) return "";
    116         return res.Value.GetProperty("url").GetString() ?? "";
    117     }
    118 
    119     public async Task<JoinRules> GetJoinRuleAsync()
    120     {
    121         var res = await GetStateAsync("m.room.join_rules");
    122         if (!res.HasValue) return new JoinRules();
    123         return res.Value.Deserialize<JoinRules>() ?? new JoinRules();
    124     }
    125 
    126     public async Task<string> GetHistoryVisibilityAsync()
    127     {
    128         var res = await GetStateAsync("m.room.history_visibility");
    129         if (!res.HasValue) return "";
    130         return res.Value.GetProperty("history_visibility").GetString() ?? "";
    131     }
    132 
    133     public async Task<string> GetGuestAccessAsync()
    134     {
    135         var res = await GetStateAsync("m.room.guest_access");
    136         if (!res.HasValue) return "";
    137         return res.Value.GetProperty("guest_access").GetString() ?? "";
    138     }
    139 
    140     public async Task<CreateEvent> GetCreateEventAsync()
    141     {
    142         var res = await GetStateAsync("m.room.create");
    143         if (!res.HasValue) return new CreateEvent();
    144 
    145         res.FindExtraJsonFields(typeof(CreateEvent));
    146 
    147         return res.Value.Deserialize<CreateEvent>() ?? new CreateEvent();
    148     }
    149 }
    150 
    151 public class CreateEvent
    152 {
    153     [JsonPropertyName("creator")] public string Creator { get; set; }
    154     [JsonPropertyName("room_version")] public string RoomVersion { get; set; }
    155     [JsonPropertyName("type")] public string? Type { get; set; }
    156     [JsonPropertyName("predecessor")] public object? Predecessor { get; set; }
    157     [JsonPropertyName("m.federate")] public bool Federate { get; set; }
    158 }
    159 
    160 public class JoinRules
    161 {
    162     private const string Public = "public";
    163     private const string Invite = "invite";
    164     private const string Knock = "knock";
    165 
    166     [JsonPropertyName("join_rule")] public string JoinRule { get; set; }
    167     [JsonPropertyName("allow")] public List<string> Allow { get; set; }
    168 }