Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions BotSecrets.json.template
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"WeatherKey": "",
"GeocodeKey": "",
"AzureTranslateKey": "",
"ApiNinjasKey" : "",
"ClassArchiveCategoryIds": [],
"ClassNotifsChannelId": ""
}
15 changes: 15 additions & 0 deletions bot/bot_secrets.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ def __init__(self) -> None:
self._weather_key: str | None = None
self._geocode_key: str | None = None
self._azure_translate_key: str | None = None
self._api_ninjas_key: str | None = None
self._startup_log_channel_ids: list[int] | None = None
self._error_log_channel_ids: list[int] | None = None
self._class_archive_category_ids: list[int] | None = None
Expand Down Expand Up @@ -151,6 +152,18 @@ def azure_translate_key(self, value: str | None) -> None:
raise ConfigAccessError("azure_translate_key has already been initialized")
self._azure_translate_key = value

@property
def api_ninjas_key(self) -> str:
if not self._api_ninjas_key:
raise ConfigAccessError("api_ninjas_key has not been initialized")
return self._api_ninjas_key

@api_ninjas_key.setter
def api_ninjas_key(self, value: str | None) -> None:
if self._api_ninjas_key:
raise ConfigAccessError("api_ninjas_key has already been initialized")
self._api_ninjas_key = value

@property
def class_archive_category_ids(self) -> list[int]:
if not self._class_archive_category_ids:
Expand Down Expand Up @@ -188,6 +201,7 @@ def load_development_secrets(self, lines: str) -> None:
self.weather_key = secrets["WeatherKey"]
self.geocode_key = secrets["GeocodeKey"]
self.azure_translate_key = secrets["AzureTranslateKey"]
self.api_ninjas_key = secrets["ApiNinjasKey"]
self.class_archive_category_ids = secrets["ClassArchiveCategoryIds"]
self.class_notifs_channel_id = secrets["ClassNotifsChannelId"]

Expand All @@ -210,6 +224,7 @@ def load_production_secrets(self) -> None:
self.weather_key = os.environ.get("WEATHER_KEY") # type: ignore
self.geocode_key = os.environ.get("GEOCODE_KEY") # type: ignore
self.azure_translate_key = os.environ.get("AZURE_TRANSLATE_KEY") # type: ignore
self.api_ninjas_key = os.environ.get("API_NINJAS_KEY") # type: ignore
self.class_archive_category_ids = [
int(n) for n in os.environ.get("CLASS_ARCHIVE_CATEGORY_IDS").split(",") # type: ignore
]
Expand Down
97 changes: 97 additions & 0 deletions bot/cogs/dad_joke_cog.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import logging
import random

import aiohttp
import discord
import discord.ext.commands as commands

import bot.extensions as ext
from bot.consts import Colors

log = logging.getLogger(__name__)
DAD_JOKE_URL = 'https://icanhazdadjoke.com/'

REQ_HEADERS = {
'User-Agent': 'SockBot (https://github.com/Jay-Madden/SockBot)',
'Accept' : 'application/json'
}

class DadJokeCog(commands.Cog):

def __init__(self, bot):
self.bot = bot

##########################
# USER EXECUTABLE COMMANDS
# Random Dad Joke
@ext.group(case_insensitive=True, invoke_without_command=True, aliases=['dad', 'dj'])
@ext.long_help(
"""
This command provides a random dad joke.
"""
)
@ext.short_help('Get a Dad Joke!')
@ext.example(('dadjoke', 'dad', 'dj'))
async def dadjoke(self, ctx):
try:
async with aiohttp.request("GET", DAD_JOKE_URL, headers=REQ_HEADERS) as response:
if (response.status != 200):
embed = discord.Embed(title='SockDad', color=Colors.Error)
ErrMsg = f'Error Code: {response.status}'
embed.add_field(name='Error with the dad joke API', value=ErrMsg, inline=False)
await ctx.send(embed=embed)
return
joke_json = await response.json()
except Exception as err:
raise Exception(err).with_traceback(err.__traceback__)

embed = discord.Embed(title='SockDad', color=Colors.Purple)
embed.add_field(name='Joke:', value=joke_json.get("joke", ""), inline=False)
await ctx.send(embed=embed)
return

# Dad joke with a focus term.
@dadjoke.command()
@ext.long_help(
"""
This command provides a dad joke for a given term.

Sometimes a Dad needs some direction.
"""
)
@ext.short_help('Get a special Dad Joke!')
@ext.example(('dadjoke focus <term>', 'dad focus hipster', 'dj focus dog'))
async def focus(self, ctx, term):

req_params = {
'term': term,
'limit': 30
}

