import { AutoRouter } from 'itty-router'; import { InteractionResponseType, InteractionType } from 'discord-interactions'; import { HOT_COMMAND, ROLEPLAY_COMMAND, NSFW_COMMAND, TOP_COMMAND, } from './discord/commands.ts'; import { getCutePost, getRoleplayPost, getNSFWPost, getTopPost, } from './reddit.ts'; import type { TimePeriod } from './discord/types.ts'; import type { Environment } from './discord/interfaces.ts'; import { createPostEmbed } from './discord/embeds.ts'; import { JSONResponse } from './discord/responses.ts'; import { verifyDiscordRequest } from './discord/verification.ts'; const router = AutoRouter(); router.get('/', (_request: Request, environment: Environment) => { return new Response(`👋 ${environment.DISCORD_APPLICATION_ID}`); }); router.post('/', async (request: Request, environment: Environment) => { const { isValid, interaction } = await server.verifyDiscordRequest( request, environment, ); if (!isValid || !interaction) return new Response('Bad request signature.', { status: 401 }); if (interaction.type === InteractionType.PING) return new JSONResponse({ type: InteractionResponseType.PONG, }); if (interaction.type === InteractionType.APPLICATION_COMMAND) { switch (interaction.data.name.toLowerCase()) { case HOT_COMMAND.name.toLowerCase(): { try { const post = await getCutePost(); const embed = createPostEmbed(post); return new JSONResponse({ type: InteractionResponseType.CHANNEL_MESSAGE_WITH_SOURCE, data: { embeds: [embed], }, }); } catch (error) { console.error('Error in hot command:', error); return new JSONResponse({ type: InteractionResponseType.CHANNEL_MESSAGE_WITH_SOURCE, data: { content: '❌ No posts found. Try again later!', flags: 64, }, }); } } case ROLEPLAY_COMMAND.name.toLowerCase(): { try { const post = await getRoleplayPost(); const embed = createPostEmbed(post); return new JSONResponse({ type: InteractionResponseType.CHANNEL_MESSAGE_WITH_SOURCE, data: { embeds: [embed], }, }); } catch (error) { console.error('Error in roleplay command:', error); return new JSONResponse({ type: InteractionResponseType.CHANNEL_MESSAGE_WITH_SOURCE, data: { content: '❌ No roleplay posts found. Try again later!', flags: 64, }, }); } } case NSFW_COMMAND.name.toLowerCase(): { if (!interaction.channel_id || !interaction.channel?.nsfw) { return new JSONResponse({ type: InteractionResponseType.CHANNEL_MESSAGE_WITH_SOURCE, data: { content: '❌ This command can only be used in NSFW channels.', flags: 64, }, }); } try { const post = await getNSFWPost(); const embed = createPostEmbed(post); return new JSONResponse({ type: InteractionResponseType.CHANNEL_MESSAGE_WITH_SOURCE, data: { embeds: [embed], }, }); } catch (error) { console.error('Error in NSFW command:', error); return new JSONResponse({ type: InteractionResponseType.CHANNEL_MESSAGE_WITH_SOURCE, data: { content: '❌ No NSFW posts found. Try again later!', flags: 64, }, }); } } case TOP_COMMAND.name.toLowerCase(): { try { const time = (interaction.data.options?.[0]?.value as TimePeriod) || 'day'; const post = await getTopPost(time); const embed = createPostEmbed(post); return new JSONResponse({ type: InteractionResponseType.CHANNEL_MESSAGE_WITH_SOURCE, data: { embeds: [embed], }, }); } catch (error) { console.error('Error in top command:', error); return new JSONResponse({ type: InteractionResponseType.CHANNEL_MESSAGE_WITH_SOURCE, data: { content: '❌ No top posts found. Try again later!', flags: 64, }, }); } } default: return new JSONResponse({ error: 'Unknown Type' }, { status: 400 }); } } console.error('Unknown Type'); return new JSONResponse({ error: 'Unknown Type' }, { status: 400 }); }); router.all('*', () => new Response('Not Found.', { status: 404 })); const server = { verifyDiscordRequest, fetch: router.fetch, }; export default server;