المستوى: متوسط — للي يعرف Git وسطر الأوامر ويحب يأتمت الشغل المتكرر.
أتمتة كشف الروابط المكسورة في موقعك
في آخر المقال هيبقى عندك سكربت واحد بيفحص كل روابط موقعك كل أسبوع، ويبعتلك المكسور منها على Slack — من غير ما تفتح المتصفح ولا مرة.
المشكلة باختصار
الرابط المكسور مبيصرخش. الصفحة بتتشال أو الـ URL بيتغيّر، والزائر بيوصل لـ 404، وانت مش واخد بالك. النتيجة تجربة سيئة، وزحف جوجل بيهدر ميزانيته على صفحات ميتة بدل ما يفهرس الجديد. الطريقة الشائعة إنك تفحص يدويًا كل فترة. دي بتفشل لأن محدش بيفتكر يعملها، وبتكتشف المشكلة بعد ما العميل يشتكي.
الفكرة بمثال بسيط الأول
تخيّل حارس عمارة عنده 600 باب. كل صباح إثنين بيلف على كل باب، يخبط، ويشوف حد بيرد. الأبواب اللي محدش بيرد من وراها بيكتبها في ورقة ويسلّمها للمدير. هو مبيصلّحش الأبواب، بس بيقولك بالظبط أنهي باب بايظ. الأوتوميشن بتاعنا هو الحارس ده: بيمر على كل رابط، يشوف السيرفر بيرد بإيه، ويجمّع البايظ في تقرير واحد.
وبالتفاصيل علميًا: كل رابط لما بيتفتح بيرجّع "كود حالة HTTP". الكود 200 معناه سليم، و404 معناه الصفحة مش موجودة، و500 معناه عطل في السيرفر، و301 أو 302 معناهم تحويل لعنوان تاني. أداة فحص الروابط بتزور كل رابط، تقرأ الكود ده، وتعتبر أي حاجة في نطاق 400 و500 رابطًا مكسورًا يستاهل تنبيه.
الحل: lychee مع GitHub Actions وSlack
فيه أدوات كتير: linkchecker بـ Python، وwget --spider، وإضافات جاهزة. إحنا اخترنا lychee لأنه مكتوب بـ Rust وبيفحص بالتوازي، فبيخلّص موقع بـ 600 صفحة في حوالي 40 ثانية بدل دقائق. الافتراض هنا إن روابطك عامة على الإنترنت ومش ورا تسجيل دخول.
- ضيف ملف الإعداد
lychee.tomlفي جذر المستودع. - ضيف workflow في GitHub Actions يشتغل بجدول أسبوعي.
- وصّل Slack Webhook علشان يوصلك التقرير في قناة واحدة.
# lychee.toml
max_redirects = 5
timeout = 20
# اعتبر بعض الأكواد سليمة حتى لو رجعت 429 (rate limit)
accept = [200, 206, 429]
# استثنِ روابط بتكذب في الرد زي بعض الشبكات الاجتماعية
exclude = ["^mailto:", "linkedin\\.com", "x\\.com"]
# .github/workflows/broken-links.yml
name: broken-links
on:
schedule:
- cron: '0 6 * * 1' # كل إثنين 6:00 صباحًا UTC
workflow_dispatch: {}
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run lychee
id: lychee
uses: lycheeverse/lychee-action@v2
with:
args: --config lychee.toml './**/*.md' 'https://example.com'
fail: false
- name: Notify Slack
if: steps.lychee.outputs.exit_code != '0'
run: |
curl -sS -X POST "$SLACK_WEBHOOK" \
-H 'Content-type: application/json' \
--data "{\"text\":\"روابط مكسورة اتكشفت: $(head -c 1500 lychee/out.md)\"}"
env:
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}