Skip to content

Commit

Permalink
Added a simple support message and message caching improvement
Browse files Browse the repository at this point in the history
  • Loading branch information
simonhyll committed May 11, 2023
1 parent 4a38249 commit 8152ce6
Show file tree
Hide file tree
Showing 7 changed files with 129 additions and 66 deletions.
95 changes: 60 additions & 35 deletions src/commands/thread.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { command } from 'jellycommands';
import { HELP_THREAD_CHANNELS } from '../config';
import { HELP_THREAD_CHANNELS, SOLVED_TAG, UNSOLVED_TAG } from '../config';
import { wrap_in_embed } from '../utils/embed_helpers';
import { get_member } from '../utils/snowflake';
import {
Expand All @@ -17,6 +17,7 @@ import {
ButtonBuilder,
MessageEditOptions,
ButtonStyle,
ForumChannel,
} from 'discord.js';

export default command({
Expand Down Expand Up @@ -132,41 +133,65 @@ export default command({

case 'solve': {
// Check if this is a help channel
if (!HELP_THREAD_CHANNELS.includes(thread.parentId)) {
throw new Error("Can't solve a non-help channel");
}
// Attempt to solve the thread
await solve_thread(
thread,
interaction.member as GuildMember,
);
// Successfully solved the thread
// Get the first message in the thread
const start_message = await thread.fetchStarterMessage();
// Get the first 2 messages after the start message
const messages = await thread.messages.fetch({
limit: 2,
after: start_message.id,
});
// Filter the messages to find the bot message with the buttons
const bot_message = messages
.filter((m) => m.components.length > 0)
.first() as Message;
// Change the message
const msg = wrap_in_embed(
'Thread solved. Thank you everyone! 🥳',
) as MessageEditOptions;
// Change the button
const row =
new ActionRowBuilder<ButtonBuilder>().addComponents(
new ButtonBuilder()
.setCustomId('reopen')
.setLabel('Mark as Unsolved')
.setStyle(ButtonStyle.Secondary)
.setEmoji('❔'),
if (HELP_THREAD_CHANNELS.includes(thread.parentId)) {
// Attempt to solve the thread
await solve_thread(
thread,
interaction.member as GuildMember,
);
msg.components = [row];
await bot_message.edit(msg);
// Successfully solved the thread
// Get the first message in the thread
const start_message = await thread.fetchStarterMessage();
// Get the first 2 messages after the start message
const messages = await thread.messages.fetch({
limit: 2,
after: start_message.id,
});
// Filter the messages to find the bot message with the buttons
const bot_message = messages
.filter((m) => m.components.length > 0)
.first() as Message;
// Change the message
const msg = wrap_in_embed(
'Thread solved. Thank you everyone! 🥳',
) as MessageEditOptions;
// Change the button
const row =
new ActionRowBuilder<ButtonBuilder>().addComponents(
new ButtonBuilder()
.setCustomId('reopen')
.setLabel('Mark as Unsolved')
.setStyle(ButtonStyle.Secondary)
.setEmoji('❔'),
);
msg.components = [row];
await bot_message.edit(msg);
// Commands require a reply
await interaction.followUp(wrap_in_embed('Thread solved.'));
// Delete the reply after 10 seconds
setTimeout(async () => {
await interaction.deleteReply();
}, 10000);
}
// Not a help channel, check if its parent is a ForumChannel
if (!(thread.parent instanceof ForumChannel))
throw new Error("Can't solve a non-help channel");
// Parent forum channel
const solveChannel = thread.guild.channels.cache.get(thread.parentId) as ForumChannel
// Solve tag
const solveTag = solveChannel.availableTags.find(tag => tag.name === SOLVED_TAG).id
// Unsolve tag
const unsolveTag = solveChannel.availableTags.find(tag => tag.name === UNSOLVED_TAG).id
// If this is a ThreadChannel
let tags = thread.appliedTags.filter(tag => tag !== solveTag && tag !== unsolveTag).splice(0, 4)
// Add the solved tag
tags.unshift(solveTag)
// If neither tag is going to exist in the channel, add unsolved
if (!tags.includes(solveTag) && !tags.includes(unsolveTag)) tags.unshift(unsolveTag)
// Ensure no duplicates are in the array
tags = [...new Set(tags)].sort()
// Apply tags
if (tags.toString() !== thread.appliedTags.sort().toString()) thread.setAppliedTags(tags)
// Commands require a reply
await interaction.followUp(wrap_in_embed('Thread solved.'));
// Delete the reply after 10 seconds
Expand Down
44 changes: 23 additions & 21 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,21 @@ export const TAURI_BLUE = 0x67d6ed;
const ADMIN_ROLES = DEV_MODE
? [process.env.DEV_ADMIN_ROLE]
: [
// admin
'985400380663935088',
// core
'616187491715907585',
// working-group
'761977421305610241',
];
// admin
'985400380663935088',
// core
'616187491715907585',
// working-group
'761977421305610241',
];

// list of support roles without admin rights
export const HELPER_ROLES = DEV_MODE
? [process.env.DEV_HELPER_ROLE]
: [
// Helping Hand
'995034988699455609',
];
// Helping Hand
'995034988699455609',
];

export const BOT_DEVS = [
// LorenzoLewis
Expand All @@ -42,43 +42,45 @@ export const THREAD_ADMIN_IDS = [...ADMIN_ROLES, ...BOT_DEVS];
export const HELP_THREAD_CHANNELS = DEV_MODE
? [process.env.DEV_HELP_CHANNEL]
: [
// #help-triage
'625037620996734986',
];
// #help-triage
'625037620996734986',
];

// channels that will be automatically threaded when a message is created
export const AUTO_THREAD_CHANNELS = DEV_MODE
? [process.env.DEV_DID_A_THING_CHANNEL, ...HELP_THREAD_CHANNELS]
: [
// #did-a-thing
'616234029842300930',
...HELP_THREAD_CHANNELS,
];
// #did-a-thing
'616234029842300930',
...HELP_THREAD_CHANNELS,
];

export const MESSAGE_READ = '✅';

export const REACTION_ROLE: {
emojiName: string;
emojiId: string;
roleId: string;
description: string;
}[] = DEV_MODE
? [
? [
{
emojiName: 'sausageroll',
emojiId: '995712110925451324',
roleId: process.env.DEV_REACTION_ROLE,
description:
'Join the conversation in the contributors channels (you can still view without this role)',
},
]
: [
]
: [
{
emojiName: 'tauri',
emojiId: '876938722266972210',
roleId: '986176820187631616',
description:
'Join the conversation in the contributors channels (you can still view without this role)',
},
];
];

export const REACTION_ROLE_CHANNEL = DEV_MODE
? process.env.DEV_REACTION_ROLE_CHANNEL
Expand Down
18 changes: 17 additions & 1 deletion src/events/messageCreateForum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import {
ForumChannel,
} from 'discord.js';
import { event } from 'jellycommands';
import { SOLVABLE_FORUMS, UNSOLVED_TAG, SOLVED_TAG } from '../config';
import { wrap_in_embed } from '../utils/embed_helpers';
import { SOLVABLE_FORUMS, UNSOLVED_TAG, SOLVED_TAG, MESSAGE_READ } from '../config';

export default event({
name: 'messageCreate',
Expand Down Expand Up @@ -36,6 +37,21 @@ export default event({
tags = [...new Set(tags)].sort()
// Apply tags
if (tags.toString() !== message.channel.appliedTags.sort().toString()) message.channel.setAppliedTags(tags)
// If this is a new post and not just a regular message
if (!message.nonce && message.position === 0) {
const msg = await message.channel.send(wrap_in_embed(
`Thank you for your message!
1. Search the #support forum for existing posts
2. Search Github issues to see if this is a known issue
3. Send the output of \`tauri info\`
4. Provide reproduction steps for your issue
5. Be polite and remember that we are all contributing our spare time, none of us are paid to be here
Once you've read this and taken the appropriate steps, react to this message`
))
await msg.react(MESSAGE_READ)
}
}
},
});
21 changes: 17 additions & 4 deletions src/events/messageReactionAdd.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,28 @@
import { ThreadChannel } from 'discord.js';
import { event } from 'jellycommands';
import { MESSAGE_READ, REACTION_ROLE_CHANNEL } from '../config'
import { hasPermission } from '../utils/reactionHandler';

export default event({
name: 'messageReactionAdd',
run: async (_, reaction, user) => {
try {
const result = await hasPermission(reaction, user);

result.member.roles.add(result.roleId);
// The bot shouldn't react to its own reactions
if (user.bot)
return
// If this is a reaction in the role reaction channel
if (reaction.message.channelId === REACTION_ROLE_CHANNEL) {
const result = await hasPermission(reaction, user);
result.member.roles.add(result.roleId);
} else {
// Otherwise we make a more general guess that if the original message was from the bot
// and it's a MESSAGE_READ emoji reaction, we assume the message should be deleted
if (reaction.message.author.bot && reaction.emoji.name === MESSAGE_READ) {
reaction.message.delete()
}
}
} catch (error) {
console.error(`Issue in reactionAdd: ${error}`);
console.error(`Issue in messageReactionAdd: ${error}`);
}
},
});
14 changes: 10 additions & 4 deletions src/events/messageReactionRemove.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
import { event } from 'jellycommands';
import { REACTION_ROLE_CHANNEL } from '../config';
import { hasPermission } from '../utils/reactionHandler';

export default event({
name: 'messageReactionRemove',
run: async (_, reaction, user) => {
try {
const result = await hasPermission(reaction, user);

result.member.roles.remove(result.roleId);
// The bot shouldn't react to its own reactions
if (user.bot)
return
// If this is a reaction in the role reaction channel
if (reaction.message.channelId === REACTION_ROLE_CHANNEL) {
const result = await hasPermission(reaction, user);
result.member.roles.remove(result.roleId);
}
} catch (error) {
console.error(`Issue in reactionRemove: ${error}`);
console.error(`Issue in messageReactionRemove: ${error}`);
}
},
});
2 changes: 1 addition & 1 deletion src/events/ready.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ export default event({
updateCache(client)
}, 60_000 * 60) // Every 60 minutes
},
});
});
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const client = new JellyCommands({
GatewayIntentBits.GuildMessages,
GatewayIntentBits.GuildMessageReactions,
GatewayIntentBits.MessageContent,
GatewayIntentBits.GuildMessages
],
},

Expand Down

0 comments on commit 8152ce6

Please sign in to comment.