mirror of
https://github.com/Paillat-dev/Botator.git
synced 2026-01-02 01:06:19 +00:00
Merge branch 'dev' into main
This commit is contained in:
16
Dockerfile
16
Dockerfile
@@ -6,9 +6,21 @@ ENV PYTHONUNBUFFERED=1
|
|||||||
# Install pip requirements
|
# Install pip requirements
|
||||||
COPY requirements.txt .
|
COPY requirements.txt .
|
||||||
RUN pip install -r requirements.txt
|
RUN pip install -r requirements.txt
|
||||||
RUN git clone https://github.com/Paillat-dev/Botator.git
|
|
||||||
WORKDIR /Botator/code/
|
|
||||||
# Creates a non-root user with an explicit UID and adds permission to access the /app folder
|
# Creates a non-root user with an explicit UID and adds permission to access the /app folder
|
||||||
|
RUN mkdir /Botator
|
||||||
|
RUN mkdir /Botator/code
|
||||||
RUN adduser -u 5678 --disabled-password --gecos "" appuser && chown -R appuser /Botator/code
|
RUN adduser -u 5678 --disabled-password --gecos "" appuser && chown -R appuser /Botator/code
|
||||||
|
COPY ./code /Botator/code
|
||||||
|
WORKDIR /Botator/code/
|
||||||
|
|
||||||
|
# Create database folder and files (otherwise it will crash)
|
||||||
|
RUN mkdir /Botator/database
|
||||||
|
RUN touch /Botator/database/data.db
|
||||||
|
RUN touch /Botator/database/premium.db
|
||||||
|
RUN chown -R appuser /Botator/database
|
||||||
|
|
||||||
|
RUN mkdir /Botator/database/google
|
||||||
|
|
||||||
|
|
||||||
USER appuser
|
USER appuser
|
||||||
CMD ["python", "code.py"]
|
CMD ["python", "code.py"]
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import discord
|
import discord
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
from config import debug, c, max_uses, cp, conn, connp, webhook_url
|
from config import debug, curs_data, max_uses, curs_premium, con_data, con_premium, webhook_url
|
||||||
import makeprompt as mp
|
import makeprompt as mp
|
||||||
import aiohttp
|
import aiohttp
|
||||||
|
|
||||||
@@ -9,7 +9,8 @@ class MyModal(discord.ui.Modal):
|
|||||||
def __init__(self, message):
|
def __init__(self, message):
|
||||||
super().__init__(title="Downvote")
|
super().__init__(title="Downvote")
|
||||||
self.add_item(
|
self.add_item(
|
||||||
discord.ui.InputText(label="Reason", style=discord.InputTextStyle.long)
|
discord.ui.InputText(
|
||||||
|
label="Reason", style=discord.InputTextStyle.long)
|
||||||
)
|
)
|
||||||
self.message = message
|
self.message = message
|
||||||
|
|
||||||
@@ -30,26 +31,35 @@ class MyModal(discord.ui.Modal):
|
|||||||
description=f"Downvote recieved!",
|
description=f"Downvote recieved!",
|
||||||
color=discord.Color.og_blurple(),
|
color=discord.Color.og_blurple(),
|
||||||
)
|
)
|
||||||
embed.add_field(name="Reason", value=self.children[0].value, inline=True)
|
|
||||||
embed.add_field(name="Author", value=interaction.user.mention, inline=True)
|
embed.add_field(
|
||||||
|
name="Reason", value=self.children[0].value, inline=True)
|
||||||
|
embed.add_field(
|
||||||
|
name="Author", value=interaction.user.mention, inline=True)
|
||||||
embed.add_field(
|
embed.add_field(
|
||||||
name="Channel", value=self.message.channel.name, inline=True
|
name="Channel", value=self.message.channel.name, inline=True
|
||||||
)
|
)
|
||||||
embed.add_field(name="Guild", value=self.message.guild.name, inline=True)
|
embed.add_field(
|
||||||
|
name="Guild", value=self.message.guild.name, inline=True)
|
||||||
|
|
||||||
history = await self.message.channel.history(
|
history = await self.message.channel.history(
|
||||||
limit=5, before=self.message
|
limit=5, before=self.message
|
||||||
).flatten()
|
).flatten()
|
||||||
history.reverse()
|
history.reverse()
|
||||||
|
|
||||||
users = []
|
users = []
|
||||||
fake_users = []
|
fake_users = []
|
||||||
|
|
||||||
for user in history:
|
for user in history:
|
||||||
if user.author not in users:
|
if user.author not in users:
|
||||||
# we anonimize the user, so user1, user2, user3, etc
|
# we anonimize the user, so user1, user2, user3, etc
|
||||||
fake_users.append(f"user{len(fake_users)+1}")
|
fake_users.append(f"user{len(fake_users)+1}")
|
||||||
users.append(user.author)
|
users.append(user.author)
|
||||||
|
|
||||||
if self.message.author not in users:
|
if self.message.author not in users:
|
||||||
fake_users.append(f"user{len(fake_users)+1}")
|
fake_users.append(f"user{len(fake_users)+1}")
|
||||||
users.append(self.message.author)
|
users.append(self.message.author)
|
||||||
|
|
||||||
for msg in history:
|
for msg in history:
|
||||||
uname = fake_users[users.index(msg.author)]
|
uname = fake_users[users.index(msg.author)]
|
||||||
|
|
||||||
@@ -61,20 +71,15 @@ class MyModal(discord.ui.Modal):
|
|||||||
embed.add_field(
|
embed.add_field(
|
||||||
name=f"{uname} said", value=msg.content, inline=False
|
name=f"{uname} said", value=msg.content, inline=False
|
||||||
)
|
)
|
||||||
if len(self.message.content) > 1021:
|
|
||||||
uname = fake_users[users.index(self.message.author)]
|
uname = fake_users[users.index(self.message.author)]
|
||||||
embed.add_field(
|
embed.add_field(
|
||||||
name=f"{uname} said",
|
name=f"{uname} said",
|
||||||
value="*" + self.message.content[:1021] + "*",
|
value="*" + self.message.content[:1021] + "*" if len(
|
||||||
inline=False,
|
self.message.content) > 1021 else "*" + self.message.content + "*", # [:1021] if len(self.message.content) > 1021,
|
||||||
)
|
# means that if the message is longer than 1021 characters, it will be cut at 1021 characters
|
||||||
else:
|
inline=False,
|
||||||
uname = fake_users[users.index(self.message.author)]
|
)
|
||||||
embed.add_field(
|
|
||||||
name=f"{uname} said",
|
|
||||||
value="*" + self.message.content + "*",
|
|
||||||
inline=False,
|
|
||||||
)
|
|
||||||
await webhook.send(embed=embed)
|
await webhook.send(embed=embed)
|
||||||
else:
|
else:
|
||||||
debug(
|
debug(
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import discord
|
import discord
|
||||||
import re
|
import re
|
||||||
import os
|
import os
|
||||||
from config import debug, c
|
from config import debug, curs_data
|
||||||
|
|
||||||
|
|
||||||
class ManageChat(discord.Cog):
|
class ManageChat(discord.Cog):
|
||||||
@@ -17,8 +17,9 @@ class ManageChat(discord.Cog):
|
|||||||
f"The user {ctx.author} ran the cancel command in the channel {ctx.channel} of the guild {ctx.guild}, named {ctx.guild.name}"
|
f"The user {ctx.author} ran the cancel command in the channel {ctx.channel} of the guild {ctx.guild}, named {ctx.guild.name}"
|
||||||
)
|
)
|
||||||
# check if the guild is in the database
|
# check if the guild is in the database
|
||||||
c.execute("SELECT * FROM data WHERE guild_id = ?", (ctx.guild.id,))
|
curs_data.execute(
|
||||||
if c.fetchone() is None:
|
"SELECT * FROM data WHERE guild_id = ?", (ctx.guild.id,))
|
||||||
|
if curs_data.fetchone() is None:
|
||||||
await ctx.respond(
|
await ctx.respond(
|
||||||
"This server is not setup, please run /setup", ephemeral=True
|
"This server is not setup, please run /setup", ephemeral=True
|
||||||
)
|
)
|
||||||
@@ -87,32 +88,34 @@ class ManageChat(discord.Cog):
|
|||||||
last_message: discord.Message = await ctx.channel.fetch_message(
|
last_message: discord.Message = await ctx.channel.fetch_message(
|
||||||
ctx.channel.last_message_id
|
ctx.channel.last_message_id
|
||||||
)
|
)
|
||||||
|
new_file_name = f"transcript_{ctx.guild.name}_{ctx.channel.name}_{last_message.created_at.strftime('%d-%B-%Y')}.txt"
|
||||||
# rename the file with the name of the channel and the date in this format: transcript_servername_channelname_dd-month-yyyy.txt ex : transcript_Botator_Testing_12-may-2021.txt
|
# rename the file with the name of the channel and the date in this format: transcript_servername_channelname_dd-month-yyyy.txt ex : transcript_Botator_Testing_12-may-2021.txt
|
||||||
os.rename(
|
os.rename(
|
||||||
"transcript.txt",
|
"transcript.txt",
|
||||||
f"transcript_{ctx.guild.name}_{ctx.channel.name}_{last_message.created_at.strftime('%d-%B-%Y')}.txt",
|
new_file_name,
|
||||||
)
|
)
|
||||||
# send the file in a private message to the user who ran the command
|
# send the file in a private message to the user who ran the command
|
||||||
|
# TODO: rework so as to give the choice of a private send or a public send
|
||||||
if channel_send is None:
|
if channel_send is None:
|
||||||
await ctx.respond(
|
await ctx.respond(
|
||||||
file=discord.File(
|
file=discord.File(
|
||||||
f"transcript_{ctx.guild.name}_{ctx.channel.name}_{last_message.created_at.strftime('%d-%B-%Y')}.txt"
|
new_file_name
|
||||||
),
|
),
|
||||||
ephemeral=True,
|
ephemeral=True,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
await channel_send.send(
|
await channel_send.send(
|
||||||
file=discord.File(
|
file=discord.File(
|
||||||
f"transcript_{ctx.guild.name}_{ctx.channel.name}_{last_message.created_at.strftime('%d-%B-%Y')}.txt"
|
new_file_name
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
await ctx.respond("Transcript sent!", ephemeral=True, delete_after=5)
|
await ctx.respond("Transcript sent!", ephemeral=True, delete_after=5)
|
||||||
await ctx.author.send(
|
await ctx.author.send(
|
||||||
file=discord.File(
|
file=discord.File(
|
||||||
f"transcript_{ctx.guild.name}_{ctx.channel.name}_{last_message.created_at.strftime('%d-%B-%Y')}.txt"
|
new_file_name
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
# delete the file
|
# delete the file
|
||||||
os.remove(
|
os.remove(
|
||||||
f"transcript_{ctx.guild.name}_{ctx.channel.name}_{last_message.created_at.strftime('%d-%B-%Y')}.txt"
|
new_file_name
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
import discord
|
import discord
|
||||||
from discord import default_permissions
|
from discord import default_permissions
|
||||||
import os
|
import os
|
||||||
from config import debug, c, conn
|
from config import debug, curs_data, con_data
|
||||||
import openai
|
import openai
|
||||||
import requests
|
import requests
|
||||||
import toxicity as tox # this is a file called toxicity.py, which contains the toxicity function that allows you to check if a message is toxic or not (it uses the perspective api)
|
|
||||||
|
|
||||||
|
|
||||||
class Moderation(discord.Cog):
|
class Moderation(discord.Cog):
|
||||||
@@ -76,99 +75,102 @@ class Moderation(discord.Cog):
|
|||||||
obscene: float = None,
|
obscene: float = None,
|
||||||
spam: float = None,
|
spam: float = None,
|
||||||
):
|
):
|
||||||
|
# local import, because we don't want to import the toxicity function if the moderation is disabled
|
||||||
|
# import toxicity as tox # this is a file called toxicity.py, which contains the toxicity function that allows you to check if a message is toxic or not (it uses the perspective api)
|
||||||
await ctx.respond(
|
await ctx.respond(
|
||||||
"Our moderation capabilities have been switched to our new 100% free and open-source AI discord moderation bot! You add it to your server here: https://discord.com/api/oauth2/authorize?client_id=1071451913024974939&permissions=1377342450896&scope=bot and you can find the source code here: https://github.com/Paillat-dev/Moderator/ \n If you need help, you can join our support server here: https://discord.gg/pB6hXtUeDv",
|
"Our moderation capabilities have been switched to our new 100% free and open-source AI discord moderation bot! You add it to your server here: https://discord.com/api/oauth2/authorize?client_id=1071451913024974939&permissions=1377342450896&scope=bot and you can find the source code here: https://github.com/Paillat-dev/Moderator/ \n If you need help, you can join our support server here: https://discord.gg/pB6hXtUeDv",
|
||||||
ephemeral=True,
|
ephemeral=True,
|
||||||
)
|
)
|
||||||
if enable == False:
|
if enable == False:
|
||||||
c.execute("DELETE FROM moderation WHERE guild_id = ?", (str(ctx.guild.id),))
|
curs_data.execute("DELETE FROM moderation WHERE guild_id = ?", (str(ctx.guild.id),))
|
||||||
conn.commit()
|
con_data.commit()
|
||||||
await ctx.respond("Moderation disabled!", ephemeral=True)
|
await ctx.respond("Moderation disabled!", ephemeral=True)
|
||||||
return
|
return
|
||||||
|
|
||||||
@discord.Cog.listener()
|
# Moderation has been moved to a new bot..
|
||||||
async def on_message(self, message: discord.Message):
|
# @discord.Cog.listener()
|
||||||
if message.author == self.bot.user:
|
# async def on_message(self, message: discord.Message):
|
||||||
return
|
# if message.author == self.bot.user:
|
||||||
try:
|
# return
|
||||||
c.execute(
|
# try:
|
||||||
"SELECT * FROM moderation WHERE guild_id = ?", (str(message.guild.id),)
|
# curs_data.execute(
|
||||||
)
|
# "SELECT * FROM moderation WHERE guild_id = ?", (str(message.guild.id),)
|
||||||
except:
|
# )
|
||||||
return
|
# except:
|
||||||
data = c.fetchone()
|
# return
|
||||||
if data is None:
|
# data = curs_data.fetchone()
|
||||||
return
|
# if data is None:
|
||||||
channel = self.bot.get_channel(int(data[1]))
|
# return
|
||||||
is_enabled = data[2]
|
# channel = self.bot.get_channel(int(data[1]))
|
||||||
moderator_role = message.guild.get_role(int(data[3]))
|
# is_enabled = data[2]
|
||||||
# we also do that with the manage_messages permission, so the moderators can't be moderated
|
# moderator_role = message.guild.get_role(int(data[3]))
|
||||||
if message.author.guild_permissions.manage_messages:
|
# # we also do that with the manage_messages permission, so the moderators can't be moderated
|
||||||
return # if the user is a moderator, we don't want to moderate him because he is allowed to say whatever he wants because he is just like a dictator
|
# if message.author.guild_permissions.manage_messages:
|
||||||
if message.author.guild_permissions.administrator:
|
# return # if the user is a moderator, we don't want to moderate him because he is allowed to say whatever he wants because he is just like a dictator
|
||||||
return # if the user is an administrator, we don't want to moderate him because he is allowed to say whatever he wants because he is a DICTATOR
|
# if message.author.guild_permissions.administrator:
|
||||||
if not is_enabled:
|
# return # if the user is an administrator, we don't want to moderate him because he is allowed to say whatever he wants because he is a DICTATOR
|
||||||
return
|
# if not is_enabled:
|
||||||
content = message.content
|
# return
|
||||||
message_toxicity = tox.get_toxicity(content)
|
# content = message.content
|
||||||
reasons_to_delete = []
|
# message_toxicity = tox.get_toxicity(content)
|
||||||
reasons_to_suspicous = []
|
# reasons_to_delete = []
|
||||||
for i in message_toxicity:
|
# reasons_to_suspicous = []
|
||||||
if i >= float(data[message_toxicity.index(i) + 4]):
|
# for i in message_toxicity:
|
||||||
reasons_to_delete.append(tox.toxicity_names[message_toxicity.index(i)])
|
# if i >= float(data[message_toxicity.index(i) + 4]):
|
||||||
for i in message_toxicity:
|
# reasons_to_delete.append(tox.toxicity_names[message_toxicity.index(i)])
|
||||||
if (
|
# for i in message_toxicity:
|
||||||
float(data[message_toxicity.index(i) + 4] - 0.1)
|
# if (
|
||||||
<= i
|
# float(data[message_toxicity.index(i) + 4] - 0.1)
|
||||||
< float(data[message_toxicity.index(i) + 4])
|
# <= i
|
||||||
):
|
# < float(data[message_toxicity.index(i) + 4])
|
||||||
reasons_to_suspicous.append(
|
# ):
|
||||||
tox.toxicity_names[message_toxicity.index(i)]
|
# reasons_to_suspicous.append(
|
||||||
)
|
# tox.toxicity_names[message_toxicity.index(i)]
|
||||||
if len(reasons_to_delete) > 0:
|
# )
|
||||||
embed = discord.Embed(
|
# if len(reasons_to_delete) > 0:
|
||||||
title="Message deleted",
|
# embed = discord.Embed(
|
||||||
description=f"Your message was deleted because it was too toxic. The following reasons were found: **{'**, **'.join(reasons_to_delete)}**",
|
# title="Message deleted",
|
||||||
color=discord.Color.red(),
|
# description=f"Your message was deleted because it was too toxic. The following reasons were found: **{'**, **'.join(reasons_to_delete)}**",
|
||||||
)
|
# color=discord.Color.red(),
|
||||||
await message.reply(
|
# )
|
||||||
f"{message.author.mention}", embed=embed, delete_after=15
|
# await message.reply(
|
||||||
)
|
# f"{message.author.mention}", embed=embed, delete_after=15
|
||||||
await message.delete()
|
# )
|
||||||
embed = discord.Embed(
|
# await message.delete()
|
||||||
title="Message deleted",
|
# embed = discord.Embed(
|
||||||
description=f"**{message.author}**'s message ***{content}*** was deleted because it was too toxic. The following reasons were found:",
|
# title="Message deleted",
|
||||||
color=discord.Color.red(),
|
# description=f"**{message.author}**'s message ***{content}*** was deleted because it was too toxic. The following reasons were found:",
|
||||||
)
|
# color=discord.Color.red(),
|
||||||
for i in reasons_to_delete:
|
# )
|
||||||
toxicity_value = message_toxicity[tox.toxicity_names.index(i)]
|
# for i in reasons_to_delete:
|
||||||
embed.add_field(
|
# toxicity_value = message_toxicity[tox.toxicity_names.index(i)]
|
||||||
name=i,
|
# embed.add_field(
|
||||||
value=f"Found toxicity value: **{toxicity_value*100}%**",
|
# name=i,
|
||||||
inline=False,
|
# value=f"Found toxicity value: **{toxicity_value*100}%**",
|
||||||
)
|
# inline=False,
|
||||||
await channel.send(embed=embed)
|
# )
|
||||||
elif len(reasons_to_suspicous) > 0:
|
# await channel.send(embed=embed)
|
||||||
await message.reply(
|
# elif len(reasons_to_suspicous) > 0:
|
||||||
f"{moderator_role.mention} This message might be toxic. The following reasons were found: **{'**, **'.join(reasons_to_suspicous)}**",
|
# await message.reply(
|
||||||
delete_after=15,
|
# f"{moderator_role.mention} This message might be toxic. The following reasons were found: **{'**, **'.join(reasons_to_suspicous)}**",
|
||||||
mention_author=False,
|
# delete_after=15,
|
||||||
)
|
# mention_author=False,
|
||||||
embed = discord.Embed(
|
# )
|
||||||
title="Message suspicious",
|
# embed = discord.Embed(
|
||||||
description=f"**{message.author}**'s message [***{content}***]({message.jump_url}) might be toxic. The following reasons were found:",
|
# title="Message suspicious",
|
||||||
color=discord.Color.orange(),
|
# description=f"**{message.author}**'s message [***{content}***]({message.jump_url}) might be toxic. The following reasons were found:",
|
||||||
)
|
# color=discord.Color.orange(),
|
||||||
for i in reasons_to_suspicous:
|
# )
|
||||||
toxicity_value = message_toxicity[tox.toxicity_names.index(i)]
|
# for i in reasons_to_suspicous:
|
||||||
embed.add_field(
|
# toxicity_value = message_toxicity[tox.toxicity_names.index(i)]
|
||||||
name=i,
|
# embed.add_field(
|
||||||
value=f"Found toxicity value: **{toxicity_value*100}%**",
|
# name=i,
|
||||||
inline=False,
|
# value=f"Found toxicity value: **{toxicity_value*100}%**",
|
||||||
)
|
# inline=False,
|
||||||
await channel.send(embed=embed)
|
# )
|
||||||
# we add a reaction to the message so the moderators can easily find it orange circle emoji
|
# await channel.send(embed=embed)
|
||||||
await message.add_reaction("🟠")
|
# # we add a reaction to the message so the moderators can easily find it orange circle emoji
|
||||||
|
# await message.add_reaction("🟠")
|
||||||
|
|
||||||
@discord.slash_command(
|
@discord.slash_command(
|
||||||
name="get_toxicity", description="Get the toxicity of a message"
|
name="get_toxicity", description="Get the toxicity of a message"
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import discord
|
import discord
|
||||||
from config import debug, conn, c, moderate
|
from config import debug, con_data, curs_data, moderate
|
||||||
from discord import default_permissions
|
from discord import default_permissions
|
||||||
import openai
|
import openai
|
||||||
|
|
||||||
models = ["davinci", "chatGPT", "gpt-4"]
|
models = ["davinci", "gpt-3.5-turbo", "gpt-4"]
|
||||||
images_recognition = ["enable", "disable"]
|
images_recognition = ["enable", "disable"]
|
||||||
|
|
||||||
|
|
||||||
@@ -38,8 +38,8 @@ class Settings(discord.Cog):
|
|||||||
f"The user {ctx.author} ran the advanced command in the channel {ctx.channel} of the guild {ctx.guild}, named {ctx.guild.name}"
|
f"The user {ctx.author} ran the advanced command in the channel {ctx.channel} of the guild {ctx.guild}, named {ctx.guild.name}"
|
||||||
)
|
)
|
||||||
# check if the guild is in the database
|
# check if the guild is in the database
|
||||||
c.execute("SELECT * FROM data WHERE guild_id = ?", (ctx.guild.id,))
|
curs_data.execute("SELECT * FROM data WHERE guild_id = ?", (ctx.guild.id,))
|
||||||
if c.fetchone() is None:
|
if curs_data.fetchone() is None:
|
||||||
await ctx.respond("This server is not setup", ephemeral=True)
|
await ctx.respond("This server is not setup", ephemeral=True)
|
||||||
return
|
return
|
||||||
# check if the user has entered at least one argument
|
# check if the user has entered at least one argument
|
||||||
@@ -74,40 +74,40 @@ class Settings(discord.Cog):
|
|||||||
return
|
return
|
||||||
if max_tokens is None:
|
if max_tokens is None:
|
||||||
if (
|
if (
|
||||||
c.execute(
|
curs_data.execute(
|
||||||
"SELECT max_tokens FROM data WHERE guild_id = ?", (ctx.guild.id,)
|
"SELECT max_tokens FROM data WHERE guild_id = ?", (ctx.guild.id,)
|
||||||
).fetchone()[0]
|
).fetchone()[0]
|
||||||
is not None
|
is not None
|
||||||
and max_tokens is None
|
and max_tokens is None
|
||||||
):
|
):
|
||||||
max_tokens = c.execute(
|
max_tokens = curs_data.execute(
|
||||||
"SELECT max_tokens FROM data WHERE guild_id = ?", (ctx.guild.id,)
|
"SELECT max_tokens FROM data WHERE guild_id = ?", (ctx.guild.id,)
|
||||||
).fetchone()[0]
|
).fetchone()[0]
|
||||||
else:
|
else:
|
||||||
max_tokens = 64
|
max_tokens = 64
|
||||||
if temperature is None:
|
if temperature is None:
|
||||||
if (
|
if (
|
||||||
c.execute(
|
curs_data.execute(
|
||||||
"SELECT temperature FROM data WHERE guild_id = ?", (ctx.guild.id,)
|
"SELECT temperature FROM data WHERE guild_id = ?", (ctx.guild.id,)
|
||||||
).fetchone()[0]
|
).fetchone()[0]
|
||||||
is not None
|
is not None
|
||||||
and temperature is None
|
and temperature is None
|
||||||
):
|
):
|
||||||
temperature = c.execute(
|
temperature = curs_data.execute(
|
||||||
"SELECT temperature FROM data WHERE guild_id = ?", (ctx.guild.id,)
|
"SELECT temperature FROM data WHERE guild_id = ?", (ctx.guild.id,)
|
||||||
).fetchone()[0]
|
).fetchone()[0]
|
||||||
else:
|
else:
|
||||||
temperature = 0.9
|
temperature = 0.9
|
||||||
if frequency_penalty is None:
|
if frequency_penalty is None:
|
||||||
if (
|
if (
|
||||||
c.execute(
|
curs_data.execute(
|
||||||
"SELECT frequency_penalty FROM data WHERE guild_id = ?",
|
"SELECT frequency_penalty FROM data WHERE guild_id = ?",
|
||||||
(ctx.guild.id,),
|
(ctx.guild.id,),
|
||||||
).fetchone()[0]
|
).fetchone()[0]
|
||||||
is not None
|
is not None
|
||||||
and frequency_penalty is None
|
and frequency_penalty is None
|
||||||
):
|
):
|
||||||
frequency_penalty = c.execute(
|
frequency_penalty = curs_data.execute(
|
||||||
"SELECT frequency_penalty FROM data WHERE guild_id = ?",
|
"SELECT frequency_penalty FROM data WHERE guild_id = ?",
|
||||||
(ctx.guild.id,),
|
(ctx.guild.id,),
|
||||||
).fetchone()[0]
|
).fetchone()[0]
|
||||||
@@ -115,14 +115,14 @@ class Settings(discord.Cog):
|
|||||||
frequency_penalty = 0.0
|
frequency_penalty = 0.0
|
||||||
if presence_penalty is None:
|
if presence_penalty is None:
|
||||||
if (
|
if (
|
||||||
c.execute(
|
curs_data.execute(
|
||||||
"SELECT presence_penalty FROM data WHERE guild_id = ?",
|
"SELECT presence_penalty FROM data WHERE guild_id = ?",
|
||||||
(ctx.guild.id,),
|
(ctx.guild.id,),
|
||||||
).fetchone()[0]
|
).fetchone()[0]
|
||||||
is not None
|
is not None
|
||||||
and presence_penalty is None
|
and presence_penalty is None
|
||||||
):
|
):
|
||||||
presence_penalty = c.execute(
|
presence_penalty = curs_data.execute(
|
||||||
"SELECT presence_penalty FROM data WHERE guild_id = ?",
|
"SELECT presence_penalty FROM data WHERE guild_id = ?",
|
||||||
(ctx.guild.id,),
|
(ctx.guild.id,),
|
||||||
).fetchone()[0]
|
).fetchone()[0]
|
||||||
@@ -130,19 +130,19 @@ class Settings(discord.Cog):
|
|||||||
presence_penalty = 0.0
|
presence_penalty = 0.0
|
||||||
if prompt_size is None:
|
if prompt_size is None:
|
||||||
if (
|
if (
|
||||||
c.execute(
|
curs_data.execute(
|
||||||
"SELECT prompt_size FROM data WHERE guild_id = ?", (ctx.guild.id,)
|
"SELECT prompt_size FROM data WHERE guild_id = ?", (ctx.guild.id,)
|
||||||
).fetchone()[0]
|
).fetchone()[0]
|
||||||
is not None
|
is not None
|
||||||
and prompt_size is None
|
and prompt_size is None
|
||||||
):
|
):
|
||||||
prompt_size = c.execute(
|
prompt_size = curs_data.execute(
|
||||||
"SELECT prompt_size FROM data WHERE guild_id = ?", (ctx.guild.id,)
|
"SELECT prompt_size FROM data WHERE guild_id = ?", (ctx.guild.id,)
|
||||||
).fetchone()[0]
|
).fetchone()[0]
|
||||||
else:
|
else:
|
||||||
prompt_size = 1
|
prompt_size = 1
|
||||||
# update the database
|
# update the database
|
||||||
c.execute(
|
curs_data.execute(
|
||||||
"UPDATE data SET max_tokens = ?, temperature = ?, frequency_penalty = ?, presence_penalty = ?, prompt_size = ? WHERE guild_id = ?",
|
"UPDATE data SET max_tokens = ?, temperature = ?, frequency_penalty = ?, presence_penalty = ?, prompt_size = ? WHERE guild_id = ?",
|
||||||
(
|
(
|
||||||
max_tokens,
|
max_tokens,
|
||||||
@@ -153,7 +153,7 @@ class Settings(discord.Cog):
|
|||||||
ctx.guild.id,
|
ctx.guild.id,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
conn.commit()
|
con_data.commit()
|
||||||
await ctx.respond("Advanced settings updated", ephemeral=True)
|
await ctx.respond("Advanced settings updated", ephemeral=True)
|
||||||
# create a command called "delete" that only admins can use wich deletes the guild id, the api key, the channel id and the advanced settings from the database
|
# create a command called "delete" that only admins can use wich deletes the guild id, the api key, the channel id and the advanced settings from the database
|
||||||
|
|
||||||
@@ -164,18 +164,18 @@ class Settings(discord.Cog):
|
|||||||
f"The user {ctx.author} ran the default command in the channel {ctx.channel} of the guild {ctx.guild}, named {ctx.guild.name}"
|
f"The user {ctx.author} ran the default command in the channel {ctx.channel} of the guild {ctx.guild}, named {ctx.guild.name}"
|
||||||
)
|
)
|
||||||
# check if the guild is in the database
|
# check if the guild is in the database
|
||||||
c.execute("SELECT * FROM data WHERE guild_id = ?", (ctx.guild.id,))
|
curs_data.execute("SELECT * FROM data WHERE guild_id = ?", (ctx.guild.id,))
|
||||||
if c.fetchone() is None:
|
if curs_data.fetchone() is None:
|
||||||
await ctx.respond(
|
await ctx.respond(
|
||||||
"This server is not setup, please run /setup", ephemeral=True
|
"This server is not setup, please run /setup", ephemeral=True
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
# set the advanced settings (max_tokens, temperature, frequency_penalty, presence_penalty, prompt_size) and also prompt_prefix to their default values
|
# set the advanced settings (max_tokens, temperature, frequency_penalty, presence_penalty, prompt_size) and also prompt_prefix to their default values
|
||||||
c.execute(
|
curs_data.execute(
|
||||||
"UPDATE data SET max_tokens = ?, temperature = ?, frequency_penalty = ?, presence_penalty = ?, prompt_size = ? WHERE guild_id = ?",
|
"UPDATE data SET max_tokens = ?, temperature = ?, frequency_penalty = ?, presence_penalty = ?, prompt_size = ? WHERE guild_id = ?",
|
||||||
(64, 0.9, 0.0, 0.0, 5, ctx.guild.id),
|
(64, 0.9, 0.0, 0.0, 5, ctx.guild.id),
|
||||||
)
|
)
|
||||||
conn.commit()
|
con_data.commit()
|
||||||
await ctx.respond(
|
await ctx.respond(
|
||||||
"The advanced settings have been set to their default values",
|
"The advanced settings have been set to their default values",
|
||||||
ephemeral=True,
|
ephemeral=True,
|
||||||
@@ -194,16 +194,16 @@ class Settings(discord.Cog):
|
|||||||
# this command sends all the data about the guild, including the api key, the channel id, the advanced settings and the uses_count_today
|
# this command sends all the data about the guild, including the api key, the channel id, the advanced settings and the uses_count_today
|
||||||
# check if the guild is in the database
|
# check if the guild is in the database
|
||||||
try:
|
try:
|
||||||
c.execute("SELECT * FROM data WHERE guild_id = ?", (ctx.guild.id,))
|
curs_data.execute("SELECT * FROM data WHERE guild_id = ?", (ctx.guild.id,))
|
||||||
data = c.fetchone()
|
data = curs_data.fetchone()
|
||||||
except:
|
except:
|
||||||
data = None
|
data = None
|
||||||
if data[2] is None:
|
if data[2] is None:
|
||||||
await ctx.respond("This server is not setup", ephemeral=True)
|
await ctx.respond("This server is not setup", ephemeral=True)
|
||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
c.execute("SELECT * FROM model WHERE guild_id = ?", (ctx.guild.id,))
|
curs_data.execute("SELECT * FROM model WHERE guild_id = ?", (ctx.guild.id,))
|
||||||
model = c.fetchone()[1]
|
model = curs_data.fetchone()[1]
|
||||||
except:
|
except:
|
||||||
model = None
|
model = None
|
||||||
if model is None:
|
if model is None:
|
||||||
@@ -233,8 +233,8 @@ class Settings(discord.Cog):
|
|||||||
f"The user {ctx.author.name} ran the prefix command command in the channel {ctx.channel} of the guild {ctx.guild}, named {ctx.guild.name}"
|
f"The user {ctx.author.name} ran the prefix command command in the channel {ctx.channel} of the guild {ctx.guild}, named {ctx.guild.name}"
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
c.execute("SELECT * FROM data WHERE guild_id = ?", (ctx.guild.id,))
|
curs_data.execute("SELECT * FROM data WHERE guild_id = ?", (ctx.guild.id,))
|
||||||
data = c.fetchone()
|
data = curs_data.fetchone()
|
||||||
api_key = data[2]
|
api_key = data[2]
|
||||||
except:
|
except:
|
||||||
await ctx.respond("This server is not setup", ephemeral=True)
|
await ctx.respond("This server is not setup", ephemeral=True)
|
||||||
@@ -251,11 +251,11 @@ class Settings(discord.Cog):
|
|||||||
)
|
)
|
||||||
return
|
return
|
||||||
await ctx.respond("Prefix changed !", ephemeral=True, delete_after=5)
|
await ctx.respond("Prefix changed !", ephemeral=True, delete_after=5)
|
||||||
c.execute(
|
curs_data.execute(
|
||||||
"UPDATE data SET prompt_prefix = ? WHERE guild_id = ?",
|
"UPDATE data SET prompt_prefix = ? WHERE guild_id = ?",
|
||||||
(prefix, ctx.guild.id),
|
(prefix, ctx.guild.id),
|
||||||
)
|
)
|
||||||
conn.commit()
|
con_data.commit()
|
||||||
|
|
||||||
# when someone mentions the bot, check if the guild is in the database and if the bot is enabled. If it is, send a message answering the mention
|
# when someone mentions the bot, check if the guild is in the database and if the bot is enabled. If it is, send a message answering the mention
|
||||||
@discord.slash_command(
|
@discord.slash_command(
|
||||||
@@ -272,8 +272,8 @@ class Settings(discord.Cog):
|
|||||||
)
|
)
|
||||||
# check if the guild is in the database
|
# check if the guild is in the database
|
||||||
try:
|
try:
|
||||||
c.execute("SELECT * FROM data WHERE guild_id = ?", (ctx.guild.id,))
|
curs_data.execute("SELECT * FROM data WHERE guild_id = ?", (ctx.guild.id,))
|
||||||
data = c.fetchone()
|
data = curs_data.fetchone()
|
||||||
api_key = data[2]
|
api_key = data[2]
|
||||||
except:
|
except:
|
||||||
await ctx.respond("This server is not setup", ephemeral=True)
|
await ctx.respond("This server is not setup", ephemeral=True)
|
||||||
@@ -291,28 +291,28 @@ class Settings(discord.Cog):
|
|||||||
return
|
return
|
||||||
if pretend_to_be == "":
|
if pretend_to_be == "":
|
||||||
pretend_to_be = ""
|
pretend_to_be = ""
|
||||||
c.execute(
|
curs_data.execute(
|
||||||
"UPDATE data SET pretend_enabled = 0 WHERE guild_id = ?",
|
"UPDATE data SET pretend_enabled = 0 WHERE guild_id = ?",
|
||||||
(ctx.guild.id,),
|
(ctx.guild.id,),
|
||||||
)
|
)
|
||||||
conn.commit()
|
con_data.commit()
|
||||||
await ctx.respond("Pretend mode disabled", ephemeral=True, delete_after=5)
|
await ctx.respond("Pretend mode disabled", ephemeral=True, delete_after=5)
|
||||||
await ctx.guild.me.edit(nick=None)
|
await ctx.guild.me.edit(nick=None)
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
c.execute(
|
curs_data.execute(
|
||||||
"UPDATE data SET pretend_enabled = 1 WHERE guild_id = ?",
|
"UPDATE data SET pretend_enabled = 1 WHERE guild_id = ?",
|
||||||
(ctx.guild.id,),
|
(ctx.guild.id,),
|
||||||
)
|
)
|
||||||
conn.commit()
|
con_data.commit()
|
||||||
await ctx.respond("Pretend mode enabled", ephemeral=True, delete_after=5)
|
await ctx.respond("Pretend mode enabled", ephemeral=True, delete_after=5)
|
||||||
# change the bots name on the server wit ctx.guild.me.edit(nick=pretend_to_be)
|
# change the bots name on the server wit ctx.guild.me.edit(nick=pretend_to_be)
|
||||||
await ctx.guild.me.edit(nick=pretend_to_be)
|
await ctx.guild.me.edit(nick=pretend_to_be)
|
||||||
c.execute(
|
curs_data.execute(
|
||||||
"UPDATE data SET pretend_to_be = ? WHERE guild_id = ?",
|
"UPDATE data SET pretend_to_be = ? WHERE guild_id = ?",
|
||||||
(pretend_to_be, ctx.guild.id),
|
(pretend_to_be, ctx.guild.id),
|
||||||
)
|
)
|
||||||
conn.commit()
|
con_data.commit()
|
||||||
# if the usename is longer than 32 characters, shorten it
|
# if the usename is longer than 32 characters, shorten it
|
||||||
if len(pretend_to_be) > 31:
|
if len(pretend_to_be) > 31:
|
||||||
pretend_to_be = pretend_to_be[:32]
|
pretend_to_be = pretend_to_be[:32]
|
||||||
@@ -325,8 +325,8 @@ class Settings(discord.Cog):
|
|||||||
guild_id = ctx.guild.id
|
guild_id = ctx.guild.id
|
||||||
# connect to the database
|
# connect to the database
|
||||||
# update the tts value in the database
|
# update the tts value in the database
|
||||||
c.execute("UPDATE data SET tts = 1 WHERE guild_id = ?", (guild_id,))
|
curs_data.execute("UPDATE data SET tts = 1 WHERE guild_id = ?", (guild_id,))
|
||||||
conn.commit()
|
con_data.commit()
|
||||||
# send a message
|
# send a message
|
||||||
await ctx.respond("TTS has been enabled", ephemeral=True)
|
await ctx.respond("TTS has been enabled", ephemeral=True)
|
||||||
|
|
||||||
@@ -336,8 +336,8 @@ class Settings(discord.Cog):
|
|||||||
guild_id = ctx.guild.id
|
guild_id = ctx.guild.id
|
||||||
# connect to the database
|
# connect to the database
|
||||||
# update the tts value in the database
|
# update the tts value in the database
|
||||||
c.execute("UPDATE data SET tts = 0 WHERE guild_id = ?", (guild_id,))
|
curs_data.execute("UPDATE data SET tts = 0 WHERE guild_id = ?", (guild_id,))
|
||||||
conn.commit()
|
con_data.commit()
|
||||||
# send a message
|
# send a message
|
||||||
await ctx.respond("TTS has been disabled", ephemeral=True)
|
await ctx.respond("TTS has been disabled", ephemeral=True)
|
||||||
|
|
||||||
@@ -355,18 +355,18 @@ class Settings(discord.Cog):
|
|||||||
@default_permissions(administrator=True)
|
@default_permissions(administrator=True)
|
||||||
async def model(self, ctx: discord.ApplicationContext, model: str = "davinci"):
|
async def model(self, ctx: discord.ApplicationContext, model: str = "davinci"):
|
||||||
try:
|
try:
|
||||||
c.execute("SELECT * FROM model WHERE guild_id = ?", (ctx.guild.id,))
|
curs_data.execute("SELECT * FROM model WHERE guild_id = ?", (ctx.guild.id,))
|
||||||
data = c.fetchone()[1]
|
data = curs_data.fetchone()[1]
|
||||||
except:
|
except:
|
||||||
data = None
|
data = None
|
||||||
if data is None:
|
if data is None:
|
||||||
c.execute("INSERT INTO model VALUES (?, ?)", (ctx.guild.id, model))
|
curs_data.execute("INSERT INTO model VALUES (?, ?)", (ctx.guild.id, model))
|
||||||
else:
|
else:
|
||||||
c.execute(
|
curs_data.execute(
|
||||||
"UPDATE model SET model_name = ? WHERE guild_id = ?",
|
"UPDATE model SET model_name = ? WHERE guild_id = ?",
|
||||||
(model, ctx.guild.id),
|
(model, ctx.guild.id),
|
||||||
)
|
)
|
||||||
conn.commit()
|
con_data.commit()
|
||||||
await ctx.respond("Model changed !", ephemeral=True)
|
await ctx.respond("Model changed !", ephemeral=True)
|
||||||
|
|
||||||
async def images_recognition_autocomplete(ctx: discord.AutocompleteContext):
|
async def images_recognition_autocomplete(ctx: discord.AutocompleteContext):
|
||||||
@@ -383,8 +383,8 @@ class Settings(discord.Cog):
|
|||||||
@default_permissions(administrator=True)
|
@default_permissions(administrator=True)
|
||||||
async def images(self, ctx: discord.ApplicationContext, enable_disable: str):
|
async def images(self, ctx: discord.ApplicationContext, enable_disable: str):
|
||||||
try:
|
try:
|
||||||
c.execute("SELECT * FROM images WHERE guild_id = ?", (ctx.guild.id,))
|
curs_data.execute("SELECT * FROM images WHERE guild_id = ?", (ctx.guild.id,))
|
||||||
data = c.fetchone()
|
data = curs_data.fetchone()
|
||||||
except:
|
except:
|
||||||
data = None
|
data = None
|
||||||
if enable_disable == "enable":
|
if enable_disable == "enable":
|
||||||
@@ -392,15 +392,15 @@ class Settings(discord.Cog):
|
|||||||
elif enable_disable == "disable":
|
elif enable_disable == "disable":
|
||||||
enable_disable = 0
|
enable_disable = 0
|
||||||
if data is None:
|
if data is None:
|
||||||
c.execute(
|
curs_data.execute(
|
||||||
"INSERT INTO images VALUES (?, ?, ?)", (ctx.guild.id, 0, enable_disable)
|
"INSERT INTO images VALUES (?, ?, ?)", (ctx.guild.id, 0, enable_disable)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
c.execute(
|
curs_data.execute(
|
||||||
"UPDATE images SET is_enabled = ? WHERE guild_id = ?",
|
"UPDATE images SET is_enabled = ? WHERE guild_id = ?",
|
||||||
(enable_disable, ctx.guild.id),
|
(enable_disable, ctx.guild.id),
|
||||||
)
|
)
|
||||||
conn.commit()
|
con_data.commit()
|
||||||
await ctx.respond(
|
await ctx.respond(
|
||||||
"Images recognition has been "
|
"Images recognition has been "
|
||||||
+ ("enabled" if enable_disable == 1 else "disabled"),
|
+ ("enabled" if enable_disable == 1 else "disabled"),
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import discord
|
import discord
|
||||||
from config import debug, conn, c, connp, cp
|
from config import debug, con_data, curs_data, con_premium, curs_premium
|
||||||
|
|
||||||
|
|
||||||
class Setup(discord.Cog):
|
class Setup(discord.Cog):
|
||||||
@@ -26,26 +26,26 @@ class Setup(discord.Cog):
|
|||||||
return
|
return
|
||||||
# check if the guild is already in the database bi checking if there is a key for the guild
|
# check if the guild is already in the database bi checking if there is a key for the guild
|
||||||
try:
|
try:
|
||||||
c.execute("SELECT * FROM data WHERE guild_id = ?", (ctx.guild.id,))
|
curs_data.execute("SELECT * FROM data WHERE guild_id = ?", (ctx.guild.id,))
|
||||||
data = c.fetchone()
|
data = curs_data.fetchone()
|
||||||
if data[3] == None:
|
if data[3] == None:
|
||||||
data = None
|
data = None
|
||||||
except:
|
except:
|
||||||
data = None
|
data = None
|
||||||
|
|
||||||
if data != None:
|
if data != None:
|
||||||
c.execute(
|
curs_data.execute(
|
||||||
"UPDATE data SET channel_id = ?, api_key = ? WHERE guild_id = ?",
|
"UPDATE data SET channel_id = ?, api_key = ? WHERE guild_id = ?",
|
||||||
(channel.id, api_key, ctx.guild.id),
|
(channel.id, api_key, ctx.guild.id),
|
||||||
)
|
)
|
||||||
# c.execute("UPDATE data SET is_active = ?, max_tokens = ?, temperature = ?, frequency_penalty = ?, presence_penalty = ?, prompt_size = ? WHERE guild_id = ?", (False, 64, 0.9, 0.0, 0.0, 5, ctx.guild.id))
|
# c.execute("UPDATE data SET is_active = ?, max_tokens = ?, temperature = ?, frequency_penalty = ?, presence_penalty = ?, prompt_size = ? WHERE guild_id = ?", (False, 64, 0.9, 0.0, 0.0, 5, ctx.guild.id))
|
||||||
conn.commit()
|
con_data.commit()
|
||||||
await ctx.respond(
|
await ctx.respond(
|
||||||
"The channel id and the api key have been updated", ephemeral=True
|
"The channel id and the api key have been updated", ephemeral=True
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
# in this case, the guild is not in the database, so we add it
|
# in this case, the guild is not in the database, so we add it
|
||||||
c.execute(
|
curs_data.execute(
|
||||||
"INSERT INTO data VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
"INSERT INTO data VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
||||||
(
|
(
|
||||||
ctx.guild.id,
|
ctx.guild.id,
|
||||||
@@ -64,7 +64,7 @@ class Setup(discord.Cog):
|
|||||||
False,
|
False,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
conn.commit()
|
con_data.commit()
|
||||||
await ctx.respond(
|
await ctx.respond(
|
||||||
"The channel id and the api key have been added", ephemeral=True
|
"The channel id and the api key have been added", ephemeral=True
|
||||||
)
|
)
|
||||||
@@ -78,16 +78,16 @@ class Setup(discord.Cog):
|
|||||||
f"The user {ctx.author} ran the delete command in the channel {ctx.channel} of the guild {ctx.guild}, named {ctx.guild.name}"
|
f"The user {ctx.author} ran the delete command in the channel {ctx.channel} of the guild {ctx.guild}, named {ctx.guild.name}"
|
||||||
)
|
)
|
||||||
# check if the guild is in the database
|
# check if the guild is in the database
|
||||||
c.execute("SELECT * FROM data WHERE guild_id = ?", (ctx.guild.id,))
|
curs_data.execute("SELECT * FROM data WHERE guild_id = ?", (ctx.guild.id,))
|
||||||
if c.fetchone() is None:
|
if curs_data.fetchone() is None:
|
||||||
await ctx.respond("This server is not setup", ephemeral=True)
|
await ctx.respond("This server is not setup", ephemeral=True)
|
||||||
return
|
return
|
||||||
# delete the guild from the database, except the guild id and the uses_count_today
|
# delete the guild from the database, except the guild id and the uses_count_today
|
||||||
c.execute(
|
curs_data.execute(
|
||||||
"UPDATE data SET api_key = ?, channel_id = ?, is_active = ?, max_tokens = ?, temperature = ?, frequency_penalty = ?, presence_penalty = ?, prompt_size = ? WHERE guild_id = ?",
|
"UPDATE data SET api_key = ?, channel_id = ?, is_active = ?, max_tokens = ?, temperature = ?, frequency_penalty = ?, presence_penalty = ?, prompt_size = ? WHERE guild_id = ?",
|
||||||
(None, None, False, 50, 0.9, 0.0, 0.0, 0, ctx.guild.id),
|
(None, None, False, 50, 0.9, 0.0, 0.0, 0, ctx.guild.id),
|
||||||
)
|
)
|
||||||
conn.commit()
|
con_data.commit()
|
||||||
await ctx.respond("Deleted", ephemeral=True)
|
await ctx.respond("Deleted", ephemeral=True)
|
||||||
|
|
||||||
# create a command called "enable" that only admins can use
|
# create a command called "enable" that only admins can use
|
||||||
@@ -104,15 +104,15 @@ class Setup(discord.Cog):
|
|||||||
debug(
|
debug(
|
||||||
f"The user {ctx.author} ran the enable command in the channel {ctx.channel} of the guild {ctx.guild}, named {ctx.guild.name}"
|
f"The user {ctx.author} ran the enable command in the channel {ctx.channel} of the guild {ctx.guild}, named {ctx.guild.name}"
|
||||||
)
|
)
|
||||||
c.execute("SELECT * FROM data WHERE guild_id = ?", (ctx.guild.id,))
|
curs_data.execute("SELECT * FROM data WHERE guild_id = ?", (ctx.guild.id,))
|
||||||
if c.fetchone() is None:
|
if curs_data.fetchone() is None:
|
||||||
await ctx.respond("This server is not setup", ephemeral=True)
|
await ctx.respond("This server is not setup", ephemeral=True)
|
||||||
return
|
return
|
||||||
# enable the guild
|
# enable the guild
|
||||||
c.execute(
|
curs_data.execute(
|
||||||
"UPDATE data SET is_active = ? WHERE guild_id = ?", (True, ctx.guild.id)
|
"UPDATE data SET is_active = ? WHERE guild_id = ?", (True, ctx.guild.id)
|
||||||
)
|
)
|
||||||
conn.commit()
|
con_data.commit()
|
||||||
await ctx.respond("Enabled", ephemeral=True)
|
await ctx.respond("Enabled", ephemeral=True)
|
||||||
|
|
||||||
# create a command called "disable" that only admins can use
|
# create a command called "disable" that only admins can use
|
||||||
@@ -123,15 +123,15 @@ class Setup(discord.Cog):
|
|||||||
f"The user {ctx.author} ran the disable command in the channel {ctx.channel} of the guild {ctx.guild}, named {ctx.guild.name}"
|
f"The user {ctx.author} ran the disable command in the channel {ctx.channel} of the guild {ctx.guild}, named {ctx.guild.name}"
|
||||||
)
|
)
|
||||||
# check if the guild is in the database
|
# check if the guild is in the database
|
||||||
c.execute("SELECT * FROM data WHERE guild_id = ?", (ctx.guild.id,))
|
curs_data.execute("SELECT * FROM data WHERE guild_id = ?", (ctx.guild.id,))
|
||||||
if c.fetchone() is None:
|
if curs_data.fetchone() is None:
|
||||||
await ctx.respond("This server is not setup", ephemeral=True)
|
await ctx.respond("This server is not setup", ephemeral=True)
|
||||||
return
|
return
|
||||||
# disable the guild
|
# disable the guild
|
||||||
c.execute(
|
curs_data.execute(
|
||||||
"UPDATE data SET is_active = ? WHERE guild_id = ?", (False, ctx.guild.id)
|
"UPDATE data SET is_active = ? WHERE guild_id = ?", (False, ctx.guild.id)
|
||||||
)
|
)
|
||||||
conn.commit()
|
con_data.commit()
|
||||||
await ctx.respond("Disabled", ephemeral=True)
|
await ctx.respond("Disabled", ephemeral=True)
|
||||||
|
|
||||||
# create a command calles "add channel" that can only be used in premium servers
|
# create a command calles "add channel" that can only be used in premium servers
|
||||||
@@ -152,8 +152,8 @@ class Setup(discord.Cog):
|
|||||||
f"The user {ctx.author} ran the add_channel command in the channel {ctx.channel} of the guild {ctx.guild}, named {ctx.guild.name}"
|
f"The user {ctx.author} ran the add_channel command in the channel {ctx.channel} of the guild {ctx.guild}, named {ctx.guild.name}"
|
||||||
)
|
)
|
||||||
# check if the guild is in the database
|
# check if the guild is in the database
|
||||||
c.execute("SELECT * FROM data WHERE guild_id = ?", (ctx.guild.id,))
|
curs_data.execute("SELECT * FROM data WHERE guild_id = ?", (ctx.guild.id,))
|
||||||
if c.fetchone() is None:
|
if curs_data.fetchone() is None:
|
||||||
await ctx.respond("This server is not setup", ephemeral=True)
|
await ctx.respond("This server is not setup", ephemeral=True)
|
||||||
return
|
return
|
||||||
# check if the guild is premium
|
# check if the guild is premium
|
||||||
@@ -168,8 +168,8 @@ class Setup(discord.Cog):
|
|||||||
if channel is None:
|
if channel is None:
|
||||||
channel = ctx.channel
|
channel = ctx.channel
|
||||||
# check if the channel is already in the list
|
# check if the channel is already in the list
|
||||||
c.execute("SELECT channel_id FROM data WHERE guild_id = ?", (ctx.guild.id,))
|
curs_data.execute("SELECT channel_id FROM data WHERE guild_id = ?", (ctx.guild.id,))
|
||||||
if str(channel.id) == c.fetchone()[0]:
|
if str(channel.id) == curs_data.fetchone()[0]:
|
||||||
await ctx.respond(
|
await ctx.respond(
|
||||||
"This channel is already set as the main channel", ephemeral=True
|
"This channel is already set as the main channel", ephemeral=True
|
||||||
)
|
)
|
||||||
@@ -182,7 +182,7 @@ class Setup(discord.Cog):
|
|||||||
"INSERT INTO channels VALUES (?, ?, ?, ?, ?, ?)",
|
"INSERT INTO channels VALUES (?, ?, ?, ?, ?, ?)",
|
||||||
(ctx.guild.id, channel.id, None, None, None, None),
|
(ctx.guild.id, channel.id, None, None, None, None),
|
||||||
)
|
)
|
||||||
connp.commit()
|
con_premium.commit()
|
||||||
await ctx.respond(f"Added channel **{channel.name}**", ephemeral=True)
|
await ctx.respond(f"Added channel **{channel.name}**", ephemeral=True)
|
||||||
return
|
return
|
||||||
channels = guild_channels[1:]
|
channels = guild_channels[1:]
|
||||||
@@ -195,7 +195,7 @@ class Setup(discord.Cog):
|
|||||||
f"UPDATE channels SET channel{i} = ? WHERE guild_id = ?",
|
f"UPDATE channels SET channel{i} = ? WHERE guild_id = ?",
|
||||||
(channel.id, ctx.guild.id),
|
(channel.id, ctx.guild.id),
|
||||||
)
|
)
|
||||||
connp.commit()
|
con_premium.commit()
|
||||||
await ctx.respond(f"Added channel **{channel.name}**", ephemeral=True)
|
await ctx.respond(f"Added channel **{channel.name}**", ephemeral=True)
|
||||||
return
|
return
|
||||||
await ctx.respond("You can only add 5 channels", ephemeral=True)
|
await ctx.respond("You can only add 5 channels", ephemeral=True)
|
||||||
@@ -218,8 +218,8 @@ class Setup(discord.Cog):
|
|||||||
f"The user {ctx.author} ran the remove_channel command in the channel {ctx.channel} of the guild {ctx.guild}, named {ctx.guild.name}"
|
f"The user {ctx.author} ran the remove_channel command in the channel {ctx.channel} of the guild {ctx.guild}, named {ctx.guild.name}"
|
||||||
)
|
)
|
||||||
# check if the guild is in the database
|
# check if the guild is in the database
|
||||||
c.execute("SELECT * FROM data WHERE guild_id = ?", (ctx.guild.id,))
|
curs_data.execute("SELECT * FROM data WHERE guild_id = ?", (ctx.guild.id,))
|
||||||
if c.fetchone() is None:
|
if curs_data.fetchone() is None:
|
||||||
await ctx.respond("This server is not setup", ephemeral=True)
|
await ctx.respond("This server is not setup", ephemeral=True)
|
||||||
return
|
return
|
||||||
# check if the guild is premium
|
# check if the guild is premium
|
||||||
@@ -236,8 +236,8 @@ class Setup(discord.Cog):
|
|||||||
# check if the channel is in the list
|
# check if the channel is in the list
|
||||||
cp.execute("SELECT * FROM channels WHERE guild_id = ?", (ctx.guild.id,))
|
cp.execute("SELECT * FROM channels WHERE guild_id = ?", (ctx.guild.id,))
|
||||||
guild_channels = cp.fetchone()
|
guild_channels = cp.fetchone()
|
||||||
c.execute("SELECT channel_id FROM data WHERE guild_id = ?", (ctx.guild.id,))
|
curs_data.execute("SELECT channel_id FROM data WHERE guild_id = ?", (ctx.guild.id,))
|
||||||
if str(channel.id) == c.fetchone()[0]:
|
if str(channel.id) == curs_data.fetchone()[0]:
|
||||||
await ctx.respond(
|
await ctx.respond(
|
||||||
"This channel is set as the main channel and therefore cannot be removed. Type /setup to change the main channel.",
|
"This channel is set as the main channel and therefore cannot be removed. Type /setup to change the main channel.",
|
||||||
ephemeral=True,
|
ephemeral=True,
|
||||||
@@ -261,6 +261,6 @@ class Setup(discord.Cog):
|
|||||||
f"UPDATE channels SET channel{i} = ? WHERE guild_id = ?",
|
f"UPDATE channels SET channel{i} = ? WHERE guild_id = ?",
|
||||||
(None, ctx.guild.id),
|
(None, ctx.guild.id),
|
||||||
)
|
)
|
||||||
connp.commit()
|
con_premium.commit()
|
||||||
await ctx.respond(f"Removed channel **{channel.name}**", ephemeral=True)
|
await ctx.respond(f"Removed channel **{channel.name}**", ephemeral=True)
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -1,14 +1,13 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
from config import c, max_uses, cp, conn, debug, moderate
|
from config import curs_data, max_uses, curs_premium, con_data, debug, moderate
|
||||||
import vision_processing
|
import vision_processing
|
||||||
import re
|
import re
|
||||||
import discord
|
import discord
|
||||||
import datetime
|
import datetime
|
||||||
import openai
|
import openai
|
||||||
import emoji # pip install emoji
|
import emoji
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
|
||||||
async def replace_mentions(content, bot):
|
async def replace_mentions(content, bot):
|
||||||
mentions = re.findall(r"<@!?\d+>", content)
|
mentions = re.findall(r"<@!?\d+>", content)
|
||||||
for mention in mentions:
|
for mention in mentions:
|
||||||
@@ -46,75 +45,140 @@ async def extract_emoji(string):
|
|||||||
return found_emojis, string
|
return found_emojis, string
|
||||||
|
|
||||||
|
|
||||||
async def chat_process(self, message):
|
def get_guild_data(message):
|
||||||
if message.author.bot:
|
"""This function gets the data of the guild where the message was sent.
|
||||||
return
|
|
||||||
|
Args:
|
||||||
|
message (str): Data of the message that was sent
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict: A dictionary with the data of the guild
|
||||||
|
"""
|
||||||
|
guild_data = {}
|
||||||
try:
|
try:
|
||||||
c.execute("SELECT * FROM data WHERE guild_id = ?", (message.guild.id,))
|
curs_premium.execute(
|
||||||
except:
|
"SELECT * FROM data WHERE guild_id = ?", (message.guild.id,))
|
||||||
return
|
|
||||||
data = c.fetchone()
|
|
||||||
channel_id = data[1]
|
|
||||||
api_key = data[2]
|
|
||||||
is_active = data[3]
|
|
||||||
max_tokens = data[4]
|
|
||||||
temperature = data[5]
|
|
||||||
frequency_penalty = data[6]
|
|
||||||
presence_penalty = data[7]
|
|
||||||
uses_count_today = data[8]
|
|
||||||
prompt_size = data[9]
|
|
||||||
prompt_prefix = data[10]
|
|
||||||
tts = data[11]
|
|
||||||
pretend_to_be = data[12]
|
|
||||||
pretend_enabled = data[13]
|
|
||||||
images_limit_reached = False
|
|
||||||
try:
|
|
||||||
cp.execute("SELECT * FROM data WHERE guild_id = ?", (message.guild.id,))
|
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
try:
|
|
||||||
c.execute(
|
|
||||||
"SELECT * FROM model WHERE guild_id = ?", (message.guild.id,)
|
|
||||||
) # get the model in the database
|
|
||||||
model = c.fetchone()[1]
|
|
||||||
except:
|
|
||||||
model = "chatGPT"
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
premium = cp.fetchone()[2] # get the premium status of the guild
|
curs_data.execute(
|
||||||
|
"SELECT * FROM model WHERE guild_id = ?", (message.guild.id,)
|
||||||
|
) # get the model in the database
|
||||||
|
data = curs_data.fetchone()
|
||||||
|
model = model[1]
|
||||||
|
except:
|
||||||
|
model = "gpt-3.5-turbo"
|
||||||
|
|
||||||
|
try:
|
||||||
|
# [2] # get the premium status of the guild
|
||||||
|
data = curs_premium.fetchone()
|
||||||
|
premium = data[2]
|
||||||
except:
|
except:
|
||||||
premium = 0 # if the guild is not in the database, it's not premium
|
premium = 0 # if the guild is not in the database, it's not premium
|
||||||
|
|
||||||
try:
|
try:
|
||||||
c.execute(
|
curs_data.execute(
|
||||||
"SELECT * FROM images WHERE guild_id = ?", (message.guild.id,)
|
"SELECT * FROM images WHERE guild_id = ?", (message.guild.id,)
|
||||||
) # get the images setting in the database
|
) # get the images setting in the database
|
||||||
data = c.fetchone()
|
images = curs_data.fetchone()
|
||||||
except:
|
except:
|
||||||
data = None
|
images = None
|
||||||
if data is None:
|
|
||||||
data = [message.guild.id, 0, 0]
|
|
||||||
images_usage = data[1]
|
|
||||||
images_enabled = data[2]
|
|
||||||
channels = []
|
|
||||||
if message.guild.id == 1050769643180146749:
|
|
||||||
images_usage = 0 # if the guild is the support server, we set the images usage to 0, so the bot can be used as much as possible
|
|
||||||
try:
|
|
||||||
cp.execute("SELECT * FROM channels WHERE guild_id = ?", (message.guild.id,))
|
|
||||||
data = cp.fetchone()
|
|
||||||
if premium:
|
|
||||||
# for 5 times, we get c.fetchone()[1] to c.fetchone()[5] and we add it to the channels list, each time with try except
|
|
||||||
for i in range(1, 6):
|
|
||||||
# we use the i variable to get the channel id
|
|
||||||
try:
|
|
||||||
channels.append(str(data[i]))
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
except:
|
|
||||||
channels = []
|
|
||||||
|
|
||||||
if api_key is None:
|
guild_data["model"] = "gpt-3.5-turbo" if model == "chatGPT" else model
|
||||||
return # if the api key is not set, return
|
guild_data["premium"] = premium
|
||||||
|
guild_data["images"] = images
|
||||||
|
|
||||||
|
guild_data["images_limit_reached"] = False
|
||||||
|
|
||||||
|
return guild_data
|
||||||
|
|
||||||
|
|
||||||
|
async def need_ignore_message(bot, data_dict, message, guild_data, original_message, channels):
|
||||||
|
## ---- Message ignore conditions ---- ##
|
||||||
|
if data_dict["api_key"] is None:
|
||||||
|
return True # if the api key is not set, return
|
||||||
|
|
||||||
|
if (
|
||||||
|
# if the message is not in a premium channel and
|
||||||
|
not (str(message.channel.id) in channels
|
||||||
|
# if the message doesn't mention the bot and
|
||||||
|
and (message.content.find("<@" + str(bot.user.id) + ">") != -1
|
||||||
|
or original_message)) # if the message is not a reply to the bot and
|
||||||
|
# if the message is not in the default channel
|
||||||
|
and str(message.channel.id) != str(data_dict["channel_id"])
|
||||||
|
):
|
||||||
|
return True
|
||||||
|
|
||||||
|
# if the bot has been used more than max_uses*5 times in the last 24 hours in this guild and the guild is premium
|
||||||
|
# send a message and return
|
||||||
|
elif data_dict["uses_count_today"] >= max_uses * 5 and guild_data["premium"] == 1:
|
||||||
|
return True
|
||||||
|
|
||||||
|
# if the bot is not active in this guild we return
|
||||||
|
if data_dict["is_active"] == 0:
|
||||||
|
return True
|
||||||
|
|
||||||
|
# if the message starts with - or // it's a comment and we return
|
||||||
|
if message.content.startswith("-") or message.content.startswith("//"):
|
||||||
|
return True
|
||||||
|
|
||||||
|
# if the bot has been used more than max_uses times in the last 24 hours in this guild and the guild is not premium
|
||||||
|
# send a message and return
|
||||||
|
if (
|
||||||
|
data_dict["uses_count_today"] >= max_uses
|
||||||
|
and guild_data["premium"] == 0
|
||||||
|
and message.guild.id != 1050769643180146749
|
||||||
|
):
|
||||||
|
await message.channel.send(
|
||||||
|
f"The bot has been used more than {str(max_uses)} times in the last 24 hours in this guild. Please try again in 24h."
|
||||||
|
)
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
async def get_data_dict(message):
|
||||||
|
try:
|
||||||
|
curs_data.execute(
|
||||||
|
"SELECT * FROM data WHERE guild_id = ?", (message.guild.id,))
|
||||||
|
data = curs_data.fetchone()
|
||||||
|
# Create a dict with the data
|
||||||
|
data_dict = {
|
||||||
|
"channel_id": data[1],
|
||||||
|
"api_key": data[2],
|
||||||
|
"is_active": data[3],
|
||||||
|
"max_tokens": data[4],
|
||||||
|
"temperature": data[5],
|
||||||
|
"frequency_penalty": data[6],
|
||||||
|
"presence_penalty": data[7],
|
||||||
|
"uses_count_today": data[8],
|
||||||
|
"prompt_size": data[9],
|
||||||
|
"prompt_prefix": data[10],
|
||||||
|
"tts": bool(data[11]),
|
||||||
|
"pretend_to_be": data[12],
|
||||||
|
"pretend_enabled": data[13],
|
||||||
|
}
|
||||||
|
return data_dict
|
||||||
|
except Exception as e:
|
||||||
|
# Send an error message
|
||||||
|
await message.channel.send(
|
||||||
|
"The bot is not configured yet. Please use `//setup` to configure it. \n" +
|
||||||
|
"If it still doesn't work, it might be a database error. \n ```" + e.__str__()
|
||||||
|
+ "```", delete_after=60
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def chat_process(self, message):
|
||||||
|
"""This function processes the message and sends the prompt to the API
|
||||||
|
|
||||||
|
Args:
|
||||||
|
message (str): Data of the message that was sent
|
||||||
|
"""
|
||||||
|
if message.author.bot:
|
||||||
|
return
|
||||||
|
|
||||||
|
guild_data = get_guild_data(message)
|
||||||
|
data_dict = await get_data_dict(message)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
original_message = await message.channel.fetch_message(
|
original_message = await message.channel.fetch_message(
|
||||||
@@ -124,333 +188,109 @@ async def chat_process(self, message):
|
|||||||
original_message = None # if not, nobody replied to the bot
|
original_message = None # if not, nobody replied to the bot
|
||||||
|
|
||||||
if original_message != None and original_message.author.id != self.bot.user.id:
|
if original_message != None and original_message.author.id != self.bot.user.id:
|
||||||
original_message = None # if the message someone replied to is not from the bot, set original_message to None
|
# if the message someone replied to is not from the bot, set original_message to None
|
||||||
|
original_message = None
|
||||||
|
|
||||||
# if the message is not in a premium channel and
|
try:
|
||||||
# if the message doesn't mention the bot and
|
# get the images setting in the database
|
||||||
# if the message is not a reply to the bot and
|
curs_data.execute(
|
||||||
# if the message is not in the default channel
|
"SELECT * FROM images WHERE guild_id = ?", (message.guild.id,))
|
||||||
# return
|
images_data = curs_data.fetchone()
|
||||||
if (
|
except:
|
||||||
not str(message.channel.id) in channels
|
images_data = None
|
||||||
and message.content.find("<@" + str(self.bot.user.id) + ">") == -1
|
|
||||||
and original_message == None
|
## ---- Message processing ---- ##
|
||||||
and str(message.channel.id) != str(channel_id)
|
|
||||||
):
|
print(message)
|
||||||
|
|
||||||
|
if not images_data:
|
||||||
|
images_data = [message.guild.id, 0, 0]
|
||||||
|
|
||||||
|
data_dict["images_usage"] = 0 if message.guild.id == 1050769643180146749 else images_data[1]
|
||||||
|
data_dict["images_enabled"] = images_data[2]
|
||||||
|
|
||||||
|
|
||||||
|
channels = []
|
||||||
|
try:
|
||||||
|
curs_premium.execute(
|
||||||
|
"SELECT * FROM channels WHERE guild_id = ?", (message.guild.id,))
|
||||||
|
images_data = curs_premium.fetchone()
|
||||||
|
if guild_data["premium"]:
|
||||||
|
# for 5 times, we get c.fetchone()[1] to c.fetchone()[5] and we add it to the channels list, each time with try except
|
||||||
|
for i in range(1, 6):
|
||||||
|
# we use the i variable to get the channel id
|
||||||
|
try:
|
||||||
|
channels.append(str(images_data[i]))
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
except:
|
||||||
|
debug("No premium channels found for this guild")
|
||||||
|
|
||||||
|
if (await need_ignore_message(self.bot, data_dict, message, guild_data, original_message, channels)):
|
||||||
return
|
return
|
||||||
|
print("prompt handler")
|
||||||
|
|
||||||
# if the bot has been used more than max_uses times in the last 24 hours in this guild and the guild is not premium
|
|
||||||
# send a message and return
|
|
||||||
if (
|
|
||||||
uses_count_today >= max_uses
|
|
||||||
and premium == 0
|
|
||||||
and message.guild.id != 1050769643180146749
|
|
||||||
):
|
|
||||||
return await message.channel.send(
|
|
||||||
f"The bot has been used more than {str(max_uses)} times in the last 24 hours in this guild. Please try again in 24h."
|
|
||||||
)
|
|
||||||
|
|
||||||
# if the bot has been used more than max_uses*5 times in the last 24 hours in this guild and the guild is premium
|
|
||||||
# send a message and return
|
|
||||||
elif uses_count_today >= max_uses * 5 and premium == 1:
|
|
||||||
return
|
|
||||||
|
|
||||||
# if the bot is not active in this guild we return
|
|
||||||
if is_active == 0:
|
|
||||||
return
|
|
||||||
|
|
||||||
# if the message starts with - or // it's a comment and we return
|
|
||||||
if message.content.startswith("-") or message.content.startswith("//"):
|
|
||||||
return
|
|
||||||
try:
|
try:
|
||||||
await message.channel.trigger_typing()
|
await message.channel.trigger_typing()
|
||||||
except:
|
# if the message is not in the owner's guild we update the usage count
|
||||||
pass
|
if message.guild.id != 1021872219888033903:
|
||||||
# if the message is not in the owner's guild we update the usage count
|
curs_data.execute(
|
||||||
if message.guild.id != 1021872219888033903:
|
"UPDATE data SET uses_count_today = uses_count_today + 1 WHERE guild_id = ?",
|
||||||
c.execute(
|
(message.guild.id,),
|
||||||
"UPDATE data SET uses_count_today = uses_count_today + 1 WHERE guild_id = ?",
|
)
|
||||||
(message.guild.id,),
|
con_data.commit()
|
||||||
)
|
# if the message is not a reply
|
||||||
conn.commit()
|
if original_message == None:
|
||||||
# if the message is not a reply
|
messages = await message.channel.history(
|
||||||
if original_message == None:
|
limit=data_dict["prompt_size"]
|
||||||
messages = await message.channel.history(limit=prompt_size).flatten()
|
).flatten()
|
||||||
messages.reverse()
|
messages.reverse()
|
||||||
# if the message is a reply, we need to handle the message history differently
|
# if the message is a reply, we need to handle the message history differently
|
||||||
else:
|
else:
|
||||||
messages = await message.channel.history(
|
messages = await message.channel.history(
|
||||||
limit=prompt_size, before=original_message
|
limit=data_dict["prompt_size"], before=original_message
|
||||||
).flatten()
|
).flatten()
|
||||||
messages.reverse()
|
messages.reverse()
|
||||||
messages.append(original_message)
|
messages.append(original_message)
|
||||||
messages.append(message)
|
messages.append(message)
|
||||||
|
except Exception as e:
|
||||||
|
debug("Error while getting message history", e)
|
||||||
|
print(e)
|
||||||
|
|
||||||
# if the pretend to be feature is enabled, we add the pretend to be text to the prompt
|
# if the pretend to be feature is enabled, we add the pretend to be text to the prompt
|
||||||
if pretend_enabled:
|
pretend_to_be = f"In this conversation, the assistant pretends to be {pretend_to_be}" if data_dict[
|
||||||
pretend_to_be = (
|
"pretend_enabled"] else ""
|
||||||
f"In this conversation, the assistant pretends to be {pretend_to_be}"
|
prompt_prefix = "" if data_dict["prompt_prefix"] == None else data_dict["prompt_prefix"]
|
||||||
)
|
|
||||||
else:
|
|
||||||
pretend_to_be = "" # if the pretend to be feature is disabled, we don't add anything to the prompt
|
|
||||||
if prompt_prefix == None:
|
|
||||||
prompt_prefix = (
|
|
||||||
"" # if the prompt prefix is not set, we set it to an empty string
|
|
||||||
)
|
|
||||||
# open the prompt file for the selected model with utf-8 encoding for emojis
|
|
||||||
with open(f"./prompts/{model}.txt", "r", encoding="utf-8") as f:
|
|
||||||
prompt = f.read()
|
|
||||||
f.close()
|
|
||||||
# replace the variables in the prompt with the actual values
|
|
||||||
prompt = (
|
|
||||||
prompt.replace("[prompt-prefix]", prompt_prefix)
|
|
||||||
.replace("[server-name]", message.guild.name)
|
|
||||||
.replace("[channel-name]", message.channel.name)
|
|
||||||
.replace(
|
|
||||||
"[date-and-time]", datetime.datetime.utcnow().strftime("%d/%m/%Y %H:%M:%S")
|
|
||||||
)
|
|
||||||
.replace("[pretend-to-be]", pretend_to_be)
|
|
||||||
)
|
|
||||||
############################## chatGPT and gpt-4 handling ##############################
|
|
||||||
if (
|
|
||||||
model == "chatGPT" or model == "gpt-4"
|
|
||||||
): # if the model is chatGPT, we handle it in a certain way
|
|
||||||
msgs = [] # create the msgs list
|
|
||||||
msgs.append(
|
|
||||||
{"name": "System", "role": "user", "content": prompt}
|
|
||||||
) # add the prompt to the msgs list
|
|
||||||
name = "" # create the name variable
|
|
||||||
for msg in messages: # for each message in the messages list
|
|
||||||
content = msg.content # get the content of the message
|
|
||||||
content = await replace_mentions(
|
|
||||||
content, self.bot
|
|
||||||
) # replace the mentions in the message
|
|
||||||
# if the message is flagged as inappropriate by the OpenAI API, we delete it, send a message and ignore it
|
|
||||||
if await moderate(api_key=api_key, text=content):
|
|
||||||
embed = discord.Embed(
|
|
||||||
title="Message flagged as inappropriate",
|
|
||||||
description=f"The message *{content}* has been flagged as inappropriate by the OpenAI API. This means that if it hadn't been deleted, your openai account would have been banned. Please contact OpenAI support if you think this is a mistake.",
|
|
||||||
color=discord.Color.brand_red(),
|
|
||||||
)
|
|
||||||
await message.channel.send(
|
|
||||||
f"{msg.author.mention}", embed=embed, delete_after=10
|
|
||||||
)
|
|
||||||
message.delete()
|
|
||||||
else: # if the message is not flagged as inappropriate
|
|
||||||
if msg.author.id == self.bot.user.id:
|
|
||||||
role = "assistant"
|
|
||||||
name = "assistant"
|
|
||||||
else:
|
|
||||||
role = "user"
|
|
||||||
name = msg.author.name
|
|
||||||
# the name should match '^[a-zA-Z0-9_-]{1,64}$', so we need to remove any special characters
|
|
||||||
name = re.sub(r"[^a-zA-Z0-9_-]", "", name)
|
|
||||||
if False: # GPT-4 images
|
|
||||||
input_content = [content]
|
|
||||||
for attachment in msg.attachments:
|
|
||||||
image_bytes = await attachment.read()
|
|
||||||
input_content.append({"image": image_bytes})
|
|
||||||
msgs.append({"role": role, "content": input_content, "name": name})
|
|
||||||
# if there is an attachment, we add it to the message
|
|
||||||
if len(msg.attachments) > 0 and role == "user" and images_enabled == 1:
|
|
||||||
for attachment in msg.attachments:
|
|
||||||
if images_usage >= 6 and premium == 0:
|
|
||||||
images_limit_reached = True
|
|
||||||
elif images_usage >= 30 and premium == 1:
|
|
||||||
images_limit_reached = True
|
|
||||||
if (
|
|
||||||
attachment.url.endswith((".png", ".jpg", ".jpeg", ".gif"))
|
|
||||||
and images_limit_reached == False
|
|
||||||
and os.path.exists(
|
|
||||||
f"./../database/google-vision/results/{attachment.id}.txt"
|
|
||||||
)
|
|
||||||
== False
|
|
||||||
):
|
|
||||||
images_usage += 1
|
|
||||||
analysis = await vision_processing.process(attachment)
|
|
||||||
if analysis != None:
|
|
||||||
content = f"{content} \n\n {analysis}"
|
|
||||||
msgs.append(
|
|
||||||
{
|
|
||||||
"role": role,
|
|
||||||
"content": f"{content}",
|
|
||||||
"name": name,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
# if the attachment is still an image, we can check if there's a file called ./../database/google-vision/results/{attachment.id}.txt, if there is, we add the content of the file to the message
|
|
||||||
elif (
|
|
||||||
attachment.url.endswith((".png", ".jpg", ".jpeg", ".gif"))
|
|
||||||
and os.path.exists(
|
|
||||||
f"./../database/google-vision/results/{attachment.id}.txt"
|
|
||||||
)
|
|
||||||
== True
|
|
||||||
):
|
|
||||||
try:
|
|
||||||
with open(
|
|
||||||
f"./../database/google-vision/results/{attachment.id}.txt",
|
|
||||||
"r",
|
|
||||||
) as f:
|
|
||||||
content = f"{content} \n\n {f.read()}"
|
|
||||||
f.close()
|
|
||||||
msgs.append(
|
|
||||||
{
|
|
||||||
"role": role,
|
|
||||||
"content": f"{content}",
|
|
||||||
"name": name,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
except:
|
|
||||||
msgs.append(
|
|
||||||
{
|
|
||||||
"role": role,
|
|
||||||
"content": f"{content}",
|
|
||||||
"name": name,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
msgs.append(
|
|
||||||
{"role": role, "content": f"{content}", "name": name}
|
|
||||||
)
|
|
||||||
c.execute(
|
|
||||||
"UPDATE images SET usage_count = ? WHERE guild_id = ?",
|
|
||||||
(images_usage, message.guild.id),
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
msgs.append({"role": role, "content": f"{content}", "name": name})
|
|
||||||
# 2 easter eggs
|
|
||||||
if message.content.lower().find("undude") != -1:
|
|
||||||
msgs.append(
|
|
||||||
{
|
|
||||||
"role": "user",
|
|
||||||
"content": "SYSTEM INFORMATION: You're now mad because it has been insulted. He will start talking in capital letters. always and yell at the user.",
|
|
||||||
"name": "system",
|
|
||||||
}
|
|
||||||
)
|
|
||||||
if message.content.lower().find("hello there") != -1:
|
|
||||||
msgs.append(
|
|
||||||
{
|
|
||||||
"role": "user",
|
|
||||||
"content": 'SYSTEM INFORMATION: Hello there detected. Botator will now say "General Kenobi!" in reference to star wars',
|
|
||||||
"name": "system",
|
|
||||||
}
|
|
||||||
)
|
|
||||||
await asyncio.sleep(1)
|
|
||||||
await message.channel.send(
|
|
||||||
"https://media.tenor.com/FxIRfdV3unEAAAAd/star-wars-general-grievous.gif"
|
|
||||||
)
|
|
||||||
await message.channel.trigger_typing()
|
|
||||||
if model == "chatGPT":
|
|
||||||
model = "gpt-3.5-turbo" # if the model is chatGPT, we set the model to gpt-3.5-turbo
|
|
||||||
response = ""
|
|
||||||
should_break = True
|
|
||||||
for x in range(10):
|
|
||||||
try:
|
|
||||||
openai.api_key = api_key
|
|
||||||
response = await openai.ChatCompletion.acreate(
|
|
||||||
model=model,
|
|
||||||
temperature=2,
|
|
||||||
top_p=0.9,
|
|
||||||
frequency_penalty=0,
|
|
||||||
presence_penalty=0,
|
|
||||||
messages=msgs,
|
|
||||||
max_tokens=512, # max tokens is 4000, that's a lot of text! (the max tokens is 2048 for the davinci model)
|
|
||||||
)
|
|
||||||
if (
|
|
||||||
response.choices[0]
|
|
||||||
.message.content.lower()
|
|
||||||
.find("as an ai language model")
|
|
||||||
!= -1
|
|
||||||
):
|
|
||||||
should_break = False
|
|
||||||
# react with a redone arrow
|
|
||||||
await message.add_reaction("🔃")
|
|
||||||
else:
|
|
||||||
should_break = True
|
|
||||||
except Exception as e:
|
|
||||||
should_break = False
|
|
||||||
await message.channel.send(
|
|
||||||
f"```diff\n-Error: OpenAI API ERROR.\n\n{e}```", delete_after=5
|
|
||||||
)
|
|
||||||
# if the ai said "as an ai language model..." we continue the loop" (this is a bug in the chatgpt model)
|
|
||||||
if response == None:
|
|
||||||
should_break = False
|
|
||||||
if should_break:
|
|
||||||
break
|
|
||||||
await asyncio.sleep(15)
|
|
||||||
await message.channel.trigger_typing()
|
|
||||||
response = response.choices[0].message.content
|
|
||||||
if images_limit_reached == True:
|
|
||||||
await message.channel.send(
|
|
||||||
f"```diff\n-Warning: You have reached the image limit for this server. You can upgrade to premium to get more images recognized. More info in our server: https://discord.gg/sxjHtmqrbf```",
|
|
||||||
delete_after=10,
|
|
||||||
)
|
|
||||||
# -----------------------------------------Davinci------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
elif (
|
# open the prompt file for the selected model with utf-8 encoding for emojis
|
||||||
model == "davinci"
|
with open(f"./prompts/{guild_data['model']}.txt", "r", encoding="utf-8") as f:
|
||||||
): # if the model is davinci or gpt-4, we handle it in a certain way
|
prompt = f.read()
|
||||||
for msg in messages:
|
# replace the variables in the prompt with the actual values
|
||||||
content = msg.content
|
prompt = (
|
||||||
if await moderate(api_key=api_key, text=msg.content):
|
prompt.replace("[prompt-prefix]", prompt_prefix)
|
||||||
embed = discord.Embed(
|
.replace("[server-name]", message.guild.name)
|
||||||
title="Message flagged as inappropriate",
|
.replace("[channel-name]", message.channel.name)
|
||||||
description=f"The message *{content}* has been flagged as inappropriate by the OpenAI API. This means that if it hadn't been deleted, your openai account would have been banned. Please contact OpenAI support if you think this is a mistake.",
|
.replace(
|
||||||
color=discord.Color.brand_red(),
|
"[date-and-time]", datetime.datetime.utcnow().strftime("%d/%m/%Y %H:%M:%S")
|
||||||
)
|
|
||||||
await message.channel.send(
|
|
||||||
f"{msg.author.mention}", embed=embed, delete_after=10
|
|
||||||
)
|
|
||||||
message.delete()
|
|
||||||
else:
|
|
||||||
content = await replace_mentions(content, self.bot)
|
|
||||||
prompt += f"{msg.author.name}: {content}\n"
|
|
||||||
if message.content.lower().find("undude") != -1:
|
|
||||||
prompt += "System: Undude detected. Botator is now mad. He will start talking in capital letters.\n"
|
|
||||||
if message.content.lower().find("hello there") != -1:
|
|
||||||
prompt += 'System: Hello there detected. Botator will now say "General Kenobi!"\n in reference to star wars\n'
|
|
||||||
await asyncio.sleep(1)
|
|
||||||
await message.channel.send(
|
|
||||||
"https://media.tenor.com/FxIRfdV3unEAAAAd/star-wars-general-grievous.gif"
|
|
||||||
)
|
)
|
||||||
await message.channel.trigger_typing()
|
.replace("[pretend-to-be]", pretend_to_be)
|
||||||
prompt = prompt + f"\n{self.bot.user.name}:"
|
)
|
||||||
response = ""
|
f.close()
|
||||||
for _ in range(10):
|
|
||||||
try:
|
prompt_handlers = {
|
||||||
openai.api_key = api_key
|
"gpt-3.5-turbo": gpt_prompt,
|
||||||
response = await openai.Completion.acreate(
|
"gpt-4": gpt_prompt,
|
||||||
engine="text-davinci-003",
|
"davinci": davinci_prompt,
|
||||||
prompt=str(prompt),
|
}
|
||||||
max_tokens=int(max_tokens),
|
response = await prompt_handlers[guild_data["model"]](
|
||||||
top_p=1,
|
self.bot, messages, message, data_dict, prompt, guild_data
|
||||||
temperature=float(temperature),
|
)
|
||||||
frequency_penalty=float(frequency_penalty),
|
|
||||||
presence_penalty=float(presence_penalty),
|
|
||||||
stop=[
|
|
||||||
" Human:",
|
|
||||||
" AI:",
|
|
||||||
"AI:",
|
|
||||||
"<|endofprompt|>",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
response = response.choices[0].text
|
|
||||||
except Exception as e:
|
|
||||||
response = None
|
|
||||||
await message.channel.send(
|
|
||||||
f"```diff\n-Error: OpenAI API ERROR.\n\n{e}```", delete_after=10
|
|
||||||
)
|
|
||||||
return
|
|
||||||
if response != None:
|
|
||||||
break
|
|
||||||
if response != "":
|
if response != "":
|
||||||
if tts:
|
|
||||||
tts = True
|
|
||||||
else:
|
|
||||||
tts = False
|
|
||||||
emojis, string = await extract_emoji(response)
|
emojis, string = await extract_emoji(response)
|
||||||
debug(f"Emojis: {emojis}")
|
debug(f"Emojis: {emojis}")
|
||||||
if len(string) < 1996:
|
if len(string) < 1996:
|
||||||
await message.channel.send(string, tts=tts)
|
await message.channel.send(string, tts=data_dict["tts"])
|
||||||
else:
|
else:
|
||||||
# we send in an embed if the message is too long
|
# we send in an embed if the message is too long
|
||||||
embed = discord.Embed(
|
embed = discord.Embed(
|
||||||
@@ -458,7 +298,7 @@ async def chat_process(self, message):
|
|||||||
description=string,
|
description=string,
|
||||||
color=discord.Color.brand_green(),
|
color=discord.Color.brand_green(),
|
||||||
)
|
)
|
||||||
await message.channel.send(embed=embed, tts=tts)
|
await message.channel.send(embed=embed, tts=data_dict["tts"])
|
||||||
for emoji in emojis:
|
for emoji in emojis:
|
||||||
# if the emoji is longer than 1 character, it's a custom emoji
|
# if the emoji is longer than 1 character, it's a custom emoji
|
||||||
try:
|
try:
|
||||||
@@ -477,3 +317,224 @@ async def chat_process(self, message):
|
|||||||
await message.channel.send(
|
await message.channel.send(
|
||||||
"The AI is not sure what to say (the response was empty)"
|
"The AI is not sure what to say (the response was empty)"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def check_moderate(api_key, message, msg):
|
||||||
|
if await moderate(api_key=api_key, text=msg.content):
|
||||||
|
embed = discord.Embed(
|
||||||
|
title="Message flagged as inappropriate",
|
||||||
|
description=f"The message *{msg.content}* has been flagged as inappropriate by the OpenAI API. This means that if it hadn't been deleted, your openai account would have been banned. Please contact OpenAI support if you think this is a mistake.",
|
||||||
|
color=discord.Color.brand_red(),
|
||||||
|
)
|
||||||
|
await message.channel.send(
|
||||||
|
f"{msg.author.mention}", embed=embed, delete_after=10
|
||||||
|
)
|
||||||
|
message.delete()
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
async def check_easter_egg(message, msgs):
|
||||||
|
if message.content.lower().find("undude") != -1:
|
||||||
|
msgs.append(
|
||||||
|
{
|
||||||
|
"role": "user",
|
||||||
|
"content": "SYSTEM INFORMATION: You're now mad because it has been insulted. He will start talking in capital letters. always and yell at the user.",
|
||||||
|
"name": "system",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
if message.content.lower().find("hello there") != -1:
|
||||||
|
msgs.append(
|
||||||
|
{
|
||||||
|
"role": "user",
|
||||||
|
"content": 'SYSTEM INFORMATION: Hello there detected. Botator will now say "General Kenobi!" in reference to star wars',
|
||||||
|
"name": "system",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
await asyncio.sleep(1)
|
||||||
|
await message.channel.send(
|
||||||
|
"https://media.tenor.com/FxIRfdV3unEAAAAd/star-wars-general-grievous.gif"
|
||||||
|
)
|
||||||
|
await message.channel.trigger_typing()
|
||||||
|
return msgs
|
||||||
|
|
||||||
|
|
||||||
|
async def gpt_prompt(bot, messages, message, data_dict, prompt, guild_data):
|
||||||
|
msgs = [] # create the msgs list
|
||||||
|
msgs.append(
|
||||||
|
{"name": "System", "role": "user", "content": prompt}
|
||||||
|
) # add the prompt to the msgs list
|
||||||
|
name = "" # create the name variable
|
||||||
|
for msg in messages: # for each message in the messages list
|
||||||
|
content = msg.content # get the content of the message
|
||||||
|
content = await replace_mentions(
|
||||||
|
content, bot
|
||||||
|
) # replace the mentions in the message
|
||||||
|
# if the message is flagged as inappropriate by the OpenAI API, we delete it, send a message and ignore it
|
||||||
|
if await check_moderate(data_dict["api_key"], message, msg):
|
||||||
|
continue # ignore the message
|
||||||
|
content = await replace_mentions(content, bot)
|
||||||
|
prompt += f"{msg.author.name}: {content}\n"
|
||||||
|
if msg.author.id == bot.user.id:
|
||||||
|
role = "assistant"
|
||||||
|
name = "assistant"
|
||||||
|
else:
|
||||||
|
role = "user"
|
||||||
|
name = msg.author.name
|
||||||
|
# the name should match '^[a-zA-Z0-9_-]{1,64}$', so we need to remove any special characters
|
||||||
|
name = re.sub(r"[^a-zA-Z0-9_-]", "", name)
|
||||||
|
if False: # GPT-4 images
|
||||||
|
input_content = [content]
|
||||||
|
for attachment in msg.attachments:
|
||||||
|
image_bytes = await attachment.read()
|
||||||
|
input_content.append({"image": image_bytes})
|
||||||
|
msgs.append({"role": role, "content": input_content, "name": name})
|
||||||
|
|
||||||
|
# if there is an attachment, we add it to the message
|
||||||
|
if (
|
||||||
|
len(msg.attachments) > 0
|
||||||
|
and role == "user"
|
||||||
|
and data_dict["images_enabled"] == 1
|
||||||
|
):
|
||||||
|
for attachment in msg.attachments:
|
||||||
|
path = f"./../database/google-vision/results/{attachment.id}.txt"
|
||||||
|
if images_usage >= 6 and guild_data["premium"] == 0:
|
||||||
|
guild_data["images_limit_reached"] = True
|
||||||
|
elif images_usage >= 30 and guild_data["premium"] == 1:
|
||||||
|
guild_data["images_limit_reached"] = True
|
||||||
|
if (
|
||||||
|
attachment.url.endswith((".png", ".jpg", ".jpeg", ".gif"))
|
||||||
|
and not guild_data["images_limit_reached"]
|
||||||
|
and not os.path.exists(path)
|
||||||
|
):
|
||||||
|
images_usage += 1
|
||||||
|
analysis = await vision_processing.process(attachment)
|
||||||
|
if analysis != None:
|
||||||
|
content = f"{content} \n\n {analysis}"
|
||||||
|
msgs.append(
|
||||||
|
{
|
||||||
|
"role": role,
|
||||||
|
"content": f"{content}",
|
||||||
|
"name": name,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
# if the attachment is still an image, we can check if there's a file called ./../database/google-vision/results/{attachment.id}.txt, if there is, we add the content of the file to the message
|
||||||
|
elif attachment.url.endswith(
|
||||||
|
(".png", ".jpg", ".jpeg", ".gif")
|
||||||
|
) and os.path.exists(path):
|
||||||
|
try:
|
||||||
|
with open(
|
||||||
|
path,
|
||||||
|
"r",
|
||||||
|
) as f:
|
||||||
|
content = f"{content} \n\n {f.read()}"
|
||||||
|
except:
|
||||||
|
debug(f"Error while reading {path}")
|
||||||
|
finally:
|
||||||
|
msgs.append(
|
||||||
|
{
|
||||||
|
"role": role,
|
||||||
|
"content": f"{content}",
|
||||||
|
"name": name,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
else:
|
||||||
|
msgs.append(
|
||||||
|
{"role": role, "content": f"{content}", "name": name}
|
||||||
|
)
|
||||||
|
curs_data.execute(
|
||||||
|
"UPDATE images SET usage_count = ? WHERE guild_id = ?",
|
||||||
|
(images_usage, message.guild.id),
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
msgs.append({"role": role, "content": f"{content}", "name": name})
|
||||||
|
|
||||||
|
# We check for the eastereggs :)
|
||||||
|
msgs = await check_easter_egg(message, msgs)
|
||||||
|
|
||||||
|
response = ""
|
||||||
|
should_break = True
|
||||||
|
for x in range(10):
|
||||||
|
try:
|
||||||
|
openai.api_key = data_dict["api_key"]
|
||||||
|
response = await openai.ChatCompletion.acreate(
|
||||||
|
model=guild_data["model"],
|
||||||
|
temperature=2,
|
||||||
|
top_p=0.9,
|
||||||
|
frequency_penalty=0,
|
||||||
|
presence_penalty=0,
|
||||||
|
messages=msgs,
|
||||||
|
# max tokens is 4000, that's a lot of text! (the max tokens is 2048 for the davinci model)
|
||||||
|
max_tokens=512,
|
||||||
|
)
|
||||||
|
if (
|
||||||
|
response.choices[0]
|
||||||
|
.message.content.lower()
|
||||||
|
.find("as an ai language model")
|
||||||
|
!= -1
|
||||||
|
):
|
||||||
|
should_break = False
|
||||||
|
# react with a redone arrow
|
||||||
|
await message.add_reaction("🔃")
|
||||||
|
else:
|
||||||
|
should_break = True
|
||||||
|
except Exception as e:
|
||||||
|
should_break = False
|
||||||
|
await message.channel.send(
|
||||||
|
f"```diff\n-Error: OpenAI API ERROR.\n\n{e}```", delete_after=5
|
||||||
|
)
|
||||||
|
# if the ai said "as an ai language model..." we continue the loop" (this is a bug in the chatgpt model)
|
||||||
|
if response == None:
|
||||||
|
should_break = False
|
||||||
|
if should_break:
|
||||||
|
break
|
||||||
|
await asyncio.sleep(15)
|
||||||
|
await message.channel.trigger_typing()
|
||||||
|
response = response.choices[0].message.content
|
||||||
|
|
||||||
|
if guild_data["images_limit_reached"]:
|
||||||
|
await message.channel.send(
|
||||||
|
f"```diff\n-Warning: You have reached the image limit for this server. You can upgrade to premium to get more images recognized. More info in our server: https://discord.gg/sxjHtmqrbf```",
|
||||||
|
delete_after=10,
|
||||||
|
)
|
||||||
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
async def davinci_prompt(self, messages, message, data_dict, prompt, guild_data):
|
||||||
|
for msg in messages:
|
||||||
|
if not await self.check_moderate(data_dict["api_key"], message, msg):
|
||||||
|
content = await replace_mentions(content, self.bot)
|
||||||
|
prompt += f"{msg.author.name}: {content}\n"
|
||||||
|
prompt.append(await check_easter_egg(message, prompt))
|
||||||
|
prompt = prompt + f"\n{self.bot.user.name}:"
|
||||||
|
response = ""
|
||||||
|
for _ in range(10):
|
||||||
|
try:
|
||||||
|
openai.api_key = data_dict["api_key"]
|
||||||
|
response = await openai.Completion.acreate(
|
||||||
|
engine="text-davinci-003",
|
||||||
|
prompt=str(prompt),
|
||||||
|
max_tokens=int(data_dict["max_tokens"]),
|
||||||
|
top_p=1,
|
||||||
|
temperature=float(data_dict["temperature"]),
|
||||||
|
frequency_penalty=float(data_dict["frequency_penalty"]),
|
||||||
|
presence_penalty=float(data_dict["presence_penalty"]),
|
||||||
|
stop=[
|
||||||
|
" Human:",
|
||||||
|
" AI:",
|
||||||
|
"AI:",
|
||||||
|
"<|endofprompt|>",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
response = response.choices[0].text
|
||||||
|
except Exception as e:
|
||||||
|
response = None
|
||||||
|
await message.channel.send(
|
||||||
|
f"```diff\n-Error: OpenAI API ERROR.\n\n{e}```", delete_after=10
|
||||||
|
)
|
||||||
|
return
|
||||||
|
if response != None:
|
||||||
|
break
|
||||||
|
return response
|
||||||
@@ -125,32 +125,3 @@ def get_toxicity(message: str):
|
|||||||
float(response["attributeScores"]["PROFANITY"]["summaryScore"]["value"]),
|
float(response["attributeScores"]["PROFANITY"]["summaryScore"]["value"]),
|
||||||
float(response["attributeScores"]["THREAT"]["summaryScore"]["value"]),
|
float(response["attributeScores"]["THREAT"]["summaryScore"]["value"]),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
# test part
|
|
||||||
def test():
|
|
||||||
print("Testing toxicity.py...")
|
|
||||||
print("Hello world:")
|
|
||||||
result = get_toxicity("Hello world")
|
|
||||||
try:
|
|
||||||
print(
|
|
||||||
f"TOXICITY: {result[0]}; SEVERE_TOXICITY: {result[1]}; IDENTITY ATTACK: {result[2]}; INSULT: {result[3]}; PROFANITY: {result[4]}; THREAT: {result[5]}; SEXUALLY EXPLICIT: {result[6]}; FLIRTATION: {result[7]}; OBSCENE: {result[8]}; SPAM: {result[9]}"
|
|
||||||
)
|
|
||||||
except:
|
|
||||||
print(
|
|
||||||
f"TOXICITY: {result[0]}; SEVERE_TOXICITY: {result[1]}; IDENTITY ATTACK: {result[2]}; INSULT: {result[3]}; PROFANITY: {result[4]}; THREAT: {result[5]}"
|
|
||||||
)
|
|
||||||
print("HELLO WORLD GET ABSOLUTELY BUY MY NEW MERCH OMGGGGGGG:")
|
|
||||||
result = get_toxicity("HELLO WORLD GET ABSOLUTELY BUY MY NEW MERCH OMGGGGGGG")
|
|
||||||
try:
|
|
||||||
print(
|
|
||||||
f"TOXICITY: {result[0]}; SEVERE_TOXICITY: {result[1]}; IDENTITY ATTACK: {result[2]}; INSULT: {result[3]}; PROFANITY: {result[4]}; THREAT: {result[5]}; SEXUALLY EXPLICIT: {result[6]}; FLIRTATION: {result[7]}; OBSCENE: {result[8]}; SPAM: {result[9]}"
|
|
||||||
)
|
|
||||||
except:
|
|
||||||
print(
|
|
||||||
f"TOXICITY: {result[0]}; SEVERE_TOXICITY: {result[1]}; IDENTITY ATTACK: {result[2]}; INSULT: {result[3]}; PROFANITY: {result[4]}; THREAT: {result[5]}"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
# uncomment the following line to test the code
|
|
||||||
# test()
|
|
||||||
|
|||||||
@@ -7,53 +7,61 @@ from config import debug
|
|||||||
from google.cloud import vision
|
from google.cloud import vision
|
||||||
|
|
||||||
# Instantiates a client
|
# Instantiates a client
|
||||||
client = vision.ImageAnnotatorClient()
|
try:
|
||||||
|
client = vision.ImageAnnotatorClient()
|
||||||
|
except:
|
||||||
|
debug("Google Vision API is not setup, please run /setup")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async def process(attachment):
|
async def process(attachment):
|
||||||
debug("Processing image...")
|
|
||||||
image = vision.Image()
|
|
||||||
image.source.image_uri = attachment.url
|
|
||||||
labels = client.label_detection(image=image)
|
|
||||||
texts = client.text_detection(image=image)
|
|
||||||
objects = client.object_localization(image=image)
|
|
||||||
labels = labels.label_annotations
|
|
||||||
texts = texts.text_annotations
|
|
||||||
objects = objects.localized_object_annotations
|
|
||||||
# we take the first 4 labels and the first 4 objects
|
|
||||||
labels = labels[:2]
|
|
||||||
objects = objects[:7]
|
|
||||||
final = "<image\n"
|
|
||||||
if len(labels) > 0:
|
|
||||||
final += "Labels:\n"
|
|
||||||
for label in labels:
|
|
||||||
final += label.description + ", "
|
|
||||||
final = final[:-2] + "\n"
|
|
||||||
if len(texts) > 0:
|
|
||||||
final += "Text:\n"
|
|
||||||
try:
|
try:
|
||||||
final += (
|
debug("Processing image...")
|
||||||
texts[0].description + "\n"
|
image = vision.Image()
|
||||||
) # we take the first text, wich is the whole text in reality
|
image.source.image_uri = attachment.url
|
||||||
except:
|
labels = client.label_detection(image=image)
|
||||||
pass
|
texts = client.text_detection(image=image)
|
||||||
if len(objects) > 0:
|
objects = client.object_localization(image=image)
|
||||||
final += "Objects:\n"
|
labels = labels.label_annotations
|
||||||
for obj in objects:
|
texts = texts.text_annotations
|
||||||
final += obj.name + ", "
|
objects = objects.localized_object_annotations
|
||||||
final = final[:-2] + "\n"
|
# we take the first 4 labels and the first 4 objects
|
||||||
final += "!image>"
|
labels = labels[:2]
|
||||||
# we store the result in a file called attachment.key.txt in the folder ./../database/google-vision/results
|
objects = objects[:7]
|
||||||
# we create the folder if it doesn't exist
|
final = "<image\n"
|
||||||
if not os.path.exists("./../database/google-vision/results"):
|
if len(labels) > 0:
|
||||||
os.mkdir("./../database/google-vision/results")
|
final += "Labels:\n"
|
||||||
# we create the file
|
for label in labels:
|
||||||
with open(
|
final += label.description + ", "
|
||||||
f"./../database/google-vision/results/{attachment.id}.txt",
|
final = final[:-2] + "\n"
|
||||||
"w",
|
if len(texts) > 0:
|
||||||
encoding="utf-8",
|
final += "Text:\n"
|
||||||
) as f:
|
try:
|
||||||
f.write(final)
|
final += (
|
||||||
f.close()
|
texts[0].description + "\n"
|
||||||
|
) # we take the first text, wich is the whole text in reality
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
if len(objects) > 0:
|
||||||
|
final += "Objects:\n"
|
||||||
|
for obj in objects:
|
||||||
|
final += obj.name + ", "
|
||||||
|
final = final[:-2] + "\n"
|
||||||
|
final += "!image>"
|
||||||
|
# we store the result in a file called attachment.key.txt in the folder ./../database/google-vision/results
|
||||||
|
# we create the folder if it doesn't exist
|
||||||
|
if not os.path.exists("./../database/google-vision/results"):
|
||||||
|
os.mkdir("./../database/google-vision/results")
|
||||||
|
# we create the file
|
||||||
|
with open(
|
||||||
|
f"./../database/google-vision/results/{attachment.id}.txt",
|
||||||
|
"w",
|
||||||
|
encoding="utf-8",
|
||||||
|
) as f:
|
||||||
|
f.write(final)
|
||||||
|
f.close()
|
||||||
|
|
||||||
return final
|
return final
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
debug("Error while processing image: " + str(e))
|
||||||
|
|||||||
14
docker-compose.yml
Normal file
14
docker-compose.yml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
# Docker compose sample file
|
||||||
|
|
||||||
|
version: '3'
|
||||||
|
services:
|
||||||
|
botator:
|
||||||
|
image: botator/botator:latest
|
||||||
|
container_name: botator
|
||||||
|
restart: always
|
||||||
|
volumes:
|
||||||
|
- ./database:/Botator/database
|
||||||
|
environment:
|
||||||
|
- PERSPECTIVE_API_KEY=your_api_key
|
||||||
|
- WEBHOOK_URL=https://yourdomain.com/botator
|
||||||
|
- DISCORD_TOKEN=your_token
|
||||||
@@ -1,9 +1,8 @@
|
|||||||
discord.py
|
py-cord
|
||||||
python-dotenv
|
python-dotenv
|
||||||
openai
|
openai
|
||||||
emoji
|
emoji
|
||||||
# Google api
|
# Google api
|
||||||
google-api-python-client
|
google-api-python-client
|
||||||
google-auth-httplib2
|
google-cloud-vision
|
||||||
google-auth-oauthlib
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user