-
Notifications
You must be signed in to change notification settings - Fork 1
/
extended slowmode.ts
141 lines (132 loc) · 4.6 KB
/
extended slowmode.ts
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
// extended slowmode, comissioned by Jack8#6482 (219514530563096576) on discord.
// essentially adds a channel permission overwrite on the channel that you define to stop users from sending messages, for the duration you specify.
type ChannelLock = {
duration: number; // in seconds
channelId: string; // id of the channel to apply the lock to
};
type MemberLock = {
expires: number; // date
id: string;
};
const kv = new pylon.KVNamespace('channelLocks');
const lockDefinitions: Array<ChannelLock> = [
{ duration: 60*60*12, channelId: 'ur channel id' }
];
async function checkExpires() {
const changes: { [key: string]: Array<MemberLock> | undefined } = {};
const items = await kv.items();
const now = Date.now();
items.map((item) => {
const value: Array<MemberLock> | undefined = <any>item.value;
if (!value) return;
const validOnly = value.filter((v) => v.expires > now);
if (validOnly.length !== value.length) {
if (validOnly.length === 0) {
changes[item.key] = undefined;
} else {
changes[item.key] = validOnly;
}
}
});
if (Object.keys(changes).length > 0) {
// @ts-ignore
await kv.transactMulti<Array<MemberLock>>(Object.keys(changes), () => {
return Object.values(changes);
});
// unblock them
await Promise.all(
Object.keys(changes).map(async (chId) => {
const channel = await discord.getChannel(chId);
if (
!(channel instanceof discord.GuildTextChannel) &&
!(channel instanceof discord.GuildNewsChannel)
)
return;
const ogItem: Array<MemberLock> | undefined = <any>(
items.find((v) => v.key === chId)?.value
);
if (!ogItem) return;
const unblockedMembers = ogItem
.filter(
(v) =>
(changes[chId] && !changes[chId]?.includes(v)) || !changes[chId]
)
.map((v) => v.id);
const newOW = channel.permissionOverwrites.filter((v) => {
// @ts-ignore
if (v.type !== 1) return true;
if (!unblockedMembers.includes(v.id)) return true;
if (typeof v.allow === 'number') {
// @ts-ignore
if (v.allow === 0 && v.deny === 2048) return false;
} else {
// @ts-ignore
if (v.allow === '0' && v.deny === '2048') return false;
}
});
if (newOW.length !== channel.permissionOverwrites.length) {
await channel.edit({ permissionOverwrites: newOW });
}
})
);
}
}
discord.on('MESSAGE_CREATE', async (message) => {
if (
message.webhookId ||
!message.member ||
!(message instanceof discord.GuildMemberMessage) ||
message.flags !== 0
) return;
const channel = await message.getChannel();
if (channel instanceof discord.DmChannel) return;
if(channel.canMember(message.member, discord.Permissions.MANAGE_CHANNELS) && channel.canMember(message.member, discord.Permissions.MANAGE_ROLES)) return;
const def = lockDefinitions.find((v) => v.channelId === channel.id);
if (!def) return;
const { result: transactRes, next } = await kv.transactWithResult<
Array<MemberLock>,
boolean
>(channel.id, (prev) => {
const newV = prev || [];
const memberDef = newV.find((v) => v.id === message.author.id);
if (!memberDef) {
return {
next: [...newV, { expires: Date.now() + def.duration * 1000, id: message.author.id }],
result: true
};
} else {
return { next: newV, result: false };
}
});
if (!transactRes) {
try {
await message.delete();
} catch (_) {}
} else {
// block them!
const newOverwrites = channel.permissionOverwrites;
const hasOW = newOverwrites.findIndex(
(v) =>
v.id === message.author.id &&
v.type === discord.Channel.PermissionOverwriteType.MEMBER
);
if (hasOW > -1) {
if (newOverwrites[hasOW].allow === 0 && newOverwrites[hasOW].deny === 2048) return;
// @ts-ignore
if (newOverwrites[hasOW].allow === '0' && newOverwrites[hasOW].deny === '2048') return;
newOverwrites[hasOW].allow = 0;
newOverwrites[hasOW].deny = 2048;
} else {
newOverwrites.push({
type: discord.Channel.PermissionOverwriteType.MEMBER,
id: message.author.id,
allow: 0,
deny: 2048
});
}
await channel.edit({ permissionOverwrites: newOverwrites });
}
});
pylon.tasks.cron('every_5_min', '0 0/5 * * * * *', async () => {
await checkExpires();
});