Gacha game centered around vore.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
vore-gacha/src/DiscordWebhookHandler.ts

88 lines
3.2 KiB

import {SavedWebhook} from "./SavedWebhook.js";
import {FastifyReply, FastifyRequest} from "fastify";
import {AccessToken, AuthorizationCode, ModuleOptions} from "simple-oauth2";
import pug from "pug";
import {renderError} from "./PugRenderer.js";
import {APIWebhook} from "discord-api-types";
import {getBaseUrl, getFirstValue, RouteWithQuerystring} from "./FastifyHelpers.js";
import { join } from "path";
interface DiscordWebhookToken extends AccessToken {
token: {webhook?: APIWebhook}
}
const AuthConfig: ModuleOptions["auth"] = {
tokenHost: "https://discord.com",
authorizePath: "/api/oauth2/authorize",
tokenPath: "/api/oauth2/token",
revokePath: "/api/oauth2/token/revoke",
}
export class DiscordWebhookHandler {
readonly webhook: SavedWebhook
readonly templateFilename: string
readonly config: ModuleOptions
readonly destinationFunc: () => string
constructor({webhook, templateFilename, appId, secret, destinationFunc}: {webhook: SavedWebhook, templateFilename: string, appId: string, secret: string, destinationFunc: () => string}) {
this.templateFilename = templateFilename
this.webhook = webhook
this.config = {
client: {
id: appId,
secret,
},
auth: AuthConfig,
}
this.destinationFunc = destinationFunc
}
async handleRequest(req: FastifyRequest<RouteWithQuerystring>, res: FastifyReply): Promise<void> {
const baseUrl = getBaseUrl(req)
const code = getFirstValue(req.query["code"]) ?? null
const client = new AuthorizationCode(this.config)
if (code === null) {
const authUrl = client.authorizeURL({
scope: ["applications.commands", "webhook.incoming"],
redirect_uri: req.url,
})
res.code(200)
res.type("text/html")
res.send(pug.renderFile(join("static/pages", this.templateFilename), {authUrl, baseUrl, isReset: this.webhook.isPresent}))
return
}
let token: DiscordWebhookToken
try {
token = await client.getToken({
code,
scope: ["applications.commands", "webhook.incoming"],
redirect_uri: getBaseUrl(req) + "setup/gameChannel"
}) as DiscordWebhookToken
} catch (e) {
return renderError({
baseUrl,
res: res,
error: e,
context: "exchanging the code you gave me for a token"
})
}
if (!token.token.webhook) {
return renderError({
baseUrl,
res: res,
error: "token did not contain webhook",
context: "processing the token I received"
})
}
const wasSet = this.webhook.isPresent
try {
await this.webhook.replaceHook(token.token.webhook)
} catch (e) {
return renderError({
baseUrl,
res: res,
error: e,
context: `saving the new webhook${wasSet ? " and deleting the old one" : ""}`
})
}
res.redirect(this.destinationFunc())
}
}