From 7a1f8b51779ed8a6112fc83d13d81c3efdf792b7 Mon Sep 17 00:00:00 2001 From: Rory& Date: Thu, 13 Mar 2025 11:50:16 +0100 Subject: Initial commit --- MatrixInviteLogger/InviteLogger.cs | 117 +++++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 MatrixInviteLogger/InviteLogger.cs (limited to 'MatrixInviteLogger/InviteLogger.cs') diff --git a/MatrixInviteLogger/InviteLogger.cs b/MatrixInviteLogger/InviteLogger.cs new file mode 100644 index 0000000..22a519b --- /dev/null +++ b/MatrixInviteLogger/InviteLogger.cs @@ -0,0 +1,117 @@ +using System.Text.Json; +using System.Text.Json.Nodes; +using ArcaneLibs; +using ArcaneLibs.Extensions; +using LibMatrix.EventTypes.Spec.State.RoomInfo; +using LibMatrix.Helpers; +using LibMatrix.Utilities.Bot.Services; +using MatrixInviteLogger; + +public class InviteLogger(ILogger logger, InviteLoggerConfiguration config) : InviteHandlerHostedService.IInviteHandler +{ + public async Task HandleInviteAsync(InviteHandlerHostedService.InviteEventArgs invite) + { + logger.LogInformation("Received invite to room {}", invite.RoomId); + var logRoom = invite.Homeserver.GetRoom(config.LogRoom); + var inviterName = await GetInviterNameAsync(invite); + string roomName = await GetRoomNameAsync(invite); + + logger.LogInformation("Inviter: {}, Room: {}", inviterName, roomName); + + var message = new MessageBuilder() + .WithBody("Received invite to ").WithMention(invite.RoomId, roomName).WithBody(" from ").WithMention(invite.MemberEvent.Sender!, inviterName) + .Build(); + + // TODO: can we filter this somehow to stay within event size limits? + // var serialisedInviteData = JsonNode.Parse(invite.InviteData.ToJson(ignoreNull: true)); + // message.AdditionalData!["gay.rory.invite_logger.invite_data"] = serialisedInviteData!; + + var inviteData = invite.InviteData.ToJsonUtf8Bytes(); + var inviteDataFileUri = await invite.Homeserver.UploadFile(invite.RoomId + ".json", inviteData, "application/json"); + logger.LogInformation("Uploaded invite data ({}) to {}", Util.BytesToString(inviteData.Length), inviteDataFileUri); + + // Dictionary + message.AdditionalData!["gay.rory.invite_logger.invite_data_uri"] = JsonDocument.Parse($"\"{inviteDataFileUri}\"").RootElement; + + await logRoom.SendMessageEventAsync(message); + + if (config.SendInviteDataAsFile) + { + await logRoom.SendMessageEventAsync(new() + { + MessageType = "m.file", + Body = invite.RoomId + ".json", + FileName = invite.RoomId + ".json", + Url = inviteDataFileUri, + FileInfo = new() { Size = inviteData.Length, MimeType = "application/json" } + }); + } + } + + private async Task GetInviterNameAsync(InviteHandlerHostedService.InviteEventArgs invite) + { + var name = invite.InviteData.InviteState?.Events? + .FirstOrDefault(evt => evt is { Type: RoomMemberEventContent.EventId } && evt.StateKey == invite.MemberEvent.Sender)? + .ContentAs()?.DisplayName; + + if (!string.IsNullOrWhiteSpace(name)) + return name; + + try + { + await invite.Homeserver.GetProfileAsync(invite.MemberEvent.Sender!); + } + catch + { + //ignored + } + + return invite.MemberEvent.Sender!; + } + + private async Task GetRoomNameAsync(InviteHandlerHostedService.InviteEventArgs invite) + { + // try get room name from invite state + var name = invite.InviteData.InviteState?.Events? + .FirstOrDefault(evt => evt is { Type: RoomNameEventContent.EventId, StateKey: "" })? + .ContentAs()?.Name; + + if (!string.IsNullOrWhiteSpace(name)) + return name; + + // try get room alias + var alias = invite.InviteData.InviteState?.Events? + .FirstOrDefault(evt => evt is { Type: RoomCanonicalAliasEventContent.EventId, StateKey: "" })? + .ContentAs()?.Alias; + + if (!string.IsNullOrWhiteSpace(alias)) + return alias; + + // try get room name via public previews + try + { + name = await invite.Homeserver.GetRoom(invite.RoomId).GetNameOrFallbackAsync(); + if (name != invite.RoomId && !string.IsNullOrWhiteSpace(name)) + return name; + } + catch + { + //ignored + } + + // fallback to room alias via public previews + try + { + alias = (await invite.Homeserver.GetRoom(invite.RoomId).GetCanonicalAliasAsync())?.Alias; + if (!string.IsNullOrWhiteSpace(alias)) + return alias; + } + catch + { + //ignored + } + + // fall back to room ID + return invite.RoomId; + } +} \ No newline at end of file -- cgit 1.5.1