diff options
author | 2021-03-16 16:09:47 +0300 | |
---|---|---|
committer | 2021-03-16 16:09:47 +0300 | |
commit | 094d125ec6e9719937f1be5fabe3ebaefbdc0e73 (patch) | |
tree | 5ec67192e191ccc5fb10ad56b182b026320ff4b8 /backend/routes | |
parent | Adds Discord Request Helper (diff) |
Moves Webhook & Role Helper To Discord File
Moves the webhook helper and the role assignment helper to the discord
file to gather all discord helpers in one location.
Signed-off-by: Hassan Abouelela <[email protected]>
Diffstat (limited to 'backend/routes')
-rw-r--r-- | backend/routes/forms/submit.py | 99 |
1 files changed, 5 insertions, 94 deletions
diff --git a/backend/routes/forms/submit.py b/backend/routes/forms/submit.py index 4d15ab7..d0c7a87 100644 --- a/backend/routes/forms/submit.py +++ b/backend/routes/forms/submit.py @@ -2,7 +2,6 @@ Submit a form. """ -import asyncio import binascii import datetime import hashlib @@ -17,7 +16,7 @@ from starlette.background import BackgroundTasks from starlette.requests import Request from starlette.responses import JSONResponse -from backend import constants +from backend import constants, discord from backend.authentication.user import User from backend.models import Form, FormResponse from backend.route import Route @@ -30,10 +29,6 @@ HCAPTCHA_HEADERS = { "Content-Type": "application/x-www-form-urlencoded" } -DISCORD_HEADERS = { - "Authorization": f"Bot {constants.DISCORD_BOT_TOKEN}" -} - class SubmissionResponse(BaseModel): form: Form @@ -88,7 +83,8 @@ class SubmitForm(Route): return response - async def submit(self, request: Request) -> JSONResponse: + @staticmethod + async def submit(request: Request) -> JSONResponse: """Helper method for handling submission logic.""" data = await request.json() data["timestamp"] = None @@ -188,7 +184,7 @@ class SubmitForm(Route): tasks = BackgroundTasks() if constants.FormFeatures.WEBHOOK_ENABLED.value in form.features: tasks.add_task( - self.send_submission_webhook, + discord.send_submission_webhook, form=form, response=response_obj, request_user=request.user @@ -196,7 +192,7 @@ class SubmitForm(Route): if constants.FormFeatures.ASSIGN_ROLE.value in form.features: tasks.add_task( - self.assign_role, + discord.assign_role, form=form, request_user=request.user ) @@ -210,88 +206,3 @@ class SubmitForm(Route): return JSONResponse({ "error": "Open form not found" }, status_code=404) - - @staticmethod - async def send_submission_webhook( - form: Form, - response: FormResponse, - request_user: User - ) -> None: - """Helper to send a submission message to a discord webhook.""" - # Stop if webhook is not available - if form.webhook is None: - raise ValueError("Got empty webhook.") - - try: - mention = request_user.discord_mention - except AttributeError: - mention = "User" - - user = response.user - - # Build Embed - embed = { - "title": "New Form Response", - "description": f"{mention} submitted a response to `{form.name}`.", - "url": f"{constants.FRONTEND_URL}/path_to_view_form/{response.id}", # noqa # TODO: Enter Form View URL - "timestamp": response.timestamp, - "color": 7506394, - } - - # Add author to embed - if request_user.is_authenticated: - embed["author"] = {"name": request_user.display_name} - - if user and user.avatar: - url = f"https://cdn.discordapp.com/avatars/{user.id}/{user.avatar}.png" - embed["author"]["icon_url"] = url - - # Build Hook - hook = { - "embeds": [embed], - "allowed_mentions": {"parse": ["users", "roles"]}, - "username": form.name or "Python Discord Forms" - } - - # Set hook message - message = form.webhook.message - if message: - # Available variables, see SCHEMA.md - ctx = { - "user": mention, - "response_id": response.id, - "form": form.name, - "form_id": form.id, - "time": response.timestamp, - } - - for key in ctx: - message = message.replace(f"{{{key}}}", str(ctx[key])) - - hook["content"] = message.replace("_USER_MENTION_", mention) - - # Post hook - async with httpx.AsyncClient() as client: - r = await client.post(form.webhook.url, json=hook) - r.raise_for_status() - - @staticmethod - async def assign_role(form: Form, request_user: User) -> None: - """Assigns Discord role to user when user submitted response.""" - if not form.discord_role: - raise ValueError("Got empty Discord role ID.") - - url = ( - f"{constants.DISCORD_API_BASE_URL}/guilds/{constants.DISCORD_GUILD}" - f"/members/{request_user.payload['id']}/roles/{form.discord_role}" - ) - - async with httpx.AsyncClient() as client: - resp = await client.put(url, headers=DISCORD_HEADERS) - # Handle Rate Limits - while resp.status_code == 429: - retry_after = float(resp.headers["X-Ratelimit-Reset-After"]) - await asyncio.sleep(retry_after) - resp = await client.put(url, headers=DISCORD_HEADERS) - - resp.raise_for_status() |