Skip to content

Commit f80fa5c

Browse files
committed
feat: Support for deleting bot messages
1 parent c71fe89 commit f80fa5c

File tree

3 files changed

+55
-8
lines changed

3 files changed

+55
-8
lines changed

src/modules/etc.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ import {
44
Module,
55
listener,
66
} from 'cookiecord';
7-
import { Message } from 'discord.js';
7+
import { Message, MessageReaction, GuildMember } from 'discord.js';
8+
import { clearMessageOwnership, ownsBotMessage } from '../util/send';
89

910
export class EtcModule extends Module {
1011
constructor(client: CookiecordClient) {
@@ -39,4 +40,15 @@ export class EtcModule extends Module {
3940
await msg.react('❌');
4041
await msg.react('🤷');
4142
}
43+
44+
@listener({ event: 'messageReactionAdd' })
45+
async onReact(reaction: MessageReaction, member: GuildMember) {
46+
if (
47+
reaction.emoji.name === '❌' &&
48+
ownsBotMessage(reaction.message, member)
49+
) {
50+
clearMessageOwnership(reaction.message);
51+
await reaction.message.delete();
52+
}
53+
}
4254
}

src/modules/twoslash.ts

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { command, Module, listener } from 'cookiecord';
22
import { Message, TextChannel } from 'discord.js';
33
import { twoslasher } from '@typescript/twoslash';
44
import { findCodeFromChannel } from '../util/findCodeblockFromChannel';
5+
import { sendWithMessageOwnership } from '../util/send';
56

67
const CODEBLOCK = '```';
78

@@ -15,18 +16,19 @@ export class TwoslashModule extends Module {
1516
const match = /^[_$a-zA-Z][_$0-9a-zA-Z]*/.exec(content);
1617

1718
if (!match) {
18-
msg.channel.send(
19+
return sendWithMessageOwnership(
20+
msg,
1921
'You need to give me a valid symbol name to look for!',
2022
);
21-
return;
2223
}
2324

2425
const symbol = match[0];
2526

2627
const code = await findCodeFromChannel(msg.channel as TextChannel);
2728

2829
if (!code)
29-
return msg.channel.send(
30+
return sendWithMessageOwnership(
31+
msg,
3032
`:warning: could not find any TypeScript codeblocks in the past 10 messages`,
3133
);
3234

@@ -38,11 +40,13 @@ export class TwoslashModule extends Module {
3840
i => i.targetString === symbol.trim(),
3941
);
4042
if (!value)
41-
return msg.channel.send(
43+
return sendWithMessageOwnership(
44+
msg,
4245
`:warning: no symbol named \`${symbol}\` in the most recent codeblock`,
4346
);
4447

45-
return msg.channel.send(
48+
await sendWithMessageOwnership(
49+
msg,
4650
`${CODEBLOCK}typescript\n${value.text}${CODEBLOCK}`,
4751
);
4852
}
@@ -55,7 +59,8 @@ export class TwoslashModule extends Module {
5559
const code = await findCodeFromChannel(msg.channel as TextChannel);
5660

5761
if (!code)
58-
return msg.channel.send(
62+
return sendWithMessageOwnership(
63+
msg,
5964
`:warning: could not find any TypeScript codeblocks in the past 10 messages`,
6065
);
6166

@@ -131,6 +136,9 @@ export class TwoslashModule extends Module {
131136
});
132137

133138
const output = resultLines.join('\n');
134-
return msg.channel.send(`${CODEBLOCK}ts\n${output}${CODEBLOCK}\n`);
139+
return sendWithMessageOwnership(
140+
msg,
141+
`${CODEBLOCK}ts\n${output}${CODEBLOCK}\n`,
142+
);
135143
}
136144
}

src/util/send.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { Message, MessageEmbed, GuildMember } from 'discord.js';
2+
3+
const MAX_TRACKED_MESSAGES = 1000;
4+
5+
const messageIdToMemberId = new Map<string, string>();
6+
7+
export async function sendWithMessageOwnership(
8+
message: Message,
9+
toSend: string | MessageEmbed,
10+
) {
11+
const sent = await message.channel.send(toSend);
12+
messageIdToMemberId.set(sent.id, message.author.id);
13+
14+
// Without this memory grows unboundedly... very slowly, but better to avoid the issue.
15+
if (messageIdToMemberId.size > MAX_TRACKED_MESSAGES) {
16+
// Keys returns an iterable in insertion order, so we remove the oldest message from the map.
17+
messageIdToMemberId.delete(messageIdToMemberId.keys().next().value);
18+
}
19+
}
20+
21+
export function ownsBotMessage(message: Message, member: GuildMember) {
22+
return messageIdToMemberId.get(message.id) === member.id;
23+
}
24+
25+
export function clearMessageOwnership(message: Message) {
26+
messageIdToMemberId.delete(message.id);
27+
}

0 commit comments

Comments
 (0)