mirror of
https://github.com/zkldi/Tachi.git
synced 2026-09-30 19:07:58 +03:00
Add database and save userID link info to the database.
This commit is contained in:
@@ -12,6 +12,7 @@ if [[ "$ENV" != "PROD" ]]; then
|
||||
echo "DEV_SERVER_ID=769803764021592104" >> "$DOT_ENV_PATH" # Where is testing taking place?
|
||||
echo "BOT_CLIENT_SECRET=${NON_PROD_BOT_CLIENT_SECRET:-"_"}" >> "$DOT_ENV_PATH"
|
||||
echo "BOT_CLIENT_ID=${NON_PROD_BOT_CLIENT_ID:-"_"}" >> "$DOT_ENV_PATH"
|
||||
echo "MONGO_URL=${NON_PROD_MONGO_URL:-"_"}" >> "$DOT_ENV_PATH"
|
||||
echo "CONF_JSON5_LOCATION=./conf.json5" >> "$DOT_ENV_PATH"
|
||||
else
|
||||
# Prod environment
|
||||
@@ -19,5 +20,6 @@ else
|
||||
echo "DISCORD_TOKEN=${PROD_DISCORD_TOKEN:-"_"}" >> "$DOT_ENV_PATH"
|
||||
echo "BOT_CLIENT_SECRET=${PROD_BOT_CLIENT_SECRET:-"_"}" >> "$DOT_ENV_PATH"
|
||||
echo "BOT_CLIENT_ID=${PROD_BOT_CLIENT_ID:-"_"}" >> "$DOT_ENV_PATH"
|
||||
echo "MONGO_URL=${PROD_MONGO_URL:-"_"}" >> "$DOT_ENV_PATH"
|
||||
echo "CONF_JSON5_LOCATION=./conf.json5" >> "$DOT_ENV_PATH"
|
||||
fi
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import { Snowflake } from "discord.js/typings/index.js";
|
||||
import monk from "monk";
|
||||
import { integer } from "tachi-common";
|
||||
import { ProcessEnv } from "../setup";
|
||||
|
||||
const monkDB = monk(ProcessEnv.MONGO_URL);
|
||||
|
||||
export interface DiscordUserMapDocument {
|
||||
userID: integer;
|
||||
discordID: Snowflake;
|
||||
tachiApiToken: string;
|
||||
}
|
||||
|
||||
const db = {
|
||||
discordUserMap: monkDB.get<DiscordUserMapDocument>("discordUserMap")
|
||||
};
|
||||
|
||||
export default db;
|
||||
+33
-15
@@ -2,9 +2,10 @@ import express, { Express } from "express";
|
||||
import { LoggerLayers } from "../config";
|
||||
import { createLayeredLogger } from "../utils/logger";
|
||||
import { ValidateWebhookRequest } from "./middleware";
|
||||
import { WebhookEvents, APITokenDocument } from "tachi-common";
|
||||
import { WebhookEvents, APITokenDocument, PublicUserDocument } from "tachi-common";
|
||||
import { BotConfig, ProcessEnv } from "../setup";
|
||||
import { RequestTypes, TachiServerV1Request } from "../utils/fetch-tachi";
|
||||
import { RequestTypes, TachiServerV1Get, TachiServerV1Request } from "../utils/fetch-tachi";
|
||||
import db from "../mongo/mongo";
|
||||
|
||||
const app: Express = express();
|
||||
|
||||
@@ -48,21 +49,21 @@ app.post("/webhook", ValidateWebhookRequest, (req, res) => {
|
||||
const statusCode = 200;
|
||||
|
||||
switch (webhookEvent.type) {
|
||||
case "class-update/v1":
|
||||
case "goal-achieved/v1":
|
||||
case "milestone-achieved/v1":
|
||||
case "class-update/v1":
|
||||
case "goal-achieved/v1":
|
||||
case "milestone-achieved/v1":
|
||||
// @TODO add actual webhook handlers.
|
||||
// These will set the value of statusCode.
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
default:
|
||||
// According to the types, this should never happen.
|
||||
// However, tachi-server/common may recieve an update
|
||||
// to define new webhooks, and the bot might not
|
||||
// get around to updating in time.
|
||||
return res.status(501).json({
|
||||
success: false,
|
||||
description: `The type ${(webhookEvent as WebhookEvents).type} is unsupported.`
|
||||
});
|
||||
return res.status(501).json({
|
||||
success: false,
|
||||
description: `The type ${(webhookEvent as WebhookEvents).type} is unsupported.`
|
||||
});
|
||||
}
|
||||
|
||||
return res.sendStatus(statusCode);
|
||||
@@ -86,7 +87,7 @@ app.get("/oauth/callback", async (req, res) => {
|
||||
return res.status(400).send("Bad Request.");
|
||||
}
|
||||
|
||||
const tokenRes = await TachiServerV1Request<APITokenDocument>(RequestTypes.POST, "/oauth/token", {
|
||||
const tokenRes = await TachiServerV1Request<APITokenDocument>(RequestTypes.POST, "/oauth/token", null, {
|
||||
code: req.query.code,
|
||||
client_id: ProcessEnv.BOT_CLIENT_ID,
|
||||
client_secret: ProcessEnv.BOT_CLIENT_SECRET,
|
||||
@@ -101,9 +102,26 @@ app.get("/oauth/callback", async (req, res) => {
|
||||
});
|
||||
}
|
||||
|
||||
// const discordID = req.query.context;
|
||||
// const apiToken = tokenRes.body.token;
|
||||
// @todo Store discordID & apiToken somewhere.
|
||||
const discordID = req.query.context;
|
||||
const apiToken = tokenRes.body.token!;
|
||||
|
||||
const whoamiRes = await TachiServerV1Get<PublicUserDocument>("/api/v1/users/me", apiToken);
|
||||
|
||||
if (!whoamiRes.success) {
|
||||
logger.error("Failed to request user with token we just got?", { discordID });
|
||||
// @todo actually make this html file
|
||||
return res.sendFile("../pages/account-link-failed.html");
|
||||
}
|
||||
|
||||
const user = whoamiRes.body;
|
||||
|
||||
logger.info(`Saving user-discord-link for ${user.username} (#${user.id}).`);
|
||||
|
||||
await db.discordUserMap.insert({
|
||||
discordID,
|
||||
tachiApiToken: apiToken,
|
||||
userID: user.id
|
||||
});
|
||||
|
||||
return res.sendFile("../pages/account-linked.html");
|
||||
});
|
||||
|
||||
+4
-2
@@ -37,7 +37,7 @@ function ParseBotConfig(fileLoc = "conf.json5"): BotConfig {
|
||||
SERVER_PORT: Prudence.isPositiveNonZeroInteger,
|
||||
TACHI_SERVER_LOCATION: "string",
|
||||
OUR_URL: "string",
|
||||
GENERIC_ERROR_MESSAGE: "string"
|
||||
GENERIC_ERROR_MESSAGE: "string",
|
||||
});
|
||||
|
||||
if (err) {
|
||||
@@ -54,6 +54,7 @@ export interface ProcessEnvironment {
|
||||
DISCORD_TOKEN: string;
|
||||
BOT_CLIENT_SECRET: string;
|
||||
BOT_CLIENT_ID: string;
|
||||
MONGO_URL: string;
|
||||
}
|
||||
|
||||
function ParseEnvVars() {
|
||||
@@ -63,7 +64,8 @@ function ParseEnvVars() {
|
||||
ENV: "string",
|
||||
DISCORD_TOKEN: "string",
|
||||
BOT_CLIENT_SECRET: "string",
|
||||
BOT_CLIENT_ID: "string"
|
||||
BOT_CLIENT_ID: "string",
|
||||
MONGO_URL: "string",
|
||||
},
|
||||
{},
|
||||
{ allowExcessKeys: true }
|
||||
|
||||
@@ -30,6 +30,7 @@ export enum RequestTypes {
|
||||
export async function TachiServerV1Request<T>(
|
||||
method: Exclude<RequestTypes, RequestTypes.GET>,
|
||||
url: string,
|
||||
token?: string | null,
|
||||
body: unknown = {}
|
||||
): Promise<APIResponse<T>> {
|
||||
const realUrl = PrependTachiUrl(url, "1");
|
||||
@@ -41,7 +42,8 @@ export async function TachiServerV1Request<T>(
|
||||
const res = await axios(realUrl, {
|
||||
method,
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
"Content-Type": "application/json",
|
||||
Authorization: token ? `Bearer ${token}` : undefined,
|
||||
},
|
||||
data: JSON.stringify(body)
|
||||
});
|
||||
@@ -69,6 +71,7 @@ export async function TachiServerV1Request<T>(
|
||||
*/
|
||||
export async function TachiServerV1Get<T = unknown>(
|
||||
url: string,
|
||||
token?: string,
|
||||
params: Record<string, string> = {}
|
||||
): Promise<APIResponse<T>> {
|
||||
try {
|
||||
@@ -76,7 +79,9 @@ export async function TachiServerV1Get<T = unknown>(
|
||||
|
||||
const realUrl = `${PrependTachiUrl(url, "1")}?${urlParams.toString()}`;
|
||||
|
||||
const res = await axios(realUrl, { method: RequestTypes.GET });
|
||||
const res = await axios(realUrl, { method: RequestTypes.GET, headers: {
|
||||
Authorization: token ? `Bearer ${token}` : undefined,
|
||||
} });
|
||||
const json = (await res.data) as APIResponse<T>;
|
||||
const contents = { ...json, statusCode: res.status };
|
||||
|
||||
|
||||
Reference in New Issue
Block a user