-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathfaqqer_bot_discord.py
More file actions
118 lines (102 loc) · 4.08 KB
/
faqqer_bot_discord.py
File metadata and controls
118 lines (102 loc) · 4.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import os
import logging
import discord
from discord import app_commands
from discord.ext import commands
import openai
from dotenv import load_dotenv
import json
import requests
# Load environment variables from the .env file
load_dotenv()
# Discord bot token and OpenAI API key
DISCORD_BOT_TOKEN = os.getenv("DISCORD_BOT_TOKEN")
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
GUILD_ID = int(os.getenv("GUILD_ID", "0")) # Replace with your server's ID or set in .env
openai.api_key = OPENAI_API_KEY
# Set up logging configuration
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s - %(levelname)s - %(message)s",
handlers=[logging.StreamHandler()]
)
# Load the FAQ content
faq_file_path = 'faq_prompt.txt'
avoidance_faq_file_path = 'avoidance_faq_prompt.txt'
with open(faq_file_path, 'r', encoding='utf-8') as faq_file:
faq_text = faq_file.read()
with open(avoidance_faq_file_path, 'r', encoding='utf-8') as avoidance_file:
faq_avoidance_text = avoidance_file.read()
# Initialize the bot
intents = discord.Intents.default()
bot = commands.Bot(command_prefix="!", intents=intents)
# Function to query OpenAI GPT and handle errors
async def query_openai_gpt(system, faq_avoidance_text, prompt):
system_prompt = (
f"{system}\n\n"
f"Do not talk about the following topics:\n"
f"{faq_avoidance_text}\n\n"
f"If you do not know the answer with certainty, tell the user that their question will be forwarded to support staff."
)
try:
response = openai.ChatCompletion.create(
model="gpt-4",
temperature=0.4,
messages=[
{"role": "system", "content": system_prompt},
{"role": "user", "content": prompt}
],
)
result = response.choices[0].message.content
logging.info(f"OpenAI response: {result}")
return result
except openai.error.OpenAIError as e:
logging.error(f"OpenAI API error: {e}")
return "Sorry, I encountered an error while trying to answer your question. Please try again."
# Function to find FAQ answers
async def find_faq_answer(question):
prompt = f"""
Search the FAQ for the answer.
Avoid mentioning banned topics.
Question: {question}
Answer in JSON format: {{'answer': '<answer>'}}
"""
answer = await query_openai_gpt(faq_text, faq_avoidance_text, prompt)
if answer:
try:
logging.info(f"Raw OpenAI response: {answer}")
sanitized_answer = answer.replace("'", '"') # Ensure valid JSON
answer_json = json.loads(sanitized_answer)
return answer_json.get('answer', "There was an error processing your request.")
except json.JSONDecodeError as e:
logging.error(f"Error decoding JSON response: {e}")
return "There was an error processing your request."
else:
return "No answer was found."
# Slash command: /faq
@bot.tree.command(name="faq", description="Ask a FAQ question.")
async def faq(interaction: discord.Interaction, question: str):
logging.info(f"Received question: {question}")
answer = await find_faq_answer(question)
await interaction.response.send_message(answer)
# Slash command: /ask (alias for /faq)
@bot.tree.command(name="ask", description="Alias for FAQ.")
async def ask(interaction: discord.Interaction, question: str):
await faq(interaction, question=question)
# Slash command: /faqqer (another alias)
@bot.tree.command(name="faqqer", description="Alias for FAQ.")
async def faqqer(interaction: discord.Interaction, question: str):
await faq(interaction, question=question)
@bot.event
async def on_ready():
logging.info(f"Bot ready! Application ID: {bot.application_id}")
try:
commands = await bot.tree.sync(guild=discord.Object(id=GUILD_ID))
logging.info(f"Synced {len(commands)} commands: {[cmd.name for cmd in commands]}")
except discord.errors.Forbidden:
logging.error("Missing permissions to sync commands")
except Exception as e:
logging.error(f"Error syncing commands: {e}")
# Run the bot
if __name__ == '__main__':
bot.run(DISCORD_BOT_TOKEN)