about summary refs log tree commit diff
path: root/MatrixContentFilter/Handlers/Filters/Generic
diff options
context:
space:
mode:
authorRory& <root@rory.gay>2025-03-12 19:52:15 +0100
committerRory& <root@rory.gay>2025-03-12 19:52:15 +0100
commitbdf058ab5c936463a022f62ffbb55bb71c26e856 (patch)
tree69914accad80f10dd8d87e3738e820c58f042537 /MatrixContentFilter/Handlers/Filters/Generic
parentInitial commit (diff)
downloadMatrixContentFilter-master.tar.xz
More work HEAD master
Diffstat (limited to 'MatrixContentFilter/Handlers/Filters/Generic')
-rw-r--r--MatrixContentFilter/Handlers/Filters/Generic/BasicMessageTypeFilter.cs88
-rw-r--r--MatrixContentFilter/Handlers/Filters/Generic/GenericEventTypeFilter.cs86
2 files changed, 174 insertions, 0 deletions
diff --git a/MatrixContentFilter/Handlers/Filters/Generic/BasicMessageTypeFilter.cs b/MatrixContentFilter/Handlers/Filters/Generic/BasicMessageTypeFilter.cs
new file mode 100644

index 0000000..2a9c674 --- /dev/null +++ b/MatrixContentFilter/Handlers/Filters/Generic/BasicMessageTypeFilter.cs
@@ -0,0 +1,88 @@ +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.Generic; + +public abstract class BasicMessageTypeFilter( + ConfigurationService cfgService, + AuthenticatedHomeserverGeneric hs, + AsyncMessageQueue msgQueue, + InfoCacheService infoCache, + AbstractAsyncActionQueue actionQueue, + MatrixContentFilterMetrics metrics) + : IContentFilter { + private protected string MessageType = null!; + private protected string MessageTypeName = null!; + private protected string MessageTypeNamePlural = null!; + + public override Task ProcessSyncAsync(SyncResponse syncResponse) { + if (syncResponse.Rooms?.Join is null) return Task.CompletedTask; + var tasks = syncResponse.Rooms.Join.Select(ProcessRoomAsync); + return Task.WhenAll(tasks); + } + + private Task ProcessRoomAsync(KeyValuePair<string, SyncResponse.RoomsDataStructure.JoinedRoomDataStructure> syncRoom) { + var (roomId, roomData) = syncRoom; + if (roomId == cfgService.LogRoom.RoomId || roomId == cfgService.ControlRoom.RoomId) return Task.CompletedTask; + if (roomData.Timeline?.Events is null) return Task.CompletedTask; + var config = cfgService.RoomConfigurationOverrides.GetValueOrDefault(roomId)?.ImageFilter; + + var room = hs.GetRoom(roomId); + + var tasks = roomData.Timeline.Events.Select(msg => ProcessEventAsync(room, msg, config)); + return Task.WhenAll(tasks); + } + + public override 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)).ToList(); + await Task.WhenAll(tasks); + }); + + return 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 != MessageType) return; + metrics.Increment(MessageTypeName + "_filter_processed_event_count"); + + await actionQueue.EqueueActionAsync(msg.EventId, async () => { + while (true) { + try { + Console.WriteLine("Redacting {0} message: {1}", MessageTypeName, msg.EventId); + await room.RedactEventAsync(msg.EventId ?? throw new ArgumentException("Event ID is null?"), $"Not allowed to send {MessageTypeNamePlural} in this room!"); + break; + } + catch (Exception e) { + msgQueue.EnqueueMessageAsync(cfgService.LogRoom, new MessageBuilder("m.notice") + .WithBody($"Error redacting {MessageTypeName} 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($"{MessageTypeName[0].ToString().ToUpper() + MessageTypeName[1..]} 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++; + } +} \ No newline at end of file diff --git a/MatrixContentFilter/Handlers/Filters/Generic/GenericEventTypeFilter.cs b/MatrixContentFilter/Handlers/Filters/Generic/GenericEventTypeFilter.cs new file mode 100644
index 0000000..64e4cff --- /dev/null +++ b/MatrixContentFilter/Handlers/Filters/Generic/GenericEventTypeFilter.cs
@@ -0,0 +1,86 @@ +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.Generic; + +public abstract class GenericEventTypeFilter( + ConfigurationService cfgService, + AuthenticatedHomeserverGeneric hs, + AsyncMessageQueue msgQueue, + InfoCacheService infoCache, + AbstractAsyncActionQueue actionQueue, + MatrixContentFilterMetrics metrics) + : IContentFilter { + private protected abstract string? GetEventType(); + + public override Task ProcessSyncAsync(SyncResponse syncResponse) { + if (syncResponse.Rooms?.Join is null) return Task.CompletedTask; + var tasks = syncResponse.Rooms.Join.Select(ProcessRoomAsync); + return Task.WhenAll(tasks); + } + + private Task ProcessRoomAsync(KeyValuePair<string, SyncResponse.RoomsDataStructure.JoinedRoomDataStructure> syncRoom) { + var (roomId, roomData) = syncRoom; + if (roomId == cfgService.LogRoom.RoomId || roomId == cfgService.ControlRoom.RoomId) return Task.CompletedTask; + if (roomData.Timeline?.Events is null) return Task.CompletedTask; + var config = cfgService.RoomConfigurationOverrides.GetValueOrDefault(roomId)?.ImageFilter; + + var room = hs.GetRoom(roomId); + + var tasks = roomData.Timeline.Events.Select(msg => ProcessEventAsync(room, msg, config)); + return Task.WhenAll(tasks); + } + + public override 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)).ToList(); + await Task.WhenAll(tasks); + }); + + return 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 != GetEventType()) return; + metrics.Increment(GetMetricsPrefix() + "_filter_processed_event_count"); + + await actionQueue.EqueueActionAsync(msg.EventId, async () => { + while (true) { + try { + Console.WriteLine("Redacting {0} message: {1}", MessageTypeName, msg.EventId); + await room.RedactEventAsync(msg.EventId ?? throw new ArgumentException("Event ID is null?"), $"Not allowed to send {MessageTypeNamePlural} in this room!"); + break; + } + catch (Exception e) { + msgQueue.EnqueueMessageAsync(cfgService.LogRoom, new MessageBuilder("m.notice") + .WithBody($"Error redacting {MessageTypeName} 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($"{MessageTypeName[0].ToString().ToUpper() + MessageTypeName[1..]} 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++; + } +} \ No newline at end of file