Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
diff --git a/src/app.ts b/src/app.ts new file mode 100644 index 0000000..3ee67c6 --- /dev/null +++ b/src/app.ts @@ -0,0 +1,64 @@ +import { InteractionType } from "discord-interactions"; +import { Hono } from "hono"; +import checkinCommand from "./interactions/applicationCommands/checkin"; +import mokumokuStartCommand from "./interactions/applicationCommands/mokumokuStart"; +import { handleApplicationCommands } from "./interactions/handleApplicationCommands"; +import { handleModalSubmits } from "./interactions/handleModalSubmit"; +import checkinModal from "./interactions/modalSubmits/checkinModal"; +import { verifyDiscordInteraction } from "./middleware/verifyDiscordInteraction"; +import { CheckinsRepository } from "./repositories/checkinsRepository"; +import { EventsRepository } from "./repositories/eventsRepository"; +import { EventsToCheckinsRepository } from "./repositories/eventsToCheckinsRepository"; +import { UsersRepository } from "./repositories/usersRepository"; +import { errorResponse } from "./responses/errorResponse"; + +type Bindings = { + DB: D1Database; +}; + +const app = new Hono<{ Bindings: Bindings }>(); + +app.post("/interaction", verifyDiscordInteraction, async (c) => { + const body = await c.req.json(); + + const repositories = { + usersRepository: new UsersRepository(c.env.DB), + checkinsRepository: new CheckinsRepository(c.env.DB), + eventsRepository: new EventsRepository(c.env.DB), + eventsToCheckinsRepository: new EventsToCheckinsRepository(c.env.DB), + }; + + try { + switch (body.type) { + case InteractionType.APPLICATION_COMMAND: + return c.json( + await handleApplicationCommands({ + repositories, + intentObj: body, + commands: [checkinCommand, mokumokuStartCommand], + }), + ); + case InteractionType.MODAL_SUBMIT: + return c.json( + await handleModalSubmits({ + repositories, + intentObj: body, + modals: [checkinModal], + }), + ); + default: + throw new Error("Invalid interaction"); + } + } catch (e) { + console.error(e); + return c.json( + errorResponse( + e instanceof Error + ? e.message + : "Unknown error. 開発者に相談してください。", + ), + ); + } +}); + +export default app; diff --git a/src/clients/discord.ts b/src/clients/discord.ts new file mode 100644 index 0000000..e65f1fd --- /dev/null +++ b/src/clients/discord.ts @@ -0,0 +1,24 @@ +export class DiscordClient { + private BASE_URL = "https://discord.com/api/v10/"; + private config: { headers: Record<string, string> }; + + constructor(botToken: string) { + this.config = { + headers: { + Authorization: `Bot ${botToken}`, + "Content-Type": "application/json", + }, + }; + } + + async sendMessage({ + channelId, + content, + }: { channelId: string; content: string }) { + await fetch(`${this.BASE_URL}/channels/${channelId}/messages`, { + method: "POST", + body: JSON.stringify({ content }), + headers: this.config.headers, + }); + } +} diff --git a/src/scheduled.ts b/src/scheduled.ts new file mode 100644 index 0000000..53df427 --- /dev/null +++ b/src/scheduled.ts @@ -0,0 +1,41 @@ +import { DiscordClient } from "./clients/discord"; +import { EventsRepository } from "./repositories/eventsRepository"; +type Bindings = { + DB: D1Database; + DISCORD_TOKEN: string; + MOKUMOKU_CHANNEL_ID: string; +}; + +const scheduled: ExportedHandler<Bindings>["scheduled"] = async ( + event, + env, +) => { + const eventsRepository = new EventsRepository(env.DB); + + // もくもく会が開催されている日のみ実行 + const todayEvent = await eventsRepository.findTodayEvent(); + if (!todayEvent) { + return; + } + + const client = new DiscordClient(env.DISCORD_TOKEN); + + switch (event.cron) { + case "0 6 * * *": + client.sendMessage({ + channelId: env.MOKUMOKU_CHANNEL_ID, + content: + "@here テックトークの時間です!発表希望者はこのメッセージに🙋♂️でリアクションしてください。", + }); + break; + case "50 8 * * * ": + client.sendMessage({ + channelId: env.MOKUMOKU_CHANNEL_ID, + content: + "@here もくもく会終了の時間です!今日の成果を共有しましょう!🍻", + }); + break; + } +}; + +export default scheduled;
- Loading branch information