mirror of
https://github.com/ZeppelinBot/Zeppelin.git
synced 2025-03-15 05:41:51 +00:00
Fix issues around embeds
This commit is contained in:
parent
dc53de8ae3
commit
81514276e9
8 changed files with 111 additions and 21 deletions
|
@ -13,6 +13,7 @@ import {
|
|||
messageSummary,
|
||||
renderRecursively,
|
||||
resolveMember,
|
||||
validateAndParseMessageContent,
|
||||
verboseChannelMention,
|
||||
verboseUserMention,
|
||||
verboseUserName,
|
||||
|
@ -134,10 +135,7 @@ export async function getLogMessage<TLogType extends keyof ILogTypeData>(
|
|||
formatted = `\`[${timestamp}]\` ${formatted}`;
|
||||
}
|
||||
} else if (formatted != null) {
|
||||
if (formatted.embed) {
|
||||
formatted.embeds = [formatted.embed];
|
||||
delete formatted.embed;
|
||||
}
|
||||
formatted = validateAndParseMessageContent(formatted);
|
||||
|
||||
if (formatted.embeds && Array.isArray(formatted.embeds) && includeEmbedTimestamp) {
|
||||
for (const embed of formatted.embeds) {
|
||||
|
|
|
@ -82,6 +82,6 @@ export const PostEmbedCmd = postCmd({
|
|||
);
|
||||
}
|
||||
|
||||
actualPostCmd(pluginData, msg, args.channel, { embed }, args);
|
||||
actualPostCmd(pluginData, msg, args.channel, { embeds: [embed] }, args);
|
||||
},
|
||||
});
|
||||
|
|
|
@ -22,8 +22,7 @@ export const ScheduledPostsListCmd = postCmd({
|
|||
|
||||
let i = 1;
|
||||
const postLines = scheduledPosts.map(p => {
|
||||
let previewText =
|
||||
p.content.content || (p.content.embed && (p.content.embed.description || p.content.embed.title)) || "";
|
||||
let previewText = p.content.content || p.content.embeds?.[0]?.description || p.content.embeds?.[0]?.title || "";
|
||||
|
||||
const isTruncated = previewText.length > SCHEDULED_POST_PREVIEW_TEXT_LENGTH;
|
||||
|
||||
|
@ -37,7 +36,7 @@ export const ScheduledPostsListCmd = postCmd({
|
|||
.format(timeAndDate.getDateFormat("pretty_datetime"));
|
||||
const parts = [`\`#${i++}\` \`[${prettyPostAt}]\` ${previewText}${isTruncated ? "..." : ""}`];
|
||||
if (p.attachments.length) parts.push("*(with attachment)*");
|
||||
if (p.content.embed) parts.push("*(embed)*");
|
||||
if (p.content.embeds?.length) parts.push("*(embed)*");
|
||||
if (p.repeat_until) {
|
||||
parts.push(`*(repeated every ${humanizeDuration(p.repeat_interval)} until ${p.repeat_until})*`);
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ export const TagEvalCmd = tagsCmd({
|
|||
{ member: msg.member },
|
||||
);
|
||||
|
||||
if (!rendered.content && !rendered.embed) {
|
||||
if (!rendered.content && !rendered.embeds?.length) {
|
||||
sendErrorMessage(pluginData, msg.channel, "Evaluation resulted in an empty text");
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import { GuildTags } from "../../data/GuildTags";
|
|||
import { tEmbed, tNullable } from "../../utils";
|
||||
|
||||
export const Tag = t.union([t.string, tEmbed]);
|
||||
export type TTag = t.TypeOf<typeof Tag>;
|
||||
|
||||
export const TagCategory = t.type({
|
||||
prefix: tNullable(t.string),
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
import * as t from "io-ts";
|
||||
import { GuildPluginData } from "knub";
|
||||
import { ExtendedMatchParams } from "knub/dist/config/PluginConfigManager";
|
||||
import { renderTemplate, TemplateSafeValueContainer } from "../../../templateFormatter";
|
||||
import { renderRecursively, StrictMessageContent } from "../../../utils";
|
||||
import { Tag, TagsPluginType } from "../types";
|
||||
import { TagsPluginType, TTag } from "../types";
|
||||
import { findTagByName } from "./findTagByName";
|
||||
|
||||
export async function renderTagBody(
|
||||
pluginData: GuildPluginData<TagsPluginType>,
|
||||
body: t.TypeOf<typeof Tag>,
|
||||
body: TTag,
|
||||
args: unknown[] = [],
|
||||
extraData = {},
|
||||
subTagPermissionMatchParams?: ExtendedMatchParams,
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
import { GuildMember } from "discord.js";
|
||||
import * as t from "io-ts";
|
||||
import { GuildPluginData } from "knub";
|
||||
import { parseArguments } from "knub-command-manager";
|
||||
import { memberToTemplateSafeMember, userToTemplateSafeUser } from "../../../utils/templateSafeObjects";
|
||||
import { LogType } from "../../../data/LogType";
|
||||
import { TemplateParseError } from "../../../templateFormatter";
|
||||
import { StrictMessageContent } from "../../../utils";
|
||||
import { StrictMessageContent, validateAndParseMessageContent } from "../../../utils";
|
||||
import { LogsPlugin } from "../../Logs/LogsPlugin";
|
||||
import { Tag, TagsPluginType } from "../types";
|
||||
import { TagsPluginType, TTag } from "../types";
|
||||
import { renderTagBody } from "./renderTagBody";
|
||||
|
||||
export async function renderTagFromString(
|
||||
|
@ -15,7 +13,7 @@ export async function renderTagFromString(
|
|||
str: string,
|
||||
prefix: string,
|
||||
tagName: string,
|
||||
tagBody: t.TypeOf<typeof Tag>,
|
||||
tagBody: TTag,
|
||||
member: GuildMember,
|
||||
): Promise<StrictMessageContent | null> {
|
||||
const variableStr = str.slice(prefix.length + tagName.length).trim();
|
||||
|
@ -23,7 +21,7 @@ export async function renderTagFromString(
|
|||
|
||||
// Format the string
|
||||
try {
|
||||
return renderTagBody(
|
||||
const rendered = await renderTagBody(
|
||||
pluginData,
|
||||
tagBody,
|
||||
tagArgs,
|
||||
|
@ -33,6 +31,8 @@ export async function renderTagFromString(
|
|||
},
|
||||
{ member },
|
||||
);
|
||||
|
||||
return validateAndParseMessageContent(rendered);
|
||||
} catch (e) {
|
||||
if (e instanceof TemplateParseError) {
|
||||
const logs = pluginData.getPlugin(LogsPlugin);
|
||||
|
|
|
@ -44,6 +44,7 @@ import { ChannelTypeStrings } from "./types";
|
|||
import { sendDM } from "./utils/sendDM";
|
||||
import { waitForButtonConfirm } from "./utils/waitForInteraction";
|
||||
import { decodeAndValidateStrict, StrictValidationError } from "./validatorUtils";
|
||||
import { z } from "zod";
|
||||
|
||||
const fsp = fs.promises;
|
||||
|
||||
|
@ -320,25 +321,117 @@ export const tEmbed = t.type({
|
|||
),
|
||||
});
|
||||
|
||||
export const zEmbedInput = z.object({
|
||||
title: z.string().optional(),
|
||||
description: z.string().optional(),
|
||||
url: z.string().optional(),
|
||||
timestamp: z.number().optional(),
|
||||
color: z.number().optional(),
|
||||
|
||||
footer: z.optional(
|
||||
z.object({
|
||||
text: z.string(),
|
||||
icon_url: z.string().optional(),
|
||||
}),
|
||||
),
|
||||
|
||||
image: z.optional(
|
||||
z.object({
|
||||
url: z.string().optional(),
|
||||
width: z.number().optional(),
|
||||
height: z.number().optional(),
|
||||
}),
|
||||
),
|
||||
|
||||
thumbnail: z.optional(
|
||||
z.object({
|
||||
url: z.string().optional(),
|
||||
width: z.number().optional(),
|
||||
height: z.number().optional(),
|
||||
}),
|
||||
),
|
||||
|
||||
video: z.optional(
|
||||
z.object({
|
||||
url: z.string().optional(),
|
||||
width: z.number().optional(),
|
||||
height: z.number().optional(),
|
||||
}),
|
||||
),
|
||||
|
||||
provider: z.optional(
|
||||
z.object({
|
||||
name: z.string(),
|
||||
url: z.string().optional(),
|
||||
}),
|
||||
),
|
||||
|
||||
fields: z.optional(
|
||||
z.array(
|
||||
z.object({
|
||||
name: z.string().optional(),
|
||||
value: z.string().optional(),
|
||||
inline: z.boolean().optional(),
|
||||
}),
|
||||
),
|
||||
),
|
||||
|
||||
author: z
|
||||
.optional(
|
||||
z.object({
|
||||
name: z.string(),
|
||||
url: z.string().optional(),
|
||||
width: z.number().optional(),
|
||||
height: z.number().optional(),
|
||||
}),
|
||||
)
|
||||
.nullable(),
|
||||
});
|
||||
|
||||
export type EmbedWith<T extends keyof MessageEmbedOptions> = MessageEmbedOptions &
|
||||
Pick<Required<MessageEmbedOptions>, T>;
|
||||
|
||||
export const zStrictMessageContent = z.object({
|
||||
content: z.string().optional(),
|
||||
tts: z.boolean().optional(),
|
||||
embeds: z.array(zEmbedInput).optional(),
|
||||
});
|
||||
|
||||
export type ZStrictMessageContent = z.infer<typeof zStrictMessageContent>;
|
||||
|
||||
export type StrictMessageContent = {
|
||||
content?: string;
|
||||
tts?: boolean;
|
||||
disableEveryone?: boolean;
|
||||
embed?: MessageEmbedOptions;
|
||||
embeds?: MessageEmbedOptions[];
|
||||
};
|
||||
|
||||
export const tStrictMessageContent = t.type({
|
||||
content: tNullable(t.string),
|
||||
tts: tNullable(t.boolean),
|
||||
disableEveryone: tNullable(t.boolean),
|
||||
embed: tNullable(tEmbed),
|
||||
embeds: tNullable(t.array(tEmbed)),
|
||||
});
|
||||
|
||||
export const tMessageContent = t.union([t.string, tStrictMessageContent]);
|
||||
|
||||
export function validateAndParseMessageContent(input: unknown): StrictMessageContent {
|
||||
if (input == null) {
|
||||
return {};
|
||||
}
|
||||
|
||||
if (typeof input !== "object") {
|
||||
return { content: String(input) };
|
||||
}
|
||||
|
||||
// Migrate embed -> embeds
|
||||
if ((input as any).embed) {
|
||||
(input as any).embeds = [(input as any).embed];
|
||||
delete (input as any).embed;
|
||||
}
|
||||
|
||||
return (zStrictMessageContent.parse(input) as unknown) as StrictMessageContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mirrors AllowedMentions from Eris
|
||||
*/
|
||||
|
|
Loading…
Add table
Reference in a new issue