mirror of
https://github.com/ZeppelinBot/Zeppelin.git
synced 2025-03-15 05:41:51 +00:00
more fixes
Signed-off-by: GitHub <noreply@github.com>
This commit is contained in:
parent
343a91e3c3
commit
c33a216857
23 changed files with 81 additions and 58 deletions
|
@ -56,7 +56,7 @@ export function initDocs(app: express.Express) {
|
|||
const name = plugin.name;
|
||||
const info = plugin.info || {};
|
||||
|
||||
const commands = (plugin.commands || []).map((cmd) => ({
|
||||
const commands = (plugin.messageCommands || []).map((cmd) => ({
|
||||
trigger: cmd.trigger,
|
||||
permission: cmd.permission,
|
||||
signature: cmd.signature,
|
||||
|
|
|
@ -1,5 +1,18 @@
|
|||
import { GuildChannel, GuildMember, Snowflake, Util, User, GuildTextBasedChannel } from "discord.js";
|
||||
import { baseCommandParameterTypeHelpers, baseTypeConverters, CommandContext, TypeConversionError } from "knub";
|
||||
import {
|
||||
GuildChannel,
|
||||
GuildMember,
|
||||
Snowflake,
|
||||
User,
|
||||
GuildTextBasedChannel,
|
||||
escapeCodeBlock,
|
||||
escapeInlineCode,
|
||||
} from "discord.js";
|
||||
import {
|
||||
baseCommandParameterTypeHelpers,
|
||||
messageCommandBaseTypeConverters,
|
||||
CommandContext,
|
||||
TypeConversionError,
|
||||
} from "knub";
|
||||
import { createTypeHelper } from "knub-command-manager";
|
||||
import {
|
||||
channelMentionRegex,
|
||||
|
@ -14,11 +27,9 @@ import {
|
|||
import { isValidTimezone } from "./utils/isValidTimezone";
|
||||
import { MessageTarget, resolveMessageTarget } from "./utils/resolveMessageTarget";
|
||||
import { inputPatternToRegExp } from "./validatorUtils";
|
||||
import { getChannelId } from "knub/dist/utils";
|
||||
import { disableCodeBlocks } from "knub/dist/helpers";
|
||||
|
||||
export const commandTypes = {
|
||||
...baseTypeConverters,
|
||||
...messageCommandBaseTypeConverters,
|
||||
|
||||
delay(value) {
|
||||
const result = convertDelayStringToMS(value);
|
||||
|
@ -32,7 +43,7 @@ export const commandTypes = {
|
|||
async resolvedUser(value, context: CommandContext<any>) {
|
||||
const result = await resolveUser(context.pluginData.client, value);
|
||||
if (result == null || result instanceof UnknownUser) {
|
||||
throw new TypeConversionError(`User \`${Util.escapeCodeBlock(value)}\` was not found`);
|
||||
throw new TypeConversionError(`User \`${escapeCodeBlock(value)}\` was not found`);
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
@ -40,7 +51,7 @@ export const commandTypes = {
|
|||
async resolvedUserLoose(value, context: CommandContext<any>) {
|
||||
const result = await resolveUser(context.pluginData.client, value);
|
||||
if (result == null) {
|
||||
throw new TypeConversionError(`Invalid user: \`${Util.escapeCodeBlock(value)}\``);
|
||||
throw new TypeConversionError(`Invalid user: \`${escapeCodeBlock(value)}\``);
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
@ -52,9 +63,7 @@ export const commandTypes = {
|
|||
|
||||
const result = await resolveMember(context.pluginData.client, context.message.channel.guild, value);
|
||||
if (result == null) {
|
||||
throw new TypeConversionError(
|
||||
`Member \`${Util.escapeCodeBlock(value)}\` was not found or they have left the server`,
|
||||
);
|
||||
throw new TypeConversionError(`Member \`${escapeCodeBlock(value)}\` was not found or they have left the server`);
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
@ -64,7 +73,7 @@ export const commandTypes = {
|
|||
|
||||
const result = await resolveMessageTarget(context.pluginData, value);
|
||||
if (!result) {
|
||||
throw new TypeConversionError(`Unknown message \`${Util.escapeInlineCode(value)}\``);
|
||||
throw new TypeConversionError(`Unknown message \`${escapeInlineCode(value)}\``);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -84,20 +93,20 @@ export const commandTypes = {
|
|||
return value as Snowflake;
|
||||
}
|
||||
|
||||
throw new TypeConversionError(`Could not parse ID: \`${Util.escapeInlineCode(value)}\``);
|
||||
throw new TypeConversionError(`Could not parse ID: \`${escapeInlineCode(value)}\``);
|
||||
},
|
||||
|
||||
regex(value: string, context: CommandContext<any>): RegExp {
|
||||
try {
|
||||
return inputPatternToRegExp(value);
|
||||
} catch (e) {
|
||||
throw new TypeConversionError(`Could not parse RegExp: \`${Util.escapeInlineCode(e.message)}\``);
|
||||
throw new TypeConversionError(`Could not parse RegExp: \`${escapeInlineCode(e.message)}\``);
|
||||
}
|
||||
},
|
||||
|
||||
timezone(value: string) {
|
||||
if (!isValidTimezone(value)) {
|
||||
throw new TypeConversionError(`Invalid timezone: ${Util.escapeInlineCode(value)}`);
|
||||
throw new TypeConversionError(`Invalid timezone: ${escapeInlineCode(value)}`);
|
||||
}
|
||||
|
||||
return value;
|
||||
|
@ -105,7 +114,7 @@ export const commandTypes = {
|
|||
|
||||
guildTextBasedChannel(value: string, context: CommandContext<any>) {
|
||||
// FIXME: Remove once Knub's types have been fixed
|
||||
return baseTypeConverters.textChannel(value, context) as GuildTextBasedChannel;
|
||||
return messageCommandBaseTypeConverters.textChannel(value, context) as GuildTextBasedChannel;
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -53,13 +53,13 @@ export class GuildSavedMessages extends BaseGuildRepository<SavedMessage> {
|
|||
title: embed.title,
|
||||
description: embed.description,
|
||||
url: embed.url,
|
||||
timestamp: embed.timestamp,
|
||||
timestamp: embed.timestamp ? Date.parse(embed.timestamp) : null,
|
||||
color: embed.color,
|
||||
|
||||
fields: embed.fields.map((field) => ({
|
||||
name: field.name,
|
||||
value: field.value,
|
||||
inline: field.inline,
|
||||
inline: field.inline ?? false,
|
||||
})),
|
||||
|
||||
author: embed.author
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Snowflake } from "discord.js";
|
||||
import { Snowflake, StickerFormatType, StickerType } from "discord.js";
|
||||
import { Column, Entity, PrimaryColumn } from "typeorm";
|
||||
|
||||
export interface ISavedMessageAttachmentData {
|
||||
|
@ -55,13 +55,13 @@ export interface ISavedMessageEmbedData {
|
|||
}
|
||||
|
||||
export interface ISavedMessageStickerData {
|
||||
format: string;
|
||||
format: StickerFormatType;
|
||||
guildId: Snowflake | null;
|
||||
id: Snowflake;
|
||||
name: string;
|
||||
description: string | null;
|
||||
available: boolean | null;
|
||||
type: string | null;
|
||||
type: StickerType | null;
|
||||
}
|
||||
|
||||
export interface ISavedMessageData {
|
||||
|
|
|
@ -38,7 +38,7 @@ export const AlertAction = automodAction({
|
|||
const channel = pluginData.guild.channels.cache.get(actionConfig.channel as Snowflake);
|
||||
const logs = pluginData.getPlugin(LogsPlugin);
|
||||
|
||||
if (channel?.isText()) {
|
||||
if (channel?.isTextBased()) {
|
||||
const text = actionConfig.text;
|
||||
const theMessageLink =
|
||||
contexts[0].message && messageLink(pluginData.guild.id, contexts[0].message.channel_id, contexts[0].message.id);
|
||||
|
|
|
@ -36,7 +36,7 @@ export const ReplyAction = automodAction({
|
|||
.filter((c) => c.message?.channel_id)
|
||||
.filter((c) => {
|
||||
const channel = pluginData.guild.channels.cache.get(c.message!.channel_id as Snowflake);
|
||||
return channel?.isText();
|
||||
return channel?.isTextBased();
|
||||
});
|
||||
|
||||
const contextsByChannelId = contextsWithTextChannels.reduce((map: Map<string, AutomodContext[]>, context) => {
|
||||
|
|
|
@ -32,7 +32,7 @@ export const StartThreadAction = automodAction({
|
|||
const threads = contexts.filter((c) => {
|
||||
if (!c.message || !c.user) return false;
|
||||
const channel = pluginData.guild.channels.cache.get(c.message.channel_id);
|
||||
if (channel?.type !== ChannelTypeStrings.TEXT || !channel.isText()) return false; // for some reason the typing here for channel.type defaults to ThreadChannelTypes (?)
|
||||
if (channel?.type !== ChannelTypeStrings.TEXT || !channel.isTextBased()) return false; // for some reason the typing here for channel.type defaults to ThreadChannelTypes (?)
|
||||
// check against max threads per channel
|
||||
if (actionConfig.limit_per_channel && actionConfig.limit_per_channel > 0) {
|
||||
const threadCount = channel.threads.cache.filter(
|
||||
|
|
|
@ -19,7 +19,7 @@ export function resolveActionContactMethods(
|
|||
}
|
||||
|
||||
const channel = pluginData.guild.channels.cache.get(actionConfig.notifyChannel as Snowflake);
|
||||
if (!channel?.isText()) {
|
||||
if (!channel?.isTextBased()) {
|
||||
throw new RecoverablePluginError(ERRORS.INVALID_USER_NOTIFICATION_CHANNEL);
|
||||
}
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@ export const ViewCounterCmd = guildPluginMessageCommand<CountersPluginType>()({
|
|||
}
|
||||
|
||||
const potentialChannel = pluginData.guild.channels.resolve(reply.content as Snowflake);
|
||||
if (!potentialChannel?.isText()) {
|
||||
if (!potentialChannel?.isTextBased()) {
|
||||
sendErrorMessage(pluginData, message.channel, "Channel is not a text channel, cancelling");
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -88,7 +88,7 @@ export async function log<TLogType extends keyof ILogTypeData>(
|
|||
|
||||
logChannelLoop: for (const [channelId, opts] of Object.entries(logChannels)) {
|
||||
const channel = pluginData.guild.channels.cache.get(channelId as Snowflake);
|
||||
if (!channel?.isText()) continue;
|
||||
if (!channel?.isTextBased()) continue;
|
||||
if (pluginData.state.channelCooldowns.isOnCooldown(channelId)) continue;
|
||||
if (opts.include?.length && !opts.include.includes(typeStr)) continue;
|
||||
if (opts.exclude && opts.exclude.includes(typeStr)) continue;
|
||||
|
|
|
@ -186,7 +186,7 @@ export async function muteUser(
|
|||
const channel = config.message_channel
|
||||
? pluginData.guild.channels.cache.get(config.message_channel as Snowflake)
|
||||
: null;
|
||||
if (useChannel && channel?.isText()) {
|
||||
if (useChannel && channel?.isTextBased()) {
|
||||
contactMethods.push({ type: "channel", channel });
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ export async function actualPostCmd(
|
|||
"repeat-times"?: number;
|
||||
} = {},
|
||||
) {
|
||||
if (!targetChannel.isText()) {
|
||||
if (!targetChannel.isTextBased()) {
|
||||
msg.channel.send(errorMessage("Specified channel is not a text-based channel"));
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ export async function postScheduledPost(pluginData: GuildPluginData<PostPluginTy
|
|||
|
||||
// Post the message
|
||||
const channel = pluginData.guild.channels.cache.get(post.channel_id as Snowflake);
|
||||
if (channel?.isText() || channel?.isThread()) {
|
||||
if (channel?.isTextBased() || channel?.isThread()) {
|
||||
const [username, discriminator] = post.author_name.split("#");
|
||||
const author: User = (await pluginData.client.users.fetch(post.author_id as Snowflake)) || {
|
||||
id: post.author_id,
|
||||
|
|
|
@ -9,7 +9,7 @@ import humanizeDuration from "humanize-duration";
|
|||
|
||||
export async function postReminder(pluginData: GuildPluginData<RemindersPluginType>, reminder: Reminder) {
|
||||
const channel = pluginData.guild.channels.cache.get(reminder.channel_id as Snowflake);
|
||||
if (channel && (channel.isText() || channel.isThread())) {
|
||||
if (channel && (channel.isTextBased() || channel.isThread())) {
|
||||
try {
|
||||
// Only show created at date if one exists
|
||||
if (moment.utc(reminder.created_at).isValid()) {
|
||||
|
|
|
@ -19,7 +19,7 @@ export async function applyRoleButtons(
|
|||
// Remove existing role buttons, if any
|
||||
if (existingSavedButtons?.channel_id) {
|
||||
const existingChannel = await pluginData.guild.channels.fetch(configItem.message.channel_id).catch(() => null);
|
||||
const existingMessage = await (existingChannel?.isText() &&
|
||||
const existingMessage = await (existingChannel?.isTextBased() &&
|
||||
existingChannel.messages.fetch(existingSavedButtons.message_id).catch(() => null));
|
||||
if (existingMessage && existingMessage.components.length) {
|
||||
await existingMessage.edit({
|
||||
|
@ -32,7 +32,7 @@ export async function applyRoleButtons(
|
|||
if ("message_id" in configItem.message) {
|
||||
// channel id + message id: apply role buttons to existing message
|
||||
const channel = await pluginData.guild.channels.fetch(configItem.message.channel_id).catch(() => null);
|
||||
const messageCandidate = await (channel?.isText() &&
|
||||
const messageCandidate = await (channel?.isTextBased() &&
|
||||
channel.messages.fetch(configItem.message.message_id).catch(() => null));
|
||||
if (!messageCandidate) {
|
||||
pluginData.getPlugin(LogsPlugin).logBotAlert({
|
||||
|
@ -55,10 +55,10 @@ export async function applyRoleButtons(
|
|||
}
|
||||
|
||||
const channel = await pluginData.guild.channels.fetch(configItem.message.channel_id).catch(() => null);
|
||||
if (channel && (!channel.isText || typeof channel.isText !== "function")) {
|
||||
if (channel && (!channel.isTextBased || typeof channel.isTextBased !== "function")) {
|
||||
console.log("wtf", pluginData.guild?.id, configItem.message.channel_id);
|
||||
}
|
||||
if (!channel || !channel?.isText?.()) {
|
||||
if (!channel || !channel?.isTextBased()) {
|
||||
pluginData.getPlugin(LogsPlugin).logBotAlert({
|
||||
body: `Text channel not found for role_buttons/${configItem.name}`,
|
||||
});
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { ChannelType } from "discord.js";
|
||||
import { GuildPluginData } from "knub";
|
||||
import { StarboardMessage } from "../../../data/entities/StarboardMessage";
|
||||
import { noop } from "../../../utils";
|
||||
|
@ -12,7 +13,7 @@ export async function removeMessageFromStarboard(
|
|||
|
||||
// this code is now Almeida-certified and no longer ugly :ok_hand: :cake:
|
||||
const channel = pluginData.client.channels.cache.find((c) => c.id === msg.starboard_channel_id);
|
||||
if (!channel?.isText()) return;
|
||||
if (channel?.type !== ChannelType.GuildText) return;
|
||||
const message = await channel.messages.fetch(msg.starboard_message_id).catch(noop);
|
||||
if (!message?.deletable) return;
|
||||
await message.delete().catch(noop);
|
||||
|
|
|
@ -81,7 +81,7 @@ export async function cleanCmd(pluginData: GuildPluginData<UtilityPluginType>, a
|
|||
}
|
||||
|
||||
const targetChannel = args.channel ? pluginData.guild.channels.cache.get(args.channel as Snowflake) : msg.channel;
|
||||
if (!targetChannel?.isText()) {
|
||||
if (!targetChannel?.isTextBased()) {
|
||||
sendErrorMessage(pluginData, msg.channel, `Invalid channel specified`);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { MessageEmbedOptions, Role } from "discord.js";
|
||||
import { MessageEmbedOptions } from "discord.js";
|
||||
import humanizeDuration from "humanize-duration";
|
||||
import { GuildPluginData } from "knub";
|
||||
import moment from "moment-timezone";
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import * as t from "io-ts";
|
||||
import { BaseConfig, Knub } from "knub";
|
||||
|
||||
export interface ZeppelinGuildConfig extends BaseConfig<any> {
|
||||
export interface ZeppelinGuildConfig extends BaseConfig {
|
||||
success_emoji?: string;
|
||||
error_emoji?: string;
|
||||
|
||||
|
@ -26,7 +26,7 @@ export const ZeppelinGuildConfigSchema = t.type({
|
|||
});
|
||||
export const PartialZeppelinGuildConfigSchema = t.partial(ZeppelinGuildConfigSchema.props);
|
||||
|
||||
export interface ZeppelinGlobalConfig extends BaseConfig<any> {
|
||||
export interface ZeppelinGlobalConfig extends BaseConfig {
|
||||
url: string;
|
||||
owners?: string[];
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ export const ZeppelinGlobalConfigSchema = t.type({
|
|||
plugins: t.record(t.string, t.unknown),
|
||||
});
|
||||
|
||||
export type TZeppelinKnub = Knub<ZeppelinGuildConfig, ZeppelinGlobalConfig>;
|
||||
export type TZeppelinKnub = Knub;
|
||||
|
||||
/**
|
||||
* Wrapper for the string type that indicates the text will be parsed as Markdown later
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import { Channel, ThreadChannel } from "discord.js";
|
||||
import { AnyThreadChannel, Channel, ChannelType } from "discord.js";
|
||||
import { ChannelTypeStrings } from "src/types";
|
||||
|
||||
export function isThreadChannel(channel: Channel): channel is ThreadChannel {
|
||||
export function isThreadChannel(channel: Channel): channel is AnyThreadChannel {
|
||||
return (
|
||||
channel.type === ChannelTypeStrings.NEWS_THREAD ||
|
||||
channel.type === ChannelTypeStrings.PUBLIC_THREAD ||
|
||||
channel.type === ChannelTypeStrings.PRIVATE_THREAD
|
||||
channel.type === ChannelType.PublicThread ||
|
||||
channel.type === ChannelType.PrivateThread ||
|
||||
channel.type === ChannelType.AnnouncementThread
|
||||
);
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ export async function resolveMessageTarget(pluginData: GuildPluginData<any>, val
|
|||
}
|
||||
|
||||
const channel = pluginData.guild.channels.resolve(result.channelId as Snowflake);
|
||||
if (!channel?.isText()) {
|
||||
if (!channel?.isTextBased()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ import {
|
|||
Snowflake,
|
||||
StageInstance,
|
||||
Sticker,
|
||||
StickerFormatType,
|
||||
ThreadChannel,
|
||||
User,
|
||||
} from "discord.js";
|
||||
|
@ -239,7 +240,7 @@ export function userToTemplateSafeUser(user: User | UnknownUser): TemplateSafeUs
|
|||
discriminator: user.discriminator,
|
||||
mention: `<@${user.id}>`,
|
||||
tag: user.tag,
|
||||
avatarURL: user.displayAvatarURL?.({ dynamic: true }),
|
||||
avatarURL: user.displayAvatarURL?.(),
|
||||
bot: user.bot,
|
||||
createdAt: user.createdTimestamp,
|
||||
});
|
||||
|
@ -305,9 +306,9 @@ export function stickerToTemplateSafeSticker(sticker: Sticker): TemplateSafeStic
|
|||
packId: sticker.packId ?? undefined,
|
||||
name: sticker.name,
|
||||
description: sticker.description ?? "",
|
||||
tags: sticker.tags?.join(", ") ?? "",
|
||||
tags: sticker.tags ?? "",
|
||||
format: sticker.format,
|
||||
animated: sticker.format === "PNG" ? false : true,
|
||||
animated: sticker.format === StickerFormatType.PNG ? false : true,
|
||||
url: sticker.url,
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,23 +1,35 @@
|
|||
import { MessageActionRow, MessageButton, MessageComponentInteraction, MessageOptions, TextChannel } from "discord.js";
|
||||
import {
|
||||
ActionRow,
|
||||
ActionRowBuilder,
|
||||
ButtonBuilder,
|
||||
ButtonComponent,
|
||||
ButtonStyle,
|
||||
Message,
|
||||
MessageActionRowComponentBuilder,
|
||||
MessageComponentInteraction,
|
||||
MessageCreateOptions,
|
||||
MessagePayloadOption,
|
||||
TextChannel,
|
||||
} from "discord.js";
|
||||
import { noop } from "knub/dist/utils";
|
||||
import moment from "moment";
|
||||
import uuidv4 from "uuid/v4";
|
||||
|
||||
export async function waitForButtonConfirm(
|
||||
channel: TextChannel,
|
||||
toPost: MessageOptions,
|
||||
toPost: MessageCreateOptions,
|
||||
options?: WaitForOptions,
|
||||
): Promise<boolean> {
|
||||
return new Promise(async (resolve) => {
|
||||
const idMod = `${channel.guild.id}-${moment.utc().valueOf()}`;
|
||||
const row = new MessageActionRow().addComponents([
|
||||
new MessageButton()
|
||||
.setStyle("SUCCESS")
|
||||
const row = new ActionRowBuilder<MessageActionRowComponentBuilder>().addComponents([
|
||||
new ButtonBuilder()
|
||||
.setStyle(ButtonStyle.Success)
|
||||
.setLabel(options?.confirmText || "Confirm")
|
||||
.setCustomId(`confirmButton:${idMod}:${uuidv4()}`),
|
||||
|
||||
new MessageButton()
|
||||
.setStyle("DANGER")
|
||||
new ButtonBuilder()
|
||||
.setStyle(ButtonStyle.Danger)
|
||||
.setLabel(options?.cancelText || "Cancel")
|
||||
.setCustomId(`cancelButton:${idMod}:${uuidv4()}`),
|
||||
]);
|
||||
|
@ -41,7 +53,7 @@ export async function waitForButtonConfirm(
|
|||
}
|
||||
});
|
||||
collector.on("end", () => {
|
||||
if (!message.deleted) message.delete().catch(noop);
|
||||
if (message.deletable) message.delete().catch(noop);
|
||||
resolve(false);
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Add table
Reference in a new issue