big bang
This commit is contained in:
@@ -0,0 +1,8 @@
|
|||||||
|
node_modules/
|
||||||
|
|
||||||
|
.env.vars
|
||||||
|
.env
|
||||||
|
wrangler.toml
|
||||||
|
|
||||||
|
src/feat/birthdays.json
|
||||||
|
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
```
|
||||||
|
┌─ minute 0
|
||||||
|
│ ┌─ hour 17
|
||||||
|
│ │ ┌─ day *
|
||||||
|
│ │ │ ┌─ month *
|
||||||
|
│ │ │ │ ┌─ weekday *
|
||||||
|
│ │ │ │ │
|
||||||
|
0 17 * * *
|
||||||
|
```
|
||||||
|
|
||||||
|
its in UTC+00, so
|
||||||
|
```
|
||||||
|
UTC cron time = UTC+7 desired time − 7 hours
|
||||||
|
00:00 − 07:00 = 17:00 UTC
|
||||||
|
|
||||||
|
17:00 UTC
|
||||||
|
+ 7 hours
|
||||||
|
----------
|
||||||
|
00:00 UTC+7
|
||||||
|
```
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
import type { Env } from "../env"
|
||||||
|
|
||||||
|
const DISCORD_API = "https://discord.com/api/v10"
|
||||||
|
|
||||||
|
// no embedbuilder cuz fuck you
|
||||||
|
export interface DiscordEmbed
|
||||||
|
{
|
||||||
|
title?: string
|
||||||
|
description?: string
|
||||||
|
fields?: Array<{
|
||||||
|
name: string
|
||||||
|
value: string
|
||||||
|
inline?: boolean
|
||||||
|
}>
|
||||||
|
footer?: {
|
||||||
|
text: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function editMessage(env: Env, content: string | null, embeds: DiscordEmbed[] = []): Promise<void>
|
||||||
|
{
|
||||||
|
const response = await fetch(`${DISCORD_API}/channels/${env.DISCORD_CHANNEL_ID}/messages/${env.DISCORD_MESSAGE_ID}`, {
|
||||||
|
method: "PATCH",
|
||||||
|
headers: {
|
||||||
|
"Authorization": `Bot ${env.DISCORD_BOT_TOKEN}`,
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
content,
|
||||||
|
embeds
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!response.ok)
|
||||||
|
{
|
||||||
|
const body = await response.text()
|
||||||
|
|
||||||
|
throw new Error(`fuckass discord returned ${response.status}: ${body}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
export interface Env
|
||||||
|
{
|
||||||
|
DISCORD_BOT_TOKEN: string
|
||||||
|
DISCORD_CHANNEL_ID: string
|
||||||
|
DISCORD_MESSAGE_ID: string
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import birthdays from "./birthdays.json"
|
||||||
|
import type { DiscordEmbed } from "../discord/mod"
|
||||||
|
|
||||||
|
interface Birthdays
|
||||||
|
{
|
||||||
|
[date: string]: string[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getBirthdays(date: string): string[]
|
||||||
|
{
|
||||||
|
return (birthdays as Birthdays)[date] ?? []
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createBirthdayEmbed(date: string): DiscordEmbed
|
||||||
|
{
|
||||||
|
const names = getBirthdays(date)
|
||||||
|
|
||||||
|
return {
|
||||||
|
fields: [{
|
||||||
|
name: "Today's Birthdays",
|
||||||
|
value: names.length > 0 ? names.map(name => `- ${name}`).join("\n") : "No birthdays today.",
|
||||||
|
inline: false
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
import type { Env } from "./env"
|
||||||
|
|
||||||
|
import { editMessage } from "./discord/mod"
|
||||||
|
|
||||||
|
import { getToday } from "./utils/date"
|
||||||
|
import { createBirthdayEmbed } from "./feat/birthdays"
|
||||||
|
|
||||||
|
async function updateMessage(env: Env): Promise<void>
|
||||||
|
{
|
||||||
|
await editMessage(
|
||||||
|
env,
|
||||||
|
`Last updated: <t:${Math.floor(Date.now() / 1000)}:F>`,
|
||||||
|
[ // embeds
|
||||||
|
createBirthdayEmbed(getToday("Asia/Jakarta"))
|
||||||
|
]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default
|
||||||
|
{
|
||||||
|
async fetch(request: Request, env: Env): Promise<Response>
|
||||||
|
{
|
||||||
|
const url = new URL(request.url)
|
||||||
|
|
||||||
|
if (url.pathname === "/invoke")
|
||||||
|
{
|
||||||
|
await updateMessage(env)
|
||||||
|
|
||||||
|
return new Response("Discord message updated")
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Response("Not Found", {
|
||||||
|
status: 404
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
async scheduled(_event: ScheduledEvent, env: Env, _ctx: ExecutionContext): Promise<void>
|
||||||
|
{
|
||||||
|
await updateMessage(env)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
export function getToday(timeZone = "Asia/Jakarta"): string
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Intl API cuz i can :P
|
||||||
|
*/
|
||||||
|
return new Intl.DateTimeFormat("en-US", {
|
||||||
|
timeZone,
|
||||||
|
month: "2-digit",
|
||||||
|
day: "2-digit"
|
||||||
|
})
|
||||||
|
.format(new Date())
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
name = "meowl-cron"
|
||||||
|
main = "src/index.ts"
|
||||||
|
compatibility_date = "2025-07-18"
|
||||||
|
|
||||||
|
[triggers]
|
||||||
|
crons = ["0 17 * * *"]
|
||||||
|
|
||||||
|
[vars]
|
||||||
|
DISCORD_CHANNEL_ID = ""
|
||||||
|
DISCORD_MESSAGE_ID = ""
|
||||||
|
DISCORD_BOT_TOKEN = ""
|
||||||
Reference in New Issue
Block a user