Initial commit
This commit is contained in:
commit
642bdf2155
4 changed files with 229 additions and 0 deletions
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
/env
|
||||
/config.toml
|
||||
/wordlist.pickle
|
||||
__pycache__
|
198
botbotbot/__main__.py
Normal file
198
botbotbot/__main__.py
Normal file
|
@ -0,0 +1,198 @@
|
|||
import asyncio
|
||||
import pickle
|
||||
import random
|
||||
import tomllib
|
||||
|
||||
import discord
|
||||
|
||||
from .ai import AIBot
|
||||
|
||||
description = """BotBotBot"""
|
||||
|
||||
with open("config.toml", "rb") as config_file:
|
||||
config = tomllib.load(config_file)
|
||||
|
||||
with open("wordlist.pickle", "rb") as word_file:
|
||||
word_list = pickle.load(word_file)
|
||||
guild_ids = config.get("guild_ids")
|
||||
delay = config.get("delay", 60)
|
||||
|
||||
aibot = AIBot(config.get("mistral_api_key"), model="open-mixtral-8x7b")
|
||||
|
||||
intents = discord.Intents.default()
|
||||
intents.members = True
|
||||
|
||||
bot = discord.Bot(description=description, intents=intents)
|
||||
|
||||
|
||||
shuffle_tasks = set()
|
||||
|
||||
|
||||
@bot.listen("on_ready")
|
||||
async def on_ready():
|
||||
print(f"We have logged in as {bot.user}")
|
||||
|
||||
|
||||
async def reply(message):
|
||||
if random.random() < 1 / 2:
|
||||
await message.reply(f"<@{message.author.id}>, {random.choice(word_list)}")
|
||||
else:
|
||||
await message.reply(f"{random.choice(word_list)}")
|
||||
|
||||
|
||||
async def ai_reply(message):
|
||||
print("Running AI")
|
||||
answer = aibot.answer(message.clean_content)
|
||||
embed = discord.Embed(
|
||||
description=answer,
|
||||
thumbnail="https://mistral.ai/images/favicon/favicon-32x32.png",
|
||||
)
|
||||
await message.reply(embed=embed)
|
||||
|
||||
|
||||
async def react(message):
|
||||
await message.add_reaction(random.choice(message.guild.emojis))
|
||||
|
||||
|
||||
@bot.listen("on_message")
|
||||
async def on_message(message):
|
||||
if message.flags.ephemeral:
|
||||
return
|
||||
|
||||
if random.random() < 1 / 12:
|
||||
await reply(message)
|
||||
elif random.random() < 1 / 48:
|
||||
await ai_reply(message)
|
||||
|
||||
if random.random() < 1 / 6:
|
||||
await react(message)
|
||||
|
||||
if message.author != bot.user and bot.user in message.mentions:
|
||||
if random.random() < 1 / 2:
|
||||
await reply(message)
|
||||
else:
|
||||
await react(message)
|
||||
|
||||
|
||||
@bot.listen("on_message")
|
||||
async def rando_shuffle(message):
|
||||
if not message.flags.ephemeral and random.random() < 1 / 24 and message.guild:
|
||||
await try_shuffle(message.guild)
|
||||
|
||||
|
||||
def save_wordlist():
|
||||
with open("wordlist.pickle", "wb") as word_file:
|
||||
pickle.dump(word_list, word_file)
|
||||
|
||||
|
||||
@bot.slash_command(name="bibl", guild_ids=guild_ids, description="Ajouter une phrase")
|
||||
async def bibl(ctx, phrase):
|
||||
word_list.append(phrase)
|
||||
embed = discord.Embed(
|
||||
title="BIBL", description=phrase, color=discord.Colour.green()
|
||||
)
|
||||
await ctx.respond(embed=embed)
|
||||
save_wordlist()
|
||||
|
||||
|
||||
@bot.slash_command(name="tabl", guild_ids=guild_ids, description="Lister les phrases")
|
||||
async def tabl(ctx):
|
||||
embed = discord.Embed(
|
||||
title="TABL", description="\n".join(word_list), color=discord.Colour.green()
|
||||
)
|
||||
await ctx.respond(embed=embed, ephemeral=True, delete_after=delay)
|
||||
|
||||
|
||||
@bot.slash_command(name="enle", guild_ids=guild_ids, description="Enlever une phrase")
|
||||
async def enle(ctx, phrase):
|
||||
try:
|
||||
word_list.remove(phrase)
|
||||
except ValueError:
|
||||
embed = discord.Embed(
|
||||
title="ERRE ENLE", description=phrase, color=discord.Colour.red()
|
||||
)
|
||||
await ctx.respond(embed=embed)
|
||||
else:
|
||||
embed = discord.Embed(
|
||||
title="ENLE", description=f"~~phrase~~", color=discord.Colour.green()
|
||||
)
|
||||
await ctx.respond(embed=embed, ephemeral=True, delete_after=delay)
|
||||
save_wordlist()
|
||||
|
||||
|
||||
async def try_shuffle(guild):
|
||||
if guild.id in shuffle_tasks:
|
||||
return False
|
||||
|
||||
shuffle_tasks.add(guild.id)
|
||||
await shuffle_nicks(guild)
|
||||
shuffle_tasks.discard(guild.id)
|
||||
return True
|
||||
|
||||
|
||||
async def shuffle_nicks(guild):
|
||||
print("ALEA")
|
||||
members = guild.members
|
||||
members.remove(guild.owner)
|
||||
|
||||
nicks = [member.nick for member in members]
|
||||
|
||||
random.shuffle(nicks)
|
||||
for member, nick in zip(members, nicks):
|
||||
print(member, nick)
|
||||
await member.edit(nick=nick)
|
||||
print("FIN ALEA")
|
||||
|
||||
|
||||
@bot.slash_command(name="alea", guild_ids=guild_ids, description="Modifier les pseudos")
|
||||
async def alea(ctx):
|
||||
await ctx.defer()
|
||||
if await try_shuffle(ctx.guild):
|
||||
embed = discord.Embed(title="ALEA", color=discord.Colour.green())
|
||||
await ctx.respond(embed=embed, ephemeral=True, delete_after=delay)
|
||||
else:
|
||||
embed = discord.Embed(title="ERRE ALEA", color=discord.Colour.red())
|
||||
await ctx.respond(embed=embed)
|
||||
|
||||
|
||||
@bot.slash_command(
|
||||
name="indu", guild_ids=guild_ids, description="Poser une question à MistralAI"
|
||||
)
|
||||
async def indu(ctx, prompt):
|
||||
await ctx.defer()
|
||||
answer = aibot.answer(prompt)
|
||||
embed = discord.Embed(
|
||||
title=prompt,
|
||||
description=answer,
|
||||
thumbnail="https://mistral.ai/images/favicon/favicon-32x32.png",
|
||||
)
|
||||
await ctx.respond(embed=embed)
|
||||
|
||||
|
||||
@bot.slash_command(
|
||||
name="chan", guild_ids=guild_ids, description="Donner de nouveaux pseudos"
|
||||
)
|
||||
async def chan(ctx, file: discord.Attachment):
|
||||
await ctx.defer()
|
||||
|
||||
members = ctx.guild.members
|
||||
members.remove(ctx.guild.owner)
|
||||
|
||||
nicks = (await file.read()).decode().splitlines()
|
||||
if len(nicks) != len(members):
|
||||
embed = discord.Embed(title="ERRE CHAN", color=discord.Colour.red())
|
||||
await ctx.respond(embed=embed)
|
||||
return
|
||||
|
||||
random.shuffle(nicks)
|
||||
for member, nick in zip(members, nicks):
|
||||
print(member, nick)
|
||||
await member.edit(nick=nick)
|
||||
|
||||
embed = discord.Embed(
|
||||
title="CHAN", description="\n".join(nicks), color=discord.Colour.green()
|
||||
)
|
||||
await ctx.respond(embed=embed)
|
||||
|
||||
|
||||
bot.run(config.get("token"))
|
21
botbotbot/ai.py
Normal file
21
botbotbot/ai.py
Normal file
|
@ -0,0 +1,21 @@
|
|||
import tomllib
|
||||
|
||||
from mistralai.client import MistralClient
|
||||
from mistralai.models.chat_completion import ChatMessage
|
||||
|
||||
|
||||
class AIBot:
|
||||
def __init__(self, api_key, model="open-mistral-7b", max_tokens=None):
|
||||
self.client = MistralClient(api_key=api_key)
|
||||
self.model = model
|
||||
self.max_tokens = max_tokens
|
||||
|
||||
def get_responses(self, message):
|
||||
return self.client.chat(
|
||||
model=self.model,
|
||||
messages=[ChatMessage(role="user", content=message)],
|
||||
max_tokens=self.max_tokens,
|
||||
)
|
||||
|
||||
def answer(self, message):
|
||||
return self.get_responses(message).choices[0].message.content
|
6
config.sample.toml
Normal file
6
config.sample.toml
Normal file
|
@ -0,0 +1,6 @@
|
|||
mistral_api_key = ""
|
||||
|
||||
token = ""
|
||||
|
||||
delay = 30
|
||||
guild_ids = [""]
|
Loading…
Reference in a new issue