Compare commits

..

No commits in common. "dc1e2bb8b29d64bc06f46ccefa236612e584b457" and "a898d0d9b8b4f9715af7d5fc79d6e199c330249f" have entirely different histories.

4 changed files with 112 additions and 72 deletions

View File

@ -11,6 +11,7 @@ This Bot uses the PyCord Library ([PyCord](https://pycord.dev/)) and the OpenAI
There are three ways to use this bot:
1. By just inviting [this Bot](https://discord.com/api/oauth2/authorize?client_id=1083786070786850959&permissions=2147486720&scope=bot) to your Server
2. Using Docker
3. Without using Docker
@ -26,7 +27,7 @@ There are three ways to use this bot:
- Server Members Intent
- Message Content Intent
4. Get an OpenAI API Key from [OpenAI](https://platform.openai.com/account/api-keys)
6. Go to the `config`-folder and create a file called `.env` in the config folder and add the following:
6. Go to the `configs`-folder and create a file called `.env` in the config folder and add the following:
```shell
DISCORD_TOKEN=Your_Bot_Token
@ -49,26 +50,36 @@ OPENAI_API_KEY=Your_OpenAI_API_Key
- Message Content Intent
3. Get an OpenAI API Key from [OpenAI](https://platform.openai.com/account/api-keys)
4. Use `docker build -t discord-bot .` to build the Docker Image
5. Make a folder called `config` and create a file called `.env` in the configs folder and add the following:
5. Make a folder called `chat`
6. Make a folder called `config` and create a file called `.env` in the configs folder and add the following:
```shell
DISCORD_TOKEN=Your_Bot_Token
OPENAI_API_KEY=Your_OpenAI_API_Key
```
7. Run the bot using `docker run -v /path/to/config:/usr/share/dcbot/config -d --name discord-bot discord-bot`
8. To stop the Bot use `docker stop discord-bot`
7. Run the bot using `docker run -v /path/to/config:/usr/share/dcbot/configs -v /path/to/chat:/usr/share/dcbot/chats -d --name discord-bot discord-bot`
8. To stop the Bot use `docker stop <container-id>`
## How to use the Bot
Once the Bot is running and you have invited it to your Server, you can use the following commands:
- /add - Opens a Dialog to add a new Server to the Bot
- /setup - Same as Add, but you can change the Channel ID
- /remove - Removes the current Channel from the Bot
- /clear - Clears the Message History used by the Bot. Does not remove Messages from Discord, only from the Bot
- /system - Opens a Dialog to change the System-Messege set to the Bot. More in [OpenAI's Docs](https://platform.openai.com/docs/guides/chat/instructing-chat-models)
- /ping - Checks if the Bot is responding
- /add text (channel-id) to Add the Bot to listen in a channel. The Bot will listen to all messages in that channel and answer them using GPT-3.5. The Bot will ignore Messages with a Prefix (Default - $)
- /add prefix (channel-id) to Add the Bot to listen in a channel. The Bot will listen to all messages in that channel that start with the prefix and answer them using GPT-3.5 (Default - !)
- /remove text/prefix (channel-id) to remove the Bot from listening in a channel.
- /list text/prefix to list all channels the Bot is listening in.
- /delete to delete the bots history from specific channels.
- /help to get a list of all commands.
- /ping to check if the Bot is online.
- /setup (channelid) (System-Message) Changes the System-Message. See OenAI's Documentation for more information. [OpenAI Docs](https://platform.openai.com/docs/guides/chat/instructing-chat-models)
### Future Improvements
- Currently I am working on an SQLite DB to store all information needed (eg. Servers, Channels, Configs, etc)
- Also I am working on a way to toggle between GPT 3.5-turbo and GPT-4
- Need to find and fix Bugs
### How to Contribute
@ -78,3 +89,4 @@ If you want to contribute to this project, feel free to open a PR or Issue.
- [OpenAI](https://openai.com/) for the GPT API
- [PyCord](https://pycord.dev/) for the Discord API Wrapper
- [Drone](https://drone.io/) for the CI/CD

View File

@ -85,32 +85,42 @@ class SetupModal(discord.ui.Modal):
embed.add_field(name="GPT", value=self.children[2].value)
embed.add_field(name="System Message", value=self.children[3].value)
# Check if Server is in DB
if await dbm.get_server_by_id(interaction.guild.id) is None:
await dbm.add_server(interaction.guild.id)
print("Added Server to DB")
# Check if Channel is already in DB. If so delete old config
if await dbm.get_channel_by_id(interaction.guild.id, self.children[0].value) is not None:
await dbm.remove_channel(interaction.guild.id, self.children[0].value)
await dbm.remove_config(interaction.guild.id, self.children[0].value)
print("Removed old Channel from DB")
# Check if Channel is in DB. If not add it
if await dbm.get_channel_by_id(interaction.guild.id, self.children[0].value) is None:
print("Added Channel to DB")
await dbm.add_channel(interaction.guild.id, self.children[0].value)
# Check for "Premium"
if await 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, self.children[1], "3", self.children[3].value)
await dbm.add_summary_zero(interaction.guild.id, self.children[0].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):
@ -121,40 +131,43 @@ class AddModal(discord.ui.Modal):
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):
print(f"Server-Type: {type(interaction.guild.id)}"
f"Channel-Type: {type(interaction.channel.id)}"
f"Prefix-Type: {type(self.children[0].value)}"
f"GPT-Type: {type(self.children[1].value)}"
f"System-Type: {type(self.children[2].value)}")
# Check if Server is in DB
if await dbm.get_server_by_id(interaction.guild.id) is None:
print("Server not in DB")
await dbm.add_server(interaction.guild.id)
print("Added Server to DB")
# Check if Channel is already in DB. If so delete old config
if await dbm.get_channel_by_id(interaction.guild.id, interaction.channel.id) is not 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, 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)
print("Removed old Channel from DB")
# Check if Channel is in DB. If not add it
if await dbm.get_channel_by_id(interaction.guild.id, interaction.channel.id) is None:
await dbm.add_channel(interaction.guild.id, interaction.channel.id)
print("Added Channel to DB")
# Check for "Premium"
if await dbm.is_premium(interaction.guild.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)
print(f"Added with Premium-Permission {self.children[1].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 dbm.add_config(interaction.guild.id, interaction.channel.id, self.children[0].value, "3", self.children[2].value)
print(f"Added without Premium-Permission 3")
await dbm.add_summary_zero(interaction.guild.id, interaction.channel.id)
await interaction.response.send_message("Configured Channel", ephemeral=True)
await interaction.response.send_message('Setup Channel (Using GPT-3.5)', ephemeral=True)
### Edit Modal
class EditSystemModal(discord.ui.Modal):
@ -183,8 +196,11 @@ async def setup(ctx: discord.ApplicationContext):
@bot.command(name="add", description="Used to add Bot answering to specific Channels")
@commands.has_permissions(administrator=True)
async def add(ctx: discord.ApplicationContext):
modal = AddModal(title="Add Channel")
await ctx.send_modal(modal)
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")
@ -192,18 +208,29 @@ async def add(ctx: discord.ApplicationContext):
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 dbm.remove_config(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):

View File

@ -22,7 +22,7 @@ async def init_db():
(server_id TEXT,
channel_id TEXT,
prefix TEXT,
gpt TEXT,
gpt INTEGER,
systemmsg TEXT,
FOREIGN KEY(server_id) REFERENCES servers(id),
FOREIGN KEY(channel_id) REFERENCES channels(id))'''
@ -56,9 +56,10 @@ async def init_db():
async def add_server(server_id):
async with aiosqlite.connect(DB_FILE) as db:
await db.execute('INSERT INTO servers (server_id, is_premium) VALUES (?, ?)', (server_id, 0))
await db.execute('INSERT OR IGNORE INTO servers (server_id) VALUES (?)', (server_id,))
await db.commit()
async def remove_server(server_id):
async with aiosqlite.connect(DB_FILE) as db:
await db.execute('DELETE FROM servers WHERE server_id = ?', (server_id,))
@ -124,9 +125,9 @@ async def get_channel_by_id(server_id, channel_id):
return channel
async def add_config(server_id, channel_id, prefix, gpt, systemmsg):
msg = f'You are talking to multiple users and can see their usernames. Usernames are named like this: Username#1234 the #1234 is an identifier and can be ignored. You do not add a username to your message. {systemmsg}'
msg = f'Users are named like this: Username#1234 the #1234 is an identifier and can be ignored. {systemmsg}'
async with aiosqlite.connect(DB_FILE) as db:
await db.execute('INSERT OR IGNORE INTO config (server_id, channel_id, prefix, gpt, systemmsg) VALUES (?, ?, ?, ?, ?)', (server_id, channel_id, str(prefix), str(gpt), str(msg)))
await db.execute('INSERT OR IGNORE INTO config (server_id, channel_id, prefix, gpt, systemmsg) VALUES (?, ?, ?, ?, ?)', (server_id, channel_id, prefix, gpt, msg))
await db.commit()
async def remove_config(server_id, channel_id):

View File

@ -60,10 +60,10 @@ async def get_answer(server_id=0, channel_id=0, mode=0, msg=''):
if mode == 0: ### Normal Mode
gptversion = await dbm.get_config_by_id(server_id, channel_id)
gptversion = gptversion[3]
if int(gptversion) == 4:
usemodel = "gpt-4"
else:
if gptversion == 3:
usemodel = "gpt-3.5-turbo"
elif gptversion == 4:
usemodel = "gpt-4"
history = await load_history(server_id, channel_id, 0)