first commit

This commit is contained in:
ForeverPyrite
2025-02-20 22:48:49 -05:00
commit 2e23dffe3d
7 changed files with 230 additions and 0 deletions

123
app.py Normal file
View File

@@ -0,0 +1,123 @@
import os
import logging
from dotenv import load_dotenv
import discord
from discord import Bot
from openai import OpenAI
from asyncio import run
from apscheduler.schedulers.background import BackgroundScheduler
from students import STUDENTS
from quotes import QUOTES, select_quote, select_student
# Logging.
logging.basicConfig(
filename="./logs/jacobs.log",
filemode="at+",
level=logging.DEBUG
)
logger = logging.getLogger(__name__)
DISCORD_TOKEN = os.getenv('DISCORD_TOKEN')
OPENAI_KEY = os.getenv('OPENAI_KEY')
# Discord
bot = Bot(intents=discord.Intents.default())
SERVER_ID: int = 1339601046745645148
GENERAL_ID: int = 1339601047294840876
ch_general = None
async def get_general():
global ch_general
global bot
if not ch_general:
ch_general = await bot.fetch_channel(GENERAL_ID)
if not ch_general:
raise(ValueError("General channel object should *not* be none!"))
return ch_general
async def send_quote(quote: str = None) -> None:
await get_general()
if not quote:
quote = select_quote()
logger.info(f"Sending quote {quote} in #general...")
await ch_general.send(quote)
async def after_class(student: int = None) -> None:
global ch_general
if not student:
student = select_quote()
logger.info(f"Sending mention to see {student} after class to #general...")
await ch_general.send(f"Come see me after class <@{student}>")
# OpenAI & Assistant configuration
client = OpenAI(
api_key=OPENAI_KEY,
project="proj_vUQ7duhKKc1jxIqllRhy6DVJ",
)
mr_jacobs = client.beta.assistants.retrieve("asst_KdPdwqNAKijujfyCRrJCOgJN")
base_instructions = mr_jacobs.instructions
instructions = base_instructions + f"\n\nHere is a dictionary containing some of your most well known quotes, organized by their frequency: \n{QUOTES}\n\nStudent: "
def get_run_status(run):
status = client.beta.threads.runs.retrieve(
run.id,
thread_id=run.thread_id
).status
logger.info(f"Status of run {run.id} is {status}")
return status
def get_instructions(student: int | None = None) -> str:
logging.info(f"Looking for {student} in students...")
if student in STUDENTS:
return instructions + STUDENTS.get(student)
else:
logging.warning(f"Couldn't find {student}")
return instructions + "Unknown"
async def run_message(run):
# ew but Python doesn't have a do while and it's less ugly than the same statement twice.
while True:
complete = get_run_status(run) == "completed"
if complete:
break
thread_messages = client.beta.threads.messages.list(run.thread_id)
for msg_ob in thread_messages.data:
if msg_ob.id == thread_messages.first_id:
response = msg_ob.content[0].text.value
return response
raise Exception(f"bro what did you do dumbass, figure it out.:\nThread Messages List:\n{thread_messages}")
@bot.slash_command(description="Talk to Mr. Jacobs!!!")
async def message(ctx: discord.ApplicationContext, text: str):
logging.info(f"User {ctx.author.global_name} sent message {text}")
instructions = get_instructions(ctx.author.id)
bot_reply = await ctx.respond("*hmmmm*...let me see here...")
run = client.beta.threads.create_and_run(
assistant_id=mr_jacobs.id,
instructions=instructions,
thread={
"messages": [
{
"role": "user",
"content": text
}
]
}
)
response = await run_message(run)
await bot_reply.edit_original_response(content=response)
# After successful initilization, schedule tasks.
task_scheduler = BackgroundScheduler()
task_scheduler.add_job(lambda: bot.loop.create_task(send_quote()), 'cron', day_of_week='mon-fri', hour=8, minute=50)
task_scheduler.add_job(lambda: bot.loop.create_task(send_quote()), 'cron', day_of_week='mon-fri', hour='8-14', minute="*/20", jitter=180)
task_scheduler.add_job(lambda: bot.loop.create_task(after_class()), 'cron', day_of_week='mon-fri', hour=10, minute=55)
task_scheduler.start()
logger.info(f"Presumably successfully initilized, starting bot.")
bot.run(DISCORD_TOKEN)