substitui a implementação dos dois jsons(guild_histories e guild_configs) para utilização de mongodb localmente ao inves de jsons:

import json

import discord

from discord import app_commands

from dotenv import load_dotenv

import os

from commands import setup_commands

from model import setup_model, generate_response, remove_message_from_history, update_message_in_history

from error_handler import handle_error, log_error

import asyncio

import time

import aiofiles

Load environment variables
load_dotenv()

TOKEN = os.getenv('DISCORD_TOKEN')

GEMINI_API_KEY = os.getenv('GEMINI_API_KEY')

intents = discord.Intents.default()

intents.message_content = True

client = discord.Client(intents=intents)

tree = app_commands.CommandTree(client)

Default configurations
DEFAULT_CONFIG = {

"temperature": 1.0,

"top_p": 0.95,

"top_k": 64,

"max_output_tokens": 1024,

"system_instruction": "",

"max_history": 10000,

"first_time": True,

"safety_settings": {

"HARM_CATEGORY_SEXUALLY_EXPLICIT": "BLOCK_ONLY_HIGH",

"HARM_CATEGORY_HATE_SPEECH": "BLOCK_ONLY_HIGH",

"HARM_CATEGORY_HARASSMENT": "BLOCK_ONLY_HIGH",

"HARM_CATEGORY_DANGEROUS_CONTENT": "BLOCK_ONLY_HIGH"

},

"allowed_channels": [],

"require_mention": False,

"model_name": "gemini-1.5-flash"

}

Dictionaries to store configurations and history per guild
guild_configs = {}

guild_histories = {}

dm_error_sent = {}

Helper functions
async def load_guild_configs():

try:

async with aiofiles.open('guild_configs.json', 'r') as f:

return json.loads(await f.read())

except FileNotFoundError:

return {}

async def save_guild_configs():

async with aiofiles.open('guild_configs.json', 'w') as f:

await f.write(json.dumps(guild_configs, indent=4))

async def load_guild_histories():

try:

async with aiofiles.open('guild_histories.json', 'r') as f:

return json.loads(await f.read())

except FileNotFoundError:

return {}

async def save_guild_histories():

async with aiofiles.open('guild_histories.json', 'w') as f:

await f.write(json.dumps(guild_histories, indent=4))

def get_guild_config(guild_id):

if guild_id not in guild_configs:

guild_configs[guild_id] = DEFAULT_CONFIG.copy()

return guild_configs[guild_id]

def get_guild_history(guild_id):

if guild_id not in guild_histories:

guild_histories[guild_id] = []

return guild_histories[guild_id]

async def update_guild_history(guild_id, message, message_id):

history = get_guild_history(guild_id)

# Check if the message already exists in history
existing_message = next((item for item in history if item["message_id"] == message_id), None)

if existing_message:
    # Update existing message
    existing_message["content"] = message
else:
    # Add new message
    history.append({"content": message, "message_id": message_id})

if len(history) > get_guild_config(guild_id)["max_history"]:
    history.pop(0)
await save_guild_histories()
New function to split long messages
def split_message(message, max_length=2000):

if len(message) <= max_length:

return [message]

parts = []
while len(message) > max_length:
    split_index = message.rfind(' ', 0, max_length)
    if split_index == -1:
        split_index = max_length
    parts.append(message[:split_index])
    message = message[split_index:].lstrip()

if message:
    parts.append(message)

return parts
Bot initialization
@client.event

async def on_ready():

global guild_configs, guild_histories

guild_configs = await load_guild_configs()

guild_histories = await load_guild_histories()

setup_model(GEMINI_API_KEY)

setup_commands(tree, get_guild_config, save_guild_configs, get_guild_history, save_guild_histories)

try:

await tree.sync()

print("Commands Synced!")

except discord.errors.HTTPException as e:

print(f"Error syncing commands: {e}")

print(f'{client.user} has connected to Discord!')

Message event to interact with the Gemini model
@client.event

async def on_message(message):

if message.author == client.user:

return

# Check if the message is a DM
if isinstance(message.channel, discord.DMChannel):
    # Check if the user has already received the error message
    if message.author.id not in dm_error_sent:
        await message.channel.send("Sorry, Alicia is not available for use in direct messages")
        dm_error_sent[message.author.id] = True
    return

guild_config = get_guild_config(str(message.guild.id))

if message.channel.id not in guild_config["allowed_channels"]:
    return

if guild_config["require_mention"] and client.user not in message.mentions:
    return

# Add user's message to history
await update_guild_history(str(message.guild.id), {"role": "user", "parts": [f"{message.author.display_name}: {message.content}"]}, message.id)

start_time = time.time()
max_retry_time = 60  # 1 minute

while time.time() - start_time < max_retry_time:
    try:
        response = await generate_response(message, message.guild.id, get_guild_config, get_guild_history)
        
        # Split the response if it's too long
        response_parts = split_message(response)
        bot_messages = []
        
        for part in response_parts:
            bot_message = await message.channel.send(part)
            bot_messages.append(bot_message)
        
        # Add bot's response to history with its message ID(s)
        full_response = {"role": "model", "parts": [response]}
        for bot_message in bot_messages:
            await update_guild_history(str(message.guild.id), full_response, bot_message.id)
        
        return
    except Exception as e:
        log_error(e)
        error_result = await handle_error(e, message.channel)
        if error_result is not None:  # If it's not an InternalServerError, stop retrying
            return
        await asyncio.sleep(1)  # Wait for 1 second before retrying

# If we've exhausted all retries
await message.channel.send(embed=discord.Embed(title="Error", description="I'm sorry, but I couldn't get a response after trying for a minute. Please try again later.", color=discord.Color.red()))
@client.event

async def on_message_edit(before, after):

if after.author == client.user:

return

guild_config = get_guild_config(str(after.guild.id))
if after.channel.id not in guild_config["allowed_channels"]:
    return

await update_message_in_history(str(after.guild.id), after.id, {"role": "user", "parts": [f"{after.author.display_name}: {after.content}"]}, get_guild_history, save_guild_histories)
@client.event

async def on_message_delete(message):

guild_config = get_guild_config(str(message.guild.id))

if message.channel.id not in guild_config["allowed_channels"]:

return

await remove_message_from_history(str(message.guild.id), message.id, get_guild_history, save_guild_histories)
Start the bot
client.run(TOKEN)