generated from nhcarrigan/template
feat: rewrite to be more generic
This commit is contained in:
@ -7,18 +7,109 @@
|
||||
/**
|
||||
* The channels to post standup reminders in.
|
||||
*/
|
||||
export const channels = [
|
||||
"1326291362483671202",
|
||||
"1329625299406684263",
|
||||
"1326291172896931921",
|
||||
"1326291132535013409",
|
||||
"1326291241045856286",
|
||||
"1326291186863833169",
|
||||
"1326291226332496026",
|
||||
"1326291379621597304",
|
||||
"1326291254421749770",
|
||||
"1326291160632655983",
|
||||
"1326291146267430912",
|
||||
"1326291198666866788",
|
||||
"1326291214026408009",
|
||||
export const channels: Array<{
|
||||
channelId: string;
|
||||
roleId: string;
|
||||
name: string;
|
||||
}> = [
|
||||
{
|
||||
channelId: "1382093555228606484",
|
||||
name: "red-script",
|
||||
roleId: "1382091453987029144",
|
||||
},
|
||||
{
|
||||
channelId: "1382093583963656223",
|
||||
name: "orange-bytes",
|
||||
roleId: "1382091462707122186",
|
||||
},
|
||||
{
|
||||
channelId: "1382093618017337574",
|
||||
name: "yellow-packet",
|
||||
roleId: "1382091466767208538",
|
||||
},
|
||||
{
|
||||
channelId: "1382093654885138439",
|
||||
name: "green-loop",
|
||||
roleId: "1382091470877491364",
|
||||
},
|
||||
{
|
||||
channelId: "1382093684925005935",
|
||||
name: "blue-stack",
|
||||
roleId: "1382091474560356393",
|
||||
},
|
||||
{
|
||||
channelId: "1382093724200210522",
|
||||
name: "purple-array",
|
||||
roleId: "1382091477710012456",
|
||||
},
|
||||
{
|
||||
channelId: "1382093753489162330",
|
||||
name: "pink-protocol",
|
||||
roleId: "1382091502255341568",
|
||||
},
|
||||
{
|
||||
channelId: "1382093785973915820",
|
||||
name: "cyan-branch",
|
||||
roleId: "1382091520533856337",
|
||||
},
|
||||
{
|
||||
channelId: "1382093811693387867",
|
||||
name: "teal-cache",
|
||||
roleId: "1382091525873336400",
|
||||
},
|
||||
{
|
||||
channelId: "1382093843918225520",
|
||||
name: "mint-syntax",
|
||||
roleId: "1382091530428219603",
|
||||
},
|
||||
{
|
||||
channelId: "1382093883722174605",
|
||||
name: "lime-variable",
|
||||
roleId: "1382091534538641458",
|
||||
},
|
||||
{
|
||||
channelId: "1382093910259798046",
|
||||
name: "rose-token",
|
||||
roleId: "1382091538900979762",
|
||||
},
|
||||
{
|
||||
channelId: "1382093973488799886",
|
||||
name: "lavender-query",
|
||||
roleId: "1382091542961066014",
|
||||
},
|
||||
{
|
||||
channelId: "1382094002526097489",
|
||||
name: "indigo-class",
|
||||
roleId: "1382091547742568559",
|
||||
},
|
||||
{
|
||||
channelId: "1382094051360116837",
|
||||
name: "golden-index",
|
||||
roleId: "1382091551982882936",
|
||||
},
|
||||
{
|
||||
channelId: "1382094088739754096",
|
||||
name: "silver-promise",
|
||||
roleId: "1382091556613394443",
|
||||
},
|
||||
{
|
||||
channelId: "1382094114467745912",
|
||||
name: "bronze-thread",
|
||||
roleId: "1382091560367292536",
|
||||
},
|
||||
{
|
||||
channelId: "1382094146206044181",
|
||||
name: "maroon-socket",
|
||||
roleId: "1382091564498681907",
|
||||
},
|
||||
{
|
||||
channelId: "1382094200211771522",
|
||||
name: "violet-function",
|
||||
roleId: "1382091568252719205",
|
||||
},
|
||||
{
|
||||
channelId: "1382094311264616670",
|
||||
name: "grey-database",
|
||||
roleId: "1382091572602212622",
|
||||
},
|
||||
];
|
||||
|
30
src/index.ts
30
src/index.ts
@ -5,9 +5,12 @@
|
||||
*/
|
||||
import { Client, Events, GatewayIntentBits } from "discord.js";
|
||||
import { scheduleJob } from "node-schedule";
|
||||
import { channels } from "./config/channels.js";
|
||||
import { standup } from "./modules/standup.js";
|
||||
import { logger } from "./utils/logger.js";
|
||||
|
||||
const activeIds: Array<string> = [];
|
||||
|
||||
process.on("unhandledRejection", (error) => {
|
||||
if (error instanceof Error) {
|
||||
void logger.error("Unhandled Rejection", error);
|
||||
@ -25,14 +28,35 @@ process.on("uncaughtException", (error) => {
|
||||
});
|
||||
|
||||
const client = new Client({
|
||||
intents: [ GatewayIntentBits.Guilds ],
|
||||
intents: [ GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages ],
|
||||
});
|
||||
|
||||
client.on(Events.ClientReady, () => {
|
||||
void logger.log("debug", "Bot is ready.");
|
||||
scheduleJob("reminders", "0 6 * * 1-5", async() => {
|
||||
await standup(client);
|
||||
scheduleJob("reminders", "0 9 * * 1-5", async() => {
|
||||
await standup(client, activeIds);
|
||||
});
|
||||
});
|
||||
|
||||
client.on(Events.MessageCreate, (message) => {
|
||||
if (!message.channel.isThread() || !message.inGuild()) {
|
||||
return;
|
||||
}
|
||||
if (message.channel.parentId === null) {
|
||||
return;
|
||||
}
|
||||
const isInTeamChannel = channels.some((channel) => {
|
||||
return channel.channelId === message.channel.parentId;
|
||||
});
|
||||
if (!isInTeamChannel) {
|
||||
return;
|
||||
}
|
||||
if (message.author.bot) {
|
||||
return;
|
||||
}
|
||||
if (!activeIds.includes(message.author.id)) {
|
||||
activeIds.push(message.author.id);
|
||||
}
|
||||
});
|
||||
|
||||
await client.login(process.env.DISCORD_TOKEN);
|
||||
|
@ -3,28 +3,58 @@
|
||||
* @license Naomi's Public License
|
||||
* @author Naomi Carrigan
|
||||
*/
|
||||
import { ChannelType, type Client } from "discord.js";
|
||||
import { AttachmentBuilder, ChannelType, type Client } from "discord.js";
|
||||
import { channels } from "../config/channels.js";
|
||||
import { logger } from "../utils/logger.js";
|
||||
|
||||
const emptyArray = (array: Array<unknown>): void => {
|
||||
array.splice(0, array.length);
|
||||
};
|
||||
|
||||
/**
|
||||
* Posts a daily standup reminder in configured channels.
|
||||
* @param client - The Discord client.
|
||||
* @param activeIds - The list of user IDs who sent a progress update yesterday.
|
||||
*/
|
||||
export const standup = async(client: Client): Promise<void> => {
|
||||
// eslint-disable-next-line max-lines-per-function -- shut up
|
||||
export const standup = async(
|
||||
client: Client,
|
||||
activeIds: Array<string>,
|
||||
): Promise<void> => {
|
||||
try {
|
||||
await client.users.
|
||||
send("465650873650118659", {
|
||||
content: `The following people sent a progress update yesterday:`,
|
||||
files: [
|
||||
new AttachmentBuilder(Buffer.from(activeIds.join("\n")), {
|
||||
name: "ids.txt",
|
||||
}),
|
||||
],
|
||||
}).
|
||||
catch(() => {
|
||||
void logger.log(
|
||||
"warn",
|
||||
"Failed to send progress update message to user.",
|
||||
);
|
||||
});
|
||||
emptyArray(activeIds);
|
||||
const mapped = await Promise.all(
|
||||
channels.map(async(channel) => {
|
||||
const fetched = await client.channels.fetch(channel).catch(() => {
|
||||
void logger.log("warn", `Failed to fetch channel ${channel}.`);
|
||||
return null;
|
||||
});
|
||||
const fetched = await client.channels.
|
||||
fetch(channel.channelId).
|
||||
catch(() => {
|
||||
void logger.log("warn", `Failed to fetch channel ${channel.name}.`);
|
||||
return null;
|
||||
});
|
||||
if (!fetched) {
|
||||
await logger.log("warn", `Channel ${channel} not found.`);
|
||||
await logger.log("warn", `Channel ${channel.name} not found.`);
|
||||
return null;
|
||||
}
|
||||
if (fetched.type !== ChannelType.GuildText) {
|
||||
await logger.log("warn", `Channel ${channel} is not a text channel.`);
|
||||
await logger.log(
|
||||
"warn",
|
||||
`Channel ${channel.name} is not a text channel.`,
|
||||
);
|
||||
return null;
|
||||
}
|
||||
return fetched;
|
||||
@ -35,12 +65,39 @@ export const standup = async(client: Client): Promise<void> => {
|
||||
});
|
||||
await Promise.all(
|
||||
filtered.map(async(channel) => {
|
||||
await channel.send(
|
||||
// eslint-disable-next-line stylistic/max-len -- This message is too long to fit on one line.
|
||||
"Good morning @everyone~! It's time for standup! Please share your goals for today.",
|
||||
).catch(() => {
|
||||
void logger.log("warn", `Failed to send standup reminder in channel ${channel.name}.`);
|
||||
});
|
||||
const sent = await channel.
|
||||
send(
|
||||
`Good morning <@&${
|
||||
channels.find((c) => {
|
||||
return c.channelId === channel.id;
|
||||
})?.roleId ?? "692816967895220344"
|
||||
}> It is time for your daily progress update. Please share the following in this thread:
|
||||
|
||||
1️⃣ What did you accomplish yesterday?
|
||||
2️⃣ What are you working on today?
|
||||
3️⃣ Are there any blockers or issues you need help with?`,
|
||||
).
|
||||
catch(() => {
|
||||
void logger.log(
|
||||
"warn",
|
||||
`Failed to send progress reminder in channel ${channel.name}.`,
|
||||
);
|
||||
return null;
|
||||
});
|
||||
if (sent) {
|
||||
await sent.
|
||||
startThread({
|
||||
autoArchiveDuration: 1440,
|
||||
name: `Daily Progress Update - ${new Date().toLocaleDateString()}`,
|
||||
}).
|
||||
catch(() => {
|
||||
void logger.log(
|
||||
"warn",
|
||||
`Failed to start thread in channel ${channel.name}.`,
|
||||
);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
}),
|
||||
);
|
||||
} catch (error) {
|
||||
|
@ -7,6 +7,6 @@
|
||||
import { Logger } from "@nhcarrigan/logger";
|
||||
|
||||
export const logger = new Logger(
|
||||
"Standup Bot",
|
||||
"Maribelle",
|
||||
process.env.LOG_TOKEN ?? "",
|
||||
);
|
||||
|
Reference in New Issue
Block a user