-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathhelp-me-archive.ts
97 lines (85 loc) · 2.79 KB
/
help-me-archive.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
import { ChannelType, Client, TextChannel, userMention } from "discord.js"
import { Robot } from "hubot"
import moment from "moment"
function weekdaysBefore(theMoment: ReturnType<typeof moment>, days: number) {
let newMoment = theMoment.clone()
let remainingDays = days
while (remainingDays > 0) {
if (newMoment.isoWeekday() < 6) {
remainingDays -= 1
}
newMoment = newMoment.subtract(1, "days")
}
return newMoment
}
export default async function webhookDiscord(
discordClient: Client,
robot: Robot,
) {
robot.hear(/help me archive (.+)/, async (msg) => {
const archiveChannelName = msg.match[1]
const senderId = msg.envelope.user.id
const guild = discordClient.guilds.cache.first()
if (guild === undefined) {
msg.send("Failed to resolve Discord server.")
return
}
const channels = await guild.channels.fetch()
const archiveChannelMatch =
channels.get(archiveChannelName) ??
channels.find(
(channel) =>
channel !== null &&
!channel.isDMBased() &&
channel.name.toLowerCase() === archiveChannelName.toLowerCase(),
) ??
undefined
const archiveChannels = archiveChannelMatch?.isTextBased()
? [archiveChannelMatch]
: archiveChannelMatch?.type === ChannelType.GuildCategory &&
archiveChannelMatch.children.cache
if (!Array.isArray(archiveChannels)) {
msg.send("No matching channel found.")
return
}
msg.send(
`Sending archiving pings for threads older than 14 days to ${senderId}!`,
)
const archiveThreshold = weekdaysBefore(moment(), 14)
// channels
archiveChannels
.filter(
(channel): channel is TextChannel =>
channel !== null && channel.isTextBased() && channel.viewable,
)
.forEach(async (channel) => {
try {
const { threads } = await channel.threads.fetch()
const threadsWithDates = (
await Promise.all(
threads.map(async (thread) => {
const messages = await thread.messages.fetch({ limit: 1 })
const firstMessage = messages.first()
const lastActivity = Math.max(
firstMessage?.createdTimestamp ?? 0,
thread.archiveTimestamp ?? 0,
)
return { thread, lastActivity: moment(lastActivity) }
}),
)
).filter(({ lastActivity }) =>
lastActivity.isBefore(archiveThreshold),
)
threadsWithDates[0]?.thread?.send(
`${userMention(senderId)} check archive status here, please.`,
)
} catch (err) {
console.error(
`Error for ${channel.name}: `,
err,
(err as Error).stack,
)
}
})
})
}