mirror of
https://github.com/ZeppelinBot/Zeppelin.git
synced 2025-05-25 10:25:01 +00:00
Merge branch 'ZeppelinBot:master' into master
This commit is contained in:
commit
00e5759233
5 changed files with 71 additions and 18 deletions
|
@ -10,6 +10,7 @@ import { onButtonInteraction } from "./events/buttonInteraction";
|
||||||
import { pluginInfo } from "./info";
|
import { pluginInfo } from "./info";
|
||||||
import { createButtonComponents } from "./functions/createButtonComponents";
|
import { createButtonComponents } from "./functions/createButtonComponents";
|
||||||
import { TooManyComponentsError } from "./functions/TooManyComponentsError";
|
import { TooManyComponentsError } from "./functions/TooManyComponentsError";
|
||||||
|
import { resetButtonsCmd } from "./commands/resetButtons";
|
||||||
|
|
||||||
export const RoleButtonsPlugin = zeppelinGuildPlugin<RoleButtonsPluginType>()({
|
export const RoleButtonsPlugin = zeppelinGuildPlugin<RoleButtonsPluginType>()({
|
||||||
name: "role_buttons",
|
name: "role_buttons",
|
||||||
|
@ -17,6 +18,21 @@ export const RoleButtonsPlugin = zeppelinGuildPlugin<RoleButtonsPluginType>()({
|
||||||
info: pluginInfo,
|
info: pluginInfo,
|
||||||
showInDocs: true,
|
showInDocs: true,
|
||||||
|
|
||||||
|
defaultOptions: {
|
||||||
|
config: {
|
||||||
|
buttons: {},
|
||||||
|
can_reset: false,
|
||||||
|
},
|
||||||
|
overrides: [
|
||||||
|
{
|
||||||
|
level: ">=100",
|
||||||
|
config: {
|
||||||
|
can_reset: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
configPreprocessor(options) {
|
configPreprocessor(options) {
|
||||||
// Auto-fill "name" property for buttons based on the object key
|
// Auto-fill "name" property for buttons based on the object key
|
||||||
const buttonsArray = Array.isArray(options.config?.buttons) ? options.config.buttons : [];
|
const buttonsArray = Array.isArray(options.config?.buttons) ? options.config.buttons : [];
|
||||||
|
@ -58,6 +74,8 @@ export const RoleButtonsPlugin = zeppelinGuildPlugin<RoleButtonsPluginType>()({
|
||||||
|
|
||||||
events: [onButtonInteraction],
|
events: [onButtonInteraction],
|
||||||
|
|
||||||
|
commands: [resetButtonsCmd],
|
||||||
|
|
||||||
beforeLoad(pluginData) {
|
beforeLoad(pluginData) {
|
||||||
pluginData.state.roleButtons = GuildRoleButtons.getGuildInstance(pluginData.guild.id);
|
pluginData.state.roleButtons = GuildRoleButtons.getGuildInstance(pluginData.guild.id);
|
||||||
},
|
},
|
||||||
|
|
27
backend/src/plugins/RoleButtons/commands/resetButtons.ts
Normal file
27
backend/src/plugins/RoleButtons/commands/resetButtons.ts
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
import { typedGuildCommand } from "knub";
|
||||||
|
import { RoleButtonsPluginType } from "../types";
|
||||||
|
import { commandTypeHelpers as ct } from "../../../commandTypes";
|
||||||
|
import { sendErrorMessage, sendSuccessMessage } from "../../../pluginUtils";
|
||||||
|
import { applyAllRoleButtons } from "../functions/applyAllRoleButtons";
|
||||||
|
|
||||||
|
export const resetButtonsCmd = typedGuildCommand<RoleButtonsPluginType>()({
|
||||||
|
trigger: "role_buttons reset",
|
||||||
|
description:
|
||||||
|
"In case of issues, you can run this command to have Zeppelin 'forget' about specific role buttons and re-apply them. This will also repost the message, if not targeting an existing message.",
|
||||||
|
usage: "!role_buttons reset my_roles",
|
||||||
|
permission: "can_reset",
|
||||||
|
signature: {
|
||||||
|
name: ct.string(),
|
||||||
|
},
|
||||||
|
async run({ pluginData, args, message }) {
|
||||||
|
const config = pluginData.config.get();
|
||||||
|
if (!config.buttons[args.name]) {
|
||||||
|
sendErrorMessage(pluginData, message.channel, `Can't find role buttons with the name "${args.name}"`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await pluginData.state.roleButtons.deleteRoleButtonItem(args.name);
|
||||||
|
await applyAllRoleButtons(pluginData);
|
||||||
|
sendSuccessMessage(pluginData, message.channel, "Done!");
|
||||||
|
},
|
||||||
|
});
|
|
@ -20,7 +20,7 @@ export async function applyRoleButtons(
|
||||||
if (existingSavedButtons?.channel_id) {
|
if (existingSavedButtons?.channel_id) {
|
||||||
const existingChannel = await pluginData.guild.channels.fetch(configItem.message.channel_id);
|
const existingChannel = await pluginData.guild.channels.fetch(configItem.message.channel_id);
|
||||||
const existingMessage = await (existingChannel?.isText() &&
|
const existingMessage = await (existingChannel?.isText() &&
|
||||||
existingChannel.messages.fetch(existingSavedButtons.message_id));
|
existingChannel.messages.fetch(existingSavedButtons.message_id).catch(() => null));
|
||||||
if (existingMessage && existingMessage.components.length) {
|
if (existingMessage && existingMessage.components.length) {
|
||||||
await existingMessage.edit({
|
await existingMessage.edit({
|
||||||
components: [],
|
components: [],
|
||||||
|
@ -32,7 +32,8 @@ export async function applyRoleButtons(
|
||||||
if ("message_id" in configItem.message) {
|
if ("message_id" in configItem.message) {
|
||||||
// channel id + message id: apply role buttons to existing message
|
// channel id + message id: apply role buttons to existing message
|
||||||
const channel = await pluginData.guild.channels.fetch(configItem.message.channel_id);
|
const channel = await pluginData.guild.channels.fetch(configItem.message.channel_id);
|
||||||
const messageCandidate = await (channel?.isText() && channel.messages.fetch(configItem.message.message_id));
|
const messageCandidate = await (channel?.isText() &&
|
||||||
|
channel.messages.fetch(configItem.message.message_id).catch(() => null));
|
||||||
if (!messageCandidate) {
|
if (!messageCandidate) {
|
||||||
pluginData.getPlugin(LogsPlugin).logBotAlert({
|
pluginData.getPlugin(LogsPlugin).logBotAlert({
|
||||||
body: `Message not found for role_buttons/${configItem.name}`,
|
body: `Message not found for role_buttons/${configItem.name}`,
|
||||||
|
@ -87,7 +88,7 @@ export async function applyRoleButtons(
|
||||||
candidateMessage = await channel.send(configItem.message.content as string | MessageOptions);
|
candidateMessage = await channel.send(configItem.message.content as string | MessageOptions);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
pluginData.getPlugin(LogsPlugin).logBotAlert({
|
pluginData.getPlugin(LogsPlugin).logBotAlert({
|
||||||
body: `Error while posting message for role_buttons/${configItem.name}`,
|
body: `Error while posting message for role_buttons/${configItem.name}: ${String(err)}`,
|
||||||
});
|
});
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -98,14 +99,19 @@ export async function applyRoleButtons(
|
||||||
|
|
||||||
if (message.author.id !== pluginData.client.user?.id) {
|
if (message.author.id !== pluginData.client.user?.id) {
|
||||||
pluginData.getPlugin(LogsPlugin).logBotAlert({
|
pluginData.getPlugin(LogsPlugin).logBotAlert({
|
||||||
body: `Error applying role buttons for role_buttons/${configItem.name}: target message must be posted by the bot`,
|
body: `Error applying role buttons for role_buttons/${configItem.name}: target message must be posted by Zeppelin`,
|
||||||
});
|
});
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply role buttons
|
// Apply role buttons
|
||||||
const components = createButtonComponents(configItem);
|
const components = createButtonComponents(configItem);
|
||||||
await message.edit({ components });
|
await message.edit({ components }).catch((err) => {
|
||||||
|
pluginData.getPlugin(LogsPlugin).logBotAlert({
|
||||||
|
body: `Error applying role buttons for role_buttons/${configItem.name}: ${String(err)}`,
|
||||||
|
});
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
channel_id: message.channelId,
|
channel_id: message.channelId,
|
||||||
|
|
|
@ -15,7 +15,7 @@ export const pluginInfo: ZeppelinGuildPluginBlueprint["info"] = {
|
||||||
config:
|
config:
|
||||||
buttons:
|
buttons:
|
||||||
my_roles: # You can use any name you want here, but make sure not to change it afterwards
|
my_roles: # You can use any name you want here, but make sure not to change it afterwards
|
||||||
messages:
|
message:
|
||||||
channel_id: "967407495544983552"
|
channel_id: "967407495544983552"
|
||||||
content: "Click the reactions below to get roles! Click again to remove the role."
|
content: "Click the reactions below to get roles! Click again to remove the role."
|
||||||
options:
|
options:
|
||||||
|
@ -37,7 +37,7 @@ export const pluginInfo: ZeppelinGuildPluginBlueprint["info"] = {
|
||||||
config:
|
config:
|
||||||
buttons:
|
buttons:
|
||||||
my_roles:
|
my_roles:
|
||||||
messages:
|
message:
|
||||||
channel_id: "967407495544983552"
|
channel_id: "967407495544983552"
|
||||||
content:
|
content:
|
||||||
embeds:
|
embeds:
|
||||||
|
@ -55,7 +55,7 @@ export const pluginInfo: ZeppelinGuildPluginBlueprint["info"] = {
|
||||||
config:
|
config:
|
||||||
buttons:
|
buttons:
|
||||||
my_roles:
|
my_roles:
|
||||||
messages:
|
message:
|
||||||
channel_id: "967407495544983552"
|
channel_id: "967407495544983552"
|
||||||
message_id: "967407554412040193"
|
message_id: "967407554412040193"
|
||||||
options:
|
options:
|
||||||
|
@ -69,7 +69,7 @@ export const pluginInfo: ZeppelinGuildPluginBlueprint["info"] = {
|
||||||
config:
|
config:
|
||||||
buttons:
|
buttons:
|
||||||
my_roles:
|
my_roles:
|
||||||
messages:
|
message:
|
||||||
channel_id: "967407495544983552"
|
channel_id: "967407495544983552"
|
||||||
message_id: "967407554412040193"
|
message_id: "967407554412040193"
|
||||||
exclusive: true # With this option set, only one role can be selected at a time
|
exclusive: true # With this option set, only one role can be selected at a time
|
||||||
|
|
|
@ -3,19 +3,20 @@ import { BasePluginType } from "knub";
|
||||||
import { tMessageContent, tNullable } from "../../utils";
|
import { tMessageContent, tNullable } from "../../utils";
|
||||||
import { GuildRoleButtons } from "../../data/GuildRoleButtons";
|
import { GuildRoleButtons } from "../../data/GuildRoleButtons";
|
||||||
|
|
||||||
enum ButtonStyles {
|
|
||||||
PRIMARY = 1,
|
|
||||||
SECONDARY = 2,
|
|
||||||
SUCCESS = 3,
|
|
||||||
DANGER = 4,
|
|
||||||
// LINK = 5, We do not want users to create link buttons, but it would be style 5
|
|
||||||
}
|
|
||||||
|
|
||||||
const RoleButtonOption = t.type({
|
const RoleButtonOption = t.type({
|
||||||
role_id: t.string,
|
role_id: t.string,
|
||||||
label: tNullable(t.string),
|
label: tNullable(t.string),
|
||||||
emoji: tNullable(t.string),
|
emoji: tNullable(t.string),
|
||||||
style: tNullable(t.keyof(ButtonStyles)), // https://discord.js.org/#/docs/discord.js/v13/typedef/MessageButtonStyle
|
// https://discord.js.org/#/docs/discord.js/v13/typedef/MessageButtonStyle
|
||||||
|
style: tNullable(
|
||||||
|
t.union([
|
||||||
|
t.literal("PRIMARY"),
|
||||||
|
t.literal("SECONDARY"),
|
||||||
|
t.literal("SUCCESS"),
|
||||||
|
t.literal("DANGER"),
|
||||||
|
// t.literal("LINK"), // Role buttons don't use link buttons, but adding this here so it's documented why it's not available
|
||||||
|
]),
|
||||||
|
),
|
||||||
start_new_row: tNullable(t.boolean),
|
start_new_row: tNullable(t.boolean),
|
||||||
});
|
});
|
||||||
export type TRoleButtonOption = t.TypeOf<typeof RoleButtonOption>;
|
export type TRoleButtonOption = t.TypeOf<typeof RoleButtonOption>;
|
||||||
|
@ -39,6 +40,7 @@ export type TRoleButtonsConfigItem = t.TypeOf<typeof RoleButtonsConfigItem>;
|
||||||
|
|
||||||
export const ConfigSchema = t.type({
|
export const ConfigSchema = t.type({
|
||||||
buttons: t.record(t.string, RoleButtonsConfigItem),
|
buttons: t.record(t.string, RoleButtonsConfigItem),
|
||||||
|
can_reset: t.boolean,
|
||||||
});
|
});
|
||||||
export type TConfigSchema = t.TypeOf<typeof ConfigSchema>;
|
export type TConfigSchema = t.TypeOf<typeof ConfigSchema>;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue