summaryrefslogtreecommitdiff
path: root/packages/interactions/discord/embeds.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/interactions/discord/embeds.ts')
-rw-r--r--packages/interactions/discord/embeds.ts181
1 files changed, 181 insertions, 0 deletions
diff --git a/packages/interactions/discord/embeds.ts b/packages/interactions/discord/embeds.ts
new file mode 100644
index 0000000..3f7c344
--- /dev/null
+++ b/packages/interactions/discord/embeds.ts
@@ -0,0 +1,181 @@
+import type { DiscordEmbed } from "./interfaces.ts";
+import type { RedditPost } from "../reddit.ts";
+
+const decodeHtmlEntities = (str: string): string => {
+ return str
+ .replace(/&/g, "&")
+ .replace(/&lt;/g, "<")
+ .replace(/&gt;/g, ">")
+ .replace(/&quot;/g, '"')
+ .replace(/&#x27;/g, "'")
+ .replace(/&#x2F;/g, "/")
+ .replace(/&#x60;/g, "`")
+ .replace(/&#x3D;/g, "=");
+};
+
+export const createPostEmbed = (post: RedditPost): DiscordEmbed => {
+ const mediaUrl =
+ post.media?.reddit_video?.fallback_url ||
+ post.secure_media?.reddit_video?.fallback_url ||
+ post.url;
+
+ let description = post.selftext || "";
+
+ if (description.length > 1000)
+ description = description.substring(0, 997).trim() + " ...";
+
+ const embed: DiscordEmbed = {
+ title: post.title,
+ description: description,
+ url: `https://reddit.com${post.permalink}`,
+ color: 0xff4500,
+ author: {
+ name: `u/${post.author}`,
+ url: `https://reddit.com/u/${post.author}`,
+ },
+ fields: [
+ {
+ name: "Score",
+ value: `${post.score} ā¬†ļø`,
+ inline: true,
+ },
+ {
+ name: "Comments",
+ value: `${post.num_comments} šŸ’¬`,
+ inline: true,
+ },
+ ],
+ timestamp: new Date(post.created_utc * 1000).toISOString(),
+ footer: {
+ text: "r/okbuddyumamusume",
+ },
+ };
+
+ if (mediaUrl)
+ if (post.media?.reddit_video || post.secure_media?.reddit_video) {
+ if (!description) description = "";
+
+ description +=
+ "\n\nšŸ“¹ **This post contains a video** - [Click here to view](" +
+ mediaUrl +
+ ")";
+ embed.description = description;
+
+ if (post.preview?.images?.[0]?.source?.url) {
+ const decodedURL = decodeHtmlEntities(
+ post.preview.images[0].source.url,
+ );
+
+ console.log("Using preview image:", decodedURL);
+
+ embed.image = { url: decodedURL };
+ } else if (
+ post.thumbnail &&
+ post.thumbnail !== "self" &&
+ post.thumbnail !== "default"
+ ) {
+ const decodedThumbnail = decodeHtmlEntities(post.thumbnail);
+
+ console.log("Using thumbnail:", decodedThumbnail);
+
+ embed.image = { url: decodedThumbnail };
+ } else {
+ console.log("No suitable thumbnail found for video post");
+ }
+ } else {
+ embed.image = { url: mediaUrl };
+ }
+
+ return embed;
+};
+
+export const createRoleDistributionEmbed = (
+ roleDistribution: Array<{ name: string; count: number }>,
+): DiscordEmbed => {
+ const totalMembers = roleDistribution.reduce(
+ (sum, role) => sum + role.count,
+ 0,
+ );
+
+ return {
+ title: "šŸŽØ Colour Role Distribution",
+ description: `Total members with colour roles: **${totalMembers}**`,
+ color: 0x5865f2,
+ fields: roleDistribution.map((role) => ({
+ name: role.name,
+ value: `${role.count} member${role.count !== 1 ? "s" : ""}`,
+ inline: true,
+ })),
+ footer: {
+ text: "Sorted by member count (highest to lowest)",
+ },
+ };
+};
+
+export const createComplaintEmbed = (
+ complaintContent: string,
+ complainant: { username: string; id: string; avatar?: string },
+ timestamp: number,
+ isDM: boolean = true,
+): DiscordEmbed => {
+ return {
+ title: "🚨 New Complaint",
+ description: complaintContent,
+ color: 0xff6b6b,
+ fields: [
+ {
+ name: "Complainant",
+ value: `${complainant.username} (${complainant.id})`,
+ inline: true,
+ },
+ {
+ name: "Timestamp",
+ value: `<t:${Math.floor(timestamp / 1000)}:F>`,
+ inline: true,
+ },
+ ],
+ thumbnail: complainant.avatar
+ ? {
+ url: `https://cdn.discordapp.com/avatars/${complainant.id}/${complainant.avatar}.png?size=256`,
+ }
+ : undefined,
+ footer: {
+ text: isDM
+ ? "Complaint submitted via DM"
+ : "Complaint submitted from server",
+ },
+ };
+};
+
+export const createAppealEmbed = (
+ appealContent: string,
+ appellant: { username: string; id: string; avatar?: string },
+ timestamp: number,
+ isDM: boolean = true,
+): DiscordEmbed => {
+ return {
+ title: "šŸ“‹ New Appeal",
+ description: appealContent,
+ color: 0x5865f2,
+ fields: [
+ {
+ name: "Appellant",
+ value: `${appellant.username} (${appellant.id})`,
+ inline: true,
+ },
+ {
+ name: "Timestamp",
+ value: `<t:${Math.floor(timestamp / 1000)}:F>`,
+ inline: true,
+ },
+ ],
+ thumbnail: appellant.avatar
+ ? {
+ url: `https://cdn.discordapp.com/avatars/${appellant.id}/${appellant.avatar}.png?size=256`,
+ }
+ : undefined,
+ footer: {
+ text: isDM ? "Appeal submitted via DM" : "Appeal submitted from server",
+ },
+ };
+};