This commit is contained in:
James Shiffer 2024-05-09 23:20:14 +00:00
parent a8b6d834f8
commit cf601a72fb
4 changed files with 86 additions and 12 deletions

View File

@ -4,8 +4,7 @@ CLIENT="123456789012345678"
GUILD="123456789012345678" GUILD="123456789012345678"
ADMIN="123456789012345678" ADMIN="123456789012345678"
LLM_HOST="127.0.0.1" LLM_HOST="http://127.0.0.1:8000"
LLM_PORT=8000
LLM_TOKEN="dfsl;kjsdl;kfja" LLM_TOKEN="dfsl;kjsdl;kfja"
REPLY_CHANCE=0.2 REPLY_CHANCE=0.2

View File

@ -32,6 +32,7 @@ import {
openDb, openDb,
reactionEmojis, reactionEmojis,
recordReaction, recordReaction,
requestTTSResponse,
sync sync
} from './util'; } from './util';
import 'dotenv/config'; import 'dotenv/config';
@ -166,11 +167,16 @@ async function onNewMessage(message: Message)
async function fetchMotd() async function fetchMotd()
{ {
const res = await fetch(process.env.MOTD_HREF); try {
const xml = await res.text(); const res = await fetch(process.env.MOTD_HREF);
const parser = new JSDOM(xml); const xml = await res.text();
const doc = parser.window.document; const parser = new JSDOM(xml);
return doc.querySelector(process.env.MOTD_QUERY).textContent; const doc = parser.window.document;
const el = doc.querySelector(process.env.MOTD_QUERY);
return el ? el.textContent : null;
} catch (err) {
logWarn('[bot] Failed to fetch MOTD; is the booru down?');
}
} }
async function requestRVCResponse(src: Attachment): Promise<Blob> async function requestRVCResponse(src: Attachment): Promise<Blob>
@ -189,7 +195,7 @@ async function requestRVCResponse(src: Attachment): Promise<Blob>
const fd = new FormData(); const fd = new FormData();
fd.append('file', fs.readFileSync(tmpFileName), 'voice-message.ogg'); fd.append('file', fs.readFileSync(tmpFileName), 'voice-message.ogg');
const rvcEndpoint = `http://${process.env.LLM_HOST}:${process.env.LLM_PORT}/rvc?${queryParams.toString()}`; const rvcEndpoint = `${process.env.LLM_HOST}/rvc?${queryParams.toString()}`;
logInfo(`[bot] Requesting RVC response for ${src.id}`); logInfo(`[bot] Requesting RVC response for ${src.id}`);
const res = await fetch(rvcEndpoint, { const res = await fetch(rvcEndpoint, {
method: 'POST', method: 'POST',
@ -206,7 +212,7 @@ async function requestLLMResponse(messages)
for (const field of Object.keys(config["llmconf"].llmSettings)) { for (const field of Object.keys(config["llmconf"].llmSettings)) {
queryParams.append(field, config["llmconf"].llmSettings[field]); queryParams.append(field, config["llmconf"].llmSettings[field]);
} }
const llmEndpoint = `http://${process.env.LLM_HOST}:${process.env.LLM_PORT}/?${queryParams.toString()}`; const llmEndpoint = `${process.env.LLM_HOST}/?${queryParams.toString()}`;
const messageList = messages.map((m: Message) => ({ const messageList = messages.map((m: Message) => ({
role: m.author.bot ? "assistant" : "user", role: m.author.bot ? "assistant" : "user",
content: m.cleanContent, content: m.cleanContent,
@ -244,8 +250,18 @@ async function scheduleRandomMessage(firstTime = false)
return; return;
} }
const randomMessage = await fetchMotd(); const randomMessage = await fetchMotd();
await channel.send(randomMessage); if (randomMessage) {
logInfo(`[bot] Sent MOTD: ${randomMessage}`); const audio = await requestTTSResponse(randomMessage);
const audioBuf = await audio.arrayBuffer();
const audioFile = new AttachmentBuilder(Buffer.from(audioBuf)).setName('mikuified.wav');
await channel.send({
content: randomMessage,
files: [audioFile]
});
logInfo(`[bot] Sent MOTD: ${randomMessage}`);
} else {
logWarn(`[bot] Could not fetch MOTD.`);
}
} }
// wait between 2-8 hours // wait between 2-8 hours
const timeoutMins = Math.random() * 360 + 120; const timeoutMins = Math.random() * 360 + 120;

View File

@ -0,0 +1,43 @@
import {
AttachmentBuilder,
ChatInputCommandInteraction,
SlashCommandBuilder
} from 'discord.js';
import 'dotenv/config';
import { logError, logInfo, logWarn } from '../../../logging';
import { requestTTSResponse } from '../../util';
const config = {
ttsSettings: {
pitch_change_oct: 1,
pitch_change_sem: 0
}
};
async function ttsCommand(interaction: ChatInputCommandInteraction)
{
const text = interaction.options.getString('text');
await interaction.reply(`generating audio for "${text}"...`);
try {
const audio = await requestTTSResponse(text);
const audioBuf = await audio.arrayBuffer();
const audioFile = new AttachmentBuilder(Buffer.from(audioBuf)).setName('mikuified.wav');
await interaction.editReply({
files: [audioFile]
});
} catch (err) {
await interaction.editReply(`Error: ${err}`);
logError(`Error while generating TTS: ${err}`);
}
}
export = {
data: new SlashCommandBuilder()
.setName('tts')
.setDescription('Read text in Miku\'s voice')
.addStringOption(
opt => opt.setName('text').setDescription('Text').setRequired(true)
),
execute: ttsCommand,
config: config
};

View File

@ -9,6 +9,7 @@ import { get as httpGet } from 'https';
import { Database, open } from 'sqlite'; import { Database, open } from 'sqlite';
import { Database as Database3 } from 'sqlite3'; import { Database as Database3 } from 'sqlite3';
import 'dotenv/config'; import 'dotenv/config';
import fetch from 'node-fetch';
import { logError, logInfo, logWarn } from '../logging'; import { logError, logInfo, logWarn } from '../logging';
import { ScoreboardMessageRow } from '../models'; import { ScoreboardMessageRow } from '../models';
@ -163,4 +164,19 @@ async function sync(guilds: GuildManager) {
} }
} }
export { db, clearDb, openDb, reactionEmojis, recordReaction, sync }; async function requestTTSResponse(txt: string): Promise<Blob>
{
const queryParams = new URLSearchParams();
queryParams.append("token", process.env.LLM_TOKEN);
queryParams.append("text", txt);
const ttsEndpoint = `${process.env.LLM_HOST}/tts?${queryParams.toString()}`;
logInfo(`[bot] Requesting TTS response for "${txt}"`);
const res = await fetch(ttsEndpoint, {
method: 'POST'
});
const resContents = await res.blob();
return resContents;
}
export { db, clearDb, openDb, reactionEmojis, recordReaction, requestTTSResponse, sync };