3
0
Fork 0
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:
Ruby 2022-04-23 21:26:33 +04:00 committed by GitHub
commit 00e5759233
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 71 additions and 18 deletions

View file

@ -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);
}, },

View 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!");
},
});

View file

@ -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,

View file

@ -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

View file

@ -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>;