255 lines
13 KiB
Python
255 lines
13 KiB
Python
import discord
|
|
from discord.ext import commands
|
|
from dotenv import load_dotenv
|
|
import os
|
|
import modules.gpt as gpt
|
|
import modules.dbmanagement as dbm
|
|
import modules.summarize as summarize
|
|
|
|
description = "ChatGPT Bot for Discord"
|
|
configfolder = "config"
|
|
|
|
load_dotenv(dotenv_path=os.path.join(configfolder, ".env"))
|
|
|
|
intents = discord.Intents.default()
|
|
intents.message_content = True
|
|
intents.members = True
|
|
|
|
bot = discord.Bot(
|
|
command_prefix=commands.when_mentioned_or("!"),
|
|
description=description,
|
|
intents=intents,
|
|
)
|
|
|
|
### \/ Events Area \/ ###
|
|
|
|
@bot.event
|
|
async def on_ready():
|
|
print(f"We have logged in as {bot.user}")
|
|
await dbm.init_db()
|
|
|
|
### Message Listener
|
|
@bot.event
|
|
async def on_message(message):
|
|
if message.author == bot.user:
|
|
return
|
|
|
|
### Check if Channel is Configured
|
|
if await dbm.get_channel_by_id(message.guild.id, message.channel.id) is not None:
|
|
config = await dbm.get_config_by_id(message.guild.id, message.channel.id)
|
|
if message.content.startswith(config[2]):
|
|
### Count Messages for Summary
|
|
counter = 0
|
|
if await dbm.get_last_chat(message.guild.id, message.channel.id) is not None:
|
|
counter = await dbm.get_last_chat(message.guild.id, message.channel.id)
|
|
counter = counter[8]
|
|
counter = counter + 1
|
|
else:
|
|
await dbm.add_summary_zero(message.guild.id, message.channel.id)
|
|
|
|
### Read and Send Message/Answer
|
|
await message.channel.trigger_typing()
|
|
msg = message.content.replace(config[2], "", 1)
|
|
await dbm.add_chat(message.guild.id, message.channel.id, message.author.id, message.author.name, "user", message.id, f'{message.author}: {msg}', counter)
|
|
answer = await gpt.get_answer(message.guild.id, message.channel.id)
|
|
sendmsg = await message.channel.send(answer)
|
|
await dbm.add_chat(message.guild.id, message.channel.id, bot.user.id, bot.user.name, "assistant", sendmsg.id, answer, counter+1)
|
|
|
|
### Check if Summary is needed
|
|
last_summary = await dbm.get_latest_summary(message.guild.id, message.channel.id)
|
|
last_summary = last_summary[4]
|
|
last_message = await dbm.get_last_chat(message.guild.id, message.channel.id)
|
|
last_message = last_message[8]
|
|
|
|
### Check if Last Summary is older than 20 Messages
|
|
if last_message - last_summary >= 30:
|
|
await summarize.new_summarize(message.guild.id, message.channel.id)
|
|
|
|
### /\ End Events Area /\ ###
|
|
|
|
### \/ Modal Area \/ ###
|
|
|
|
### Modal Class for Setup
|
|
class SetupModal(discord.ui.Modal):
|
|
def __init__(self, *args, **kwargs) -> None:
|
|
super().__init__(*args, **kwargs)
|
|
self.add_item(discord.ui.InputText(label="Channel-ID", placeholder="Channel-ID", required=True))
|
|
self.add_item(discord.ui.InputText(label="Prefix", placeholder="!", required=False))
|
|
self.add_item(discord.ui.InputText(label="GPT", placeholder="3", required=True))
|
|
self.add_item(discord.ui.InputText(label="System Message", placeholder="System Message", required=False, style=discord.InputTextStyle.long))
|
|
|
|
async def callback(self, interaction: discord.Interaction):
|
|
embed = discord.Embed(title="Setup Vals")
|
|
embed.add_field(name="Channel-ID", value=self.children[0].value)
|
|
embed.add_field(name="Prefix", value=self.children[1].value)
|
|
embed.add_field(name="GPT", value=self.children[2].value)
|
|
embed.add_field(name="System Message", value=self.children[3].value)
|
|
|
|
await interaction.response.send_message(embeds=[embed], ephemeral=True)
|
|
|
|
if await dbm.get_server_by_id(interaction.guild.id) is None:
|
|
print("Server not in DB")
|
|
await dbm.add_server(interaction.guild.id)
|
|
await dbm.add_channel(interaction.guild.id, self.children[0].value)
|
|
if dbm.is_premium(interaction.guild.id):
|
|
await dbm.add_config(interaction.guild.id, self.children[0].value, self.children[1].value, self.children[2].value, self.children[3].value)
|
|
else:
|
|
await dbm.add_config(interaction.guild.id, self.children[0].value, 3, self.children[2].value, self.children[3].value)
|
|
await dbm.add_summary_zero(interaction.guild.id, self.children[0].value)
|
|
await dbm.default_premium(interaction.guild.id)
|
|
print("Setup: Server")
|
|
|
|
elif await dbm.get_server_by_id(interaction.guild.id) is not None and await dbm.get_channel_by_id(interaction.guild.id, self.children[0].value) is None:
|
|
print("Server in DB, but Channel not")
|
|
await dbm.add_channel(interaction.guild.id, self.children[0].value)
|
|
if dbm.is_premium(interaction.guild.id):
|
|
await dbm.add_config(interaction.guild.id, self.children[0].value, self.children[1].value, self.children[2].value, self.children[3].value)
|
|
else:
|
|
await dbm.add_config(interaction.guild.id, self.children[0].value, 3, self.children[2].value, self.children[3].value)
|
|
|
|
await dbm.add_summary_zero(interaction.guild.id, self.children[0].value)
|
|
print("Setup: Channel, Config")
|
|
|
|
elif await dbm.get_server_by_id(interaction.guild.id) is not None and await dbm.get_channel_by_id(interaction.guild.id, self.children[0].value) is not None:
|
|
print("Server and Channel in DB, rerun Setup")
|
|
await dbm.remove_channel(interaction.guild.id, self.children[0].value)
|
|
await dbm.remove_config(interaction.guild.id, self.children[0].value)
|
|
await dbm.add_channel(interaction.guild.id, self.children[0].value)
|
|
if dbm.is_premium(interaction.guild.id):
|
|
await dbm.add_config(interaction.guild.id, self.children[0].value, self.children[1].value, self.children[2].value, self.children[3].value)
|
|
else:
|
|
await dbm.add_config(interaction.guild.id, self.children[0].value, 3, self.children[2].value, self.children[3].value)
|
|
await dbm.add_summary_zero(interaction.guild.id, self.children[0].value)
|
|
print("Setup: Channel, Config")
|
|
|
|
### Add Modal
|
|
class AddModal(discord.ui.Modal):
|
|
def __init__(self, *args, **kwargs) -> None:
|
|
super().__init__(*args, **kwargs)
|
|
self.add_item(discord.ui.InputText(label="Prefix (Leave empty for no Prefix)", placeholder="!", required=False))
|
|
self.add_item(discord.ui.InputText(label="GPT (3 - GPT-3.5-Turbo; 4- GPT-4)", placeholder="3", required=True))
|
|
self.add_item(discord.ui.InputText(label="System Message", placeholder="System Message", required=False, style=discord.InputTextStyle.long))
|
|
|
|
async def callback(self, interaction: discord.Interaction):
|
|
if await dbm.get_server_by_id(interaction.guild.id) is None:
|
|
print("Server not in DB")
|
|
await dbm.add_server(interaction.guild.id)
|
|
await dbm.add_channel(interaction.guild.id, interaction.channel.id)
|
|
if dbm.is_premium(interaction.guild.id):
|
|
await dbm.add_config(interaction.guild.id, interaction.channel.id, self.children[0].value, self.children[1].value, self.children[2].value)
|
|
else:
|
|
await dbm.add_config(interaction.guild.id, interaction.channel.id, self.children[0].value, 3, self.children[2].value)
|
|
await dbm.add_summary_zero(interaction.guild.id, interaction.channel.id)
|
|
print("Setup: Channel, Server, Config")
|
|
elif await dbm.get_server_by_id(interaction.guild.id) is not None and await dbm.get_channel_by_id(interaction.guild.id, interaction.channel.id) is None:
|
|
await dbm.add_channel(interaction.guild.id, interaction.channel.id)
|
|
if dbm.is_premium(interaction.guild.id):
|
|
await dbm.add_config(interaction.guild.id, interaction.channel.id, self.children[0].value,
|
|
self.children[1].value, self.children[2].value)
|
|
else:
|
|
await dbm.add_config(interaction.guild.id, interaction.channel.id, self.children[0].value, 3,
|
|
self.children[2].value)
|
|
await dbm.add_summary_zero(interaction.guild.id, interaction.channel.id)
|
|
print("Setup: Channel, Config")
|
|
elif await dbm.get_server_by_id(interaction.guild.id) is not None and await dbm.get_channel_by_id(interaction.guild.id, interaction.channel.id) is not None:
|
|
await dbm.remove_channel(interaction.guild.id, interaction.channel.id)
|
|
await dbm.remove_config(interaction.guild.id, interaction.channel.id)
|
|
if dbm.is_premium(interaction.guild.id):
|
|
await dbm.add_config(interaction.guild.id, interaction.channel.id, self.children[0].value,
|
|
self.children[1].value, self.children[2].value)
|
|
else:
|
|
await dbm.add_config(interaction.guild.id, interaction.channel.id, self.children[0].value, 3,
|
|
self.children[2].value)
|
|
await dbm.add_config(interaction.guild.id, interaction.channel.id, self.children[0].value, self.children[1].value, self.children[2].value)
|
|
await dbm.add_summary_zero(interaction.guild.id, interaction.channel.id)
|
|
print("Setup: Channel, Config")
|
|
|
|
if dbm.is_premium(interaction.guild.id):
|
|
await interaction.response.send_message('Setup Channel', ephemeral=True)
|
|
else:
|
|
await interaction.response.send_message('Setup Channel (Using GPT-3.5)', ephemeral=True)
|
|
|
|
### Edit Modal
|
|
class EditSystemModal(discord.ui.Modal):
|
|
def __init__(self, *args, **kwargs) -> None:
|
|
super().__init__(*args, **kwargs)
|
|
self.add_item(discord.ui.InputText(label="System Message", placeholder="System Message", required=False, style=discord.InputTextStyle.long))
|
|
|
|
async def callback(self, interaction: discord.Interaction):
|
|
server, channel, prefix, gptver, systemmsg = await dbm.get_config_by_id(interaction.guild.id, interaction.channel.id)
|
|
await dbm.remove_config(interaction.guild.id, interaction.channel.id)
|
|
await dbm.add_config(interaction.guild.id, interaction.channel.id, prefix, gptver, self.children[0].value)
|
|
await interaction.response.send_message("System Message changed", ephemeral=True)
|
|
|
|
### /\ End Modal Area /\ ###
|
|
|
|
### \/ Commands Area \/ ###
|
|
|
|
### Setup Command
|
|
@bot.command(name="setup", description="Used to setup the Bot")
|
|
@commands.has_permissions(administrator=True)
|
|
async def setup(ctx: discord.ApplicationContext):
|
|
modal = SetupModal(title="Setup ChatGPT")
|
|
await ctx.send_modal(modal)
|
|
|
|
|
|
@bot.command(name="add", description="Used to add Bot answering to specific Channels")
|
|
@commands.has_permissions(administrator=True)
|
|
async def add(ctx: discord.ApplicationContext):
|
|
if await dbm.get_channel_by_id(ctx.guild.id, ctx.channel.id) is None:
|
|
modal = AddModal(title="Add Channel")
|
|
await ctx.send_modal(modal)
|
|
else:
|
|
await ctx.respond("Channel has already been added. Use /setup", ephemeral=True)
|
|
|
|
|
|
@bot.command(name="remove", description="Used to remove Bot answering to specific Channels")
|
|
@commands.has_permissions(administrator=True)
|
|
async def remove(ctx: discord.ApplicationContext):
|
|
if await dbm.get_channel_by_id(ctx.guild.id, ctx.channel.id) is not None:
|
|
await dbm.remove_channel(ctx.guild.id, ctx.channel.id)
|
|
await ctx.respond("Channel removed", ephemeral=True)
|
|
else:
|
|
await ctx.respond("Channel not active. Nothing Done", ephemeral=True)
|
|
|
|
|
|
@bot.command(name="list", description="Used to list all Channels in the Server")
|
|
@commands.has_permissions(administrator=True)
|
|
async def list(ctx: discord.ApplicationContext):
|
|
|
|
await ctx.respond("This command is WIP")
|
|
|
|
|
|
@bot.command(name="clear", description="Used to clear chat history of specific Channels/Users")
|
|
@commands.has_permissions(administrator=True)
|
|
async def clear(ctx: discord.ApplicationContext):
|
|
await dbm.add_summary_zero(ctx.guild.id, ctx.channel.id)
|
|
await ctx.respond("Bot got Amnesia", ephemeral=True)
|
|
|
|
# Old System, Rewrite needed
|
|
@bot.command(name="help", description="Used to get help")
|
|
async def help(ctx: discord.ApplicationContext):
|
|
await ctx.respond(f'Here is a list of all commands:\n'
|
|
'Needs Rewrite\n', ephemeral=True)
|
|
|
|
@bot.command(name="ping", description="Used to check if the bot is alive")
|
|
async def ping(ctx: discord.ApplicationContext):
|
|
await ctx.respond(f'pong', ephemeral=True)
|
|
|
|
# Old System, Rewrite needed
|
|
@bot.command(name="system", description="Used to setup the bot with a custom system message")
|
|
@commands.has_permissions(administrator=True)
|
|
async def system(ctx: discord.ApplicationContext):
|
|
try:
|
|
modal = EditSystemModal(title="Change System Message")
|
|
await ctx.send_modal(modal)
|
|
except:
|
|
await ctx.respond("No Config found for this Channel", ephemeral=True)
|
|
|
|
### /\ End Commands Area /\ ###
|
|
|
|
|
|
|
|
|
|
bot.run(str(os.environ.get('DISCORD_TOKEN')))
|