generated from nhcarrigan/template
fix: fix lint erorr
This commit is contained in:
@@ -1,3 +1,9 @@
|
|||||||
|
/**
|
||||||
|
* @copyright NHCarrigan
|
||||||
|
* @license Naomi's Public License
|
||||||
|
* @author Teklu Abayneh
|
||||||
|
*/
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ContextMenuCommandBuilder,
|
ContextMenuCommandBuilder,
|
||||||
ApplicationCommandType,
|
ApplicationCommandType,
|
||||||
@@ -9,13 +15,14 @@ import {
|
|||||||
ButtonStyle,
|
ButtonStyle,
|
||||||
} from "discord.js";
|
} from "discord.js";
|
||||||
import { ids } from "../config/ids.js";
|
import { ids } from "../config/ids.js";
|
||||||
|
import { logger } from "../utils/logger.js";
|
||||||
|
|
||||||
export const forwardOwnerDM = {
|
export const forwardOwnerDM = {
|
||||||
data: new ContextMenuCommandBuilder()
|
data: new ContextMenuCommandBuilder().setName("Forward to Naomi").
|
||||||
.setName("Forward to Naomi")
|
setType(ApplicationCommandType.Message),
|
||||||
.setType(ApplicationCommandType.Message),
|
|
||||||
|
|
||||||
async execute(interaction: MessageContextMenuCommandInteraction) {
|
async execute(interaction: MessageContextMenuCommandInteraction):
|
||||||
|
Promise<void> {
|
||||||
await interaction.deferReply({ ephemeral: true });
|
await interaction.deferReply({ ephemeral: true });
|
||||||
|
|
||||||
if (interaction.user.id !== ids.users.naomi) {
|
if (interaction.user.id !== ids.users.naomi) {
|
||||||
@@ -26,47 +33,58 @@ export const forwardOwnerDM = {
|
|||||||
const message = interaction.targetMessage;
|
const message = interaction.targetMessage;
|
||||||
|
|
||||||
if (message.author.id === ids.users.naomi) {
|
if (message.author.id === ids.users.naomi) {
|
||||||
await interaction.editReply("No need to forward your own message to yourself 😄");
|
await interaction.editReply(
|
||||||
|
"No need to forward your own message to yourself 😄",
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const naomi = await interaction.client.users.fetch(ids.users.naomi);
|
const naomi = await interaction.client.users.fetch(ids.users.naomi);
|
||||||
|
const forwardedEmbed = new EmbedBuilder().
|
||||||
|
setColor(0x58_65_F2).
|
||||||
|
setTitle(`Message from ${String(message.author.tag)}!`).
|
||||||
|
setDescription(
|
||||||
|
`${(message.attachments.size > 0
|
||||||
|
? `**Attachments:** ${String(message.attachments.size)}
|
||||||
|
file(s)\n\n`
|
||||||
|
: "\n")
|
||||||
|
+ (message.embeds.length > 0
|
||||||
|
? `**Embeds:** ${String(message.embeds.length)}\n\n`
|
||||||
|
: "")}
|
||||||
|
\n${message.content !== "" || message.content !== null
|
||||||
|
? message.content
|
||||||
|
: "*[No text content]*"}\n\n`,
|
||||||
|
);
|
||||||
|
|
||||||
const forwardedEmbed = new EmbedBuilder()
|
const viewButton = new ButtonBuilder().
|
||||||
.setColor(0x5865F2)
|
setLabel("View Message").
|
||||||
.setTitle(`Message from ${message.author.tag}!`)
|
setURL(message.url).
|
||||||
.setDescription(
|
setStyle(ButtonStyle.Link);
|
||||||
(message.attachments.size > 0 ? `**Attachments:** ${message.attachments.size} file(s)\n\n` : "\n") +
|
|
||||||
(message.embeds.length > 0 ? `**Embeds:** ${message.embeds.length}\n\n` : "") + "\n" +
|
|
||||||
(message.content || "*[No text content]*") + "\n\n");
|
|
||||||
|
|
||||||
const viewButton = new ButtonBuilder()
|
const row = new ActionRowBuilder<ButtonBuilder>().addComponents(
|
||||||
.setLabel("View Message")
|
viewButton,
|
||||||
.setURL(message.url)
|
);
|
||||||
.setStyle(ButtonStyle.Link);
|
await naomi.send({
|
||||||
|
components: [ row ],
|
||||||
const row = new ActionRowBuilder<ButtonBuilder>()
|
embeds: [ forwardedEmbed ],
|
||||||
.addComponents(viewButton);
|
files: message.attachments.map((att) => {
|
||||||
await naomi.send({
|
return att.url;
|
||||||
embeds: [forwardedEmbed],
|
}),
|
||||||
files: message.attachments.map((att) => att.url),
|
|
||||||
components: [row],
|
|
||||||
});
|
});
|
||||||
|
|
||||||
await interaction.editReply({
|
await interaction.editReply({
|
||||||
content: "✅ Forwarded to your DMs!",
|
content: "✅ Forwarded to your DMs!",
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Failed to forward:", error);
|
|
||||||
|
|
||||||
let replyText = "❌ Failed to forward message.";
|
let replyText = "❌ Failed to forward message.";
|
||||||
|
if (error instanceof DiscordAPIError && error.code === 50_007) {
|
||||||
if (error instanceof DiscordAPIError && error.code === 50007) {
|
replyText = `${replyText} (Naomi's DMs might be closed)`;
|
||||||
replyText += " (Naomi's DMs might be closed)";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await interaction.editReply(replyText);
|
await interaction.editReply(replyText);
|
||||||
|
if (error instanceof Error) {
|
||||||
|
await logger.error("operation", error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
+1
-1
@@ -70,6 +70,6 @@ export const ids = {
|
|||||||
amari: "1406431359345496255",
|
amari: "1406431359345496255",
|
||||||
naomi: "465650873650118659",
|
naomi: "465650873650118659",
|
||||||
nhcarrigan: "1382837581649150104",
|
nhcarrigan: "1382837581649150104",
|
||||||
teklu:"1381735115163570198",
|
teklu: "1381735115163570198",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
+107
-105
@@ -6,11 +6,11 @@
|
|||||||
|
|
||||||
import { DiscordAnalytics } from "@nhcarrigan/discord-analytics";
|
import { DiscordAnalytics } from "@nhcarrigan/discord-analytics";
|
||||||
import {
|
import {
|
||||||
Client,
|
Client,
|
||||||
GatewayIntentBits,
|
GatewayIntentBits,
|
||||||
Events,
|
Events,
|
||||||
Partials,
|
Partials,
|
||||||
MessageFlags,
|
MessageFlags,
|
||||||
} from "discord.js";
|
} from "discord.js";
|
||||||
import { scheduleJob } from "node-schedule";
|
import { scheduleJob } from "node-schedule";
|
||||||
import { App } from "octokit";
|
import { App } from "octokit";
|
||||||
@@ -32,148 +32,150 @@ import { logger } from "./utils/logger.js";
|
|||||||
import type { Amari } from "./interfaces/amari.js";
|
import type { Amari } from "./interfaces/amari.js";
|
||||||
|
|
||||||
if (
|
if (
|
||||||
process.env.GH_CLIENT_ID === undefined
|
process.env.GH_CLIENT_ID === undefined
|
||||||
|| process.env.GH_PRIVATE_KEY === undefined
|
|| process.env.GH_PRIVATE_KEY === undefined
|
||||||
) {
|
) {
|
||||||
throw new Error("Cannot initialise GitHub!");
|
throw new Error("Cannot initialise GitHub!");
|
||||||
}
|
}
|
||||||
|
|
||||||
const githubApp = new App({
|
const githubApp = new App({
|
||||||
appId: process.env.GH_CLIENT_ID,
|
appId: process.env.GH_CLIENT_ID,
|
||||||
privateKey: process.env.GH_PRIVATE_KEY.replaceAll("\\n", "\n"),
|
privateKey: process.env.GH_PRIVATE_KEY.replaceAll("\\n", "\n"),
|
||||||
});
|
});
|
||||||
|
|
||||||
const octokit = await githubApp.getInstallationOctokit(83_119_105);
|
const octokit = await githubApp.getInstallationOctokit(83_119_105);
|
||||||
const { data } = await octokit.rest.apps.getAuthenticated();
|
const { data } = await octokit.rest.apps.getAuthenticated();
|
||||||
await logger.log(
|
await logger.log(
|
||||||
"debug",
|
"debug",
|
||||||
`Authenticated to GitHub as ${data?.name ?? "unknown"}`,
|
`Authenticated to GitHub as ${data?.name ?? "unknown"}`,
|
||||||
);
|
);
|
||||||
|
|
||||||
const amari: Amari = {
|
const amari: Amari = {
|
||||||
discord: new Client({
|
discord: new Client({
|
||||||
intents: [
|
intents: [
|
||||||
GatewayIntentBits.Guilds,
|
GatewayIntentBits.Guilds,
|
||||||
GatewayIntentBits.GuildMessages,
|
GatewayIntentBits.GuildMessages,
|
||||||
GatewayIntentBits.MessageContent,
|
GatewayIntentBits.MessageContent,
|
||||||
GatewayIntentBits.GuildMembers,
|
GatewayIntentBits.GuildMembers,
|
||||||
GatewayIntentBits.DirectMessages,
|
GatewayIntentBits.DirectMessages,
|
||||||
],
|
],
|
||||||
partials: [Partials.Channel],
|
partials: [ Partials.Channel ],
|
||||||
}),
|
}),
|
||||||
github: octokit,
|
github: octokit,
|
||||||
lastRssItems: {
|
lastRssItems: {
|
||||||
freeCodeCamp: null,
|
freeCodeCamp: null,
|
||||||
hackerNews: null,
|
hackerNews: null,
|
||||||
},
|
},
|
||||||
recentlyActiveChannels: new Set<string>(),
|
recentlyActiveChannels: new Set<string>(),
|
||||||
};
|
};
|
||||||
|
|
||||||
const analytics = new DiscordAnalytics(amari.discord, logger);
|
const analytics = new DiscordAnalytics(amari.discord, logger);
|
||||||
|
|
||||||
amari.discord.once(Events.ClientReady, () => {
|
amari.discord.once(Events.ClientReady, () => {
|
||||||
void logger.log(
|
void logger.log(
|
||||||
"debug",
|
"debug",
|
||||||
`Authenticated to Discord as ${amari.discord.user?.username ?? "unknown"}`,
|
`Authenticated to Discord as ${amari.discord.user?.username ?? "unknown"}`,
|
||||||
);
|
);
|
||||||
void cacheData(amari);
|
void cacheData(amari);
|
||||||
analytics.startCron();
|
analytics.startCron();
|
||||||
scheduleJob("post news", "0 * * * *", async () => {
|
scheduleJob("post news", "0 * * * *", async() => {
|
||||||
await postFreeCodeCampNews(amari);
|
await postFreeCodeCampNews(amari);
|
||||||
await postHackerNews(amari);
|
await postHackerNews(amari);
|
||||||
});
|
});
|
||||||
scheduleJob("check guild tags", "0 0 * * *", async () => {
|
scheduleJob("check guild tags", "0 0 * * *", async() => {
|
||||||
await logger.log("debug", "Auditing guild tags.");
|
await logger.log("debug", "Auditing guild tags.");
|
||||||
await cacheData(amari);
|
await cacheData(amari);
|
||||||
});
|
});
|
||||||
scheduleJob("post progress reminders", "0 9 * * 1-5", async () => {
|
scheduleJob("post progress reminders", "0 9 * * 1-5", async() => {
|
||||||
await postProgressReminders(amari);
|
await postProgressReminders(amari);
|
||||||
});
|
});
|
||||||
setInterval(() => {
|
setInterval(
|
||||||
amari.recentlyActiveChannels = new Set<string>();
|
() => {
|
||||||
}, 10 * 60 * 1000);
|
amari.recentlyActiveChannels = new Set<string>();
|
||||||
setInterval(() => {
|
},
|
||||||
void checkRetroAchievements(amari);
|
10 * 60 * 1000,
|
||||||
}, 10 * 60 * 1000);
|
);
|
||||||
|
setInterval(
|
||||||
|
() => {
|
||||||
|
void checkRetroAchievements(amari);
|
||||||
|
},
|
||||||
|
10 * 60 * 1000,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
amari.discord.on(Events.MessageCreate, (message) => {
|
amari.discord.on(Events.MessageCreate, (message) => {
|
||||||
if (!message.inGuild()) {
|
if (!message.inGuild()) {
|
||||||
void respondToDm(amari, message);
|
void respondToDm(amari, message);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
void handleMessageCreate(amari, message);
|
void handleMessageCreate(amari, message);
|
||||||
});
|
});
|
||||||
|
|
||||||
amari.discord.on(Events.InteractionCreate, (interaction) => {
|
amari.discord.on(Events.InteractionCreate, (interaction) => {
|
||||||
void analytics.logGatewayEvent(Events.InteractionCreate, { ...interaction });
|
void analytics.logGatewayEvent(Events.InteractionCreate, { ...interaction });
|
||||||
|
|
||||||
if (interaction.isMessageContextMenuCommand() && interaction.commandName === "Forward to Naomi") {
|
if (
|
||||||
void forwardOwnerDM.execute(interaction);
|
interaction.isMessageContextMenuCommand()
|
||||||
return
|
&& interaction.commandName === "Forward to Naomi"
|
||||||
|
) {
|
||||||
|
void forwardOwnerDM.execute(interaction);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (interaction.isButton() && interaction.customId === "resolve") {
|
||||||
|
if (interaction.user.id !== ids.users.naomi) {
|
||||||
|
return void interaction.reply({
|
||||||
|
content: "Who are you????",
|
||||||
|
flags: [ MessageFlags.Ephemeral ],
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (interaction.isButton() && interaction.customId === "resolve") {
|
return void interaction.message.delete();
|
||||||
if (interaction.user.id !== ids.users.naomi) {
|
}
|
||||||
return void interaction.reply({
|
if (interaction.isAutocomplete()) {
|
||||||
content: "Who are you????",
|
return void interaction;
|
||||||
flags: [MessageFlags.Ephemeral],
|
}
|
||||||
});
|
return void interaction.reply({
|
||||||
}
|
content: "What?",
|
||||||
|
flags: [ MessageFlags.Ephemeral ],
|
||||||
return void interaction.message.delete();
|
});
|
||||||
}
|
|
||||||
if (interaction.isAutocomplete()) {
|
|
||||||
return void interaction;
|
|
||||||
}
|
|
||||||
return void interaction.reply({
|
|
||||||
content: "What?",
|
|
||||||
flags: [MessageFlags.Ephemeral],
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
amari.discord.on(Events.ThreadCreate, (thread) => {
|
amari.discord.on(Events.ThreadCreate, (thread) => {
|
||||||
if (thread.parent?.isThreadOnly() !== true) {
|
if (thread.parent?.isThreadOnly() !== true) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const { bugReports, communityFeedback, featureRequests, policyIdeation }
|
const { bugReports, communityFeedback, featureRequests, policyIdeation }
|
||||||
= ids.channels;
|
= ids.channels;
|
||||||
if (
|
if (
|
||||||
![bugReports,
|
![ bugReports, communityFeedback, featureRequests, policyIdeation ].includes(
|
||||||
communityFeedback,
|
thread.parent.id,
|
||||||
featureRequests,
|
)
|
||||||
policyIdeation].includes(
|
) {
|
||||||
thread.parent.id,
|
return;
|
||||||
)
|
}
|
||||||
) {
|
const tagId = getForumTagId(thread.parent.id);
|
||||||
return;
|
if (tagId === null) {
|
||||||
}
|
return;
|
||||||
const tagId = getForumTagId(thread.parent.id);
|
}
|
||||||
if (tagId === null) {
|
void thread.setAppliedTags([ tagId ]);
|
||||||
return;
|
|
||||||
}
|
|
||||||
void thread.setAppliedTags([tagId]);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
amari.discord.on(Events.UserUpdate, (_oldUser, updatedUser) => {
|
amari.discord.on(Events.UserUpdate, (_oldUser, updatedUser) => {
|
||||||
void processUserGuildTag(amari, updatedUser);
|
void processUserGuildTag(amari, updatedUser);
|
||||||
});
|
});
|
||||||
|
|
||||||
amari.discord.on(Events.GuildMemberUpdate, (oldMember, updatedMember) => {
|
amari.discord.on(Events.GuildMemberUpdate, (oldMember, updatedMember) => {
|
||||||
void processMentorshipRole(amari, oldMember, updatedMember);
|
void processMentorshipRole(amari, oldMember, updatedMember);
|
||||||
});
|
});
|
||||||
|
|
||||||
amari.discord.on(Events.GuildMemberAdd, (member) => {
|
amari.discord.on(Events.GuildMemberAdd, (member) => {
|
||||||
void logMenteeJoin(amari, member);
|
void logMenteeJoin(amari, member);
|
||||||
});
|
});
|
||||||
|
|
||||||
amari.discord.on(Events.GuildMemberRemove, (member) => {
|
amari.discord.on(Events.GuildMemberRemove, (member) => {
|
||||||
void logMenteeLeave(amari, member);
|
void logMenteeLeave(amari, member);
|
||||||
});
|
});
|
||||||
|
|
||||||
await amari.discord.login(process.env.BOT_TOKEN);
|
await amari.discord.login(process.env.BOT_TOKEN);
|
||||||
amari.discord.on(Events.MessageCreate, (message) => {
|
|
||||||
const channelType = message.channel.type;
|
|
||||||
console.log(`📩 [${channelType}] ${message.author.tag}: ${message.content}`);
|
|
||||||
});
|
|
||||||
instantiateServer(amari);
|
instantiateServer(amari);
|
||||||
|
|||||||
@@ -1,10 +1,14 @@
|
|||||||
|
/**
|
||||||
|
* @copyright NHCarrigan
|
||||||
|
* @license Naomi's Public License
|
||||||
|
* @author Teklu Abayneh
|
||||||
|
*/
|
||||||
|
|
||||||
import { REST, Routes } from "discord.js";
|
import { REST, Routes } from "discord.js";
|
||||||
import { forwardOwnerDM } from "../commands/forwardToOwner.js";
|
import { forwardOwnerDM } from "../commands/forwardToOwner.js";
|
||||||
|
import { logger } from "../utils/logger.js";
|
||||||
|
|
||||||
const commands = [
|
const commands = [ forwardOwnerDM.data.toJSON() ];
|
||||||
forwardOwnerDM.data.toJSON(),
|
|
||||||
];
|
|
||||||
|
|
||||||
const token = process.env.BOT_TOKEN;
|
const token = process.env.BOT_TOKEN;
|
||||||
const clientId = process.env.GH_CLIENT_ID;
|
const clientId = process.env.GH_CLIENT_ID;
|
||||||
|
|
||||||
@@ -16,17 +20,13 @@ if (clientId === undefined) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const rest = new REST({ version: "10" }).setToken(token);
|
const rest = new REST({ version: "10" }).setToken(token);
|
||||||
(async() => {
|
const requestCommand = async(): Promise<void> => {
|
||||||
try {
|
try {
|
||||||
console.log("Registering GLOBAL context menu command... wait till appear everywhere.");
|
await rest.put(Routes.applicationCommands(clientId), { body: commands });
|
||||||
|
|
||||||
await rest.put(
|
|
||||||
Routes.applicationCommands(clientId),
|
|
||||||
{ body: commands },
|
|
||||||
);
|
|
||||||
|
|
||||||
console.log("Global registration sent! then check right-click on a message → Apps.");
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Registration failed:", error);
|
if (error instanceof Error) {
|
||||||
|
await logger.error("operation", error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})();
|
};
|
||||||
|
requestCommand();
|
||||||
Reference in New Issue
Block a user