Add slash command
This commit is contained in:
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@ -3,6 +3,8 @@
|
|||||||
"anewdawn",
|
"anewdawn",
|
||||||
"asctime",
|
"asctime",
|
||||||
"audioop",
|
"audioop",
|
||||||
|
"automerge",
|
||||||
|
"buildx",
|
||||||
"docstrings",
|
"docstrings",
|
||||||
"dotenv",
|
"dotenv",
|
||||||
"forgefilip",
|
"forgefilip",
|
||||||
@ -17,6 +19,7 @@
|
|||||||
"plubplub",
|
"plubplub",
|
||||||
"pycodestyle",
|
"pycodestyle",
|
||||||
"pydocstyle",
|
"pydocstyle",
|
||||||
|
"pyproject",
|
||||||
"PYTHONDONTWRITEBYTECODE",
|
"PYTHONDONTWRITEBYTECODE",
|
||||||
"PYTHONUNBUFFERED",
|
"PYTHONUNBUFFERED",
|
||||||
"testpaths",
|
"testpaths",
|
||||||
|
90
main.py
90
main.py
@ -3,7 +3,6 @@ from __future__ import annotations
|
|||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
import hikari
|
import hikari
|
||||||
import lightbulb
|
import lightbulb
|
||||||
@ -11,8 +10,7 @@ import openai
|
|||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
from openai import OpenAI
|
from openai import OpenAI
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
from misc import chat, get_allowed_users, get_trigger_keywords
|
||||||
from openai.types.chat.chat_completion import ChatCompletion
|
|
||||||
|
|
||||||
logger: logging.Logger = logging.getLogger(__name__)
|
logger: logging.Logger = logging.getLogger(__name__)
|
||||||
logger.setLevel(logging.DEBUG)
|
logger.setLevel(logging.DEBUG)
|
||||||
@ -26,49 +24,47 @@ if not discord_token or not openai_api_key:
|
|||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
bot = lightbulb.BotApp(token=discord_token, intents=hikari.Intents.GUILD_MESSAGES | hikari.Intents.GUILD_MESSAGE_TYPING)
|
bot = hikari.GatewayBot(
|
||||||
|
token=discord_token,
|
||||||
|
intents=hikari.Intents.GUILD_MESSAGES | hikari.Intents.GUILD_MESSAGE_TYPING,
|
||||||
|
logs="INFO",
|
||||||
|
)
|
||||||
|
bot_client: lightbulb.GatewayEnabledClient = lightbulb.client_from_app(bot)
|
||||||
|
bot.subscribe(hikari.StartingEvent, bot_client.start)
|
||||||
|
|
||||||
openai_client = OpenAI(api_key=openai_api_key)
|
openai_client = OpenAI(api_key=openai_api_key)
|
||||||
|
|
||||||
|
|
||||||
def chat(user_message: str) -> str | None:
|
@bot_client.register(guilds=[hikari.Snowflake(98905546077241344), hikari.Snowflake(341001473661992962)])
|
||||||
"""Chat with the bot using the OpenAI API.
|
class Ask(
|
||||||
|
lightbulb.SlashCommand,
|
||||||
|
name="ask",
|
||||||
|
description="Ask the AI a question.",
|
||||||
|
):
|
||||||
|
"""A command to ask the AI a question."""
|
||||||
|
|
||||||
Args:
|
text: str = lightbulb.string("text", "The question or message to ask the AI.")
|
||||||
user_message: The message to send to OpenAI.
|
|
||||||
|
|
||||||
Returns:
|
@lightbulb.invoke
|
||||||
The response from the AI model.
|
async def invoke(self, ctx: lightbulb.Context) -> None:
|
||||||
"""
|
"""Handle the /ask command."""
|
||||||
completion: ChatCompletion = openai_client.chat.completions.create(
|
user_message: str = self.text
|
||||||
model="gpt-4o-mini",
|
|
||||||
messages=[
|
|
||||||
{
|
|
||||||
"role": "developer",
|
|
||||||
"content": "You are in a Discord group chat with people above the age of 30. Use Discord Markdown to format messages if needed.", # noqa: E501
|
|
||||||
},
|
|
||||||
{"role": "user", "content": user_message},
|
|
||||||
],
|
|
||||||
)
|
|
||||||
response: str | None = completion.choices[0].message.content
|
|
||||||
logger.info("AI response: %s", response)
|
|
||||||
|
|
||||||
return response
|
if not user_message:
|
||||||
|
await ctx.respond("You need to provide a question or message.")
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
response: str | None = chat(user_message, openai_client)
|
||||||
|
except openai.OpenAIError as e:
|
||||||
|
logger.exception("An error occurred while chatting with the AI model.")
|
||||||
|
await ctx.respond(f"An error occurred: {e}")
|
||||||
|
return
|
||||||
|
|
||||||
def get_allowed_users() -> list[str]:
|
if response:
|
||||||
"""Get the list of allowed users to interact with the bot.
|
await ctx.respond(response)
|
||||||
|
else:
|
||||||
Returns:
|
await ctx.respond("I forgor how to think 💀")
|
||||||
The list of allowed users.
|
|
||||||
"""
|
|
||||||
return [
|
|
||||||
"thelovinator",
|
|
||||||
"killyoy",
|
|
||||||
"forgefilip",
|
|
||||||
"plubplub",
|
|
||||||
"nobot",
|
|
||||||
"kao172",
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
@bot.listen(hikari.MessageCreateEvent)
|
@bot.listen(hikari.MessageCreateEvent)
|
||||||
@ -89,13 +85,13 @@ async def on_message(event: hikari.MessageCreateEvent) -> None:
|
|||||||
return
|
return
|
||||||
|
|
||||||
lowercase_message: str = incoming_message.lower() if incoming_message else ""
|
lowercase_message: str = incoming_message.lower() if incoming_message else ""
|
||||||
trigger_keywords: list[str] = get_trigger_keywords()
|
trigger_keywords: list[str] = get_trigger_keywords(bot)
|
||||||
if any(trigger in lowercase_message for trigger in trigger_keywords):
|
if any(trigger in lowercase_message for trigger in trigger_keywords):
|
||||||
logger.info("Received message: %s from: %s", incoming_message, event.author.username)
|
logger.info("Received message: %s from: %s", incoming_message, event.author.username)
|
||||||
|
|
||||||
async with bot.rest.trigger_typing(event.channel_id):
|
async with bot.rest.trigger_typing(event.channel_id):
|
||||||
try:
|
try:
|
||||||
response: str | None = chat(incoming_message)
|
response: str | None = chat(incoming_message, openai_client)
|
||||||
except openai.OpenAIError as e:
|
except openai.OpenAIError as e:
|
||||||
logger.exception("An error occurred while chatting with the AI model.")
|
logger.exception("An error occurred while chatting with the AI model.")
|
||||||
e.add_note(f"Message: {incoming_message}\nEvent: {event}\nWho: {event.author.username}")
|
e.add_note(f"Message: {incoming_message}\nEvent: {event}\nWho: {event.author.username}")
|
||||||
@ -112,18 +108,6 @@ async def on_message(event: hikari.MessageCreateEvent) -> None:
|
|||||||
await bot.rest.create_message(event.channel_id, "I forgor how to think 💀")
|
await bot.rest.create_message(event.channel_id, "I forgor how to think 💀")
|
||||||
|
|
||||||
|
|
||||||
def get_trigger_keywords() -> list[str]:
|
|
||||||
"""Get the list of trigger keywords to respond to.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
The list of trigger keywords.
|
|
||||||
"""
|
|
||||||
bot_user: hikari.OwnUser | None = bot.get_me()
|
|
||||||
bot_mention_string: str = f"<@{bot_user.id}>" if bot_user else ""
|
|
||||||
notification_keywords: list[str] = ["lovibot", bot_mention_string]
|
|
||||||
return notification_keywords
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
logger.info("Starting the bot.")
|
logger.info("Starting the bot.")
|
||||||
bot.run(asyncio_debug=True, check_for_updates=True)
|
bot.run()
|
||||||
|
66
misc.py
Normal file
66
misc.py
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import logging
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
import hikari
|
||||||
|
from openai import OpenAI
|
||||||
|
from openai.types.chat.chat_completion import ChatCompletion
|
||||||
|
|
||||||
|
|
||||||
|
logger: logging.Logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def get_allowed_users() -> list[str]:
|
||||||
|
"""Get the list of allowed users to interact with the bot.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The list of allowed users.
|
||||||
|
"""
|
||||||
|
return [
|
||||||
|
"thelovinator",
|
||||||
|
"killyoy",
|
||||||
|
"forgefilip",
|
||||||
|
"plubplub",
|
||||||
|
"nobot",
|
||||||
|
"kao172",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def get_trigger_keywords(bot: hikari.GatewayBotAware) -> list[str]:
|
||||||
|
"""Get the list of trigger keywords to respond to.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The list of trigger keywords.
|
||||||
|
"""
|
||||||
|
bot_user: hikari.OwnUser | None = bot.get_me()
|
||||||
|
bot_mention_string: str = f"<@{bot_user.id}>" if bot_user else ""
|
||||||
|
notification_keywords: list[str] = ["lovibot", bot_mention_string]
|
||||||
|
return notification_keywords
|
||||||
|
|
||||||
|
|
||||||
|
def chat(user_message: str, openai_client: OpenAI) -> str | None:
|
||||||
|
"""Chat with the bot using the OpenAI API.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
user_message: The message to send to OpenAI.
|
||||||
|
openai_client: The OpenAI client to use.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The response from the AI model.
|
||||||
|
"""
|
||||||
|
completion: ChatCompletion = openai_client.chat.completions.create(
|
||||||
|
model="gpt-4o-mini",
|
||||||
|
messages=[
|
||||||
|
{
|
||||||
|
"role": "developer",
|
||||||
|
"content": "You are in a Discord group chat with people above the age of 30. Use Discord Markdown to format messages if needed.", # noqa: E501
|
||||||
|
},
|
||||||
|
{"role": "user", "content": user_message},
|
||||||
|
],
|
||||||
|
)
|
||||||
|
response: str | None = completion.choices[0].message.content
|
||||||
|
logger.info("AI response: %s", response)
|
||||||
|
|
||||||
|
return response
|
@ -4,7 +4,12 @@ version = "0.1.0"
|
|||||||
description = "My shit bot"
|
description = "My shit bot"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
requires-python = ">=3.13"
|
requires-python = ">=3.13"
|
||||||
dependencies = ["hikari-lightbulb", "hikari", "openai", "python-dotenv"]
|
dependencies = [
|
||||||
|
"hikari-lightbulb>=3.0.0a15",
|
||||||
|
"hikari",
|
||||||
|
"openai",
|
||||||
|
"python-dotenv",
|
||||||
|
]
|
||||||
|
|
||||||
[dependency-groups]
|
[dependency-groups]
|
||||||
dev = ["pytest-asyncio", "pytest", "ruff"]
|
dev = ["pytest-asyncio", "pytest", "ruff"]
|
||||||
|
Reference in New Issue
Block a user