Skip to content

Commit

Permalink
Adds message context menu commands for verification and unverification
Browse files Browse the repository at this point in the history
  • Loading branch information
PolariTOON committed Nov 3, 2023
1 parent bee1bc7 commit cf9534a
Show file tree
Hide file tree
Showing 13 changed files with 425 additions and 3 deletions.
4 changes: 4 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,12 @@ $ npm start

- `trailer` gives the links to the trailers of the game on `www.youtube.com`

- `unverification` refuses the author of the given message

- `update` gives the links to the latest updates of the game on `play.google.com` and `apps.apple.com`

- `verification` approves the author of the given message

### Hooks

- `approval` posts the latest member approval in the server in the given channel (set to `$SHICKA_APPROVAL_DEFAULT_CHANNEL` by default) and sends a direct message
Expand Down
6 changes: 6 additions & 0 deletions src/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ import soundtrackCommand from "./commands/soundtrack.js";
import storeCommand from "./commands/store.js";
import trackerCommand from "./commands/tracker.js";
import trailerCommand from "./commands/trailer.js";
import unverificationCommand from "./commands/unverification.js";
import updateCommand from "./commands/update.js";
import verificationCommand from "./commands/verification.js";
type ApplicationCommandData = ChatInputApplicationCommandData | MessageApplicationCommandData;
type ApplicationUserInteraction = AutocompleteInteraction<"cached"> | ChatInputCommandInteraction<"cached"> | MessageContextMenuCommandInteraction<"cached">;
type Command = {
Expand All @@ -45,7 +47,9 @@ const soundtrack: Command = soundtrackCommand;
const store: Command = storeCommand;
const tracker: Command = trackerCommand;
const trailer: Command = trailerCommand;
const unverification: Command = unverificationCommand;
const update: Command = updateCommand;
const verification: Command = verificationCommand;
export type {Command as default};
export type {
ApplicationCommand,
Expand All @@ -68,5 +72,7 @@ export {
store,
tracker,
trailer,
unverification,
update,
verification,
};
120 changes: 120 additions & 0 deletions src/commands/unverification.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import type {
Guild,
Message,
MessageReaction,
Role,
MessageContextMenuCommandInteraction,
GuildMember,
} from "discord.js";
import type Command from "../commands.js";
import type {ApplicationCommand, ApplicationCommandData, ApplicationUserInteraction} from "../commands.js";
import type {Unverification as UnverificationCompilation} from "../compilations.js";
import type {Unverification as UnverificationDefinition} from "../definitions.js";
import type {Unverification as UnverificationDependency} from "../dependencies.js";
import type {Locale, Localized} from "../utils/string.js";
import {
ApplicationCommandType,
} from "discord.js";
import {unverification as unverificationCompilation} from "../compilations.js";
import {unverification as unverificationDefinition} from "../definitions.js";
import {composeAll, localize, resolve} from "../utils/string.js";
type HelpGroups = UnverificationDependency["help"];
const {
commandName,
commandDescription,
}: UnverificationDefinition = unverificationDefinition;
const {
help: helpLocalizations,
reply: replyLocalizations,
noMemberReply: noMemberReplyLocalizations,
noPermissionReply: noPermissionReplyLocalizations,
}: UnverificationCompilation = unverificationCompilation;
const {
SHICKA_APPROVAL_VERIFICATION_ROLE,
SHICKA_REFUSAL_UNVERIFICATION_ROLE,
}: NodeJS.ProcessEnv = process.env;
const commandUnverificationRole: string = SHICKA_REFUSAL_UNVERIFICATION_ROLE ?? "";
const commandVerificationRole: string = SHICKA_APPROVAL_VERIFICATION_ROLE ?? "";
const unverificationCommand: Command = {
register(): ApplicationCommandData {
return {
type: ApplicationCommandType.Message,
name: commandName,
nameLocalizations: commandDescription,
defaultMemberPermissions: [],
dmPermission: false,
};
},
async interact(interaction: ApplicationUserInteraction): Promise<void> {
if (!interaction.isMessageContextMenuCommand()) {
return;
}
const {guild, locale, targetMessage}: MessageContextMenuCommandInteraction<"cached"> = interaction;
const resolvedLocale: Locale = resolve(locale);
const {roles}: Guild = guild;
const unverificationRole: Role | undefined = roles.cache.find((role: Role): boolean => {
return role.name === commandUnverificationRole;
});
if (unverificationRole == null) {
return;
}
const verificationRole: Role | undefined = roles.cache.find((role: Role): boolean => {
return role.name === commandVerificationRole;
});
if (verificationRole == null) {
return;
}
const member: GuildMember | undefined = await (async (): Promise<GuildMember | undefined> => {
try {
const {author, member}: Message<true> = targetMessage;
if (member == null) {
const memberId: string = author.id;
const member: GuildMember | undefined = guild.members.cache.get(memberId);
if (member == null) {
return await guild.members.fetch(memberId);
}
return member;
}
return member;
} catch {}
})();
if (member == null) {
await interaction.reply({
content: noMemberReplyLocalizations[resolvedLocale]({}),
ephemeral: true,
});
return;
}
try {
await member.roles.remove(verificationRole);
await member.roles.remove(unverificationRole);
} catch {
await interaction.reply({
content: noPermissionReplyLocalizations[resolvedLocale]({}),
ephemeral: true,
});
return;
}
await targetMessage.react("❎");
const reaction: MessageReaction | undefined = targetMessage.reactions.cache.find((reaction: MessageReaction): boolean => {
return (reaction.emoji.name ?? "") === "✅";
});
if (reaction != null) {
await reaction.users.remove();
}
await interaction.reply({
content: replyLocalizations[resolvedLocale]({}),
ephemeral: true,
});
},
describe(applicationCommand: ApplicationCommand): Localized<(groups: {}) => string> {
return composeAll<HelpGroups, {}>(helpLocalizations, localize<HelpGroups>((locale: Locale): HelpGroups => {
return {
commandMention: (): string => {
return commandDescription[locale];
},
};
}));
},
};
export default unverificationCommand;
120 changes: 120 additions & 0 deletions src/commands/verification.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import type {
Guild,
Message,
MessageReaction,
Role,
MessageContextMenuCommandInteraction,
GuildMember,
} from "discord.js";
import type Command from "../commands.js";
import type {ApplicationCommand, ApplicationCommandData, ApplicationUserInteraction} from "../commands.js";
import type {Verification as VerificationCompilation} from "../compilations.js";
import type {Verification as VerificationDefinition} from "../definitions.js";
import type {Verification as VerificationDependency} from "../dependencies.js";
import type {Locale, Localized} from "../utils/string.js";
import {
ApplicationCommandType,
} from "discord.js";
import {verification as verificationCompilation} from "../compilations.js";
import {verification as verificationDefinition} from "../definitions.js";
import {composeAll, localize, resolve} from "../utils/string.js";
type HelpGroups = VerificationDependency["help"];
const {
commandName,
commandDescription,
}: VerificationDefinition = verificationDefinition;
const {
help: helpLocalizations,
reply: replyLocalizations,
noMemberReply: noMemberReplyLocalizations,
noPermissionReply: noPermissionReplyLocalizations,
}: VerificationCompilation = verificationCompilation;
const {
SHICKA_APPROVAL_VERIFICATION_ROLE,
SHICKA_REFUSAL_UNVERIFICATION_ROLE,
}: NodeJS.ProcessEnv = process.env;
const commandUnverificationRole: string = SHICKA_REFUSAL_UNVERIFICATION_ROLE ?? "";
const commandVerificationRole: string = SHICKA_APPROVAL_VERIFICATION_ROLE ?? "";
const verificationCommand: Command = {
register(): ApplicationCommandData {
return {
type: ApplicationCommandType.Message,
name: commandName,
nameLocalizations: commandDescription,
defaultMemberPermissions: [],
dmPermission: false,
};
},
async interact(interaction: ApplicationUserInteraction): Promise<void> {
if (!interaction.isMessageContextMenuCommand()) {
return;
}
const {guild, locale, targetMessage}: MessageContextMenuCommandInteraction<"cached"> = interaction;
const resolvedLocale: Locale = resolve(locale);
const {roles}: Guild = guild;
const unverificationRole: Role | undefined = roles.cache.find((role: Role): boolean => {
return role.name === commandUnverificationRole;
});
if (unverificationRole == null) {
return;
}
const verificationRole: Role | undefined = roles.cache.find((role: Role): boolean => {
return role.name === commandVerificationRole;
});
if (verificationRole == null) {
return;
}
const member: GuildMember | undefined = await (async (): Promise<GuildMember | undefined> => {
try {
const {author, member}: Message<true> = targetMessage;
if (member == null) {
const memberId: string = author.id;
const member: GuildMember | undefined = guild.members.cache.get(memberId);
if (member == null) {
return await guild.members.fetch(memberId);
}
return member;
}
return member;
} catch {}
})();
if (member == null) {
await interaction.reply({
content: noMemberReplyLocalizations[resolvedLocale]({}),
ephemeral: true,
});
return;
}
try {
await member.roles.add(verificationRole);
await member.roles.remove(unverificationRole);
} catch {
await interaction.reply({
content: noPermissionReplyLocalizations[resolvedLocale]({}),
ephemeral: true,
});
return;
}
await targetMessage.react("✅");
const reaction: MessageReaction | undefined = targetMessage.reactions.cache.find((reaction: MessageReaction): boolean => {
return (reaction.emoji.name ?? "") === "❎";
});
if (reaction != null) {
await reaction.users.remove();
}
await interaction.reply({
content: replyLocalizations[resolvedLocale]({}),
ephemeral: true,
});
},
describe(applicationCommand: ApplicationCommand): Localized<(groups: {}) => string> {
return composeAll<HelpGroups, {}>(helpLocalizations, localize<HelpGroups>((locale: Locale): HelpGroups => {
return {
commandMention: (): string => {
return commandDescription[locale];
},
};
}));
},
};
export default verificationCommand;
12 changes: 11 additions & 1 deletion src/compilations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ import soundtrackCompilation from "./compilations/soundtrack.js";
import storeCompilation from "./compilations/store.js";
import trackerCompilation from "./compilations/tracker.js";
import trailerCompilation from "./compilations/trailer.js";
import unverificationCompilation from "./compilations/unverification.js";
import updateCompilation from "./compilations/update.js";
import verificationCompilation from "./compilations/verification.js";
type About = typeof aboutCompilation;
type Approval = typeof approvalCompilation;
type Arrival = typeof arrivalCompilation;
Expand All @@ -41,8 +43,10 @@ type Soundtrack = typeof soundtrackCompilation;
type Store = typeof storeCompilation;
type Tracker = typeof trackerCompilation;
type Trailer = typeof trailerCompilation;
type Unverification = typeof unverificationCompilation;
type Update = typeof updateCompilation;
type Compilation = About | Approval | Arrival | Bear | Chat | Count | Departure | Emoji | Help | Leaderboard | Mission | Outfit | Raw | Record | Refusal | Roadmap | Rule7 | Soundtrack | Store | Tracker | Trailer | Update;
type Verification = typeof verificationCompilation;
type Compilation = About | Approval | Arrival | Bear | Chat | Count | Departure | Emoji | Help | Leaderboard | Mission | Outfit | Raw | Record | Refusal | Roadmap | Rule7 | Soundtrack | Store | Tracker | Trailer | Unverification | Update | Verification;
const about: About = aboutCompilation;
const approval: Approval = approvalCompilation;
const arrival: Arrival = arrivalCompilation;
Expand All @@ -64,7 +68,9 @@ const soundtrack: Soundtrack = soundtrackCompilation;
const store: Store = storeCompilation;
const tracker: Tracker = trackerCompilation;
const trailer: Trailer = trailerCompilation;
const unverification: Unverification = unverificationCompilation;
const update: Update = updateCompilation;
const verification: Verification = verificationCompilation;
export type {Compilation as default};
export type {
About,
Expand All @@ -88,7 +94,9 @@ export type {
Store,
Tracker,
Trailer,
Unverification,
Update,
Verification,
};
export {
about,
Expand All @@ -112,5 +120,7 @@ export {
store,
tracker,
trailer,
unverification,
update,
verification,
};
25 changes: 25 additions & 0 deletions src/compilations/unverification.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import type {Unverification} from "../dependencies.js";
import type {Localized} from "../utils/string.js";
import {unverification} from "../definitions.js";
import {compileAll} from "../utils/string.js";
type HelpLocalizations = Localized<(groups: Unverification["help"]) => string>;
type ReplyLocalizations = Localized<(groups: Unverification["reply"]) => string>;
type NoMemberReplyLocalizations = Localized<(groups: Unverification["noMemberReply"]) => string>;
type NoPermissionReplyLocalizations = Localized<(groups: Unverification["noPermissionReply"]) => string>;
type UnverificationCompilation = {
help: HelpLocalizations,
reply: ReplyLocalizations,
noMemberReply: NoMemberReplyLocalizations,
noPermissionReply: NoPermissionReplyLocalizations,
};
const helpLocalizations: HelpLocalizations = compileAll<Unverification["help"]>(unverification["help"]);
const replyLocalizations: ReplyLocalizations = compileAll<Unverification["reply"]>(unverification["reply"]);
const noMemberReplyLocalizations: NoMemberReplyLocalizations = compileAll<Unverification["noMemberReply"]>(unverification["noMemberReply"]);
const noPermissionReplyLocalizations: NoPermissionReplyLocalizations = compileAll<Unverification["noPermissionReply"]>(unverification["noPermissionReply"]);
const unverificationCompilation: UnverificationCompilation = {
help: helpLocalizations,
reply: replyLocalizations,
noMemberReply: noMemberReplyLocalizations,
noPermissionReply: noPermissionReplyLocalizations,
};
export default unverificationCompilation;
25 changes: 25 additions & 0 deletions src/compilations/verification.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import type {Verification} from "../dependencies.js";
import type {Localized} from "../utils/string.js";
import {verification} from "../definitions.js";
import {compileAll} from "../utils/string.js";
type HelpLocalizations = Localized<(groups: Verification["help"]) => string>;
type ReplyLocalizations = Localized<(groups: Verification["reply"]) => string>;
type NoMemberReplyLocalizations = Localized<(groups: Verification["noMemberReply"]) => string>;
type NoPermissionReplyLocalizations = Localized<(groups: Verification["noPermissionReply"]) => string>;
type VerificationCompilation = {
help: HelpLocalizations,
reply: ReplyLocalizations,
noMemberReply: NoMemberReplyLocalizations,
noPermissionReply: NoPermissionReplyLocalizations,
};
const helpLocalizations: HelpLocalizations = compileAll<Verification["help"]>(verification["help"]);
const replyLocalizations: ReplyLocalizations = compileAll<Verification["reply"]>(verification["reply"]);
const noMemberReplyLocalizations: NoMemberReplyLocalizations = compileAll<Verification["noMemberReply"]>(verification["noMemberReply"]);
const noPermissionReplyLocalizations: NoPermissionReplyLocalizations = compileAll<Verification["noPermissionReply"]>(verification["noPermissionReply"]);
const verificationCompilation: VerificationCompilation = {
help: helpLocalizations,
reply: replyLocalizations,
noMemberReply: noMemberReplyLocalizations,
noPermissionReply: noPermissionReplyLocalizations,
};
export default verificationCompilation;
Loading

0 comments on commit cf9534a

Please sign in to comment.