Skip to content
Closed
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
2 changes: 1 addition & 1 deletion .do/app.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ services:
github:
branch: main
deploy_on_push: true
repo: digitalocean/sample-python
repo: Mralbert93/chapaa-bot
name: sample-python
18 changes: 18 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
aiohttp==3.8.6
aiosignal==1.3.1
async-timeout==4.0.3
attrs==23.1.0
charset-normalizer==3.3.1
discord.py==2.3.2
discord-py-interactions==5.10.0
discord-typings==0.7.0
emoji==2.8.0
frozenlist==1.4.0
idna==3.4
multidict==6.0.4
pip==23.3.1
python-dotenv==1.0.0
tomli==2.0.1
typing_extensions==4.8.0
wheel==0.41.2
yarl==1.9.2
218 changes: 205 additions & 13 deletions server.py
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,19 +1,211 @@
import asyncio
from datetime import datetime
from interactions import Client, Intents, listen, slash_command, SlashContext, OptionType, slash_option, ActionRow, Button, ButtonStyle, StringSelectMenu
from interactions.api.events import Component
import os
import http.server
import socketserver
import uuid

from http import HTTPStatus
token= os.environ.get("DISCORD_TOKEN")

bot = Client(intents=Intents.DEFAULT)

class Handler(http.server.SimpleHTTPRequestHandler):
def do_GET(self):
self.send_response(HTTPStatus.OK)
self.end_headers()
msg = 'Hello! you requested %s' % (self.path)
self.wfile.write(msg.encode())
class Party:
def __init__(self, Type, Quantity, Host, Multi=None, **kwargs):
self.ID = str(uuid.uuid4())
self.Type = Type
self.Quantity = Quantity
self.Host = Host
self.Multi = Multi if Multi is not None else True
self.Roles = {
"Starter": ["Open"],
"Batter": ["Open"]*3,
"Froster": ["Open"],
"Leafer": ["Open"]*4,
"Fruit Froster": ["Open"]*3,
"Oven/Spreader": ["Open"]*3,
"Flexible (TBD)": ["Open"]*4,
}
self.Roles.update(kwargs)
self.MessageID = None

def has_user_signed_up(self, user_id):
for role in self.Roles.values():
if user_id in role:
return True
return False

port = int(os.getenv('PORT', 80))
print('Listening on port %s' % (port))
httpd = socketserver.TCPServer(('', port), Handler)
httpd.serve_forever()
def set_user_id_for_role(self, role, user_id):
if role in self.Roles:
role_list = self.Roles[role]
if "Open" in self.Roles[role]:
open_index = role_list.index("Open")
role_list[open_index] = user_id

def remove_user_from_role(self, user_id):
for role, role_list in self.Roles.items():
if user_id in role_list:
user_index = role_list.index(user_id)
role_list[user_index] = "Open"
return role

def generate_description(self):
description = f"Hosted by {self.Host}\n\n"

required_ingredients = {
"Starter": ":blueberries: Blueberries",
"Batter": ":butter: Butter, :egg: Eggs, 🌾 Flour",
"Froster": ":milk: Milk, :butter: Butter",
"Leafer": ":leaves: Sweet Leaves",
"Fruit Froster": ":apple: Fruit, :ice_cube: Sugar"
}

for role, members in self.Roles.items():
description += f"**{role}:** {required_ingredients.get(role, 'No ingredients required')}\n"

if members:
for member in members:
description += f"- {member}\n"

return description

async def edit_message(ctx, message_id: int):
message = await ctx.channel.fetch_message(message_id)
description = party.generate_description()
embed = {
"title": f"{party.Quantity}x {party.Type} Party",
"description": description,
"thumbnail": {
"url": "https://emojiisland.com/cdn/shop/products/4_large.png",
"height": 0,
"width": 0
},
"footer": {
"text": "Last updated"
},
"timestamp": f"{datetime.utcnow()}"
}
components: list[ActionRow] = [
ActionRow(
Button(
style=ButtonStyle.GREEN,
label="Sign Up",
custom_id="signup",
),
Button(
style=ButtonStyle.RED,
label="Unsign Up",
custom_id="unsignup",
)
)
]
await message.edit(embed=embed,components=components)

@slash_command(
name="party",
description="Used to manage Palia parties",
sub_cmd_name="create",
sub_cmd_description="Create a Palia Party",
)
@slash_option(
name="type",
description="Type of party",
required=True,
opt_type=OptionType.STRING
)
@slash_option(
name="quantity",
description="Quantity to be made",
required=True,
opt_type=OptionType.STRING
)
@slash_option(
name="host",
description="In game name of host",
required=True,
opt_type=OptionType.STRING
)
@slash_option(
name="multi",
description="Whether player can have multiple roles (true/false)",
required=False,
opt_type=OptionType.BOOLEAN
)
async def create(ctx: SlashContext, type: str, quantity: str, host: str, multi: bool = True):
global party
party = Party(Type=type, Quantity=quantity, Host=host, Multi=multi)
description = party.generate_description()
embed = {
"title": f"{party.Quantity}x {party.Type} Party",
"description": description,
"thumbnail": {
"url": "https://emojiisland.com/cdn/shop/products/4_large.png",
"height": 0,
"width": 0
},
"footer": {
"text": "Last updated"
},
"timestamp": f"{datetime.utcnow()}"
}

components: list[ActionRow] = [
ActionRow(
Button(
style=ButtonStyle.GREEN,
label="Sign Up",
custom_id="signup",
),
Button(
style=ButtonStyle.RED,
label="Unsign Up",
custom_id="unsignup",
)
)
]

posting = await ctx.send(embed=embed,components=components)
party.MessageID = posting.id

@listen(Component)
async def on_component(event: Component):
ctx = event.ctx
signup_message = None

async def set_deleted():
nonlocal signup_message
if signup_message:
await signup_message.delete()
signup_message = None

match ctx.custom_id:
case "signup":
if party.has_user_signed_up(f"<@{ctx.author.id}>") and party.Multi == False:
await ctx.author.send("You have already signed up for a role. Please remove your current role to switch roles.")
else:
components = StringSelectMenu(
"Starter", "Batter", "Froster", "Leafer", "Fruit Froster", "Oven/Spreader","Flexible (TBD)",
placeholder="Choose your role",
custom_id="role"
)
signup_message = await ctx.send(f"<@{ctx.author.id}>",components=components)
await asyncio.sleep(15)
await set_deleted()

case "unsignup":
while party.has_user_signed_up(f"<@{ctx.author.id}>"):
party.remove_user_from_role(f"<@{ctx.author.id}>")
await edit_message(ctx, party.MessageID)
confirmation = await ctx.send(f"<@{ctx.author.id}>, you have been removed from the party.")
await asyncio.sleep(3)
await confirmation.delete()

case "role":
selected_role = ctx.values[0]
party.set_user_id_for_role(selected_role, f"<@{ctx.author.id}>")
await edit_message(ctx, party.MessageID)
await set_deleted()
confirmation = await ctx.send(f"<@{ctx.author.id}>, you have been added to {selected_role}")
await asyncio.sleep(1)
await confirmation.delete()

bot.start(token)