Files
tardis-bot/src/modules/canttalk.ts
2026-05-14 20:33:31 +02:00

84 lines
2.9 KiB
TypeScript

import { readdirSync } from "node:fs";
import { join } from "node:path";
import { respond } from "../audio/AudioService.js";
import type { TTSPreferencesRow } from "../db/schema.js";
import { formatCandidates } from "../tts/BaseEngine.js";
import type { Module } from "./types.js";
export const canttalk: Module = ({ client, audio, commands, tts, db, t, config, rootDir }) => {
const sysmsg = join(rootDir, "sysmsg.wav");
client.on("messageCreate", async (message) => {
if (message.author.bot) return;
if (message.content.startsWith(config.PREFIX)) return;
if (!config.TTS_CHANNEL || message.channel.id !== config.TTS_CHANNEL) return;
const voiceChannel = message.member?.voice.channel;
if (!voiceChannel) return;
let userRow = await db.get<TTSPreferencesRow>(
"select * from TTSPreferences where user_id=?",
message.author.id,
);
if (!userRow) {
await db.run("insert into TTSPreferences (user_id,engine,voice) values (?,?,?)", [
message.author.id,
tts.announcement.shortName,
tts.announcementVoice,
]);
userRow = await db.get<TTSPreferencesRow>(
"select * from TTSPreferences where user_id=?",
message.author.id,
);
}
if (!userRow) return;
const engine = tts.get(userRow.engine);
if (engine) {
await audio.speak(voiceChannel, message.content, engine, userRow.voice);
}
});
commands.register("myvoice", async (args, message) => {
const engineName = args[1];
if (!engineName || args.length < 3) {
return respond(audio, sysmsg, message, t("TOO_MANY_ARGUMENTS"));
}
const engine = tts.get(engineName);
if (!engine) {
return respond(audio, sysmsg, message, t("INVALID_ENGINE", engineName));
}
const voiceInput = args.slice(2).join(" ");
const res = engine.resolveVoice(voiceInput);
let chosenVoice: string;
if (res.kind === "exact" || res.kind === "fuzzy") {
chosenVoice = res.voice;
respond(audio, sysmsg, message, t("USER_VOICE_CHANGED", chosenVoice, engine.longName));
} else if (res.kind === "ambiguous") {
return respond(
audio,
sysmsg,
message,
t("AMBIGUOUS_VOICE", voiceInput, formatCandidates(res.candidates)),
);
} else {
chosenVoice = engine.getDefaultVoice();
respond(audio, sysmsg, message, t("INVALID_VOICE", chosenVoice, engine.longName));
}
await db.run("update TTSPreferences set engine=?, voice=? where user_id=?", [
engineName,
chosenVoice,
message.author.id,
]);
});
commands.register("random", async (_args, _message) => {
const tmpPath = config.VOICE_TMP_PATH;
const files = readdirSync(tmpPath);
if (files.length === 0) return;
const rnd = files[Math.floor(Math.random() * files.length)];
if (!rnd) return;
audio.queue.add(sysmsg);
audio.queue.add(join(tmpPath, rnd));
});
};