1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
using System.Text.Json;
using ArcaneLibs;
using ArcaneLibs.Extensions;
using LibMatrix.Helpers;
using LibMatrix.RoomTypes;
using LibMatrix.Utilities.Bot.Interfaces;
using Microsoft.Extensions.Logging;
namespace MatrixAntiDmSpam.Core;
public class RoomInviteHandler(ILogger<RoomInviteHandler> logger, AntiDmSpamConfiguration config) : IRoomInviteHandler {
public List<RoomInviteContext> Invites { get; } = [];
public List<Func<RoomInviteContext, Task>> OnInviteReceived { get; set; } = [];
private GenericRoom? LogRoom { get; set; }
public async Task HandleInviteAsync(RoomInviteContext invite) {
if (!string.IsNullOrWhiteSpace(config.LogRoom))
LogRoom = invite.Homeserver.GetRoom(config.LogRoom);
Invites.Add(invite);
await LogInvite(invite);
foreach (var handler in OnInviteReceived) {
try {
await handler.Invoke(invite);
}
catch (Exception e) {
if (!string.IsNullOrWhiteSpace(config.LogRoom)) {
var logRoom = invite.Homeserver.GetRoom(config.LogRoom);
await logRoom.SendMessageEventAsync(
new MessageBuilder()
.WithBody($"Failed to execute invite handler {handler}...").WithNewline()
.WithCollapsibleSection("Stack trace", msb => msb.WithCodeBlock(e.ToString(), "cs"))
.Build()
);
}
}
}
}
private async Task LogInvite(RoomInviteContext invite) {
logger.LogInformation("Received invite to {} from {}", invite.RoomId, invite.MemberEvent.Sender);
if (LogRoom is null) return;
var inviteData = invite.InviteData.ToJsonUtf8Bytes(ignoreNull: true);
var inviterNameTask = invite.TryGetInviterNameAsync();
var roomNameTask = invite.TryGetRoomNameAsync();
var inviteDataFileUriTask = invite.Homeserver.UploadFile(invite.RoomId + ".json", inviteData, "application/json");
logger.LogInformation("Uploaded invite data ({}) to {}", Util.BytesToString(inviteData.Length), await inviteDataFileUriTask);
await Task.WhenAll(inviterNameTask, roomNameTask, inviteDataFileUriTask);
var message = new MessageBuilder()
.WithBody("Received invite to ").WithMention(invite.RoomId, await roomNameTask).WithBody(" from ").WithMention(invite.MemberEvent.Sender!, await inviterNameTask)
.Build();
message.AdditionalData!["gay.rory.invite_logger.invite_data_uri"] = JsonDocument.Parse($"\"{await inviteDataFileUriTask}\"").RootElement;
await LogRoom.SendMessageEventAsync(message);
if (config.LogInviteDataAsFile) {
await LogRoom.SendMessageEventAsync(new() {
MessageType = "m.file",
Body = invite.RoomId + ".json",
FileName = invite.RoomId + ".json",
Url = await inviteDataFileUriTask,
FileInfo = new() { Size = inviteData.Length, MimeType = "application/json" }
});
}
}
public async Task RejectInvite(RoomInviteContext invite, MessageBuilder reason) {
if (LogRoom is not null)
_ = LogRoom.SendMessageEventAsync(reason.Build());
try {
await invite.Homeserver.GetRoom(invite.RoomId).LeaveAsync();
}
catch (Exception e) {
if (LogRoom is not null)
await LogRoom.SendMessageEventAsync(
new MessageBuilder().WithColoredBody("#FF8800", $"Failed to leave {invite.RoomId}:").WithNewline()
.WithCodeBlock(e.ToString(), "cs")
.Build()
);
}
Invites.Remove(invite);
}
}
|