Files
tardis-bot/src/modules/wordbyword.ts
2026-05-14 21:33:18 +02:00

79 lines
2.7 KiB
TypeScript

import { join } from "node:path";
import levenshtein from "fast-levenshtein";
import { respond } from "../audio/AudioService.js";
const isStringInt = (s: string): boolean => /^-?\d+$/.test(s);
import type { BotStateRow, WBWStoryRow } from "../db/schema.js";
import type { Module } from "./types.js";
export const wordbyword: Module = ({ audio, commands, db, t, rootDir }) => {
const sysmsg = join(rootDir, "sysmsg.wav");
let currentWBW = "";
commands.register("wbw", async (args, message) => {
if (args.length === 1) {
return respond(
audio,
sysmsg,
message,
currentWBW ? t("CURRENT_STORY", currentWBW) : t("NO_STORY"),
);
}
if (args.length > 2) {
return respond(audio, sysmsg, message, t("TOO_MANY_ARGUMENTS"));
}
const arg1 = args[1];
if (arg1 === undefined) return;
if (isStringInt(arg1)) {
const story = await db.get<WBWStoryRow>(
"select * from WBWStories where story_id=?",
parseInt(arg1, 10),
);
if (!story) return respond(audio, sysmsg, message, t("WBW_INVALID_ID"));
return respond(audio, sysmsg, message, story.story_text);
}
const lastUser = await db.get<BotStateRow>(
"select value from BotState where key='last_wbw'",
);
if (lastUser && message.author.id === lastUser.value && currentWBW !== "") {
const lastWord =
currentWBW.indexOf(" ") === currentWBW.lastIndexOf(" ")
? currentWBW.trim()
: currentWBW.slice(currentWBW.slice(0, -1).lastIndexOf(" ") + 1).trim();
if (levenshtein.get(arg1, lastWord) <= 3) {
currentWBW = currentWBW.replace(
new RegExp(`${escapeRegExp(lastWord)}([^${escapeRegExp(lastWord)}]*)$`),
`${arg1}$1 `,
);
respond(audio, sysmsg, message, t("WBW_REPLACED", lastWord, arg1));
} else {
return respond(audio, sysmsg, message, t("WBW_TOO_DIFFERENT"));
}
} else {
currentWBW += `${arg1} `;
respond(audio, sysmsg, message, t("WBW_NEW_WORD"));
const toSay =
currentWBW.indexOf(".") === -1 ? currentWBW : currentWBW.slice(currentWBW.lastIndexOf(".") + 2);
const voiceChannel = message.member?.voice.channel;
if (voiceChannel) await audio.speak(voiceChannel, toSay);
await db.run("insert or replace into BotState (key, value) values (?, ?)", [
"last_wbw",
message.author.id,
]);
}
});
commands.register("newwbw", async (_args, message) => {
await db.run("insert into WBWStories (story_text) values(?)", [currentWBW]);
currentWBW = "";
respond(audio, sysmsg, message, t("WBW_RESET"));
});
};
function escapeRegExp(s: string): string {
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}