From 7b0d45d17e2a9227a2bf6b3f4b532ad7a2c646a0 Mon Sep 17 00:00:00 2001 From: DaInfLoop Date: Sun, 16 Feb 2025 13:03:40 +0000 Subject: [PATCH] idk what changed, i just need to commit so i can start proper commits --- bun.lockb | Bin 98401 -> 100630 bytes index.ts | 158 ++++++++++++++++++++++++++++++++++++++++++--------- package.json | 2 + 3 files changed, 134 insertions(+), 26 deletions(-) diff --git a/bun.lockb b/bun.lockb index 8645e16810d0129f42544bef74a516dee14212c2..0b0866a4b08201dc26c41bf32eb82627cd3563f7 100755 GIT binary patch delta 20064 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 delta 18868 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 CXLL9K diff --git a/index.ts b/index.ts index e771046..bf691f3 100644 --- a/index.ts +++ b/index.ts @@ -6,6 +6,7 @@ import "dotenv/config"; import bcrypt from "bcrypt"; import type { StaticSelectAction } from "@slack/bolt"; import { inspect } from "node:util"; +import { scheduleJob } from "node-schedule"; const sql = postgres({ host: '/var/run/postgresql', @@ -162,22 +163,30 @@ async function getTemporaryToken(): Promise { return data.access_token; } -async function getAccessToken(slack_id: string): Promise { +async function getAccessToken(slack_id: string): Promise { const user = await sql`SELECT * FROM links WHERE slack_id = ${slack_id}`; if (!user.length) return null - const data = await fetch("https://osu.ppy.sh/oauth/token", { - method: "POST", - headers: { - "Content-Type": "application/x-www-form-urlencoded" - }, - body: `client_id=33126&client_secret=${encodeURIComponent(process.env.CLIENT_SECRET!)}&grant_type=refresh_token&refresh_token=${user[0].refresh_token}&scope=public` - }).then(res => res.json()); - await sql`UPDATE links SET refresh_token = ${data.refresh_token} WHERE slack_id = ${slack_id}`; + try { + const data = await fetch("https://osu.ppy.sh/oauth/token", { + method: "POST", + headers: { + "Content-Type": "application/x-www-form-urlencoded" + }, + body: `client_id=33126&client_secret=${encodeURIComponent(process.env.CLIENT_SECRET!)}&grant_type=refresh_token&refresh_token=${user[0].refresh_token}&scope=public` + }).then(res => res.json()); - return data.access_token; + console.log(data) + + await sql`UPDATE links SET refresh_token = ${data.refresh_token} WHERE slack_id = ${slack_id}`; + + return data.access_token; + } catch (err) { + console.error(err) + return null + } } async function sendGET(path: string, token?: string): Promise { @@ -480,17 +489,22 @@ app.command('/osu-profile', async (ctx) => { app.command('/osu-leaderboard', async (ctx) => { await ctx.ack(); - const cached = splitArray(cache, 10)[0].sort((a, b) => { + const cached = splitArray(cache.sort((a, b) => { return b.score.osu - a.score.osu - }); + }), 10); const users = []; for (let i in cached) { - const cachedU = cached[i]; - const slackProfile = (await ctx.client.users.info({ user: cachedU.slackId })).user!; + try { + const cachedU = cached[i]; + const slackProfile = (await ctx.client.users.info({ user: cachedU.slackId })).user!; - users.push(`${parseInt(i) + 1}. / - ${cachedU.score.osu.toLocaleString()}`) + users.push(`${users.length + 1}. / - ${cachedU.score.osu.toLocaleString()}`) + } catch (e) { + console.error(e) + continue; + } } ctx.respond({ @@ -590,17 +604,22 @@ app.action(/change-leaderboard\|.+/, async (ctx) => { const selected = action.selected_option.value; - const cached = splitArray(cache, 10)[0].sort((a, b) => { + const cached = splitArray(cache.sort((a, b) => { return b.score[selected] - a.score[selected] - }); + }), 10)[0]; const users = []; for (let i in cached) { - const cachedU = cached[i]; - const slackProfile = (await ctx.client.users.info({ user: cachedU.slackId })).user!; + try { + const cachedU = cached[i]; + const slackProfile = (await ctx.client.users.info({ user: cachedU.slackId })).user!; - users.push(`${parseInt(i) + 1}. / - ${cachedU.score[selected].toLocaleString()}`) + users.push(`${users.length + 1}. / - ${cachedU.score[selected].toLocaleString()}`) + } catch (e) { + console.error(e) + continue; + } } ctx.respond({ @@ -1090,12 +1109,99 @@ receiver.router.get('*', (req, res) => { res.redirect(`https://osu.ppy.sh${req.path}`) }) - ; (async () => { - await app.start(41691); +enum Mods { + EZ = "Easy", + NF = "No Fail", + HT = "Half Time", + HR = "Hard Rock", + SD = "Sudden Death", + PF = "Perfect", + DT = "Double Time", + NC = "Nightcore", + HD = "Hidden", + FI = "Fade In", + FL = "Flashlight", + RL = "Relax", + AP = "Autopilot", + SO = "Spun Out", + "1K" = "One Key", + "2K" = "Two Keys", + "3K" = "Three Keys", + "4K" = "Four Keys", + "5K" = "Five Keys", + "6K" = "Six Keys", + "7K" = "Seven Keys", + "8K" = "Eight Keys", + "9K" = "Nine Keys", + "10K" = "Ten Keys" +} - console.log('⚡️ Bolt app is running!'); +async function debugDailyChallenge() { + // Daily Challenge!! - cacheStuff(); + const tohken = await getAccessToken("U06TBP41C3E"); - setInterval(cacheStuff, 60 * 1000) // Cache every minute. Ratelimit is 1200 req/m anyways. - })(); + const rooms: any[] = await fetch(`https://osu.ppy.sh/api/v2/rooms`, { + headers: { + 'Authorization': `Bearer ${tohken}`, + 'X-Api-Version': '20240529' + } + }).then(res => res.json()); + + const dailyChallenge = rooms.find(room => room.host.id == 3 && room.active && room.category == "daily_challenge"); + + const currentSong = dailyChallenge.current_playlist_item + + const ruleset = [":osu-standard: osu!standard", ":osu-taiko: osu!taiko", ":osu-catch: osu!catch", ":osu-mania: osu!mania"][currentSong.ruleset_id] + + return app.client.chat.postMessage({ + channel: "C165V7XT9", + text: "A new daily challenge has started!", + "blocks": [ + { + "type": "header", + text: { + text: ruleset.split(' ').shift() + " A new daily challenge has started!", + emoji: true, + type: "plain_text" + } + }, + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": ` + +*Ruleset:* ${ruleset} +*Required mods:* ${currentSong.required_mods.length === 0 ? "None" : currentSong.required_mods.map((mod: any) => + // @ts-ignore I HATE THIS + Mods[mod.acronym] || mod.acronym + ).join(', ')}` + }, + "accessory": { + "type": "image", + "image_url": dailyChallenge.host.avatar_url, + "alt_text": `${dailyChallenge.host.username}'s osu profile picture` + } + } + ], + unfurl_links: true + }) +} + +; (async () => { + await app.start(41691); + + console.log('⚡️ Bolt app is running!'); + + cacheStuff(); + + setInterval(cacheStuff, 60 * 1000) // Cache every minute. Ratelimit is 1200 req/m anyways. + + scheduleJob('30 5 0 * * *', debugDailyChallenge) +})(); diff --git a/package.json b/package.json index 768b291..ceec3e2 100644 --- a/package.json +++ b/package.json @@ -11,8 +11,10 @@ "dependencies": { "@slack/bolt": "^3.19.0", "@types/bcrypt": "^5.0.2", + "@types/node-schedule": "^2.1.7", "bcrypt": "^5.1.1", "dotenv": "^16.4.5", + "node-schedule": "^2.1.1", "postgres": "^3.4.4" } } \ No newline at end of file