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);
}
|