about summary refs log tree commit diff
path: root/MatrixContentFilter/Handlers
diff options
context:
space:
mode:
Diffstat (limited to 'MatrixContentFilter/Handlers')
-rw-r--r--MatrixContentFilter/Handlers/CommandResultHandler.cs40
-rw-r--r--MatrixContentFilter/Handlers/Filters/ImageFilter.cs92
-rw-r--r--MatrixContentFilter/Handlers/InviteHandler.cs29
3 files changed, 161 insertions, 0 deletions
diff --git a/MatrixContentFilter/Handlers/CommandResultHandler.cs b/MatrixContentFilter/Handlers/CommandResultHandler.cs
new file mode 100644

index 0000000..f05d2bb --- /dev/null +++ b/MatrixContentFilter/Handlers/CommandResultHandler.cs
@@ -0,0 +1,40 @@ +using ArcaneLibs; +using LibMatrix.Helpers; +using LibMatrix.Utilities.Bot.Interfaces; + +namespace MatrixContentFilter.Handlers; + +public static class CommandResultHandler { + private static string binDir = FileUtils.GetBinDir(); + + public static async Task HandleAsync(CommandResult res) { + { + if (res.Success) return; + var room = res.Context.Room; + var hs = res.Context.Homeserver; + var msb = new MessageBuilder(); + if (res.Result == CommandResult.CommandResultType.Failure_Exception) { + var angryEmojiPath = Path.Combine(binDir, "Resources", "Stickers", "JennyAngryPink.webp"); + var hash = await FileUtils.GetFileSha384Async(angryEmojiPath); + var angryEmoji = await hs.NamedCaches.FileCache.GetOrSetValueAsync(hash, async () => { + await using var fs = File.OpenRead(angryEmojiPath); + return await hs.UploadFile("JennyAngryPink.webp", fs, "image/webp"); + }); + msb.WithCustomEmoji(angryEmoji, "JennyAngryPink") + .WithColoredBody("#EE4444", "An error occurred during the execution of this command") + .WithCodeBlock(res.Exception!.ToString(), "csharp"); + } + // else if(res.Result == CommandResult.CommandResultType.) { + // msb.AddMessage(new RoomMessageEventContent("m.notice", "An error occurred during the execution of this command")); + // } + // var msg = res.Result switch { + // CommandResult.CommandResultType.Failure_Exception => MessageFormatter.FormatException("An error occurred during the execution of this command", res.Exception!) + // CommandResult.CommandResultType.Failure_NoPermission => new RoomMessageEventContent("m.notice", "You do not have permission to run this command!"), + // CommandResult.CommandResultType.Failure_InvalidCommand => new RoomMessageEventContent("m.notice", $"Command \"{res.Context.CommandName}\" not found!"), + // _ => throw new ArgumentOutOfRangeException() + // }; + + await room.SendMessageEventAsync(msb.Build()); + } + } +} \ No newline at end of file diff --git a/MatrixContentFilter/Handlers/Filters/ImageFilter.cs b/MatrixContentFilter/Handlers/Filters/ImageFilter.cs new file mode 100644
index 0000000..13a68f9 --- /dev/null +++ b/MatrixContentFilter/Handlers/Filters/ImageFilter.cs
@@ -0,0 +1,92 @@ +using System.Runtime.Loader; +using System.Security.Cryptography; +using System.Text.Json.Nodes; +using ArcaneLibs.Collections; +using ArcaneLibs.Extensions; +using LibMatrix; +using LibMatrix.EventTypes.Spec; +using LibMatrix.Helpers; +using LibMatrix.Homeservers; +using LibMatrix.Responses; +using LibMatrix.RoomTypes; +using MatrixContentFilter.Abstractions; +using MatrixContentFilter.EventTypes; +using MatrixContentFilter.Services; +using MatrixContentFilter.Services.AsyncActionQueues; + +namespace MatrixContentFilter.Handlers.Filters; + +public class ImageFilter( + ConfigurationService cfgService, + AuthenticatedHomeserverGeneric hs, + AsyncMessageQueue msgQueue, + InfoCacheService infoCache, + AbstractAsyncActionQueue actionQueue) + : IContentFilter { + public override async Task ProcessSyncAsync(SyncResponse syncResponse) { + Console.WriteLine("Processing image filter"); + if (syncResponse.Rooms?.Join is null) return; + var tasks = syncResponse.Rooms.Join.Select(ProcessRoomAsync); + await Task.WhenAll(tasks); + } + + // private SemaphoreSlim semaphore = new(8, 8); + + private async Task ProcessRoomAsync(KeyValuePair<string, SyncResponse.RoomsDataStructure.JoinedRoomDataStructure> syncRoom) { + var (roomId, roomData) = syncRoom; + if (roomId == cfgService.LogRoom.RoomId || roomId == cfgService.ControlRoom.RoomId) return; + if (roomData.Timeline?.Events is null) return; + var config = cfgService.RoomConfigurationOverrides.GetValueOrDefault(roomId)?.ImageFilter; + + var room = hs.GetRoom(roomId); + + var tasks = roomData.Timeline.Events.Select(msg => ProcessEventAsync(room, msg, config)); + await Task.WhenAll(tasks); + } + + public override async Task ProcessEventListAsync(List<StateEventResponse> events) { + var tasks = events.GroupBy(x => x.RoomId).Select(async x => { + var room = hs.GetRoom(x.Key); + var config = cfgService.RoomConfigurationOverrides.GetValueOrDefault(x.Key)?.ImageFilter; + var tasks = x.Select(msg => ProcessEventAsync(room, msg, config)); + await Task.WhenAll(tasks); + }); + + await Task.WhenAll(tasks); + } + + private async Task ProcessEventAsync(GenericRoom room, StateEventResponse msg, FilterConfiguration.BasicFilterConfiguration roomConfiguration) { + if (msg.Type != "m.room.message") return; + var content = msg.TypedContent as RoomMessageEventContent; + if (content?.MessageType != "m.image") return; + + // await semaphore.WaitAsync(); + + await actionQueue.EqueueActionAsync(msg.EventId, async () => { + while (true) { + try { + Console.WriteLine("Redacting image message: {0}", msg.EventId); + await room.RedactEventAsync(msg.EventId ?? throw new ArgumentException("Event ID is null?"), "Not allowed to send images in this room!"); + break; + } + catch (Exception e) { + msgQueue.EnqueueMessageAsync(cfgService.LogRoom, new MessageBuilder("m.notice") + .WithBody($"Error redacting image message in {room.RoomId}!") + .WithCollapsibleSection("Error data", msb => msb.WithCodeBlock(e.ToString(), "csharp")) + .Build()); + } + } + + var displayName = await infoCache.GetDisplayNameAsync(room.RoomId, msg.Sender); + var roomName = await infoCache.GetRoomNameAsync(room.RoomId); + + msgQueue.EnqueueMessageAsync(cfgService.LogRoom, new MessageBuilder("m.notice") + .WithBody($"Image sent by ").WithMention(msg.Sender, displayName).WithBody(" in ").WithMention(room.RoomId, roomName).WithBody(" was removed!").WithNewline() + .WithCollapsibleSection("Message data", msb => msb.WithCodeBlock(content.ToJson(ignoreNull: true), "json")) + .Build()); + }); + ActionCount++; + + // semaphore.Release(); + } +} \ No newline at end of file diff --git a/MatrixContentFilter/Handlers/InviteHandler.cs b/MatrixContentFilter/Handlers/InviteHandler.cs new file mode 100644
index 0000000..75e5506 --- /dev/null +++ b/MatrixContentFilter/Handlers/InviteHandler.cs
@@ -0,0 +1,29 @@ +using LibMatrix.EventTypes.Spec; +using LibMatrix.Helpers; +using LibMatrix.Utilities.Bot.Services; + +namespace MatrixContentFilter.Handlers; + +public static class InviteHandler { + public static async Task HandleAsync(InviteHandlerHostedService.InviteEventArgs invite) { + var room = invite.Homeserver.GetRoom(invite.RoomId); + if (!invite.MemberEvent.Sender!.EndsWith("rory.gay")) { + await room.LeaveAsync($"{invite.MemberEvent.Sender} is not allowed to invite this bot!"); + return; + } + + try { + await room.JoinAsync(reason: $"I was invited by {invite.MemberEvent.Sender}"); + await room.SendMessageEventAsync(new RoomMessageEventContent("m.notice", "Hello! I've arrived!")); + } catch (Exception e) { + var newroom = await invite.Homeserver.CreateRoom(new() { + Name = $"Join error report", + Invite = [invite.MemberEvent.Sender] + }); + var msb = new MessageBuilder(); + msb.WithColoredBody("#EE4444", $"An error occurred during accepting the invite to {invite.RoomId}") + .WithCodeBlock(e.ToString(), "csharp"); + await newroom.SendMessageEventAsync(msb.Build()); + } + } +} \ No newline at end of file