Skip to content

Commit

Permalink
added discord integration and updated dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
uberfastman committed Oct 15, 2024
1 parent 0d07260 commit 3a37d01
Show file tree
Hide file tree
Showing 6 changed files with 152 additions and 4 deletions.
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
* [Google Drive](#google-drive-setup)
* [Slack](#slack-setup)
* [GroupMe](#groupme-setup)
* [Discord](#discord-setup)
* [Troubleshooting](#troubleshooting)
* [Logs](#logs)
* [Yahoo](#yahoo)
Expand Down Expand Up @@ -731,6 +732,30 @@ The following setup steps are ***required*** in order to allow the GroupMe integ
---
<a name="discord-setup"></a>
#### Discord Setup
The Fantasy Football Metrics Weekly Report application includes integration with the popular chat and messaging app Discord, allowing your generated reports (or links to where they are stored on Google Drive) to be uploaded directly to Discord, making it easy to share the report with all league members.
The following setup steps are ***required*** in order to allow the Discord integration to function properly (see the Discord documentation on [Intro to Webhooks](https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks) for more detailed information and instructions):
1. Sign in to Discord and select the server on which you want to post reports.
2. Click the server name on the top left and then click `Server Settings`.
3. Select `Integrations` in the menu on the left (in the `APPS` section).
4. Click on `Webhooks`.
5. Click `New Webhook`.
6. A new webhook will be created. Click the webhook to expand it and update the configuration:
1. `NAME`: `Fantasy Football Metrics Weekly Report` (this name can be anything you want)
2. Profile picture: Upload [football.png](resources/images/football.png) (this picture can be anything you want)
3. `CHANNEL`: Select the target Discord channel from the `CHANNEL` dropdown.
7. Click `Copy Webhook URL` to copy the value of the webhook URL and paste the webhook ID portion of the URL into the `DISCORD_WEBHOOK_ID` environment variable in your `.env` file.
8. *You can now upload your reports to Discord, either by updating the following values in the `.env` file:*
* `DISCORD_POST_BOOL=True`
*Or by setting the value of `REUPLOAD_FILE_PATH` in the `.env` file to the filepath of the report you wish to upload, opening a Terminal window, and running `python integrations/discord.py`*.
---
<a name="troubleshooting"></a>
### Troubleshooting
Expand Down
2 changes: 1 addition & 1 deletion compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
services:

app:
image: ghcr.io/uberfastman/fantasy-football-metrics-weekly-report:19.1.1
image: ghcr.io/uberfastman/fantasy-football-metrics-weekly-report:19.2.0
platform: linux/amd64
ports:
- "5001:5000"
Expand Down
76 changes: 76 additions & 0 deletions integrations/discord.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import json
from datetime import datetime
from pathlib import Path
from typing import Dict

from colorama import Fore, Style
from discord_webhook import DiscordWebhook
from requests import Response

from integrations.base.integration import BaseIntegration
from utilities.logger import get_logger
from utilities.settings import settings

logger = get_logger(__name__, propagate=False)


class DiscordIntegration(BaseIntegration):

def __init__(self):
self.root_dir = Path(__file__).parent.parent
self.base_url = f"https://discord.com/api/webhooks"
super().__init__("discord")

def _authenticate(self) -> None:

if not settings.integration_settings.discord_webhook_id:
settings.integration_settings.discord_webhook_id = input(
f"{Fore.GREEN}What is your Discord webhook ID? -> {Style.RESET_ALL}"
)
settings.write_settings_to_env_file(self.root_dir / ".env")

self.webhook_url = f"{self.base_url}/{settings.integration_settings.discord_webhook_id}"

self.client = DiscordWebhook(url=self.webhook_url, allowed_mentions={"parse": ["everyone"]})

def post_message(self, message: str) -> Dict:
logger.debug(f"Posting message to Discord: \n{message}")

if settings.integration_settings.discord_channel_notify_bool:
message = f"@everyone\n\n{message}"

self.client.set_content(message)

return self.client.execute().json()

def upload_file(self, file_path: Path) -> Response:
logger.debug(f"Uploading file to Discord: \n{file_path}")

message = (
f"\nFantasy Football Report for {file_path.name}\n"
f"Generated {datetime.now():%Y-%b-%d %H:%M:%S}\n"
)

if settings.integration_settings.discord_channel_notify_bool:
message = f"@everyone\n{message}"

# discord_embed = DiscordEmbed()
# discord_embed.set_title(file_path.name)
# discord_embed.set_description(message)
# self.client.add_embed(discord_embed)

self.client.set_content(message)
self.client.add_file(file_path.read_bytes(), file_path.name)

return self.client.execute().json()


if __name__ == "__main__":
reupload_file = Path(__file__).parent.parent / settings.integration_settings.reupload_file_path

logger.info(f"Re-uploading {reupload_file.name} ({reupload_file}) to Discord...")

discord_integration = DiscordIntegration()

# logger.info(f"{json.dumps(discord_integration.post_message('test message'), indent=2)}")
logger.info(f"{json.dumps(discord_integration.upload_file(reupload_file), indent=2)}")
29 changes: 29 additions & 0 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import colorama
from colorama import Fore, Style

from integrations.discord import DiscordIntegration
from integrations.drive import GoogleDriveIntegration
from integrations.groupme import GroupMeIntegration
from integrations.slack import SlackIntegration
Expand Down Expand Up @@ -372,3 +373,31 @@ def select_week(use_default: bool = False) -> Union[int, None]:
)
else:
logger.info("Test report NOT posted to GroupMe.")

if settings.integration_settings.discord_post_bool:
if not options.get("test", False):
discord_integration = DiscordIntegration()

# post PDF or link to PDF to Discord
post_or_file = settings.integration_settings.discord_post_or_file
if post_or_file == "post":
# post shareable link to uploaded Google Drive PDF on Discord
discord_response = discord_integration.post_message(upload_message)
elif post_or_file == "file":
# upload PDF report directly to Discord
discord_response = discord_integration.upload_file(report_pdf)
else:
logger.warning(
f"The \".env\" file contains unsupported Discord setting: "
f"DISCORD_POST_OR_FILE={post_or_file}. Please choose \"post\" or \"file\" and try again."
)
sys.exit(1)

if discord_response["type"] == 0:
logger.info(f"Report {str(report_pdf)} successfully posted to Discord!")
else:
logger.error(
f"Report {str(report_pdf)} was NOT posted to Discord with error: {discord_response}"
)
else:
logger.info("Test report NOT posted to Discord.")
7 changes: 4 additions & 3 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
beautifulsoup4==4.12.3
camel-converter==4.0.0
camel-converter==4.0.1
colorama==0.4.6
discord-webhook==1.3.1
espn-api==0.39.0
GitPython==3.1.43
google-api-python-client==2.147.0
google-api-python-client==2.149.0
httplib2==0.22.0
numpy==2.1.1
numpy==2.1.2
oauth2client==4.1.3
pillow==10.4.0
pydantic==2.9.2
Expand Down
17 changes: 17 additions & 0 deletions utilities/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,23 @@ class IntegrationSettings(CustomSettings):
groupme_bot_id: Optional[str] = Field(None, title=__qualname__)
groupme_group: Optional[str] = Field(None, title=__qualname__)

# discord
discord_post_bool: bool = Field(
False,
title=__qualname__,
description="change DISCORD_POST_BOOL to True/False to turn on/off posting of the report to Discord"
)
discord_post_or_file: str = Field(
"file",
title=__qualname__,
description=(
"options for DISCORD_POST_OR_FILE: post (if you wish to post a link to the report), file (if you wish to "
"post the report PDF)"
)
)
discord_webhook_id: Optional[str] = Field(None, title=__qualname__)
discord_channel_notify_bool: bool = Field(False, title=__qualname__)


class AppSettings(CustomSettings):
model_config = SettingsConfigDict(
Expand Down

0 comments on commit 3a37d01

Please sign in to comment.