styling fixes and some typing
diff --git a/src/reflex/guide.ts b/src/reflex/guide.ts
index 849c880..ef7b255 100644
--- a/src/reflex/guide.ts
+++ b/src/reflex/guide.ts
@@ -1,6 +1,15 @@
import { LoadingEmbed } from "./../utils/defaultEmbeds.js";
-import { SelectMenuOption } from "@discordjs/builders";
-import Discord, { MessageActionRow, MessageButton } from "discord.js";
+import Discord, {
+ MessageActionRow,
+ MessageButton,
+ MessageComponentInteraction,
+ MessageSelectOptionData,
+ Guild,
+ CommandInteraction,
+ GuildTextBasedChannel,
+ Message,
+ SelectMenuInteraction
+} from "discord.js";
import EmojiEmbed from "../utils/generateEmojiEmbed.js";
import getEmojiByName from "../utils/getEmojiByName.js";
import createPageIndicator from "../utils/createPageIndicator.js";
@@ -10,6 +19,11 @@
title: string;
description = "";
pageId = 0;
+
+ constructor() {
+ this.embed = new Discord.MessageEmbed();
+ this.title = "";
+ }
setEmbed(embed: Discord.MessageEmbed) {
this.embed = embed;
return this;
@@ -28,16 +42,26 @@
}
}
-export default async (guild, interaction?) => {
- let c = guild.publicUpdatesChannel ? guild.publicUpdatesChannel : guild.systemChannel;
+export default async (guild: Guild, interaction?: CommandInteraction) => {
+ let c: GuildTextBasedChannel | null = guild.publicUpdatesChannel ? guild.publicUpdatesChannel : guild.systemChannel;
c = c
? c
- : guild.channels.cache.find(
+ : (guild.channels.cache.find(
(ch) =>
- ch.type === "GUILD_TEXT" &&
+ [
+ "GUILD_TEXT",
+ "GUILD_NEWS",
+ "GUILD_NEWS_THREAD",
+ "GUILD_PRIVATE_THREAD",
+ "GUILD_PUBLIC_THREAD"
+ ].includes(ch.type) &&
ch.permissionsFor(guild.roles.everyone).has("SEND_MESSAGES") &&
- ch.permissionsFor(guild.me).has("EMBED_LINKS")
- );
+ ch.permissionsFor(guild.me!).has("EMBED_LINKS")
+ ) as GuildTextBasedChannel | undefined) ?? null;
+ if (interaction) c = interaction.channel as GuildTextBasedChannel;
+ if (!c) {
+ return;
+ }
const pages = [
new Embed()
.setEmbed(
@@ -188,37 +212,35 @@
.setDescription("Premium features")
.setPageId(7)
];
- let m;
+ let m: Message;
if (interaction) {
- m = await interaction.reply({
+ m = (await interaction.reply({
embeds: LoadingEmbed,
fetchReply: true,
ephemeral: true
- });
+ })) as Message;
} else {
m = await c.send({ embeds: LoadingEmbed });
}
let page = 0;
- const f = async (component) => {
+ const f = async (component: MessageComponentInteraction) => {
return (component.member as Discord.GuildMember).permissions.has("MANAGE_GUILD");
};
let selectPaneOpen = false;
while (true) {
- let selectPane = [];
+ let selectPane: MessageActionRow[] = [];
if (selectPaneOpen) {
- const options = [];
+ const options: MessageSelectOptionData[] = [];
pages.forEach((embed) => {
- options.push(
- new SelectMenuOption({
- label: embed.title,
- value: embed.pageId.toString(),
- description: embed.description || ""
- })
- );
+ options.push({
+ label: embed.title,
+ value: embed.pageId.toString(),
+ description: embed.description || ""
+ });
});
selectPane = [
new MessageActionRow().addComponents([
@@ -250,20 +272,19 @@
])
]);
if (interaction) {
- const em = new Discord.MessageEmbed(pages[page].embed);
+ const em = new Discord.MessageEmbed(pages[page]!.embed);
em.setDescription(em.description + "\n\n" + createPageIndicator(pages.length, page));
await interaction.editReply({
embeds: [em],
components: components
});
} else {
- const em = new Discord.MessageEmbed(pages[page].embed);
+ const em = new Discord.MessageEmbed(pages[page]!.embed);
em.setDescription(em.description + "\n\n" + createPageIndicator(pages.length, page));
- await m.edit({
+ (await m.edit({
embeds: [em],
- components: components,
- fetchReply: true
- });
+ components: components
+ })) as Message;
}
let i;
try {
@@ -279,7 +300,9 @@
break;
}
i.deferUpdate();
- if (i.component.customId === "left") {
+ if (!("customId" in i.component)) {
+ continue;
+ } else if (i.component.customId === "left") {
if (page > 0) page--;
selectPaneOpen = false;
} else if (i.component.customId === "right") {
@@ -288,11 +311,11 @@
} else if (i.component.customId === "select") {
selectPaneOpen = !selectPaneOpen;
} else if (i.component.customId === "page") {
- page = parseInt(i.values[0]);
+ page = parseInt((i as SelectMenuInteraction).values[0]!);
selectPaneOpen = false;
} else {
if (interaction) {
- const em = new Discord.MessageEmbed(pages[page].embed);
+ const em = new Discord.MessageEmbed(pages[page]!.embed);
em.setDescription(em.description + "\n\n" + createPageIndicator(pages.length, page));
em.setFooter({ text: "Message closed" });
interaction.editReply({
@@ -324,7 +347,7 @@
}
}
if (interaction) {
- const em = new Discord.MessageEmbed(pages[page].embed);
+ const em = new Discord.MessageEmbed(pages[page]!.embed);
em.setDescription(em.description + "\n\n" + createPageIndicator(pages.length, page)).setFooter({
text: "Message timed out"
});
@@ -351,7 +374,7 @@
]
});
} else {
- const em = new Discord.MessageEmbed(pages[page].embed);
+ const em = new Discord.MessageEmbed(pages[page]!.embed);
em.setDescription(em.description + "\n\n" + createPageIndicator(pages.length, page)).setFooter({
text: "Message timed out"
});
diff --git a/src/reflex/scanners.ts b/src/reflex/scanners.ts
index bd60f54..9761e4b 100644
--- a/src/reflex/scanners.ts
+++ b/src/reflex/scanners.ts
@@ -1,10 +1,10 @@
-// @ts-expect-error
-import * as us from "unscan";
import fetch from "node-fetch";
-import { writeFileSync } from "fs";
+import FormData from "form-data";
+import { writeFileSync, createReadStream } from "fs";
import generateFileName from "../utils/temp/generateFileName.js";
import Tesseract from "node-tesseract-ocr";
import type Discord from "discord.js";
+import client from "../utils/client.js";
interface NSFWSchema {
nsfw: boolean;
@@ -15,14 +15,68 @@
export async function testNSFW(link: string): Promise<NSFWSchema> {
const p = await saveAttachment(link);
- const result = await us.nsfw.file(p);
- return { nsfw: result.nsfw ?? false };
+ const data = new FormData();
+ console.log(link);
+ data.append("file", createReadStream(p));
+ const result = await fetch("https://unscan.p.rapidapi.com/", {
+ method: "POST",
+ headers: {
+ "X-RapidAPI-Key": client.config.rapidApiKey,
+ "X-RapidAPI-Host": "unscan.p.rapidapi.com"
+ },
+ body: data
+ })
+ .then((response) => response.json() as Promise<NSFWSchema>)
+ .catch((err) => {
+ console.error(err);
+ return { nsfw: false };
+ });
+ console.log(result);
+ return { nsfw: result.nsfw };
}
export async function testMalware(link: string): Promise<MalwareSchema> {
const p = await saveAttachment(link);
- const result = await us.malware.file(p);
- return { safe: result.safe ?? true };
+ const data = new FormData();
+ data.append("file", createReadStream(p));
+ console.log(link);
+ const result = await fetch("https://unscan.p.rapidapi.com/malware", {
+ method: "POST",
+ headers: {
+ "X-RapidAPI-Key": client.config.rapidApiKey,
+ "X-RapidAPI-Host": "unscan.p.rapidapi.com"
+ },
+ body: data
+ })
+ .then((response) => response.json() as Promise<MalwareSchema>)
+ .catch((err) => {
+ console.error(err);
+ return { safe: true };
+ });
+ console.log(result);
+ return { safe: result.safe };
+}
+
+export async function testLink(link: string): Promise<{ safe: boolean; tags: string[] }> {
+ console.log(link);
+ const scanned: { safe?: boolean; tags?: string[] } = await fetch("https://unscan.p.rapidapi.com/malware", {
+ method: "POST",
+ headers: {
+ "X-RapidAPI-Key": client.config.rapidApiKey,
+ "X-RapidAPI-Host": "unscan.p.rapidapi.com"
+ },
+ body: `{"link":"${link}"}`
+ })
+ .then((response) => response.json() as Promise<MalwareSchema>)
+ .catch((err) => {
+ console.error(err);
+ return { safe: true, tags: [] };
+ });
+ console.log(scanned);
+ return {
+ safe: scanned.safe ?? true,
+ tags: scanned.tags ?? []
+ };
}
export async function saveAttachment(link: string): Promise<string> {
@@ -32,19 +86,6 @@
return fileName;
}
-const defaultLinkTestResult: { safe: boolean; tags: string[] } = {
- safe: true,
- tags: []
-};
-export async function testLink(link: string): Promise<{ safe: boolean; tags: string[] }> {
- const scanned: { safe?: boolean; tags?: string[] } | undefined = await us.link.scan(link);
- if (scanned === undefined) return defaultLinkTestResult;
- return {
- safe: scanned.safe ?? defaultLinkTestResult.safe,
- tags: scanned.tags ?? defaultLinkTestResult.tags
- };
-}
-
const linkTypes = {
PHISHING: "Links designed to trick users into clicking on them.",
DATING: "Dating sites.",
diff --git a/src/reflex/statsChannelUpdate.ts b/src/reflex/statsChannelUpdate.ts
index a331537..644a75f 100644
--- a/src/reflex/statsChannelUpdate.ts
+++ b/src/reflex/statsChannelUpdate.ts
@@ -1,13 +1,15 @@
+// @ts-expect-error
+import type { HaikuClient } from "jshaiku";
+import type { GuildMember } from "discord.js";
import convertCurlyBracketString from "../utils/convertCurlyBracketString.js";
import singleNotify from "../utils/singleNotify.js";
-import client from "../utils/client.js";
interface PropSchema {
enabled: boolean;
name: string;
}
-export async function callback(_, member) {
+export async function callback(client: HaikuClient, member: GuildMember) {
const guild = await client.guilds.fetch(member.guild.id);
const config = await client.database.guilds.read(guild.id);
Object.entries(config.getKey("stats")).forEach(async ([channel, props]) => {
diff --git a/src/reflex/verify.ts b/src/reflex/verify.ts
index c366c8b..37f8d6c 100644
--- a/src/reflex/verify.ts
+++ b/src/reflex/verify.ts
@@ -1,5 +1,5 @@
import { LoadingEmbed } from "./../utils/defaultEmbeds.js";
-import Discord, { CommandInteraction, GuildMember, Interaction } from "discord.js";
+import Discord, { CommandInteraction, GuildMember, Interaction, Permissions, Role } from "discord.js";
import EmojiEmbed from "../utils/generateEmojiEmbed.js";
import fetch from "node-fetch";
import { TestString, NSFWCheck } from "./scanners.js";
@@ -28,7 +28,7 @@
ephemeral: true,
fetchReply: true
});
- const config = await client.database.guilds.read(interaction.guild.id);
+ const config = await client.database.guilds.read(interaction.guild!.id);
if (!config.verify.enabled || !config.verify.role)
return interaction.editReply({
embeds: [
@@ -36,15 +36,13 @@
.setTitle("Verify")
.setDescription("Verify is not enabled on this server")
.setFooter({
- text: interaction.member.permissions.has("MANAGE_GUILD")
+ text: (interaction.member!.permissions as Permissions).has("MANAGE_GUILD")
? "You can enable it by running /settings verify"
: ""
})
.setStatus("Danger")
.setEmoji("CONTROL.BLOCKCROSS")
- ],
- ephemeral: true,
- fetchReply: true
+ ]
});
if ((interaction.member as GuildMember).roles.cache.has(config.verify.role)) {
return await interaction.editReply({
@@ -114,7 +112,7 @@
});
if (
await NSFWCheck(
- (interaction.member as GuildMember).user.avatarURL({
+ (interaction.member as GuildMember).user.displayAvatarURL({
format: "png"
})
)
@@ -191,21 +189,37 @@
}
break;
}
+ const role: Role | null = await interaction.guild!.roles.fetch(config.verify.role);
+ if (!role) {
+ await interaction.editReply({
+ embeds: [
+ new EmojiEmbed()
+ .setTitle("Verify")
+ .setDescription(
+ "The server's verify role was deleted, or could not be found. Please contact a staff member to fix this issue." +
+ step(4)
+ )
+ .setStatus("Danger")
+ .setEmoji("CONTROL.BLOCKCROSS")
+ ]
+ });
+ return; // TODO: SEN
+ }
verify[code] = {
- uID: interaction.member.user.id,
- gID: interaction.guild.id,
+ uID: interaction.member!.user.id,
+ gID: interaction.guild!.id,
rID: config.verify.role,
- rName: (await interaction.guild.roles.fetch(config.verify.role)).name,
- uName: interaction.member.user.username,
- gName: interaction.guild.name,
- gIcon: interaction.guild.iconURL({ format: "png" }),
+ rName: role.name,
+ uName: interaction.member!.user.username,
+ gName: interaction.guild!.name,
+ gIcon: interaction.guild!.iconURL({ format: "png" }),
interaction: interaction
};
await interaction.editReply({
embeds: [
new EmojiEmbed()
.setTitle("Verify")
- .setDescription("Looking good!\nClick the button below to get verified" + step(4))
+ .setDescription("Looking good!\nClick the button below to get verified." + step(4))
.setStatus("Success")
.setEmoji("MEMBER.JOIN")
],
diff --git a/src/reflex/welcome.ts b/src/reflex/welcome.ts
index 56391ec..36a93fb 100644
--- a/src/reflex/welcome.ts
+++ b/src/reflex/welcome.ts
@@ -1,9 +1,12 @@
+// @ts-expect-error
+import type { HaikuClient } from "jshaiku";
import convertCurlyBracketString from "../utils/convertCurlyBracketString.js";
import client from "../utils/client.js";
import EmojiEmbed from "../utils/generateEmojiEmbed.js";
+import { GuildChannel, GuildMember, BaseGuildTextChannel } from "discord.js";
-export async function callback(_, member) {
- if (member.bot) return;
+export async function callback(_client: HaikuClient, member: GuildMember) {
+ if (member.user.bot) return;
const config = await client.database.guilds.read(member.guild.id);
if (!config.welcome.enabled) return;
@@ -22,9 +25,10 @@
embeds: [new EmojiEmbed().setDescription(string).setStatus("Success")]
});
} else {
- const channel = await member.guild.channels.fetch(config.welcome.channel);
+ const channel: GuildChannel | null = await member.guild.channels.fetch(config.welcome.channel);
+ if (!channel) return; // TODO: SEN
+ if (!(channel instanceof BaseGuildTextChannel)) return;
if (channel.guild.id !== member.guild.id) return;
- if (!channel) return;
try {
await channel.send({
embeds: [new EmojiEmbed().setDescription(string).setStatus("Success")],