import type { DiscordEmbed } from "./interfaces.ts"; import type { RedditPost } from "../reddit.ts"; const decodeHtmlEntities = (str: string): string => { return str .replace(/&/g, "&") .replace(/</g, "<") .replace(/>/g, ">") .replace(/"/g, '"') .replace(/'/g, "'") .replace(///g, "/") .replace(/`/g, "`") .replace(/=/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: ``, inline: true, }, ], thumbnail: complainant.avatar ? { url: `https://cdn.discordapp.com/avatars/${complainant.id}/${complainant.avatar}${complainant.avatar.startsWith("a_") ? ".gif" : ".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: ``, inline: true, }, ], thumbnail: appellant.avatar ? { url: `https://cdn.discordapp.com/avatars/${appellant.id}/${appellant.avatar}${appellant.avatar.startsWith("a_") ? ".gif" : ".png"}?size=256`, } : undefined, footer: { text: isDM ? "Appeal submitted via DM" : "Appeal submitted from server", }, }; };