try:
async with aiohttp.request("GET", DAD_JOKE_URL + 'search', headers=REQ_HEADERS, params=req_params) as response:
if (response.status != 200):
embed = discord.Embed(title='SockDad', color=Colors.Error)
ErrMsg = f'Error Code: {response.status}'
embed.add_field(name='Error with the dad joke API', value=ErrMsg, inline=False)
await ctx.send(embed=embed)
return
joke_json = await response.json()
except Exception as err:
raise Exception(err).with_traceback(err.__traceback__)

joke = joke_json.get("results", [])

if len(joke) > 0:
joke = random.choice(joke).get("joke", "")
else:
joke = 'No results for that term. :\'('

embed = discord.Embed(title='SockDad', color=Colors.Purple)
embed.add_field(name='Joke:', value=joke, inline=False)
await ctx.send(embed=embed)
return


async def setup(bot):
await bot.add_cog(DadJokeCog(bot))
121 changes: 121 additions & 0 deletions bot/cogs/riddle_cog.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import logging
import random

import aiohttp
import discord
import discord.ext.commands as commands

import bot.extensions as ext
import bot.bot_secrets as bot_secrets
from bot.consts import Colors

log = logging.getLogger(__name__)
RIDDLES_API_URL = 'https://api.api-ninjas.com/v1/riddles'

EMOJI_MAP = {
'🇦': 0,
'🇧': 1,
'🇨': 2,
'🇩': 3
}
REV_EMOJI_MAP = {
0: '🇦',
1: '🇧',
2: '🇨',
3: '🇩'
}

class RiddleCog(commands.Cog):

def __init__(self, bot):
self.bot = bot


##########################
# USER EXECUTABLE COMMANDS
# Guess the riddle
@ext.group(case_insensitive=True, invoke_without_command=True, aliases=['riddler'])
@ext.long_help(
"""
This command allows you to play a riddle guessing game.

Choose between 4 answers to guess the riddle's answer.
"""
)
@ext.short_help('Guess a riddle!')
@ext.example(('riddle', 'riddler'))
async def riddle(self, ctx):
self.api_ninjas_key = bot_secrets.secrets.api_ninjas_key

headers = {
'X-Api-Key': self.api_ninjas_key
}

params = {
'limit': 4
}

try:
async with aiohttp.request("GET", RIDDLES_API_URL, headers=headers, params=params) as response:
if (response.status != 200):
embed = discord.Embed(title='The Riddler (in Socks)', color=Colors.Error)
ErrMsg = f'Error Code: {response.status}'
embed.add_field(name='Error with the riddle API', value=ErrMsg, inline=False)
await ctx.send(embed=embed)
return
riddle_list = await response.json()
except Exception as err:
raise Exception(err).with_traceback(err.__traceback__)

correct_riddle = riddle_list[0]

# Keep track of original index since 0 is correct
answers = [
{
"answer": riddle.get("answer", "default answer"),
"index": index
}
for index, riddle in enumerate(riddle_list)
]
random.shuffle(answers)

options_text = ""
for index, answer in enumerate(answers):
options_text += f"{REV_EMOJI_MAP[index]} : {answer.get('answer', '')}\n\n"

embed = discord.Embed(title='The Riddler (in Socks)', color=Colors.Purple)
embed.add_field(name=correct_riddle.get("title", "Riddle:"), value=correct_riddle.get("question", "No question. :\'("), inline=False)
embed.add_field(name="Options:", value=options_text, inline=False)
message = await ctx.send(embed=embed)

for key in EMOJI_MAP.keys():
await message.add_reaction(key)

reaction, _ = await self.bot.wait_for(
"reaction_add",
check=lambda r, u: r.message.id == message.id
and ctx.author.id == u.id,
timeout=None,
)

await message.delete()

# This means it is correct
if answers[EMOJI_MAP[reaction.emoji]].get("index") == 0:
embed = discord.Embed(title='Correct!', color=0x008000)
embed.add_field(name=correct_riddle.get("title", "Riddle:"), value=correct_riddle.get("question", "No question. :\'("), inline=False)
embed.add_field(name="Correct Answer:", value=correct_riddle.get("answer", "default answer"), inline=False)
embed.add_field(name="Your Answer:", value=answers[EMOJI_MAP[reaction.emoji]].get("answer", "default answer"), inline=False)
await ctx.send(embed=embed)
# Incorrect
else:
embed = discord.Embed(title='Wrong!', color=Colors.Error)
embed.add_field(name=correct_riddle.get("title", "Riddle:"), value=correct_riddle.get("question", "No question. :\'("), inline=False)
embed.add_field(name="Correct Answer:", value=correct_riddle.get("answer", "default answer"), inline=False)
embed.add_field(name="Your Answer:", value=answers[EMOJI_MAP[reaction.emoji]].get("answer", "default answer"), inline=False)
await ctx.send(embed=embed)

return

async def setup(bot):
await bot.add_cog(RiddleCog(bot))