2025-01-03 01:22:32 +00:00
import os
import discord
from discord . ext import commands
import openai
2025-01-03 01:53:16 +00:00
from openai import OpenAI
2025-01-03 01:22:32 +00:00
from collections import deque
from dotenv import load_dotenv
# Load environment variables
load_dotenv ( )
# Get environment variables
DISCORD_TOKEN = os . getenv ( ' DISCORD_TOKEN ' )
OPENAI_API_KEY = os . getenv ( ' OPENAI_API_KEY ' )
OPENWEBUI_API_BASE = os . getenv ( ' OPENWEBUI_API_BASE ' )
MODEL_NAME = os . getenv ( ' MODEL_NAME ' )
2025-01-03 01:53:16 +00:00
# Configure OpenAI client to point to OpenWebUI
client = OpenAI (
api_key = os . getenv ( ' OPENAI_API_KEY ' ) ,
base_url = os . getenv ( ' OPENWEBUI_API_BASE ' ) # e.g., "http://localhost:8080/v1"
)
2025-01-03 01:22:32 +00:00
# Configure OpenAI
2025-01-03 01:53:16 +00:00
# TODO: The 'openai.api_base' option isn't read in the client API. You will need to pass it when you instantiate the client, e.g. 'OpenAI(base_url=OPENWEBUI_API_BASE)'
# openai.api_base = OPENWEBUI_API_BASE
2025-01-03 01:22:32 +00:00
# Initialize Discord bot
intents = discord . Intents . default ( )
intents . message_content = True
intents . messages = True
bot = commands . Bot ( command_prefix = ' ! ' , intents = intents )
# Message history cache
channel_history = { }
async def get_chat_history ( channel , limit = 100 ) :
messages = [ ]
async for message in channel . history ( limit = limit ) :
messages . append ( f " { message . author . name } : { message . content } " )
return " \n " . join ( reversed ( messages ) )
async def get_ai_response ( context , user_message ) :
formatted_prompt = f " ##CONTEXT## \n { context } \n ##ENDCONTEXT## \n \n { user_message } "
2025-01-03 01:53:16 +00:00
2025-01-03 01:22:32 +00:00
try :
2025-01-03 01:53:16 +00:00
response = client . chat . completions . create ( model = MODEL_NAME ,
messages = [
{ " role " : " user " , " content " : formatted_prompt }
] )
2025-01-03 01:22:32 +00:00
return response . choices [ 0 ] . message . content
except Exception as e :
return f " Error: { str ( e ) } "
@bot.event
async def on_ready ( ) :
print ( f ' { bot . user } has connected to Discord! ' )
@bot.event
async def on_message ( message ) :
# Ignore messages from the bot itself
if message . author == bot . user :
return
should_respond = False
2025-01-03 01:53:16 +00:00
2025-01-03 01:22:32 +00:00
# Check if bot was mentioned
if bot . user in message . mentions :
should_respond = True
2025-01-03 01:53:16 +00:00
2025-01-03 01:22:32 +00:00
# Check if message is a DM
if isinstance ( message . channel , discord . DMChannel ) :
should_respond = True
if should_respond :
async with message . channel . typing ( ) :
# Get chat history
history = await get_chat_history ( message . channel )
2025-01-03 01:53:16 +00:00
2025-01-03 01:22:32 +00:00
# Remove bot mention from the message
user_message = message . content . replace ( f ' <@ { bot . user . id } > ' , ' ' ) . strip ( )
2025-01-03 01:53:16 +00:00
2025-01-03 01:22:32 +00:00
# Get AI response
response = await get_ai_response ( history , user_message )
2025-01-03 01:53:16 +00:00
2025-01-03 01:22:32 +00:00
# Send response
await message . reply ( response )
await bot . process_commands ( message )
def main ( ) :
if not all ( [ DISCORD_TOKEN , OPENAI_API_KEY , OPENWEBUI_API_BASE , MODEL_NAME ] ) :
print ( " Error: Missing required environment variables " )
return
2025-01-03 01:53:16 +00:00
2025-01-03 01:22:32 +00:00
bot . run ( DISCORD_TOKEN )
if __name__ == " __main__ " :
main ( )