diff options
Diffstat (limited to 'Utilities')
7 files changed, 132 insertions, 27 deletions
diff --git a/Utilities/LibMatrix.Utilities.Bot/AppServiceConfiguration.cs b/Utilities/LibMatrix.Utilities.Bot/AppServiceConfiguration.cs new file mode 100644 index 0000000..4de139e --- /dev/null +++ b/Utilities/LibMatrix.Utilities.Bot/AppServiceConfiguration.cs @@ -0,0 +1,87 @@ +namespace PluralContactBotPoC; + +public class AppServiceConfiguration { + public string Id { get; set; } = null!; + public string? Url { get; set; } = null!; + public string SenderLocalpart { get; set; } = null!; + public string AppserviceToken { get; set; } = null!; + public string HomeserverToken { get; set; } = null!; + public List<string>? Protocols { get; set; } = null!; + public bool? RateLimited { get; set; } = null!; + + public AppserviceNamespaces Namespaces { get; set; } = null!; + + public class AppserviceNamespaces { + public List<AppserviceNamespace>? Users { get; set; } = null; + public List<AppserviceNamespace>? Aliases { get; set; } = null; + public List<AppserviceNamespace>? Rooms { get; set; } = null; + + public class AppserviceNamespace { + public bool Exclusive { get; set; } + public string Regex { get; set; } = null!; + } + } + + /// <summary> + /// Please dont look at code, it's horrifying but works + /// </summary> + /// <returns></returns> + public string ToYaml() { + var yaml = $""" + id: "{Id ?? throw new NullReferenceException("Id is null")}" + url: {(Url is null ? "null" : $"\"{Url}\"")} + as_token: "{AppserviceToken ?? throw new NullReferenceException("AppserviceToken is null")}" + hs_token: "{HomeserverToken ?? throw new NullReferenceException("HomeserverToken is null")}" + sender_localpart: "{SenderLocalpart ?? throw new NullReferenceException("SenderLocalpart is null")}" + + """; + + if (Protocols is not null && Protocols.Count > 0) + yaml += $""" + protocols: + - "{Protocols[0] ?? throw new NullReferenceException("Protocols[0] is null")}" + """; + else + yaml += "protocols: []"; + yaml += "\n"; + if (RateLimited is not null) + yaml += $"rate_limited: {RateLimited!.ToString().ToLower()}\n"; + else + yaml += "rate_limited: false\n"; + + yaml += "namespaces: \n"; + + if (Namespaces.Users is null || Namespaces.Users.Count == 0) + yaml += " users: []"; + else + Namespaces.Users.ForEach(x => + yaml += $""" + users: + - exclusive: {x.Exclusive.ToString().ToLower()} + regex: "{x.Regex ?? throw new NullReferenceException("x.Regex is null")}" + """); + yaml += "\n"; + + if (Namespaces.Aliases is null || Namespaces.Aliases.Count == 0) + yaml += " aliases: []"; + else + Namespaces.Aliases.ForEach(x => + yaml += $""" + aliases: + - exclusive: {x.Exclusive.ToString().ToLower()} + regex: "{x.Regex ?? throw new NullReferenceException("x.Regex is null")}" + """); + yaml += "\n"; + if (Namespaces.Rooms is null || Namespaces.Rooms.Count == 0) + yaml += " rooms: []"; + else + Namespaces.Rooms.ForEach(x => + yaml += $""" + rooms: + - exclusive: {x.Exclusive.ToString().ToLower()} + regex: "{x.Regex ?? throw new NullReferenceException("x.Regex is null")}" + """); + + return yaml; + } +} diff --git a/Utilities/LibMatrix.Utilities.Bot/BotCommandInstaller.cs b/Utilities/LibMatrix.Utilities.Bot/BotCommandInstaller.cs index 42cdb6c..a13f1bd 100644 --- a/Utilities/LibMatrix.Utilities.Bot/BotCommandInstaller.cs +++ b/Utilities/LibMatrix.Utilities.Bot/BotCommandInstaller.cs @@ -22,7 +22,7 @@ public static class BotCommandInstaller { return services; } - public static IServiceCollection AddBot(this IServiceCollection services, bool withCommands = true) { + public static IServiceCollection AddBot(this IServiceCollection services, bool withCommands = true, bool isAppservice = false) { services.AddSingleton<LibMatrixBotConfiguration>(); services.AddScoped<AuthenticatedHomeserverGeneric>(x => { diff --git a/Utilities/LibMatrix.Utilities.Bot/Commands/HelpCommand.cs b/Utilities/LibMatrix.Utilities.Bot/Commands/HelpCommand.cs index c975c8b..de033ef 100644 --- a/Utilities/LibMatrix.Utilities.Bot/Commands/HelpCommand.cs +++ b/Utilities/LibMatrix.Utilities.Bot/Commands/HelpCommand.cs @@ -17,6 +17,6 @@ public class HelpCommand(IServiceProvider services) : ICommand { sb.AppendLine($"- {command.Name}: {command.Description}"); } - await ctx.Room.SendMessageEventAsync("m.room.message", new RoomMessageEventData(messageType: "m.notice", body: sb.ToString())); + await ctx.Room.SendMessageEventAsync("m.room.message", new RoomMessageEventContent(messageType: "m.notice", body: sb.ToString())); } } diff --git a/Utilities/LibMatrix.Utilities.Bot/Commands/PingCommand.cs b/Utilities/LibMatrix.Utilities.Bot/Commands/PingCommand.cs index e7f3b10..b008be9 100644 --- a/Utilities/LibMatrix.Utilities.Bot/Commands/PingCommand.cs +++ b/Utilities/LibMatrix.Utilities.Bot/Commands/PingCommand.cs @@ -8,6 +8,6 @@ public class PingCommand : ICommand { public string Description { get; } = "Pong!"; public async Task Invoke(CommandContext ctx) { - await ctx.Room.SendMessageEventAsync("m.room.message", new RoomMessageEventData(body: "pong!")); + await ctx.Room.SendMessageEventAsync("m.room.message", new RoomMessageEventContent(body: "pong!")); } } diff --git a/Utilities/LibMatrix.Utilities.Bot/Interfaces/CommandContext.cs b/Utilities/LibMatrix.Utilities.Bot/Interfaces/CommandContext.cs index 0ad3e09..bdb93d5 100644 --- a/Utilities/LibMatrix.Utilities.Bot/Interfaces/CommandContext.cs +++ b/Utilities/LibMatrix.Utilities.Bot/Interfaces/CommandContext.cs @@ -1,3 +1,4 @@ +using LibMatrix; using LibMatrix.Homeservers; using LibMatrix.Responses; using LibMatrix.RoomTypes; @@ -10,7 +11,7 @@ public class CommandContext { public StateEventResponse MessageEvent { get; set; } public string MessageContentWithoutReply => - (MessageEvent.TypedContent as RoomMessageEventData)! + (MessageEvent.TypedContent as RoomMessageEventContent)! .Body.Split('\n') .SkipWhile(x => x.StartsWith(">")) .Aggregate((x, y) => $"{x}\n{y}"); @@ -18,4 +19,6 @@ public class CommandContext { public string CommandName => MessageContentWithoutReply.Split(' ')[0][1..]; public string[] Args => MessageContentWithoutReply.Split(' ')[1..]; public AuthenticatedHomeserverGeneric Homeserver { get; set; } + + public async Task<EventIdResponse> Reply(string eventType, RoomMessageEventContent content) => await Room.SendMessageEventAsync(eventType, content); } diff --git a/Utilities/LibMatrix.Utilities.Bot/LibMatrixBotConfiguration.cs b/Utilities/LibMatrix.Utilities.Bot/LibMatrixBotConfiguration.cs index 118b4df..27ce06b 100644 --- a/Utilities/LibMatrix.Utilities.Bot/LibMatrixBotConfiguration.cs +++ b/Utilities/LibMatrix.Utilities.Bot/LibMatrixBotConfiguration.cs @@ -7,4 +7,5 @@ public class LibMatrixBotConfiguration { public string Homeserver { get; set; } = ""; public string AccessToken { get; set; } = ""; public string Prefix { get; set; } = "?"; + public string? LogRoom { get; set; } } diff --git a/Utilities/LibMatrix.Utilities.Bot/Services/CommandListenerHostedService.cs b/Utilities/LibMatrix.Utilities.Bot/Services/CommandListenerHostedService.cs index d5e7dd6..df702f4 100644 --- a/Utilities/LibMatrix.Utilities.Bot/Services/CommandListenerHostedService.cs +++ b/Utilities/LibMatrix.Utilities.Bot/Services/CommandListenerHostedService.cs @@ -1,3 +1,4 @@ +using LibMatrix.Helpers; using LibMatrix.Homeservers; using LibMatrix.StateEventTypes.Spec; using MediaModeratorPoC.Bot.Interfaces; @@ -37,34 +38,47 @@ public class CommandListenerHostedService : IHostedService { private async Task? Run(CancellationToken cancellationToken) { _logger.LogInformation("Starting command listener!"); _hs.SyncHelper.TimelineEventHandlers.Add(async @event => { - var room = await _hs.GetRoom(@event.RoomId); - // _logger.LogInformation(eventResponse.ToJson(indent: false)); - if (@event is { Type: "m.room.message", TypedContent: RoomMessageEventData message }) { - if (message is { MessageType: "m.text" }) { - var messageContentWithoutReply = message.Body.Split('\n', StringSplitOptions.RemoveEmptyEntries).SkipWhile(x=>x.StartsWith(">")).Aggregate((x, y) => $"{x}\n{y}"); - if (messageContentWithoutReply.StartsWith(_config.Prefix)) { - var command = _commands.FirstOrDefault(x => x.Name == messageContentWithoutReply.Split(' ')[0][_config.Prefix.Length..]); - if (command == null) { - await room.SendMessageEventAsync("m.room.message", - new RoomMessageEventData(messageType: "m.notice", body: "Command not found!")); - return; - } + try { + var room = await _hs.GetRoom(@event.RoomId); + // _logger.LogInformation(eventResponse.ToJson(indent: false)); + if (@event is { Type: "m.room.message", TypedContent: RoomMessageEventContent message }) { + if (message is { MessageType: "m.text" }) { + var messageContentWithoutReply = + message.Body.Split('\n', StringSplitOptions.RemoveEmptyEntries).SkipWhile(x => x.StartsWith(">")).Aggregate((x, y) => $"{x}\n{y}"); + if (messageContentWithoutReply.StartsWith(_config.Prefix)) { + var command = _commands.FirstOrDefault(x => x.Name == messageContentWithoutReply.Split(' ')[0][_config.Prefix.Length..]); + if (command == null) { + await room.SendMessageEventAsync("m.room.message", + new RoomMessageEventContent(messageType: "m.notice", body: "Command not found!")); + return; + } - var ctx = new CommandContext { - Room = room, - MessageEvent = @event, - Homeserver = _hs - }; - if (await command.CanInvoke(ctx)) { - await command.Invoke(ctx); - } - else { - await room.SendMessageEventAsync("m.room.message", - new RoomMessageEventData(messageType: "m.notice", body: "You do not have permission to run this command!")); + var ctx = new CommandContext { + Room = room, + MessageEvent = @event, + Homeserver = _hs + }; + + if (await command.CanInvoke(ctx)) { + try { + await command.Invoke(ctx); + } + catch (Exception e) { + await room.SendMessageEventAsync("m.room.message", + MessageFormatter.FormatException("An error occurred during the execution of this command", e)); + } + } + else { + await room.SendMessageEventAsync("m.room.message", + new RoomMessageEventContent(messageType: "m.notice", body: "You do not have permission to run this command!")); + } } } } } + catch (Exception e) { + _logger.LogError(e, "Error in command listener!"); + } }); await _hs.SyncHelper.RunSyncLoop(cancellationToken: cancellationToken); } |