diff --git a/ExampleBots/LibMatrix.ExampleBot/Bot/MRUBot.cs b/ExampleBots/LibMatrix.ExampleBot/Bot/MRUBot.cs
index 0211f74..8cf4f1f 100644
--- a/ExampleBots/LibMatrix.ExampleBot/Bot/MRUBot.cs
+++ b/ExampleBots/LibMatrix.ExampleBot/Bot/MRUBot.cs
@@ -4,6 +4,7 @@ using LibMatrix.EventTypes.Spec;
using LibMatrix.EventTypes.Spec.State;
using LibMatrix.ExampleBot.Bot.Interfaces;
using LibMatrix.Extensions;
+using LibMatrix.Helpers;
using LibMatrix.Homeservers;
using LibMatrix.Services;
using Microsoft.Extensions.DependencyInjection;
@@ -44,6 +45,8 @@ public class MRUBot : IHostedService {
throw;
}
+ var syncHelper = new SyncHelper(hs);
+
await (hs.GetRoom("!DoHEdFablOLjddKWIp:rory.gay")).JoinAsync();
// foreach (var room in await hs.GetJoinedRooms()) {
@@ -54,7 +57,7 @@ public class MRUBot : IHostedService {
// _logger.LogInformation($"Got room state for {room.RoomId}!");
// }
- hs.SyncHelper.InviteReceivedHandlers.Add(async Task (args) => {
+ syncHelper.InviteReceivedHandlers.Add(async Task (args) => {
var inviteEvent =
args.Value.InviteState.Events.FirstOrDefault(x =>
x.Type == "m.room.member" && x.StateKey == hs.UserId);
@@ -71,7 +74,7 @@ public class MRUBot : IHostedService {
}
}
});
- hs.SyncHelper.TimelineEventHandlers.Add(async @event => {
+ syncHelper.TimelineEventHandlers.Add(async @event => {
_logger.LogInformation(
"Got timeline event in {}: {}", @event.RoomId, @event.ToJson(indent: false, ignoreNull: true));
@@ -100,7 +103,7 @@ public class MRUBot : IHostedService {
}
}
});
- await hs.SyncHelper.RunSyncLoop(cancellationToken: cancellationToken);
+ await syncHelper.RunSyncLoopAsync(cancellationToken: cancellationToken);
}
/// <summary>Triggered when the application host is performing a graceful shutdown.</summary>
diff --git a/ExampleBots/MediaModeratorPoC/Bot/AccountData/BotData.cs b/ExampleBots/MediaModeratorPoC/AccountData/BotData.cs
index b4e1167..0fee4eb 100644
--- a/ExampleBots/MediaModeratorPoC/Bot/AccountData/BotData.cs
+++ b/ExampleBots/MediaModeratorPoC/AccountData/BotData.cs
@@ -1,6 +1,6 @@
using System.Text.Json.Serialization;
-namespace MediaModeratorPoC.Bot.AccountData;
+namespace MediaModeratorPoC.AccountData;
public class BotData {
[JsonPropertyName("control_room")]
@@ -8,7 +8,4 @@ public class BotData {
[JsonPropertyName("log_room")]
public string? LogRoom { get; set; } = "";
-
- [JsonPropertyName("policy_room")]
- public string? PolicyRoom { get; set; } = "";
}
diff --git a/ExampleBots/MediaModeratorPoC/Bot/Commands/BanMediaCommand.cs b/ExampleBots/MediaModeratorPoC/Commands/BanMediaCommand.cs
index fd6866c..69c0583 100644
--- a/ExampleBots/MediaModeratorPoC/Bot/Commands/BanMediaCommand.cs
+++ b/ExampleBots/MediaModeratorPoC/Commands/BanMediaCommand.cs
@@ -1,14 +1,14 @@
using System.Security.Cryptography;
using ArcaneLibs.Extensions;
+using LibMatrix;
using LibMatrix.EventTypes.Spec;
using LibMatrix.Helpers;
-using LibMatrix.Responses;
using LibMatrix.Services;
using LibMatrix.Utilities.Bot.Interfaces;
-using MediaModeratorPoC.Bot.AccountData;
-using MediaModeratorPoC.Bot.StateEventTypes;
+using MediaModeratorPoC.AccountData;
+using MediaModeratorPoC.StateEventTypes;
-namespace MediaModeratorPoC.Bot.Commands;
+namespace MediaModeratorPoC.Commands;
public class BanMediaCommand(IServiceProvider services, HomeserverProviderService hsProvider, HomeserverResolverService hsResolver) : ICommand {
public string Name { get; } = "banmedia";
@@ -16,7 +16,7 @@ public class BanMediaCommand(IServiceProvider services, HomeserverProviderServic
public async Task<bool> CanInvoke(CommandContext ctx) {
//check if user is admin in control room
- var botData = await ctx.Homeserver.GetAccountData<BotData>("gay.rory.media_moderator_poc_data");
+ var botData = await ctx.Homeserver.GetAccountDataAsync<BotData>("gay.rory.modbot_data");
var controlRoom = ctx.Homeserver.GetRoom(botData.ControlRoom);
var isAdmin = (await controlRoom.GetPowerLevelsAsync())!.UserHasPermission(ctx.MessageEvent.Sender, "m.room.ban");
if (!isAdmin) {
@@ -29,7 +29,7 @@ public class BanMediaCommand(IServiceProvider services, HomeserverProviderServic
}
public async Task Invoke(CommandContext ctx) {
- var botData = await ctx.Homeserver.GetAccountData<BotData>("gay.rory.media_moderator_poc_data");
+ var botData = await ctx.Homeserver.GetAccountDataAsync<BotData>("gay.rory.modbot_data");
var policyRoom = ctx.Homeserver.GetRoom(botData.PolicyRoom ?? botData.ControlRoom);
var logRoom = ctx.Homeserver.GetRoom(botData.LogRoom ?? botData.ControlRoom);
@@ -54,7 +54,9 @@ public class BanMediaCommand(IServiceProvider services, HomeserverProviderServic
var recommendation = ctx.Args[0];
if (recommendation is not ("ban" or "kick" or "mute" or "redact" or "spoiler" or "warn" or "warn_admins")) {
- await ctx.Room.SendMessageEventAsync(MessageFormatter.FormatError($"Invalid recommendation type {recommendation}, must be `warn_admins`, `warn`, `spoiler`, `redact`, `mute`, `kick` or `ban`!"));
+ await ctx.Room.SendMessageEventAsync(
+ MessageFormatter.FormatError(
+ $"Invalid recommendation type {recommendation}, must be `warn_admins`, `warn`, `spoiler`, `redact`, `mute`, `kick` or `ban`!"));
return;
}
@@ -70,16 +72,16 @@ public class BanMediaCommand(IServiceProvider services, HomeserverProviderServic
}
catch (Exception ex) {
await logRoom.SendMessageEventAsync(
- MessageFormatter.FormatException($"Error calculating file hash for {mxcUri} via {mxcUri.Split('/')[2]}, retrying via {ctx.Homeserver.HomeServerDomain}...",
+ MessageFormatter.FormatException($"Error calculating file hash for {mxcUri} via {mxcUri.Split('/')[2]}, retrying via {ctx.Homeserver.BaseUrl}...",
ex));
try {
- resolvedUri = await hsResolver.ResolveMediaUri(ctx.Homeserver.HomeServerDomain, mxcUri);
+ resolvedUri = await hsResolver.ResolveMediaUri(ctx.Homeserver.BaseUrl, mxcUri);
fileHash = await hashAlgo.ComputeHashAsync(await ctx.Homeserver._httpClient.GetStreamAsync(resolvedUri));
}
catch (Exception ex2) {
await ctx.Room.SendMessageEventAsync(MessageFormatter.FormatException("Error calculating file hash", ex2));
await logRoom.SendMessageEventAsync(
- MessageFormatter.FormatException($"Error calculating file hash via {ctx.Homeserver.HomeServerDomain}!", ex2));
+ MessageFormatter.FormatException($"Error calculating file hash via {ctx.Homeserver.BaseUrl}!", ex2));
}
}
@@ -98,7 +100,7 @@ public class BanMediaCommand(IServiceProvider services, HomeserverProviderServic
await logRoom.SendMessageEventAsync(MessageFormatter.FormatException("Error creating policy", e));
await ctx.Room.SendMessageEventAsync(MessageFormatter.FormatException("Error creating policy", e));
await using var stream = new MemoryStream(e.ToString().AsBytes().ToArray());
- await logRoom.SendFileAsync("m.file", "error.log.cs", stream);
+ await logRoom.SendFileAsync("error.log.cs", stream);
}
}
else {
diff --git a/ExampleBots/MediaModeratorPoC/Bot/MediaModBot.cs b/ExampleBots/MediaModeratorPoC/MediaModBot.cs
index f9bbcf3..0aacf61 100644
--- a/ExampleBots/MediaModeratorPoC/Bot/MediaModBot.cs
+++ b/ExampleBots/MediaModeratorPoC/MediaModBot.cs
@@ -1,8 +1,4 @@
-using System.Buffers.Text;
-using System.Data;
using System.Security.Cryptography;
-using System.Text;
-using System.Text.Encodings.Web;
using System.Text.RegularExpressions;
using ArcaneLibs.Extensions;
using LibMatrix;
@@ -14,12 +10,12 @@ using LibMatrix.Responses;
using LibMatrix.RoomTypes;
using LibMatrix.Services;
using LibMatrix.Utilities.Bot.Interfaces;
-using MediaModeratorPoC.Bot.AccountData;
-using MediaModeratorPoC.Bot.StateEventTypes;
+using MediaModeratorPoC.AccountData;
+using MediaModeratorPoC.StateEventTypes;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
-namespace MediaModeratorPoC.Bot;
+namespace MediaModeratorPoC;
public class MediaModBot(AuthenticatedHomeserverGeneric hs, ILogger<MediaModBot> logger, MediaModBotConfiguration configuration,
HomeserverResolverService hsResolver) : IHostedService {
@@ -31,6 +27,8 @@ public class MediaModBot(AuthenticatedHomeserverGeneric hs, ILogger<MediaModBot>
private GenericRoom _logRoom;
private GenericRoom _controlRoom;
+
+
/// <summary>Triggered when the application host is ready to start the service.</summary>
/// <param name="cancellationToken">Indicates that the start process has been aborted.</param>
public async Task StartAsync(CancellationToken cancellationToken) {
@@ -44,7 +42,7 @@ public class MediaModBot(AuthenticatedHomeserverGeneric hs, ILogger<MediaModBot>
BotData botData;
try {
- botData = await hs.GetAccountData<BotData>("gay.rory.media_moderator_poc_data");
+ botData = await hs.GetAccountDataAsync<BotData>("gay.rory.modbot_data");
}
catch (Exception e) {
if (e is not MatrixException { ErrorCode: "M_NOT_FOUND" }) {
@@ -63,10 +61,10 @@ public class MediaModBot(AuthenticatedHomeserverGeneric hs, ILogger<MediaModBot>
creationContent.InitialState.Add(new StateEvent {
Type = "m.room.join_rules",
StateKey = "",
- TypedContent = new JoinRulesEventContent {
+ TypedContent = new RoomJoinRulesEventContent {
JoinRule = "knock_restricted",
Allow = new() {
- new JoinRulesEventContent.AllowEntry {
+ new RoomJoinRulesEventContent.AllowEntry {
Type = "m.room_membership",
RoomId = botData.ControlRoom
}
@@ -84,12 +82,13 @@ public class MediaModBot(AuthenticatedHomeserverGeneric hs, ILogger<MediaModBot>
creationContent.CreationContent["type"] = "gay.rory.media_moderator_poc.policy_room";
botData.PolicyRoom = (await hs.CreateRoom(creationContent)).RoomId;
- await hs.SetAccountData("gay.rory.media_moderator_poc_data", botData);
+ await hs.SetAccountData("gay.rory.modbot_data", botData);
}
_policyRoom = hs.GetRoom(botData.PolicyRoom ?? botData.ControlRoom);
_logRoom = hs.GetRoom(botData.LogRoom ?? botData.ControlRoom);
_controlRoom = hs.GetRoom(botData.ControlRoom);
+ var syncHelper = new SyncHelper(hs);
List<string> admins = new();
@@ -98,7 +97,9 @@ public class MediaModBot(AuthenticatedHomeserverGeneric hs, ILogger<MediaModBot>
while (!cancellationToken.IsCancellationRequested) {
var controlRoomMembers = _controlRoom.GetMembersAsync();
await foreach (var member in controlRoomMembers) {
- if ((member.TypedContent as RoomMemberEventContent).Membership == "join") admins.Add(member.UserId);
+ if ((member.TypedContent as RoomMemberEventContent)?
+
+ .Membership == "join") admins.Add(member.UserId);
}
await Task.Delay(TimeSpan.FromSeconds(30), cancellationToken);
@@ -106,13 +107,12 @@ public class MediaModBot(AuthenticatedHomeserverGeneric hs, ILogger<MediaModBot>
}, cancellationToken);
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
- hs.SyncHelper.InviteReceivedHandlers.Add(async Task (args) => {
+ syncHelper.InviteReceivedHandlers.Add(async Task (args) => {
var inviteEvent =
args.Value.InviteState.Events.FirstOrDefault(x =>
x.Type == "m.room.member" && x.StateKey == hs.UserId);
- logger.LogInformation(
- $"Got invite to {args.Key} by {inviteEvent.Sender} with reason: {(inviteEvent.TypedContent as RoomMemberEventContent).Reason}");
- if (inviteEvent.Sender.EndsWith(":rory.gay") || inviteEvent.Sender.EndsWith(":conduit.rory.gay")) {
+ logger.LogInformation("Got invite to {RoomId} by {Sender} with reason: {Reason}", args.Key, inviteEvent!.Sender, (inviteEvent.TypedContent as RoomMemberEventContent)!.Reason);
+ if (inviteEvent.Sender.EndsWith(":rory.gay") || inviteEvent!.Sender.EndsWith(":conduit.rory.gay")) {
try {
var senderProfile = await hs.GetProfileAsync(inviteEvent.Sender);
await hs.GetRoom(args.Key).JoinAsync(reason: $"I was invited by {senderProfile.DisplayName ?? inviteEvent.Sender}!");
@@ -124,7 +124,7 @@ public class MediaModBot(AuthenticatedHomeserverGeneric hs, ILogger<MediaModBot>
}
});
- hs.SyncHelper.TimelineEventHandlers.Add(async @event => {
+ syncHelper.TimelineEventHandlers.Add(async @event => {
var room = hs.GetRoom(@event.RoomId);
try {
logger.LogInformation(
@@ -256,8 +256,8 @@ public class MediaModBot(AuthenticatedHomeserverGeneric hs, ILogger<MediaModBot>
await _logRoom.SendMessageEventAsync(
MessageFormatter.FormatException($"Unable to ban user in {MessageFormatter.HtmlFormatMention(room.RoomId)}", e));
await using var stream = new MemoryStream(e.ToString().AsBytes().ToArray());
- await _controlRoom.SendFileAsync("m.file", "error.log.cs", stream);
- await _logRoom.SendFileAsync("m.file", "error.log.cs", stream);
+ await _controlRoom.SendFileAsync("error.log.cs", stream);
+ await _logRoom.SendFileAsync("error.log.cs", stream);
}
});
}
@@ -282,15 +282,15 @@ public class MediaModBot(AuthenticatedHomeserverGeneric hs, ILogger<MediaModBot>
}
catch (Exception ex) {
await _logRoom.SendMessageEventAsync(
- MessageFormatter.FormatException($"Error calculating file hash for {mxcUri} via {mxcUri.Split('/')[2]} ({resolvedUri}), retrying via {hs.HomeServerDomain}...",
+ MessageFormatter.FormatException($"Error calculating file hash for {mxcUri} via {mxcUri.Split('/')[2]} ({resolvedUri}), retrying via {hs.BaseUrl}...",
ex));
try {
- resolvedUri = await hsResolver.ResolveMediaUri(hs.HomeServerDomain, mxcUri);
+ resolvedUri = await hsResolver.ResolveMediaUri(hs.BaseUrl, mxcUri);
fileHash = await hashAlgo.ComputeHashAsync(await hs._httpClient.GetStreamAsync(resolvedUri));
}
catch (Exception ex2) {
await _logRoom.SendMessageEventAsync(
- MessageFormatter.FormatException($"Error calculating file hash via {hs.HomeServerDomain} ({resolvedUri})!", ex2));
+ MessageFormatter.FormatException($"Error calculating file hash via {hs.BaseUrl} ({resolvedUri})!", ex2));
}
}
diff --git a/ExampleBots/MediaModeratorPoC/Bot/MediaModBotConfiguration.cs b/ExampleBots/MediaModeratorPoC/MediaModBotConfiguration.cs
index d848abe..cb5b596 100644
--- a/ExampleBots/MediaModeratorPoC/Bot/MediaModBotConfiguration.cs
+++ b/ExampleBots/MediaModeratorPoC/MediaModBotConfiguration.cs
@@ -1,6 +1,6 @@
using Microsoft.Extensions.Configuration;
-namespace MediaModeratorPoC.Bot;
+namespace MediaModeratorPoC;
public class MediaModBotConfiguration {
public MediaModBotConfiguration(IConfiguration config) => config.GetRequiredSection("MediaMod").Bind(this);
diff --git a/ExampleBots/MediaModeratorPoC/PolicyEngine.cs b/ExampleBots/MediaModeratorPoC/PolicyEngine.cs
new file mode 100644
index 0000000..0a0a565
--- /dev/null
+++ b/ExampleBots/MediaModeratorPoC/PolicyEngine.cs
@@ -0,0 +1,86 @@
+using LibMatrix.EventTypes.Spec;
+using LibMatrix.Helpers;
+using LibMatrix.Homeservers;
+using LibMatrix.RoomTypes;
+using LibMatrix.Services;
+using MediaModeratorPoC.AccountData;
+using MediaModeratorPoC.StateEventTypes;
+using Microsoft.Extensions.Logging;
+
+namespace MediaModeratorPoC;
+
+public class PolicyEngine(AuthenticatedHomeserverGeneric hs, ILogger<MediaModBot> logger, MediaModBotConfiguration configuration,
+ HomeserverResolverService hsResolver) {
+ public List<PolicyList> ActivePolicyLists { get; set; } = new();
+ private GenericRoom? _logRoom;
+ private GenericRoom? _controlRoom;
+
+ public async Task ReloadActivePolicyLists() {
+ // first time init
+ if (_logRoom is null || _controlRoom is null) {
+ var botData = await hs.GetAccountDataAsync<BotData>("gay.rory.modbot_data");
+ _logRoom ??= hs.GetRoom(botData.LogRoom ?? botData.ControlRoom);
+ _controlRoom ??= hs.GetRoom(botData.ControlRoom);
+ }
+
+ await _controlRoom?.SendMessageEventAsync(MessageFormatter.FormatSuccess("Reloading policy lists!"))!;
+ await _logRoom?.SendMessageEventAsync(
+ new RoomMessageEventContent(
+ body: "Reloading policy lists!",
+ messageType: "m.text"))!;
+
+ await _controlRoom?.SendMessageEventAsync(MessageFormatter.FormatSuccess("0/? policy lists loaded"))!;
+
+ var policyLists = new List<PolicyList>();
+ var policyListAccountData = await hs.GetAccountDataAsync<Dictionary<string, PolicyList>>("gay.rory.modbot.policy_lists");
+ foreach (var (roomId, policyList) in policyListAccountData) {
+ _logRoom?.SendMessageEventAsync(
+ new RoomMessageEventContent(
+ body: $"Loading policy list {MessageFormatter.HtmlFormatMention(roomId)}!",
+ messageType: "m.text"));
+ var room = hs.GetRoom(roomId);
+
+ policyList.Room = room;
+
+ var stateEvents = room.GetFullStateAsync();
+ await foreach (var stateEvent in stateEvents) {
+ if (stateEvent != null && stateEvent.GetType.IsAssignableTo(typeof(BasePolicy))) {
+ policyList.Policies.Add(stateEvent);
+ }
+ }
+
+ //html table of policy count by type
+ var policyCount = policyList.Policies.GroupBy(x => x.Type).ToDictionary(x => x.Key, x => x.Count());
+ var policyCountTable = policyCount.Aggregate(
+ "<table><tr><th>Policy Type</th><th>Count</th></tr>",
+ (current, policy) => current + $"<tr><td>{policy.Key}</td><td>{policy.Value}</td></tr>");
+ policyCountTable += "</table>";
+
+ var policyCountTablePlainText = policyCount.Aggregate(
+ "Policy Type | Count\n",
+ (current, policy) => current + $"{policy.Key,-16} | {policy.Value}\n");
+ await _logRoom?.SendMessageEventAsync(
+ new RoomMessageEventContent() {
+ MessageType = "org.matrix.custom.html",
+ Body = $"Policy count for {roomId}:\n{policyCountTablePlainText}",
+ FormattedBody = $"Policy count for {MessageFormatter.HtmlFormatMention(roomId)}:\n{policyCountTable}",
+ })!;
+
+ await _logRoom?.SendMessageEventAsync(
+ new RoomMessageEventContent(
+ body: $"Loaded {policyList.Policies.Count} policies for {MessageFormatter.HtmlFormatMention(roomId)}!",
+ messageType: "m.text"))!;
+
+ policyLists.Add(policyList);
+
+ var progressMsgContent = MessageFormatter.FormatSuccess($"{policyLists.Count}/{policyListAccountData.Count} policy lists loaded");
+ //edit old message
+ progressMsgContent.RelatesTo = new() {
+
+ };
+ _controlRoom?.SendMessageEventAsync(progressMsgContent);
+ }
+
+ ActivePolicyLists = policyLists;
+ }
+}
diff --git a/ExampleBots/MediaModeratorPoC/PolicyList.cs b/ExampleBots/MediaModeratorPoC/PolicyList.cs
new file mode 100644
index 0000000..0f49c97
--- /dev/null
+++ b/ExampleBots/MediaModeratorPoC/PolicyList.cs
@@ -0,0 +1,17 @@
+using System.Text.Json.Serialization;
+using LibMatrix;
+using LibMatrix.RoomTypes;
+using MediaModeratorPoC.StateEventTypes;
+
+namespace MediaModeratorPoC;
+
+public class PolicyList {
+ [JsonIgnore]
+ public GenericRoom Room { get; set; }
+
+ [JsonPropertyName("trusted")]
+ public bool Trusted { get; set; } = false;
+
+ [JsonIgnore]
+ public List<StateEvent> Policies { get; set; } = new();
+}
diff --git a/ExampleBots/MediaModeratorPoC/Program.cs b/ExampleBots/MediaModeratorPoC/Program.cs
index 413d91d..5b8e734 100644
--- a/ExampleBots/MediaModeratorPoC/Program.cs
+++ b/ExampleBots/MediaModeratorPoC/Program.cs
@@ -2,7 +2,7 @@
using LibMatrix.Services;
using LibMatrix.Utilities.Bot;
-using MediaModeratorPoC.Bot;
+using MediaModeratorPoC;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
diff --git a/ExampleBots/MediaModeratorPoC/Bot/StateEventTypes/MediaPolicyStateEventData.cs b/ExampleBots/MediaModeratorPoC/StateEventTypes/BasePolicy.cs
index 0096c78..048c1d0 100644
--- a/ExampleBots/MediaModeratorPoC/Bot/StateEventTypes/MediaPolicyStateEventData.cs
+++ b/ExampleBots/MediaModeratorPoC/StateEventTypes/BasePolicy.cs
@@ -1,27 +1,18 @@
+using System.ComponentModel.DataAnnotations;
using System.Text.Json.Serialization;
-using LibMatrix.Helpers;
-using LibMatrix.Interfaces;
+using LibMatrix;
-namespace MediaModeratorPoC.Bot.StateEventTypes;
+namespace MediaModeratorPoC.StateEventTypes;
-[
- MatrixEvent(EventName = "gay.rory.media_moderator_poc.rule.homeserver")]
-[MatrixEvent(EventName = "gay.rory.media_moderator_poc.rule.media")]
-public class MediaPolicyEventContent : EventContent {
+public abstract class BasePolicy : StateEvent {
/// <summary>
- /// This is an MXC URI, hashed with SHA3-256.
+ /// Entity this policy applies to
/// </summary>
[JsonPropertyName("entity")]
- public byte[] Entity { get; set; }
+ public string Entity { get; set; }
/// <summary>
- /// Server this ban applies to, can use * and ? as globs.
- /// </summary>
- [JsonPropertyName("server_entity")]
- public string? ServerEntity { get; set; }
-
- /// <summary>
- /// Reason this user is banned
+ /// Reason this policy exists
/// </summary>
[JsonPropertyName("reason")]
public string? Reason { get; set; }
@@ -30,6 +21,7 @@ public class MediaPolicyEventContent : EventContent {
/// Suggested action to take, one of `ban`, `kick`, `mute`, `redact`, `spoiler`, `warn` or `warn_admins`
/// </summary>
[JsonPropertyName("recommendation")]
+ [AllowedValues("ban", "kick", "mute", "redact", "spoiler", "warn", "warn_admins")]
public string Recommendation { get; set; } = "warn";
/// <summary>
@@ -47,7 +39,4 @@ public class MediaPolicyEventContent : EventContent {
get => Expiry == null ? null : DateTimeOffset.FromUnixTimeMilliseconds(Expiry.Value).DateTime;
set => Expiry = value is null ? null : ((DateTimeOffset)value).ToUnixTimeMilliseconds();
}
-
- [JsonPropertyName("file_hash")]
- public byte[]? FileHash { get; set; }
}
diff --git a/ExampleBots/MediaModeratorPoC/StateEventTypes/MediaPolicyStateEventData.cs b/ExampleBots/MediaModeratorPoC/StateEventTypes/MediaPolicyStateEventData.cs
new file mode 100644
index 0000000..603a858
--- /dev/null
+++ b/ExampleBots/MediaModeratorPoC/StateEventTypes/MediaPolicyStateEventData.cs
@@ -0,0 +1,17 @@
+using System.Text.Json.Serialization;
+using LibMatrix.EventTypes;
+
+namespace MediaModeratorPoC.StateEventTypes;
+
+/// <summary>
+/// File policy event, entity is the MXC URI of the file, hashed with SHA3-256.
+/// </summary>
+[MatrixEvent(EventName = "gay.rory.media_moderator_poc.rule.homeserver")]
+[MatrixEvent(EventName = "gay.rory.media_moderator_poc.rule.media")]
+public class MediaPolicyEventContent : BasePolicy {
+ /// <summary>
+ /// Hash of the file
+ /// </summary>
+ [JsonPropertyName("file_hash")]
+ public byte[]? FileHash { get; set; }
+}
diff --git a/ExampleBots/PluralContactBotPoC/Bot/AccountData/BotData.cs b/ExampleBots/PluralContactBotPoC/Bot/AccountData/BotData.cs
index 9477488..5d11432 100644
--- a/ExampleBots/PluralContactBotPoC/Bot/AccountData/BotData.cs
+++ b/ExampleBots/PluralContactBotPoC/Bot/AccountData/BotData.cs
@@ -1,4 +1,5 @@
using System.Text.Json.Serialization;
+using LibMatrix.EventTypes;
using LibMatrix.Helpers;
using LibMatrix.Interfaces;
diff --git a/ExampleBots/PluralContactBotPoC/Bot/AccountData/SystemData.cs b/ExampleBots/PluralContactBotPoC/Bot/AccountData/SystemData.cs
index 5edfc0e..42edd23 100644
--- a/ExampleBots/PluralContactBotPoC/Bot/AccountData/SystemData.cs
+++ b/ExampleBots/PluralContactBotPoC/Bot/AccountData/SystemData.cs
@@ -1,4 +1,5 @@
using System.Text.Json.Serialization;
+using LibMatrix.EventTypes;
using LibMatrix.Helpers;
using LibMatrix.Interfaces;
diff --git a/ExampleBots/PluralContactBotPoC/Bot/Commands/CreateSystemCommand.cs b/ExampleBots/PluralContactBotPoC/Bot/Commands/CreateSystemCommand.cs
index 55624a8..4a7d646 100644
--- a/ExampleBots/PluralContactBotPoC/Bot/Commands/CreateSystemCommand.cs
+++ b/ExampleBots/PluralContactBotPoC/Bot/Commands/CreateSystemCommand.cs
@@ -25,7 +25,7 @@ public class CreateSystemCommand(IServiceProvider services, HomeserverProviderSe
var sysName = ctx.Args[0];
try {
try {
- await ctx.Homeserver.GetAccountData<BotData>("gay.rory.plural_contact_bot.system_data");
+ await ctx.Homeserver.GetAccountDataAsync<BotData>("gay.rory.plural_contact_bot.system_data");
await ctx.Reply(MessageFormatter.FormatError($"System {sysName} already exists!"));
}
catch (MatrixException e) {
diff --git a/ExampleBots/PluralContactBotPoC/Bot/PluralContactBot.cs b/ExampleBots/PluralContactBotPoC/Bot/PluralContactBot.cs
index 0bd2bbf..231af95 100644
--- a/ExampleBots/PluralContactBotPoC/Bot/PluralContactBot.cs
+++ b/ExampleBots/PluralContactBotPoC/Bot/PluralContactBot.cs
@@ -38,14 +38,16 @@ public class PluralContactBot(AuthenticatedHomeserverGeneric hs, ILogger<PluralC
_logRoom = hs.GetRoom(botConfiguration.LogRoom);
- hs.SyncHelper.InviteReceivedHandlers.Add(async Task (args) => {
+ var syncHelper = new SyncHelper(hs);
+
+ syncHelper.InviteReceivedHandlers.Add(async Task (args) => {
var inviteEvent =
args.Value.InviteState.Events.FirstOrDefault(x =>
x.Type == "m.room.member" && x.StateKey == hs.UserId);
logger.LogInformation("Got invite to {} by {} with reason: {}", args.Key, inviteEvent.Sender, (inviteEvent.TypedContent as RoomMemberEventContent).Reason);
try {
- var accountData = await hs.GetAccountData<SystemData>($"gay.rory.plural_contact_bot.system_data#{inviteEvent.StateKey}");
+ var accountData = await hs.GetAccountDataAsync<SystemData>($"gay.rory.plural_contact_bot.system_data#{inviteEvent.StateKey}");
if (accountData.Members.Contains(inviteEvent.Sender)) {
await (hs.GetRoom(args.Key)).JoinAsync(reason: "I was invited by a system member!");
@@ -74,7 +76,7 @@ public class PluralContactBot(AuthenticatedHomeserverGeneric hs, ILogger<PluralC
}
});
- hs.SyncHelper.TimelineEventHandlers.Add(async @event => {
+ syncHelper.TimelineEventHandlers.Add(async @event => {
var room = hs.GetRoom(@event.RoomId);
try {
logger.LogInformation(
@@ -87,7 +89,7 @@ public class PluralContactBot(AuthenticatedHomeserverGeneric hs, ILogger<PluralC
await _logRoom.SendMessageEventAsync(
MessageFormatter.FormatException($"Exception handling event {@event.EventId} by {@event.Sender} in {MessageFormatter.HtmlFormatMention(room.RoomId)}", e));
await using var stream = new MemoryStream(Encoding.UTF8.GetBytes(e.ToString()));
- await _logRoom.SendFileAsync("m.file", "error.log.cs", stream);
+ await _logRoom.SendFileAsync("error.log.cs", stream);
}
});
}
|