diff options
Diffstat (limited to 'src/discord')
| -rw-r--r-- | src/discord/commands.ts | 125 | ||||
| -rw-r--r-- | src/discord/embeds.ts | 181 | ||||
| -rw-r--r-- | src/discord/interfaces.ts | 86 | ||||
| -rw-r--r-- | src/discord/responses.ts | 15 | ||||
| -rw-r--r-- | src/discord/types.ts | 1 | ||||
| -rw-r--r-- | src/discord/verification.ts | 24 |
6 files changed, 0 insertions, 432 deletions
diff --git a/src/discord/commands.ts b/src/discord/commands.ts deleted file mode 100644 index 601591b..0000000 --- a/src/discord/commands.ts +++ /dev/null @@ -1,125 +0,0 @@ -import type { DiscordCommand } from "./interfaces.ts"; - -export type { DiscordCommand }; - -export const HOT_COMMAND: DiscordCommand = { - name: "hot", - description: "Fetch a random hot post from r/okbuddyumamusume", -}; - -export const ROLEPLAY_COMMAND: DiscordCommand = { - name: "roleplay", - description: "Fetch a random hot roleplay post from r/okbuddyumamusume", -}; - -export const NSFW_COMMAND: DiscordCommand = { - name: "nsfw", - description: - "Fetch a random NSFW post from r/okbuddyumamusume (NSFW channels only)", -}; - -export const TOP_COMMAND: DiscordCommand = { - name: "top", - description: - "Fetch a random top post from r/okbuddyumamusume (defaults to today)", - options: [ - { - type: 3, - name: "time", - description: "Time period for top posts (defaults to today)", - required: false, - choices: [ - { - name: "Now", - value: "hour", - }, - { - name: "Today", - value: "day", - }, - { - name: "This Week", - value: "week", - }, - { - name: "This Month", - value: "month", - }, - { - name: "This Year", - value: "year", - }, - { - name: "All Time", - value: "all", - }, - ], - }, - ], -}; - -export const COMPLAIN_COMMAND: DiscordCommand = { - name: "complain", - description: "Submit a complaint to the moderators", - contexts: [0], - options: [ - { - type: 3, - name: "message", - description: "Your complaint message", - required: true, - }, - ], -}; - -export const APPEAL_COMMAND: DiscordCommand = { - name: "appeal", - description: "Submit an appeal to the moderators", - contexts: [0], - options: [ - { - type: 3, - name: "message", - description: "Your appeal message", - required: true, - }, - ], -}; - -export const COLOURS_COMMAND: DiscordCommand = { - name: "colours", - description: "Show the distribution of colour roles in the server", -}; - -export const ROLEPLAY_SERIOUS_COMMAND: DiscordCommand = { - name: "roleplay-serious", - description: "Manage the serious roleplay role (Admin/Roleplay Curator only)", - options: [ - { - type: 3, - name: "action", - description: "Action to perform on the role", - required: true, - choices: [ - { - name: "Add Role", - value: "add", - }, - { - name: "Remove Role", - value: "remove", - }, - { - name: "Toggle Role", - value: "toggle", - }, - ], - }, - { - type: 6, - name: "user", - description: "User to perform the action on", - required: true, - }, - ], -}; diff --git a/src/discord/embeds.ts b/src/discord/embeds.ts deleted file mode 100644 index 3f7c344..0000000 --- a/src/discord/embeds.ts +++ /dev/null @@ -1,181 +0,0 @@ -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: `<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", - }, - }; -}; diff --git a/src/discord/interfaces.ts b/src/discord/interfaces.ts deleted file mode 100644 index bc8683c..0000000 --- a/src/discord/interfaces.ts +++ /dev/null @@ -1,86 +0,0 @@ -export interface Environment { - DISCORD_APPLICATION_ID: string; - DISCORD_PUBLIC_KEY: string; - DISCORD_TOKEN: string; -} - -export interface DiscordInteraction { - type: number; - data: { - name: string; - options?: Array<{ - name: string; - value: string; - }>; - }; - channel_id?: string; - channel?: { - nsfw: boolean; - }; - guild_id?: string; - user?: { - id: string; - username: string; - avatar?: string; - }; - member?: { - user?: { - id: string; - username: string; - avatar?: string; - }; - roles?: string[]; - permissions?: string; - }; -} - -export interface DiscordEmbed { - title: string; - description: string; - url?: string; - color: number; - author?: { - name: string; - url: string; - }; - fields?: Array<{ - name: string; - value: string; - inline: boolean; - }>; - timestamp?: string; - footer?: { - text: string; - }; - image?: { url: string }; - thumbnail?: { url: string }; -} - -export interface DiscordResponse { - type: number; - data?: { - content?: string; - embeds?: DiscordEmbed[]; - flags?: number; - }; -} - -export interface DiscordCommand { - name: string; - description: string; - options?: DiscordCommandOption[]; - contexts?: number[]; -} - -export interface DiscordCommandOption { - type: number; - name: string; - description: string; - required?: boolean; - choices?: DiscordCommandChoice[]; -} - -export interface DiscordCommandChoice { - name: string; - value: string; -} diff --git a/src/discord/responses.ts b/src/discord/responses.ts deleted file mode 100644 index 4dcc777..0000000 --- a/src/discord/responses.ts +++ /dev/null @@ -1,15 +0,0 @@ -import type { DiscordResponse } from "./interfaces.ts"; - -export class JSONResponse extends Response { - constructor(body: DiscordResponse | { error: string }, init?: ResponseInit) { - const jsonBody = JSON.stringify(body); - - init = init || { - headers: { - "content-type": "application/json;charset=UTF-8", - }, - }; - - super(jsonBody, init); - } -} diff --git a/src/discord/types.ts b/src/discord/types.ts deleted file mode 100644 index 4f6e85e..0000000 --- a/src/discord/types.ts +++ /dev/null @@ -1 +0,0 @@ -export type TimePeriod = "hour" | "day" | "week" | "month" | "year" | "all"; diff --git a/src/discord/verification.ts b/src/discord/verification.ts deleted file mode 100644 index 89d26db..0000000 --- a/src/discord/verification.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { verifyKey } from "discord-interactions"; -import type { Environment, DiscordInteraction } from "./interfaces.ts"; - -export const verifyDiscordRequest = async ( - request: Request, - environment: Environment, -): Promise<{ isValid: boolean; interaction?: DiscordInteraction }> => { - const signature = request.headers.get("x-signature-ed25519"); - const timestamp = request.headers.get("x-signature-timestamp"); - const body = await request.text(); - const isValidRequest = - signature && - timestamp && - (await verifyKey( - body, - signature, - timestamp, - environment.DISCORD_PUBLIC_KEY, - )); - - if (!isValidRequest) return { isValid: false }; - - return { interaction: JSON.parse(body) as DiscordInteraction, isValid: true }; -}; |