diff --git a/.github/workflows/link_checker.yml b/.github/workflows/link_checker.yml new file mode 100644 index 0000000..3a8d702 --- /dev/null +++ b/.github/workflows/link_checker.yml @@ -0,0 +1,33 @@ +name: Discord 404 checker (cron + manual test) + +on: + schedule: + # Runs every 15 minutes (UTC). Change as needed. + - cron: "*/15 * * * *" + workflow_dispatch: {} + +jobs: + check-links: + runs-on: ubuntu-latest + permissions: + contents: read + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install deps (none for this script) + run: python -m pip install --upgrade pip + + - name: Run script + env: + DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }} + USER_ID: ${{ secrets.USER_ID }} + run: | + python -u scripts/link_checker.py + diff --git a/scripts/link_checker.py b/scripts/link_checker.py new file mode 100644 index 0000000..c86468d --- /dev/null +++ b/scripts/link_checker.py @@ -0,0 +1,54 @@ +import os, json, urllib.request, urllib.error +from pathlib import Path + + +def send_discord(webhook_url: str, content: list[str]): + payload = {"content": "\n".join(content)} + print(payload) + req = urllib.request.Request( + webhook_url, + data=json.dumps(payload).encode("utf-8"), + headers={"Content-Type": "application/json", "User-Agent": "link-checker/1.0"}, + method="POST", + ) + # lets try to use logs instead of print + try: + with urllib.request.urlopen(req) as resp: + print("Discord status:", resp.status) + print(resp.read().decode("utf-8", errors="ignore")) + except urllib.error.HTTPError as e: + print("Discord HTTPError:", e.code) + body = e.read().decode("utf-8", errors="ignore") + print("Discord response body:", body) + raise + + +# can add a hardcoded webhook for the time being (when testing the file itself) +webhook = os.environ["DISCORD_WEBHOOK_URL"] +# webhook = "https://discord.com/api/webhooks/1523440196232937632/K-aVVdgRNxrTOIUbpcGzhfsE4Jon8Rw_g9w94UqPDubew3Hkvfsw9PSrcsq38iRyvOjR" +# here goes the user id of the user we want to ping +user_id = os.environ["USER_ID"] +# user_id = "1523427702571536500" + +REPO_ROOT = Path(__file__).resolve().parents[1] # works only if the script is in /scripts +URL_LIST_PATH = REPO_ROOT / "data" / "webpages" / "test_list.json" + +failed_urls = [] + +with open(URL_LIST_PATH) as f: + urls = json.load(f) + +for url in urls: + url_status = urllib.request.urlopen(url).getcode() + print(f"url status: {url_status}") + # uncomment this so that ts actually works with 404 calls or any other calls which arent 200 + # if url_status != 200: + # failed_urls.append(f"FAILED URL: {url}") + # adds "FAILED URL:" before each url + failed_urls.append("FAILED URL: " + url) # remove this after testing + + +payload = failed_urls +payload.insert(0, f"<@{user_id}>, these links are returning a 404! Check these links.") +if failed_urls: # add 'not' later after testing and shit + send_discord(webhook, payload)