-
Notifications
You must be signed in to change notification settings - Fork 10
/
module_pm.lua
173 lines (143 loc) · 4.39 KB
/
module_pm.lua
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
-- Copyright (C) 2018 Jérôme Leclercq
-- This file is part of the "Not a Bot" application
-- For conditions of distribution and use, see copyright notice in LICENSE
local client = Client
local discordia = Discordia
local bot = Bot
local enums = discordia.enums
Module.Global = true
Module.Name = "pm"
function Module:GetConfigTable()
return {
{
Global = true,
Name = "TargetChannel",
Description = "Where private messages should be logged",
Type = bot.ConfigType.Channel,
Optional = true
},
{
Global = true,
Array = true,
Name = "BlockedUsers",
Description = "Users who are not allowed to contact the bot",
Type = Bot.ConfigType.User,
Default = {}
},
}
end
function Module:HandleResponse(message)
local function Failure(text, ...)
message:reply({
content = string.format("❌ " .. text, ...),
reference = {
message = message,
mention = true
}
})
end
if message.type ~= enums.messageType.reply then
return Failure("You must reply to a message so I know whom to send your message")
end
local mirrorMessage = message.referencedMessage
if not mirrorMessage then
return Failure("Failed to retrieve referenced message, maybe its too old?")
end
local mirrorMessageId = mirrorMessage.id
local persistentData = self:GetPersistentData()
local mirrorData = persistentData.mirrors[mirrorMessageId]
if not mirrorData then
return Failure("Failed to identify message, maybe its too old?")
end
local user, err = client:getUser(mirrorData.userId)
if not user then
return Failure("Failed to get user: %s", err)
end
local privateMessageChannel, err = user:getPrivateChannel()
if not privateMessageChannel then
return Failure("Failed to get private channel: %s", err)
end
local authorData = persistentData.users[mirrorData.userId]
if not authorData then
return Failure("An internal error occurred (no author data found)")
end
local reply, err = privateMessageChannel:send({
attachments = message.attachments,
content = message.content,
reference = authorData.lastMessageId ~= mirrorData.messageId and { message = mirrorData.messageId } or nil -- only reply if we're answering another message than the last one
})
if not reply then
return Failure("Failed to send reply to user: %s", err)
end
local success, err = message:addReaction("✅")
if not success then
self:LogError("failed to add confirmation reaction to message: %s", err)
end
end
function Module:HandlePrivateMessage(message)
if not self.GlobalConfig.TargetChannel then
return
end
local logChannel = client:getChannel(self.GlobalConfig.TargetChannel)
if not logChannel then
self:LogError("invalid target channel (%s)", self.GlobalConfig.TargetGuild)
return
end
local authorId = message.author.id
if table.search(self.GlobalConfig.BlockedUsers, authorId) then
self:LogInfo("blocked a message from " .. message.author.tag)
return
end
local messageId = message.id
local embed = Bot:BuildQuoteEmbed(message)
embed.footer = {
text = string.format("Author ID: %s | Message ID: %s", authorId, messageId)
}
local mirrorMessage, err = logChannel:send({
embed = embed
})
if not mirrorMessage then
self:LogError("failed to log private message: %s", err)
return
end
local mirrorMessageId = mirrorMessage.id
local persistentData = self:GetPersistentData()
persistentData.mirrors[mirrorMessageId] = {
userId = authorId,
messageId = messageId
}
local authorData = persistentData.users[authorId]
if not authorData then
authorData = {
mirrorMessages = {}
}
persistentData.users[authorId] = authorData
end
authorData.lastMessageId = messageId
table.insert(authorData.mirrorMessages, mirrorMessageId)
-- Keep only 100 previous message IDs per user (just in case)
while #authorData.mirrorMessages > 100 do
local mirrorMessageId = table.remove(authorData.mirrorMessages, 1)
persistentData.mirrors[mirrorMessageId] = nil
end
end
function Module:OnLoaded()
local persistentData = self:GetPersistentData()
persistentData.mirrors = persistentData.mirrors or {}
persistentData.users = persistentData.users or {}
return true
end
function Module:OnMessageCreate(message)
local channel = message.channel
if not channel then
return
end
if (message.author.bot) then
return
end
if channel.type == enums.channelType.private then
self:HandlePrivateMessage(message)
elseif channel.id == self.GlobalConfig.TargetChannel then
self:HandleResponse(message)
end
end