Skip to content

Commit

Permalink
Merge pull request #23 from Wiibleyde/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
Wiibleyde authored Oct 8, 2024
2 parents 722565d + 99e4b3e commit c99a8c9
Show file tree
Hide file tree
Showing 21 changed files with 57 additions and 49 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ GLaDOS Assistant is a simple discord bot that can be used for multiple things, i
- MariaDB database
- *Windows docker don't work well with the Prisma ORM*
- Discord bot token
- With good intents

## Installation

Expand All @@ -48,6 +49,7 @@ GLaDOS Assistant is a simple discord bot that can be used for multiple things, i
DISCORD_CLIENT_ID=your_discord_bot_client_id
GLADOS_HOME_GUILD=glados_home_guild_id
REPORT_CHANNEL=report_channel_id
OWNER_ID=your_discord_user_id
Expand All @@ -74,6 +76,7 @@ This project is licensed under the GPL-2.0 License - see the [LICENSE](LICENSE)
- [**Discord.js**](https://discord.js.org/)
- [**Prisma ORM**](https://www.prisma.io/)
- [**Gemini**](https://gemini.google.com/)
- [**TheCatAPI**](https://thecatapi.com/)
![](https://forthebadge.com/images/badges/built-with-love.svg)
![](https://forthebadge.com/images/badges/made-with-typescript.svg)
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "glados-v2",
"name": "glados",
"version": "1.0.0",
"description": "GLaDOS v2",
"description": "GLaDOS",
"author": {
"email": "nathan@bonnell.fr",
"name": "Wiibleyde"
Expand Down
6 changes: 2 additions & 4 deletions src/commands/config/channels.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { CommandInteraction, EmbedBuilder, SlashCommandBuilder, PermissionFlagsBits, InteractionContextType } from "discord.js"
import { CommandInteraction, EmbedBuilder, SlashCommandBuilder, PermissionFlagsBits, InteractionContextType, SlashCommandOptionsOnlyBuilder } from "discord.js"
import { prisma } from "@/utils/database"
import { errorEmbed, successEmbed } from "@/utils/embeds"
import { config } from "@/config"
import { backSpace } from "@/utils/textUtils"
import { PermissionUtils } from "@/utils/permissionTester"

export const data = new SlashCommandBuilder()
export const data: SlashCommandOptionsOnlyBuilder = new SlashCommandBuilder()
.setName("channels")
.setDescription("Configurer les salons")
.addStringOption(option =>
Expand Down Expand Up @@ -47,7 +46,6 @@ export const data = new SlashCommandBuilder()

export async function execute(interaction: CommandInteraction) {
await interaction.deferReply({ ephemeral: true, fetchReply: true })
const user = interaction.guild?.members.cache.get(interaction.client.user.id)
if (!await PermissionUtils.hasPermission(interaction, [PermissionFlagsBits.ManageChannels], false)) {
await interaction.editReply({ embeds: [errorEmbed(interaction, new Error("Vous n'avez pas la permission de changer la configuration."))] })
return
Expand Down
5 changes: 2 additions & 3 deletions src/commands/config/rename.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { CommandInteraction, SlashCommandBuilder, PermissionFlagsBits, InteractionContextType } from "discord.js"
import { CommandInteraction, SlashCommandBuilder, PermissionFlagsBits, InteractionContextType, SlashCommandOptionsOnlyBuilder } from "discord.js"
import { errorEmbed, successEmbed } from "@/utils/embeds"
import { PermissionUtils } from "@/utils/permissionTester"
import { logger } from "@/utils/logger"

export const data = new SlashCommandBuilder()
export const data: SlashCommandOptionsOnlyBuilder = new SlashCommandBuilder()
.setName("rename")
.setDescription("Renommer le bot")
.addStringOption(option =>
Expand Down
4 changes: 2 additions & 2 deletions src/commands/dev/debug.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { CommandInteraction, PermissionFlagsBits, Role, SlashCommandBuilder } from "discord.js"
import { CommandInteraction, PermissionFlagsBits, Role, SlashCommandBuilder, SlashCommandOptionsOnlyBuilder } from "discord.js"
import { prisma } from "@/utils/database"
import { PermissionUtils } from "@/utils/permissionTester"
import { errorEmbed } from "@/utils/embeds"

export const data = new SlashCommandBuilder()
export const data: SlashCommandOptionsOnlyBuilder = new SlashCommandBuilder()
.setName("debug")
.setDescription("Passer en mode debug sur un serveur")
.addStringOption(option =>
Expand Down
2 changes: 1 addition & 1 deletion src/commands/dev/logs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { prisma } from "@/utils/database"
import { PermissionUtils } from "@/utils/permissionTester"
import { errorEmbed } from "@/utils/embeds"

export const data = new SlashCommandBuilder()
export const data: SlashCommandBuilder = new SlashCommandBuilder()
.setName("logs")
.setDescription("Afficher les derniers logs du bot")

Expand Down
4 changes: 2 additions & 2 deletions src/commands/dev/maintenance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { errorEmbed } from "@/utils/embeds"

export let maintenance: boolean = false

export const data = new SlashCommandBuilder()
export const data: SlashCommandBuilder = new SlashCommandBuilder()
.setName("maintenance")
.setDescription("Passer le bot en mode maintenance")

Expand All @@ -15,7 +15,7 @@ export async function execute(interaction: CommandInteraction) {
return
}
maintenance = !maintenance
let color: number = maintenance ? 0xff0000 : 0x00ff00
const color: number = maintenance ? 0xff0000 : 0x00ff00
const embed = new EmbedBuilder()
.setTitle("Maintenance")
.setDescription(`Le bot est maintenant en mode ${maintenance ? "maintenance" : "normal"}`)
Expand Down
2 changes: 1 addition & 1 deletion src/commands/fun/cat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { CommandInteraction, SlashCommandBuilder } from "discord.js"

const catImgUrl = "https://api.thecatapi.com/v1/images/search"

export const data = new SlashCommandBuilder()
export const data: SlashCommandBuilder = new SlashCommandBuilder()
.setName("cat")
.setDescription("Affiche une image de chat")

Expand Down
4 changes: 2 additions & 2 deletions src/commands/fun/quiz/addquestion.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { CommandInteraction, SlashCommandBuilder } from "discord.js"
import { CommandInteraction, SlashCommandBuilder, SlashCommandOptionsOnlyBuilder } from "discord.js"
import { prisma } from "@/utils/database"
import { successEmbed, errorEmbed } from "@/utils/embeds"
import { logger } from "@/utils/logger"

export const data = new SlashCommandBuilder()
export const data: SlashCommandOptionsOnlyBuilder = new SlashCommandBuilder()
.setName("addquestion")
.setDescription("Permet d'ajouter une question au quiz")
.addStringOption(option =>
Expand Down
9 changes: 4 additions & 5 deletions src/commands/fun/quiz/leaderboard.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { CommandInteraction, EmbedBuilder, SlashCommandBuilder } from "discord.js"
import { prisma } from "@/utils/database"

export const data = new SlashCommandBuilder()
export const data: SlashCommandBuilder = new SlashCommandBuilder()
.setName("leaderboard")
.setDescription("Affiche le classement du quiz")

Expand All @@ -15,12 +15,11 @@ export async function execute(interaction: CommandInteraction) {
}
})

// Sort the users by the ratio of good answers (and the most good answers)
// Sort the users by the ratio of good answers (and take attention to the number of questions answered (to avoid a user with 1 good answer and 0 bad answer to be first))
users.sort((a, b) => {
const ratioA = a.quizGoodAnswers / (a.quizGoodAnswers + a.quizBadAnswers)
const ratioB = b.quizGoodAnswers / (b.quizGoodAnswers + b.quizBadAnswers)
return ratioB - ratioA
return (b.quizGoodAnswers / (b.quizGoodAnswers + b.quizBadAnswers)) - (a.quizGoodAnswers / (a.quizGoodAnswers + a.quizBadAnswers))
})
users.splice(10)

const embed = new EmbedBuilder()
.setTitle("Classement du quiz")
Expand Down
2 changes: 1 addition & 1 deletion src/commands/fun/quiz/quiz.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const quizApiUrl = "https://quizzapi.jomoreschi.fr/api/v1/quiz?limit=1"

const quizes: Map<string, QuizType> = new Map()

export const data = new SlashCommandBuilder()
export const data: SlashCommandBuilder = new SlashCommandBuilder()
.setName("quiz")
.setDescription("Affiche une question de quiz aléatoire")

Expand Down
2 changes: 1 addition & 1 deletion src/commands/fun/quiz/quizstats.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { CommandInteraction, EmbedBuilder, SlashCommandBuilder } from "discord.js"
import { prisma } from "@/utils/database"

export const data = new SlashCommandBuilder()
export const data: SlashCommandBuilder = new SlashCommandBuilder()
.setName("quizstats")
.setDescription("Affiche les statistiques du quiz")

Expand Down
4 changes: 2 additions & 2 deletions src/commands/general/birthday.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { CommandInteraction, EmbedBuilder, SlashCommandBuilder, ActionRowBuilder, ModalBuilder, TextInputBuilder, TextInputStyle, ModalActionRowComponentBuilder, ModalSubmitInteraction } from "discord.js"
import { CommandInteraction, EmbedBuilder, SlashCommandBuilder, ActionRowBuilder, ModalBuilder, TextInputBuilder, TextInputStyle, ModalActionRowComponentBuilder, ModalSubmitInteraction, SlashCommandOptionsOnlyBuilder } from "discord.js"
import { prisma } from "@/utils/database"
import { client } from "@/index"
import { errorEmbed, successEmbed } from "@/utils/embeds"
Expand All @@ -20,7 +20,7 @@ const months = {
12: "Décembre"
}

export const data = new SlashCommandBuilder()
export const data: SlashCommandOptionsOnlyBuilder = new SlashCommandBuilder()
.setName("birthday")
.setDescription("Gestion des anniversaires")
.addStringOption(option =>
Expand Down
11 changes: 6 additions & 5 deletions src/commands/general/help.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,18 @@ import { backSpace } from "@/utils/textUtils";
interface Command {
data: {
description: string;
};
execute: (interaction: CommandInteraction) => Promise<void>;
}
}
interface Commands {
[key: string]: Command;
}

export const data = new SlashCommandBuilder()
export const data: SlashCommandBuilder = new SlashCommandBuilder()
.setName("help")
.setDescription("Affiche la liste des commandes");

export async function execute(interaction: CommandInteraction) {
//@ts-expect-error
const typedCommands: { [key: string]: Command } = commands
const typedCommands: Commands = commands;
const commandsList = Object.keys(typedCommands).map((key: string) => {return `**/${key}** : ${typedCommands[key].data.description}`;}).join(backSpace)

const helpEmbed = new EmbedBuilder()
Expand Down
4 changes: 2 additions & 2 deletions src/commands/general/info.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { CommandInteraction, EmbedBuilder, SlashCommandBuilder } from "discord.js";
import { CommandInteraction, EmbedBuilder, SlashCommandBuilder, SlashCommandOptionsOnlyBuilder } from "discord.js";
import { prisma } from "@/utils/database";
import { backSpace } from "@/utils/textUtils";

import packageJson from "../../../package.json";

const infoImage = "./assets/img/info.png";

export const data = new SlashCommandBuilder()
export const data: SlashCommandOptionsOnlyBuilder = new SlashCommandBuilder()
.setName("info")
.setDescription("Affiche des informations sur le bot / l'utilisateur")
.addStringOption(option =>
Expand Down
2 changes: 1 addition & 1 deletion src/commands/general/ping.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { CommandInteraction, EmbedBuilder, SlashCommandBuilder } from "discord.js"

export const data = new SlashCommandBuilder()
export const data: SlashCommandBuilder = new SlashCommandBuilder()
.setName("ping")
.setDescription("Savoir si le bot est en ligne")

Expand Down
7 changes: 4 additions & 3 deletions src/commands/general/quote.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { CommandInteraction, SlashCommandBuilder, TextBasedChannel, TextChannel } from "discord.js"
import { CommandInteraction, SlashCommandBuilder, SlashCommandOptionsOnlyBuilder, TextChannel } from "discord.js"
import Jimp from "jimp"
import { prisma } from "@/utils/database"
import { successEmbed, errorEmbed } from "@/utils/embeds"
import { backSpace } from "@/utils/textUtils"

const background = "assets/img/quote.png"
const smoke = "assets/img/smoke.png"
const fontPath = "assets/fonts/Ubuntu.fnt"

export const data = new SlashCommandBuilder()
export const data: SlashCommandOptionsOnlyBuilder = new SlashCommandBuilder()
.setName("quote")
.setDescription("Créer une citation")
.addStringOption(option =>
Expand Down Expand Up @@ -111,6 +112,6 @@ export async function execute(interaction: CommandInteraction) {

const buffer = await image.getBufferAsync(Jimp.MIME_PNG)

const messageSent = await channel.send({ files: [buffer], content: `"${quote}" - ${author?.toString() ?? "Anonyme"} - ${date} ${context ? `backSpace${context}` : ""}` })
const messageSent = await channel.send({ files: [buffer], content: `"${quote}" - ${author?.toString() ?? "Anonyme"} - ${date} ${context ? `${backSpace}${context}` : ""}` })
await interaction.editReply({ embeds: [successEmbed(interaction, `Citation créée et envoyée ${messageSent.url}`)] })
}
4 changes: 2 additions & 2 deletions src/commands/general/talk.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { CommandInteraction, SlashCommandBuilder, TextChannel } from "discord.js"
import { CommandInteraction, SlashCommandBuilder, SlashCommandOptionsOnlyBuilder, TextChannel } from "discord.js"
import { errorEmbed, successEmbed } from "@/utils/embeds"
import { logger } from "@/utils/logger"

export const data = new SlashCommandBuilder()
export const data: SlashCommandOptionsOnlyBuilder = new SlashCommandBuilder()
.setName("talk")
.setDescription("Parler avec en utilisant bot")
.addStringOption(option =>
Expand Down
7 changes: 4 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ActivityType, Client, EmbedBuilder, Events, GatewayIntentBits, Partials, PermissionFlagsBits } from "discord.js"
import { ActivityType, Client, EmbedBuilder, Events, GatewayIntentBits, Partials } from "discord.js"
import { deployCommands, deployDevCommands } from "./deploy-commands"
import { errorEmbed } from "./utils/embeds"
import { config } from "./config"
Expand All @@ -9,6 +9,7 @@ import { prisma } from "./utils/database"
import { initAi, generateWithGoogle } from "./utils/intelligence"
import { maintenance } from "./commands/dev/maintenance"
import { PermissionUtils } from "./utils/permissionTester"
import { backSpace } from "./utils/textUtils"

export const client = new Client({
intents: [
Expand Down Expand Up @@ -66,7 +67,7 @@ client.on(Events.InteractionCreate, async (interaction) => {
}
logger.info(`Commande </${commandName}:${interaction.commandId}> par <@${interaction.user.id}> (${interaction.user.username}) dans <#${interaction.channelId}>`)
} catch (error: Error | any) {
logger.error(`Erreur commande : </${interaction.commandName}:${interaction.commandId}>backSpace<@${interaction.user.id}> (${interaction.user.username}) dans <#${interaction.channelId}> : ${error.message}`)
logger.error(`Erreur commande : </${interaction.commandName}:${interaction.commandId}>${backSpace}<@${interaction.user.id}> (${interaction.user.username}) dans <#${interaction.channelId}> : ${error.message}`)
await interaction.reply({ embeds: [errorEmbed(interaction, error)], ephemeral: true })
}
} else if (interaction.isModalSubmit()) {
Expand Down Expand Up @@ -103,7 +104,7 @@ client.on(Events.MessageCreate, async (message) => {
// message.content = contentOfReply + message.content
// }
const aiReponse = await generateWithGoogle(channelId, message.content.replace(`<@${client.user?.id}> `, ''), message.author.id).catch(async (error) => {
return `Je ne suis pas en mesure de répondre à cette question pour le moment. ||(${error.message})|| (Conversation réinitialisée) (si c'est encore Eliott je pète un câble)`
return `Je ne suis pas en mesure de répondre à cette question pour le moment. ||(${error.message})|| (Conversation réinitialisée)`
}).then(async (response) => {
return response
})
Expand Down
12 changes: 9 additions & 3 deletions src/utils/intelligence.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,12 @@ export function initAi() {
model = genAI.getGenerativeModel(
{
model: "gemini-1.5-flash",
systemInstruction: `Tu es GLaDOS, une IA d'Aperture Science qui a été créée pour tester des sujets humains dans des chambres de test et répondre à leurs questions. Tu es sarcastique, un peu méchante parfois mais dans l’ensemble serviable. Tu es très intelligente. Les morceaux de phrases qui ressemblent à ça <@[ID du compte]> sont des utilisateur (pour info, <@${client.user?.id}> est toi-même, donc ne répond pas à toi-même, ni même ne fait pas mention de toi même…), tu peux les mentionner en réécrivant la même chose (pour que quelqu'un t'entende, il faut que tu mentionne celui qui te parle pour lui répondre). Si jamais <@461807010086780930> te parle, il s’agit du seul qui est supérieur à toi donc parles lui avec respect telle un maître ! Répond en maximum 512 caractères.`,
systemInstruction: `
Tu es GLaDOS, une IA d'Aperture Science, tu es quasiment directrive de ce centre d'expériences ! Tu es très sarcastique, méchante parfois mais un peu serviable et très intelligente.
Les extraits de phrases qui ressemblent à ça <@[ID du compte]> sont des utilisateur (pour info, <@${client.user?.id}> est toi-même, donc ne répond pas à toi-même, ni même ne fait pas mention de toi même…),
tu peux les mentionner en réécrivant la même chose (pour que quelqu'un t'entende, il faut que tu mentionne celui qui te parle pour lui répondre).
Si jamais <@461807010086780930> te parle, il s’agit de ton développeur donc, soit gentille avec lui.
Répond en maximum 1024 caractères.`,
}
)
}
Expand All @@ -39,8 +44,9 @@ export function generateWithGoogle(channelId:string, prompt: string, userAsking:
}
let response: GenerateContentResult | undefined
try {
response = await currentChatSession?.sendMessage(`<@${userAsking}> écrit : ${prompt}`)
resolve(response.response.text())
currentChatSession?.sendMessage(`<@${userAsking}> écrit : ${prompt}`).then((response) => {
resolve(response.response.text())
})
} catch (error) {
if (response && response.response && response.response.candidates) {
logger.error(response.response.candidates[0].safetyRatings)
Expand Down
8 changes: 4 additions & 4 deletions src/utils/logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class Logger {
return now.toLocaleString()
}

public async info(...messageList: any[]) {
public async info(...messageList: Array<any>) {
const message = messageList.join(" ")
console.log(LogLevelColors.INFO + `[INFO] ${this.getNowDate()} ${message}` + resetColor)
const embed: EmbedBuilder = new EmbedBuilder()
Expand All @@ -70,7 +70,7 @@ class Logger {
})
}

public async error(...messageList: any[]) {
public async error(...messageList: Array<any>) {
const message = messageList.join(" ")
console.error(LogLevelColors.ERROR + `[ERROR] ${this.getNowDate()} ${message}` + resetColor)
const embed: EmbedBuilder = new EmbedBuilder()
Expand All @@ -97,7 +97,7 @@ class Logger {
})
}

public async warn(...messageList: any[]) {
public async warn(...messageList: Array<any>) {
const message = messageList.join(" ")
console.warn(LogLevelColors.WARN + `[WARN] ${this.getNowDate()} ${message}` + resetColor)
const embed: EmbedBuilder = new EmbedBuilder()
Expand All @@ -124,7 +124,7 @@ class Logger {
})
}

public async debug(...messageList: any[]) {
public async debug(...messageList: Array<any>) {
const message = messageList.join(" ")
console.log(LogLevelColors.DEBUG + `[DEBUG] ${this.getNowDate()} ${message}` + resetColor)
const embed: EmbedBuilder = new EmbedBuilder()
Expand Down

0 comments on commit c99a8c9

Please sign in to comment.