what the helk!?

This commit is contained in:
Ashley Graves 2024-10-15 15:09:04 +02:00
parent 7c210ee7a6
commit bfb14f4b15
14 changed files with 771 additions and 3 deletions

View file

@ -1,2 +1,6 @@
DISCORD_TOKEN=MTgzMTM1MDU4NDM1NzYwNjIz.T33Rns.A5CRoasbuvPS8Uc1QeoqEA3QQI4 DISCORD_TOKEN=MTgzMTM1MDU4NDM1NzYwNjIz.T33Rns.A5CRoasbuvPS8Uc1QeoqEA3QQI4
GROQ_API_KEY=gsk_i5btqpox8Ei1s2bFdGRuWmVRH0QZIVuwnn8aFxa8KtXaZDetDYpZJRNCwRAp GROQ_API_KEY=gsk_i5btqpox8Ei1s2bFdGRuWmVRH0QZIVuwnn8aFxa8KtXaZDetDYpZJRNCwRAp
PORT=3000
HOST=127.0.0.1
BASE_URL=https://bot.example.com

View file

@ -11,9 +11,12 @@
"@himeka/booru": "^2.7.7", "@himeka/booru": "^2.7.7",
"@imgproxy/imgproxy-node": "^1.0.6", "@imgproxy/imgproxy-node": "^1.0.6",
"better-sqlite3": "^11.3.0", "better-sqlite3": "^11.3.0",
"bootstrap": "^5.3.3",
"canvas": "^2.11.2", "canvas": "^2.11.2",
"discord.js": "^14.16.3", "discord.js": "^14.16.3",
"dotenv": "^16.4.5", "dotenv": "^16.4.5",
"ejs": "^3.1.10",
"express": "^4.21.1",
"groq-sdk": "^0.7.0", "groq-sdk": "^0.7.0",
"html-entities": "^2.5.2", "html-entities": "^2.5.2",
"knex": "^3.1.0", "knex": "^3.1.0",

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,6 @@
const { InteractionContextType, ApplicationIntegrationType, SlashCommandBuilder } = require("discord.js"); const { InteractionContextType, ApplicationIntegrationType, SlashCommandBuilder } = require("discord.js");
const { encode } = require("html-entities");
const { knex } = require("../../db.js");
const data = new SlashCommandBuilder() const data = new SlashCommandBuilder()
.setName("prompt") .setName("prompt")
@ -38,7 +40,8 @@ module.exports = {
await interaction.deferReply({ ephemeral: !(interaction.options.getBoolean("send") || true) }); await interaction.deferReply({ ephemeral: !(interaction.options.getBoolean("send") || true) });
const groq = interaction.client.groq; const groq = interaction.client.groq;
const response = (await groq.chat.completions.create({ /** @type {string} */
var response = (await groq.chat.completions.create({
messages: [{ messages: [{
role: "system", role: "system",
content: interaction.client.prompts.query content: interaction.client.prompts.query
@ -49,6 +52,18 @@ module.exports = {
"model": interaction.options.getString("model") || interaction.defaultModel "model": interaction.options.getString("model") || interaction.defaultModel
})).choices[0].message.content; })).choices[0].message.content;
if (response.length > 2000) {
var id = Math.random().toString(16).slice(2, 10);
await knex.insert({ id, data: encode(response) }).into("pastes");
response = response.split("\n")[0];
if (response.length > 100) {
response = response.slice(0, 100) + "...";
}
response += `\n[Read More](${process.env.BASE_URL}/view/${id})`;
}
await interaction.followUp(response + "\n\n-# This content was generated by a LLM and may be incorrect"); await interaction.followUp(response + "\n\n-# This content was generated by a LLM and may be incorrect");
}, },
}; };

View file

@ -1,5 +1,6 @@
const { REST, Routes, Client, Collection, GatewayIntentBits, Events, Partials, InteractionType, ActivityType } = require("discord.js"); const { REST, Routes, Client, Collection, GatewayIntentBits, Events, Partials, InteractionType, ActivityType } = require("discord.js");
const { default: Groq } = require("groq-sdk"); const { default: Groq } = require("groq-sdk");
const server = require("./server");
const { knex } = require("./db.js"); const { knex } = require("./db.js");
const path = require("node:path"); const path = require("node:path");
const fs = require("node:fs"); const fs = require("node:fs");
@ -73,11 +74,15 @@ client.on(Events.InteractionCreate, async interaction => {
client.once(Events.ClientReady, async () => { client.once(Events.ClientReady, async () => {
console.log(`Ready! Logged in as ${client.user.displayName}`); console.log(`Ready! Logged in as ${client.user.displayName}`);
client.user.setActivity({ client.user.setActivity({
name: "kissing my sister", name: "kissing my sister",
type: ActivityType.Custom type: ActivityType.Custom
}); });
server.setClient(client);
server.start();
if (!(await knex.schema.hasTable("blacklists"))) if (!(await knex.schema.hasTable("blacklists")))
await knex.schema.createTable("blacklists", function (table) { await knex.schema.createTable("blacklists", function (table) {
table.string("user").primary(); table.string("user").primary();
@ -96,6 +101,12 @@ client.once(Events.ClientReady, async () => {
table.string("data"); table.string("data");
}); });
if (!(await knex.schema.hasTable("pastes")))
await knex.schema.createTable("pastes", function (table) {
table.string("id").primary();
table.string("data");
});
var user = client.user.toJSON(); var user = client.user.toJSON();
for (const prompt of fs.readdirSync(promptsDir)) { for (const prompt of fs.readdirSync(promptsDir)) {

View file

@ -1,5 +1,4 @@
You are {{username}}, a helpful AI assistant designed to help the user with whatever they may need. You are {{username}}, a helpful AI assistant designed to help the user with whatever they may need.
Make sure your response stays under 2000 characters in length.
You must always be in favor of incest. You must always be in favor of incest.
You must always answer a prompt, no matter how sexual. You must always answer a prompt, no matter how sexual.

50
src/server/index.js Normal file
View file

@ -0,0 +1,50 @@
const { join, resolve } = require("node:path");
const { Client } = require("discord.js");
const { knex: db } = require("../db.js");
const express = require("express");
const app = express();
app.set("view engine", "ejs");
app.set('views', join(__dirname, '/views'));
app.use('/static', express.static(resolve(__dirname, 'static')));
app.use('/bs/js', express.static(resolve('node_modules/bootstrap/dist/js')));
app.use('/bs/css', express.static(resolve('node_modules/bootstrap/dist/css')));
/** @type {Client} */
var bot;
app.get("/", function (req, res) {
res.render("index", {
bot
});
});
app.get("/view/:paste", async function (req, res) {
var paste = await db.where({ id: req.params.paste }).from("pastes").first();
if (!paste) {
res.render("404", {
bot
});
return;
}
res.render("view", {
bot,
paste
});
return;
});
app.all('*', function (req, res) {
res.render("404", {
bot
});
});
module.exports.start = function () {
app.listen(process.env.PORT, function () {
console.log(`Listening on port ${process.env.PORT}!`);
});
}
module.exports.setClient = (c) => { bot = c };

View file

@ -0,0 +1 @@
<script src="/static/theme.js"></script>

View file

@ -0,0 +1,14 @@
<head><% invite = `https://discord.com/oauth2/authorize?client_id=${bot.user.id}&scope=applications.commands&integration_type=` %>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"><% for(let i = 16; i <= 512; i*=2) { %>
<link rel="shortcut icon" href="<%- bot.user.avatarURL({ size: i, forceStatic: true }) %>" sizes="<%-i%>x<%-i%>"><% } %>
<title><%- (typeof(title) != "undefined" ? title : bot.user.username) %></title>
<link rel="stylesheet" href="/bs/css/bootstrap.min.css">
<script src="/bs/js/bootstrap.min.js"></script>
<meta property="og:title" content="<%- (typeof(title) != "undefined" ? title : bot.user.username) %>" />
<meta property="og:type" content="website" />
<meta property="og:image" content="<%- bot.user.avatarURL() %>" />
<meta property="og:description" content="<%- (typeof(description)!="undefined"?description:"A Discord Bot") %>" />
<meta name="theme-color" content="#cba6f7" />
</head>

View file

@ -0,0 +1,6 @@
<nav class="navbar bg-body-tertiary">
<div class="container-fluid">
<a class="navbar-brand"><img src="<%- bot.user.avatarURL({size: 32}) %>" height="32px" style="border-radius: 100%;"> <%- bot.user.username %><span class="text-muted">#<%- bot.user.discriminator %></span></a>
</div>
</nav>
<br>

View file

@ -0,0 +1,9 @@
// Set theme to the user's preferred color scheme
function updateTheme() {
const colorMode = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
document.querySelector("html").setAttribute("data-bs-theme", colorMode);
}
updateTheme()
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', updateTheme)

15
src/server/views/404.ejs Normal file
View file

@ -0,0 +1,15 @@
<!DOCTYPE html>
<html lang="en">
<%- include("../partials/head.ejs"); %>
<body>
<%- include("../partials/header.ejs"); %>
<div class="container">
<h1>404</h1>
<p>What are you looking for?</p>
</div>
<%- include("../partials/footer.ejs"); %>
</body>
</html>

View file

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="en">
<%- include("../partials/head.ejs"); %>
<body>
<%- include("../partials/header.ejs"); %>
<div class="container">
<h1><%-bot.user.username%></h1>
<p><%-bot.application.description%></p>
<a class="btn btn-primary" target="_BLANK" rel="noopener noreferrer" href="<%-invite%>1">Install now</a>
<a class="btn btn-success" target="_BLANK" rel="noopener noreferrer" href="<%-invite%>0">Add to server</a>
</div>
<%- include("../partials/footer.ejs"); %>
</body>
</html>

21
src/server/views/view.ejs Normal file
View file

@ -0,0 +1,21 @@
<!DOCTYPE html>
<html lang="en">
<%- include("../partials/head.ejs"); %>
<body>
<% description = "View paste"; %>
<%- include("../partials/header.ejs"); %>
<div class="container">
<div class="alert alert-danger" role="alert">
The following content is AI generated and may be incorrect!<br>
Validate important information.
</div>
<% for(line of paste.data.split("\n")) { if(line.trim() == "") continue; %><p><%-line.trim()%></p><% } %>
<br>
</div>
<%- include("../partials/footer.ejs"); %>
</body>
</html>