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,
|
messageSummary,
|
||||||
renderRecursively,
|
renderRecursively,
|
||||||
resolveMember,
|
resolveMember,
|
||||||
|
validateAndParseMessageContent,
|
||||||
verboseChannelMention,
|
verboseChannelMention,
|
||||||
verboseUserMention,
|
verboseUserMention,
|
||||||
verboseUserName,
|
verboseUserName,
|
||||||
|
@ -134,10 +135,7 @@ export async function getLogMessage<TLogType extends keyof ILogTypeData>(
|
||||||
formatted = `\`[${timestamp}]\` ${formatted}`;
|
formatted = `\`[${timestamp}]\` ${formatted}`;
|
||||||
}
|
}
|
||||||
} else if (formatted != null) {
|
} else if (formatted != null) {
|
||||||
if (formatted.embed) {
|
formatted = validateAndParseMessageContent(formatted);
|
||||||
formatted.embeds = [formatted.embed];
|
|
||||||
delete formatted.embed;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (formatted.embeds && Array.isArray(formatted.embeds) && includeEmbedTimestamp) {
|
if (formatted.embeds && Array.isArray(formatted.embeds) && includeEmbedTimestamp) {
|
||||||
for (const embed of formatted.embeds) {
|
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;
|
let i = 1;
|
||||||
const postLines = scheduledPosts.map(p => {
|
const postLines = scheduledPosts.map(p => {
|
||||||
let previewText =
|
let previewText = p.content.content || p.content.embeds?.[0]?.description || p.content.embeds?.[0]?.title || "";
|
||||||
p.content.content || (p.content.embed && (p.content.embed.description || p.content.embed.title)) || "";
|
|
||||||
|
|
||||||
const isTruncated = previewText.length > SCHEDULED_POST_PREVIEW_TEXT_LENGTH;
|
const isTruncated = previewText.length > SCHEDULED_POST_PREVIEW_TEXT_LENGTH;
|
||||||
|
|
||||||
|
@ -37,7 +36,7 @@ export const ScheduledPostsListCmd = postCmd({
|
||||||
.format(timeAndDate.getDateFormat("pretty_datetime"));
|
.format(timeAndDate.getDateFormat("pretty_datetime"));
|
||||||
const parts = [`\`#${i++}\` \`[${prettyPostAt}]\` ${previewText}${isTruncated ? "..." : ""}`];
|
const parts = [`\`#${i++}\` \`[${prettyPostAt}]\` ${previewText}${isTruncated ? "..." : ""}`];
|
||||||
if (p.attachments.length) parts.push("*(with attachment)*");
|
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) {
|
if (p.repeat_until) {
|
||||||
parts.push(`*(repeated every ${humanizeDuration(p.repeat_interval)} until ${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 },
|
{ member: msg.member },
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!rendered.content && !rendered.embed) {
|
if (!rendered.content && !rendered.embeds?.length) {
|
||||||
sendErrorMessage(pluginData, msg.channel, "Evaluation resulted in an empty text");
|
sendErrorMessage(pluginData, msg.channel, "Evaluation resulted in an empty text");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import { GuildTags } from "../../data/GuildTags";
|
||||||
import { tEmbed, tNullable } from "../../utils";
|
import { tEmbed, tNullable } from "../../utils";
|
||||||
|
|
||||||
export const Tag = t.union([t.string, tEmbed]);
|
export const Tag = t.union([t.string, tEmbed]);
|
||||||
|
export type TTag = t.TypeOf<typeof Tag>;
|
||||||
|
|
||||||
export const TagCategory = t.type({
|
export const TagCategory = t.type({
|
||||||
prefix: tNullable(t.string),
|
prefix: tNullable(t.string),
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
import * as t from "io-ts";
|
|
||||||
import { GuildPluginData } from "knub";
|
import { GuildPluginData } from "knub";
|
||||||
import { ExtendedMatchParams } from "knub/dist/config/PluginConfigManager";
|
import { ExtendedMatchParams } from "knub/dist/config/PluginConfigManager";
|
||||||
import { renderTemplate, TemplateSafeValueContainer } from "../../../templateFormatter";
|
import { renderTemplate, TemplateSafeValueContainer } from "../../../templateFormatter";
|
||||||
import { renderRecursively, StrictMessageContent } from "../../../utils";
|
import { renderRecursively, StrictMessageContent } from "../../../utils";
|
||||||
import { Tag, TagsPluginType } from "../types";
|
import { TagsPluginType, TTag } from "../types";
|
||||||
import { findTagByName } from "./findTagByName";
|
import { findTagByName } from "./findTagByName";
|
||||||
|
|
||||||
export async function renderTagBody(
|
export async function renderTagBody(
|
||||||
pluginData: GuildPluginData<TagsPluginType>,
|
pluginData: GuildPluginData<TagsPluginType>,
|
||||||
body: t.TypeOf<typeof Tag>,
|
body: TTag,
|
||||||
args: unknown[] = [],
|
args: unknown[] = [],
|
||||||
extraData = {},
|
extraData = {},
|
||||||
subTagPermissionMatchParams?: ExtendedMatchParams,
|
subTagPermissionMatchParams?: ExtendedMatchParams,
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
import { GuildMember } from "discord.js";
|
import { GuildMember } from "discord.js";
|
||||||
import * as t from "io-ts";
|
|
||||||
import { GuildPluginData } from "knub";
|
import { GuildPluginData } from "knub";
|
||||||
import { parseArguments } from "knub-command-manager";
|
import { parseArguments } from "knub-command-manager";
|
||||||
import { memberToTemplateSafeMember, userToTemplateSafeUser } from "../../../utils/templateSafeObjects";
|
import { memberToTemplateSafeMember, userToTemplateSafeUser } from "../../../utils/templateSafeObjects";
|
||||||
import { LogType } from "../../../data/LogType";
|
|
||||||
import { TemplateParseError } from "../../../templateFormatter";
|
import { TemplateParseError } from "../../../templateFormatter";
|
||||||
import { StrictMessageContent } from "../../../utils";
|
import { StrictMessageContent, validateAndParseMessageContent } from "../../../utils";
|
||||||
import { LogsPlugin } from "../../Logs/LogsPlugin";
|
import { LogsPlugin } from "../../Logs/LogsPlugin";
|
||||||
import { Tag, TagsPluginType } from "../types";
|
import { TagsPluginType, TTag } from "../types";
|
||||||
import { renderTagBody } from "./renderTagBody";
|
import { renderTagBody } from "./renderTagBody";
|
||||||
|
|
||||||
export async function renderTagFromString(
|
export async function renderTagFromString(
|
||||||
|
@ -15,7 +13,7 @@ export async function renderTagFromString(
|
||||||
str: string,
|
str: string,
|
||||||
prefix: string,
|
prefix: string,
|
||||||
tagName: string,
|
tagName: string,
|
||||||
tagBody: t.TypeOf<typeof Tag>,
|
tagBody: TTag,
|
||||||
member: GuildMember,
|
member: GuildMember,
|
||||||
): Promise<StrictMessageContent | null> {
|
): Promise<StrictMessageContent | null> {
|
||||||
const variableStr = str.slice(prefix.length + tagName.length).trim();
|
const variableStr = str.slice(prefix.length + tagName.length).trim();
|
||||||
|
@ -23,7 +21,7 @@ export async function renderTagFromString(
|
||||||
|
|
||||||
// Format the string
|
// Format the string
|
||||||
try {
|
try {
|
||||||
return renderTagBody(
|
const rendered = await renderTagBody(
|
||||||
pluginData,
|
pluginData,
|
||||||
tagBody,
|
tagBody,
|
||||||
tagArgs,
|
tagArgs,
|
||||||
|
@ -33,6 +31,8 @@ export async function renderTagFromString(
|
||||||
},
|
},
|
||||||
{ member },
|
{ member },
|
||||||
);
|
);
|
||||||
|
|
||||||
|
return validateAndParseMessageContent(rendered);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e instanceof TemplateParseError) {
|
if (e instanceof TemplateParseError) {
|
||||||
const logs = pluginData.getPlugin(LogsPlugin);
|
const logs = pluginData.getPlugin(LogsPlugin);
|
||||||
|
|
|
@ -44,6 +44,7 @@ import { ChannelTypeStrings } from "./types";
|
||||||
import { sendDM } from "./utils/sendDM";
|
import { sendDM } from "./utils/sendDM";
|
||||||
import { waitForButtonConfirm } from "./utils/waitForInteraction";
|
import { waitForButtonConfirm } from "./utils/waitForInteraction";
|
||||||
import { decodeAndValidateStrict, StrictValidationError } from "./validatorUtils";
|
import { decodeAndValidateStrict, StrictValidationError } from "./validatorUtils";
|
||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
const fsp = fs.promises;
|
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 &
|
export type EmbedWith<T extends keyof MessageEmbedOptions> = MessageEmbedOptions &
|
||||||
Pick<Required<MessageEmbedOptions>, T>;
|
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 = {
|
export type StrictMessageContent = {
|
||||||
content?: string;
|
content?: string;
|
||||||
tts?: boolean;
|
tts?: boolean;
|
||||||
disableEveryone?: boolean;
|
embeds?: MessageEmbedOptions[];
|
||||||
embed?: MessageEmbedOptions;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const tStrictMessageContent = t.type({
|
export const tStrictMessageContent = t.type({
|
||||||
content: tNullable(t.string),
|
content: tNullable(t.string),
|
||||||
tts: tNullable(t.boolean),
|
tts: tNullable(t.boolean),
|
||||||
disableEveryone: tNullable(t.boolean),
|
disableEveryone: tNullable(t.boolean),
|
||||||
embed: tNullable(tEmbed),
|
embeds: tNullable(t.array(tEmbed)),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const tMessageContent = t.union([t.string, tStrictMessageContent]);
|
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
|
* Mirrors AllowedMentions from Eris
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Add table
Reference in a new issue