Skip to content

Commit b661678

Browse files
authored
Merge pull request #180 from tjjfvi/suggestions
Use bot to manage #ts-discord-suggestions
2 parents 135673a + dd8679e commit b661678

File tree

3 files changed

+61
-3
lines changed

3 files changed

+61
-3
lines changed

.env.example

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,5 @@ GENERAL_HELP_CHANNEL=
1919

2020
# Time in milliseconds before !helper can be run
2121
TIME_BEFORE_HELPER_PING=
22+
23+
SUGGESTIONS_CHANNEL=

src/env.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,5 @@ export const BLOCKQUOTE_GREY = '#4f545c';
3232
export const timeBeforeHelperPing = parseInt(
3333
process.env.TIME_BEFORE_HELPER_PING!,
3434
);
35+
36+
export const suggestionsChannelId = process.env.SUGGESTIONS_CHANNEL!;

src/modules/etc.ts

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,18 @@ import {
55
listener,
66
CommonInhibitors,
77
} from 'cookiecord';
8+
import { ThreadAutoArchiveDuration } from 'discord-api-types';
89
import {
910
Message,
1011
MessageReaction,
1112
GuildMember,
1213
User,
1314
ReactionEmoji,
1415
TextChannel,
16+
ThreadChannel,
1517
} from 'discord.js';
16-
import { MessageChannel } from 'worker_threads';
18+
import { MessageChannel, threadId } from 'worker_threads';
19+
import { suggestionsChannelId } from '../env';
1720
import {
1821
clearMessageOwnership,
1922
DELETE_EMOJI,
@@ -22,6 +25,8 @@ import {
2225

2326
const emojiRegex = /<:\w+?:(\d+?)>|(\p{Emoji_Presentation})/gu;
2427

28+
const defaultPollEmojis = ['✅', '❌', '🤷'];
29+
2530
export class EtcModule extends Module {
2631
constructor(client: CookiecordClient) {
2732
super(client);
@@ -33,18 +38,67 @@ export class EtcModule extends Module {
3338
}
3439

3540
@listener({ event: 'messageCreate' })
36-
async onMessage(msg: Message) {
41+
async onPoll(msg: Message) {
3742
if (msg.author.bot || !msg.content.toLowerCase().startsWith('poll:'))
3843
return;
3944
let emojis = [
4045
...new Set(
4146
[...msg.content.matchAll(emojiRegex)].map(x => x[1] ?? x[2]),
4247
),
4348
];
44-
if (!emojis.length) emojis = ['✅', '❌', '🤷'];
49+
if (!emojis.length) emojis = defaultPollEmojis;
4550
for (const emoji of emojis) await msg.react(emoji);
4651
}
4752

53+
@listener({ event: 'messageCreate' })
54+
async onSuggestion(msg: Message) {
55+
if (msg.author.bot || msg.channelId !== suggestionsChannelId) return;
56+
// First 50 characters of the first line of the content (without cutting off a word)
57+
const title =
58+
msg.content
59+
.split('\n')[0]
60+
.split(/(^.{0,50}\b)/)
61+
.find(x => x) ?? 'Suggestion';
62+
await msg.startThread({
63+
name: title,
64+
autoArchiveDuration: ThreadAutoArchiveDuration.OneDay,
65+
});
66+
for (let emoji of defaultPollEmojis) await msg.react(emoji);
67+
}
68+
69+
@listener({ event: 'threadUpdate' })
70+
async onSuggestionClose(thread: ThreadChannel) {
71+
if (
72+
thread.parentId !== suggestionsChannelId ||
73+
!((await thread.fetch()) as ThreadChannel).archived
74+
)
75+
return;
76+
const channel = thread.parent!;
77+
let lastMessage = null;
78+
let suggestion: Message;
79+
while (!suggestion!) {
80+
const msgs = await channel.messages.fetch({
81+
before: lastMessage ?? undefined,
82+
limit: 5,
83+
});
84+
suggestion = msgs.find(msg => msg.thread?.id === thread.id)!;
85+
lastMessage = msgs.last()!.id as string;
86+
}
87+
const pollingResults = defaultPollEmojis.map(emoji => {
88+
const reactions = suggestion.reactions.resolve(emoji);
89+
// Subtract the bot's vote
90+
const count = (reactions?.count ?? 0) - 1;
91+
return [emoji, count] as const;
92+
});
93+
const pollingResultStr = pollingResults
94+
.sort((a, b) => b[1] - a[1])
95+
.map(([emoji, count], i) => `${count} ${emoji}`)
96+
.join(' ');
97+
await suggestion.reply({
98+
content: `Polling finished; result: ${pollingResultStr}`,
99+
});
100+
}
101+
48102
@listener({ event: 'messageReactionAdd' })
49103
async onReact(reaction: MessageReaction, member: GuildMember) {
50104
if (reaction.partial) return;

0 commit comments

Comments
 (0)