start fixing apiRoll

This commit is contained in:
Ean Milligan 2025-04-26 14:49:11 -04:00
parent d2a7c25879
commit 1069b99091
5 changed files with 54 additions and 55 deletions

View File

@ -16,7 +16,7 @@ import stdResp from './endpoints/stdResponses.ts';
// start() returns nothing // start() returns nothing
// start initializes and runs the entire API for the bot // start initializes and runs the entire API for the bot
const start = async (): Promise<void> => { const start = () => {
log(LT.INFO, `HTTP api running at: http://localhost:${config.api.port}/`); log(LT.INFO, `HTTP api running at: http://localhost:${config.api.port}/`);
// rateLimitTime holds all users with the last time they started a rate limit timer // rateLimitTime holds all users with the last time they started a rate limit timer
@ -102,13 +102,13 @@ const start = async (): Promise<void> => {
switch (path.toLowerCase()) { switch (path.toLowerCase()) {
case '/key': case '/key':
case '/key/': case '/key/':
return await endpoints.get.apiKeyAdmin(query, apiUserid); return endpoints.get.apiKeyAdmin(query, apiUserid);
case '/channel': case '/channel':
case '/channel/': case '/channel/':
return await endpoints.get.apiChannel(query, apiUserid); return endpoints.get.apiChannel(query, apiUserid);
case '/roll': case '/roll':
case '/roll/': case '/roll/':
return await endpoints.get.apiRoll(query, apiUserid, request); return endpoints.get.apiRoll(query, apiUserid);
default: default:
// Alert API user that they messed up // Alert API user that they messed up
return stdResp.NotFound('Auth Get'); return stdResp.NotFound('Auth Get');
@ -118,7 +118,7 @@ const start = async (): Promise<void> => {
switch (path.toLowerCase()) { switch (path.toLowerCase()) {
case '/channel/add': case '/channel/add':
case '/channel/add/': case '/channel/add/':
return await endpoints.post.apiChannelAdd(query, apiUserid); return endpoints.post.apiChannelAdd(query, apiUserid);
default: default:
// Alert API user that they messed up // Alert API user that they messed up
return stdResp.NotFound('Auth Post'); return stdResp.NotFound('Auth Post');
@ -134,17 +134,17 @@ const start = async (): Promise<void> => {
case '/key/activate/': case '/key/activate/':
case '/key/deactivate': case '/key/deactivate':
case '/key/deactivate/': case '/key/deactivate/':
return await endpoints.put.apiKeyManage(query, apiUserid, path); return endpoints.put.apiKeyManage(query, apiUserid, path);
case '/channel/ban': case '/channel/ban':
case '/channel/ban/': case '/channel/ban/':
case '/channel/unban': case '/channel/unban':
case '/channel/unban/': case '/channel/unban/':
return await endpoints.put.apiChannelManageBan(query, apiUserid, path); return endpoints.put.apiChannelManageBan(query, apiUserid, path);
case '/channel/activate': case '/channel/activate':
case '/channel/activate/': case '/channel/activate/':
case '/channel/deactivate': case '/channel/deactivate':
case '/channel/deactivate/': case '/channel/deactivate/':
return await endpoints.put.apiChannelManageActive(query, apiUserid, path); return endpoints.put.apiChannelManageActive(query, apiUserid, path);
default: default:
// Alert API user that they messed up // Alert API user that they messed up
return stdResp.NotFound('Auth Put'); return stdResp.NotFound('Auth Put');
@ -154,7 +154,7 @@ const start = async (): Promise<void> => {
switch (path.toLowerCase()) { switch (path.toLowerCase()) {
case '/key/delete': case '/key/delete':
case '/key/delete/': case '/key/delete/':
return await endpoints.delete.apiKeyDelete(query, apiUserid, apiUserEmail, apiUserDelCode); return endpoints.delete.apiKeyDelete(query, apiUserid, apiUserEmail, apiUserDelCode);
default: default:
// Alert API user that they messed up // Alert API user that they messed up
return stdResp.NotFound('Auth Del'); return stdResp.NotFound('Auth Del');
@ -164,14 +164,14 @@ const start = async (): Promise<void> => {
// Alert API user that they messed up // Alert API user that they messed up
return stdResp.MethodNotAllowed('Auth'); return stdResp.MethodNotAllowed('Auth');
} }
} else if (!authenticated) { } else {
// Handle the unathenticated request // Handle the unathenticated request
switch (request.method) { switch (request.method) {
case 'GET': case 'GET':
switch (path.toLowerCase()) { switch (path.toLowerCase()) {
case '/key': case '/key':
case '/key/': case '/key/':
return await endpoints.get.apiKey(query); return endpoints.get.apiKey(query);
case '/heatmap.png': case '/heatmap.png':
return endpoints.get.heatmapPng(); return endpoints.get.heatmapPng();
default: default:

View File

@ -12,7 +12,6 @@ import {
import { rollingEmbed, warnColor } from '../commandUtils.ts'; import { rollingEmbed, warnColor } from '../commandUtils.ts';
import rollFuncs from './roll/_index.ts'; import rollFuncs from './roll/_index.ts';
import { queueRoll } from '../solver/rollQueue.ts'; import { queueRoll } from '../solver/rollQueue.ts';
import { QueuedRoll } from '../mod.d.ts';
import utils from '../utils.ts'; import utils from '../utils.ts';
export const roll = async (message: DiscordenoMessage, args: string[], command: string) => { export const roll = async (message: DiscordenoMessage, args: string[], command: string) => {
@ -53,15 +52,13 @@ export const roll = async (message: DiscordenoMessage, args: string[], command:
// Rejoin all of the args and send it into the solver, if solver returns a falsy item, an error object will be substituded in // Rejoin all of the args and send it into the solver, if solver returns a falsy item, an error object will be substituded in
const rollCmd = message.content.substring(2); const rollCmd = message.content.substring(2);
queueRoll( queueRoll({
<QueuedRoll> { apiRoll: false,
apiRoll: false, dd: { m, message },
dd: { m, message }, rollCmd,
rollCmd, modifiers,
modifiers, originalCommand,
originalCommand, });
},
);
} catch (e) { } catch (e) {
log(LT.ERROR, `Undandled Error: ${JSON.stringify(e)}`); log(LT.ERROR, `Undandled Error: ${JSON.stringify(e)}`);
} }

View File

@ -8,14 +8,14 @@ import {
log, log,
LT, LT,
} from '../../../deps.ts'; } from '../../../deps.ts';
import { QueuedRoll, RollModifiers } from '../../mod.d.ts'; import { RollModifiers } from '../../mod.d.ts';
import utils from '../../utils.ts'; import utils from '../../utils.ts';
import { queueRoll } from '../../solver/rollQueue.ts'; import { queueRoll } from '../../solver/rollQueue.ts';
import stdResp from '../stdResponses.ts'; import stdResp from '../stdResponses.ts';
const apiWarning = `The following roll was conducted using my built in API. If someone in this channel did not request this roll, please report API abuse here: <${config.api.supportURL}>`; const apiWarning = `The following roll was conducted using my built in API. If someone in this channel did not request this roll, please report API abuse here: <${config.api.supportURL}>`;
export const apiRoll = async (query: Map<string, string>, apiUserid: bigint, request: Request): Promise<Response> => { export const apiRoll = async (query: Map<string, string>, apiUserid: bigint): Promise<Response> => {
// Make sure query contains all the needed parts // Make sure query contains all the needed parts
if ( if (
query.has('rollstr') && query.has('rollstr') &&
@ -61,7 +61,7 @@ export const apiRoll = async (query: Map<string, string>, apiUserid: bigint, req
try { try {
// Make sure rollCmd is not undefined // Make sure rollCmd is not undefined
let rollCmd = query.get('rollstr') || ''; let rollCmd = query.get('rollstr') || '';
const originalCommand = query.get('rollstr'); const originalCommand = query.get('rollstr') || '';
if (rollCmd.length === 0) { if (rollCmd.length === 0) {
// Always log API rolls for abuse detection // Always log API rolls for abuse detection
@ -101,15 +101,13 @@ export const apiRoll = async (query: Map<string, string>, apiUserid: bigint, req
}; };
// Parse the roll and get the return text // Parse the roll and get the return text
await queueRoll( await queueRoll({
<QueuedRoll> { apiRoll: true,
apiRoll: true, api: { channelId: BigInt(query.get('channel') || '0'), userId: BigInt(query.get('user') || '') },
api: { request, channelId: BigInt(query.get('channel') || '0'), userId: BigInt(query.get('user') || '') }, rollCmd,
rollCmd, modifiers,
modifiers, originalCommand,
originalCommand, });
},
);
} catch (err) { } catch (err) {
// Handle any errors we missed // Handle any errors we missed
log(LT.ERROR, `Unhandled Error: ${JSON.stringify(err)}`); log(LT.ERROR, `Unhandled Error: ${JSON.stringify(err)}`);
@ -118,7 +116,7 @@ export const apiRoll = async (query: Map<string, string>, apiUserid: bigint, req
} else { } else {
// Alert API user that they messed up // Alert API user that they messed up
return stdResp.Forbidden( return stdResp.Forbidden(
`Verify you are a member of the guild you are sending this roll to. If you are, the ${config.name} may not have that registered, please send a message in the guild so ${config.name} can register this. This registration is temporary, so if you see this error again, just poke your server again.`, `Verify you are a member of the guild you are sending this roll to. If you are, the ${config.name} may not have that registered, please send a message in the guild so ${config.name} can register this. This registration is temporary, so if you see this error again, just poke your server again.`
); );
} }
} else { } else {

18
src/mod.d.ts vendored
View File

@ -26,21 +26,25 @@ export type RollModifiers = {
}; };
// QueuedRoll is the structure to track rolls we could not immediately handle // QueuedRoll is the structure to track rolls we could not immediately handle
export type QueuedRoll = { interface QueuedRoll {
apiRoll: boolean; rollCmd: string;
modifiers: RollModifiers;
originalCommand: string;
}
export interface ApiQueuedRoll extends QueuedRoll {
apiRoll: true;
api: { api: {
request: Request;
channelId: bigint; channelId: bigint;
userId: bigint; userId: bigint;
}; };
}
export interface DDQueuedRoll extends QueuedRoll {
apiRoll: false;
dd: { dd: {
m: DiscordenoMessage; m: DiscordenoMessage;
message: DiscordenoMessage; message: DiscordenoMessage;
}; };
originalCommand: string; }
rollCmd: string;
modifiers: RollModifiers;
};
export type PastCommandCount = { export type PastCommandCount = {
command: string; command: string;

View File

@ -13,16 +13,16 @@ import {
sendMessage, sendMessage,
} from '../../deps.ts'; } from '../../deps.ts';
import { SolvedRoll } from '../solver/solver.d.ts'; import { SolvedRoll } from '../solver/solver.d.ts';
import { QueuedRoll, RollModifiers } from '../mod.d.ts'; import { ApiQueuedRoll, DDQueuedRoll, RollModifiers } from '../mod.d.ts';
import { generateCountDetailsEmbed, generateDMFailed, generateRollEmbed, infoColor2, rollingEmbed } from '../commandUtils.ts'; import { generateCountDetailsEmbed, generateDMFailed, generateRollEmbed, infoColor2, rollingEmbed } from '../commandUtils.ts';
import stdResp from '../endpoints/stdResponses.ts'; import stdResp from '../endpoints/stdResponses.ts';
import utils from '../utils.ts'; import utils from '../utils.ts';
let currentWorkers = 0; let currentWorkers = 0;
const rollQueue: Array<QueuedRoll> = []; const rollQueue: Array<ApiQueuedRoll | DDQueuedRoll> = [];
// Handle setting up and calling the rollWorker // Handle setting up and calling the rollWorker
const handleRollWorker = async (rq: QueuedRoll) => { const handleRollWorker = async (rq: ApiQueuedRoll | DDQueuedRoll) => {
currentWorkers++; currentWorkers++;
// gmModifiers used to create gmEmbed (basically just turn off the gmRoll) // gmModifiers used to create gmEmbed (basically just turn off the gmRoll)
@ -43,12 +43,12 @@ const handleRollWorker = async (rq: QueuedRoll) => {
( (
await generateRollEmbed( await generateRollEmbed(
rq.dd.message.authorId, rq.dd.message.authorId,
<SolvedRoll> { <SolvedRoll>{
error: true, error: true,
errorCode: 'TooComplex', errorCode: 'TooComplex',
errorMsg: 'Error: Roll took too long to process, try breaking roll down into simpler parts', errorMsg: 'Error: Roll took too long to process, try breaking roll down into simpler parts',
}, },
<RollModifiers> {}, <RollModifiers>{}
) )
).embed, ).embed,
], ],
@ -170,14 +170,14 @@ const handleRollWorker = async (rq: QueuedRoll) => {
JSON.stringify( JSON.stringify(
rq.modifiers.count rq.modifiers.count
? { ? {
counts: countEmbed, counts: countEmbed,
details: pubEmbedDetails, details: pubEmbedDetails,
} }
: { : {
details: pubEmbedDetails, details: pubEmbedDetails,
}, }
), )
), )
); );
} }
} }
@ -191,7 +191,7 @@ const handleRollWorker = async (rq: QueuedRoll) => {
}; };
// Runs the roll or queues it depending on how many workers are currently running // Runs the roll or queues it depending on how many workers are currently running
export const queueRoll = async (rq: QueuedRoll) => { export const queueRoll = async (rq: ApiQueuedRoll | DDQueuedRoll) => {
if (rq.apiRoll) { if (rq.apiRoll) {
handleRollWorker(rq); handleRollWorker(rq);
} else if (!rollQueue.length && currentWorkers < config.limits.maxWorkers) { } else if (!rollQueue.length && currentWorkers < config.limits.maxWorkers) {
@ -218,7 +218,7 @@ The results for this roll will replace this message when it is done.`,
setInterval(async () => { setInterval(async () => {
log( log(
LT.LOG, LT.LOG,
`Checking rollQueue for items, rollQueue length: ${rollQueue.length}, currentWorkers: ${currentWorkers}, config.limits.maxWorkers: ${config.limits.maxWorkers}`, `Checking rollQueue for items, rollQueue length: ${rollQueue.length}, currentWorkers: ${currentWorkers}, config.limits.maxWorkers: ${config.limits.maxWorkers}`
); );
if (rollQueue.length && currentWorkers < config.limits.maxWorkers) { if (rollQueue.length && currentWorkers < config.limits.maxWorkers) {
const temp = rollQueue.shift(); const temp = rollQueue.shift();