-
-
Notifications
You must be signed in to change notification settings - Fork 94
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
✨ Discord notification provider #280
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
""" | ||
Push Notifications via Discord | ||
""" | ||
|
||
import logging | ||
from typing import List | ||
|
||
import requests | ||
|
||
from camply.config import DiscordConfig | ||
from camply.containers import AvailableCampsite | ||
from camply.notifications.base_notifications import BaseNotifications | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
class DiscordNotifications(BaseNotifications): | ||
""" | ||
Push Notifications via Discord | ||
""" | ||
|
||
def __init__(self): | ||
super().__init__() | ||
self.session.headers.update({"Content-Type": "application/json"}) | ||
if any([DiscordConfig.DISCORD_WEBHOOK is None, DiscordConfig.DISCORD_WEBHOOK == ""]): | ||
warning_message = ( | ||
"Discord is not configured properly. To send Discord messages " | ||
"make sure to run `camply configure` or set the " | ||
"proper environment variable: `DISCORD_WEBHOOK`." | ||
) | ||
logger.error(warning_message) | ||
raise EnvironmentError(warning_message) | ||
|
||
def send_message(self, message: str, **kwargs) -> requests.Response: | ||
""" | ||
Send a message via Discord - if environment variables are configured. | ||
|
||
Parameters | ||
---------- | ||
message: str | ||
|
||
Returns | ||
------- | ||
requests.Response | ||
""" | ||
message_json = kwargs | ||
if message: | ||
message_json["content"] = message | ||
|
||
logger.debug(message_json) | ||
response = self.session.post( | ||
url=DiscordConfig.DISCORD_WEBHOOK, | ||
json=message_json, | ||
) | ||
try: | ||
response.raise_for_status() | ||
except requests.HTTPError as he: | ||
logger.warning( | ||
"Notifications weren't able to be sent to Discord. " | ||
"Your configuration might be incorrect." | ||
) | ||
raise ConnectionError(response.text) from he | ||
return response | ||
|
||
def block_for_campsite(self, campsite: AvailableCampsite): | ||
message_title, formatted_dict = self.format_standard_campsites( | ||
campsite=campsite, | ||
) | ||
|
||
# Remove items that will be templated as part of the embed. | ||
del formatted_dict["Recreation Area"] | ||
del formatted_dict["Booking Date"] | ||
del formatted_dict["Booking End Date"] | ||
del formatted_dict["Facility Name"] | ||
del formatted_dict["Booking Link"] | ||
del formatted_dict["Campsite Site Name"] | ||
del formatted_dict["Campsite Loop Name"] | ||
del formatted_dict["Recreation Area Id"] | ||
del formatted_dict["Facility Id"] | ||
del formatted_dict["Campsite Id"] | ||
|
||
return { | ||
"author": { | ||
"name": f"🏕 {campsite.recreation_area}" | ||
}, | ||
"title": f"{campsite.facility_name} {campsite.campsite_loop_name} #{campsite.campsite_site_name}", | ||
"description": f"{campsite.booking_date:%Y/%m/%d} to {campsite.booking_end_date:%Y/%m/%d}", | ||
"url": campsite.booking_url, | ||
"color": 2375436, | ||
"fields": [ | ||
{ | ||
"name": key, | ||
"value": str(value) | ||
} for key, value in formatted_dict.items() | ||
], | ||
"footer": { | ||
"text": "camply, the campsite finder ⛺️" | ||
} | ||
} | ||
Comment on lines
+70
to
+99
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A couple notes on this - I think there are a good number of fields that we want to keep from our
See here for the camply test-notifications --notifications discord Here's the same notification, that instead uses |
||
|
||
def send_campsites(self, campsites: List[AvailableCampsite], **kwargs): | ||
""" | ||
Send a message with a campsite object | ||
|
||
Parameters | ||
---------- | ||
campsites: AvailableCampsite | ||
""" | ||
if campsites: | ||
self.send_message( | ||
message="", | ||
embeds=[self.block_for_campsite(campsite) for campsite in campsites], | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are a couple lines like this that haven't been formatted by black / ruff - that's why we're seeing linting errors.
pre-commit resolves this with hatch - so either of these commands will format the codebase for you:
This part is kind of confusing. CI/CD runs both linting (black/ruff) and type checking (mypy) on the codebase inside the
Lint
job - but only linting errors actually cause it to fail. type-checking issues (on related and unrelated code) will still show up as annotations on the PR but won't actually cause theLint
job to fail.