بناء أداة تلخيص تلقائي للمقالات (RSS → Python → OpenAI → Notion) خطوة بخطوة | GateOfAI

Share:

📘 بناء أداة تلخيص تلقائي للمقالات (RSS → Python → OpenAI → Notion)

التصنيف: دروس الذكاء الاصطناعي — المستوى: مبتدئ/متوسط — المدة: 45–60 دقيقة

💡 الفكرة

سننشئ أداة تُراقب أي RSS، تجمع الروابط الجديدة، تستخرج نص المقال، تُلخّصه باستخدام واجهة OpenAI، ثم تحفظ الملخّص تلقائيًا في قاعدة بيانات Notion. يمكنك تشغيلها يدويًا أو عبر جدولة/Zap.

🧰 المتطلبات

  • حساب OpenAI ومفتاح API فعّال.
  • مساحة عمل Notion وقاعدة بيانات (Database) لحفظ الملخصات.
  • Python 3.10+ على جهازك.
  • رابط RSS لمصدر الأخبار/المدوّنة.
  • (اختياري) حساب Zapier لتشغيل الكود عند ورود عنصر RSS جديد.

🔧 الخطوة 1: فهم RSS واختيار المصدر

RSS صيغة معيارية لبث المحتوى المُحدّث (عناوين/ملخص/رابط). ستجد رابط RSS في كثير من المواقع أو عبر أيقونة RSS البرتقالية. سنستخدم الرابط كمدخل للأداة.

🗂️ الخطوة 2: تجهيز قاعدة بيانات في Notion

  1. أنشئ Database في Notion بعنوان مثل: AI Summaries.
  2. أضِف الخصائص التالية:
    • Title (عنوان الصفحة) — نوعه Title.
    • URL — نوعه URL.
    • Source — نص قصير.
    • Summary — نص طويل.
    • Published — تاريخ/وقت (اختياري).
  3. أنشئ تكامل Integration من Notion Developers، وامنحه صلاحية الوصول لقاعدة البيانات، واحتفظ بـ NOTION_TOKEN وDATABASE_ID. راجع مرجع الإنشاء عبر API إذا احتجت ضبطًا أدق.

🔐 الخطوة 3: حفظ المفاتيح كمتغيرات بيئية

# macOS/Linux
export OPENAI_API_KEY="ضع_المفتاح_هنا"
export NOTION_TOKEN="ضع_رمز_نوتشن"
export NOTION_DATABASE_ID="ضع_معرّف_القاعدة"

📦 الخطوة 4: تثبيت الحزم

pip install feedparser trafilatura requests python-dotenv

feedparser لقراءة RSS، وtrafilatura لاستخراج نص المقال من HTML، وrequests لإرسال الطلبات إلى Notion.

🤖 الخطوة 5: كود Python الكامل

ينفّذ: قراءة RSS → تنزيل نص المقال → تلخيص عبر OpenAI → إنشاء صفحة في Notion.

import os, time, feedparser, requests
from datetime import datetime
import trafilatura

OPENAI_API_KEY = os.environ["OPENAI_API_KEY"]
NOTION_TOKEN = os.environ["NOTION_TOKEN"]
NOTION_DB = os.environ["NOTION_DATABASE_ID"]

RSS_URL = "https://example.com/feed"  # استبدلها بخلاصة RSS الخاصة بك

# 1) قراءة RSS
feed = feedparser.parse(RSS_URL)
items = feed.entries[:5]  # جرّب على آخر 5 عناصر

def fetch_article_text(url: str) -> str:
    downloaded = trafilatura.fetch_url(url, timeout=20)
    return trafilatura.extract(downloaded) or ""

def summarize(text: str, title: str) -> str:
    # نستخدم واجهة Responses/Chat في OpenAI
    import json, urllib.request
    endpoint = "https://api.openai.com/v1/chat/completions"
    payload = {
      "model": "gpt-4.1-mini",
      "messages": [
        {"role": "system", "content": "أنت مساعد يلخص نصوصًا عربية بدقة وبشكل موجز."},
        {"role": "user", "content": f"لخّص المقال التالي في 6 نقاط واضحة مع إبراز الفكرة الأساسية، واحتفِظ بالأسماء الصحيحة والعناوين:\nالعنوان: {title}\nالنص:\n{text[:12000]}"}  # حد للحجم
      ],
      "temperature": 0.2
    }
    req = urllib.request.Request(endpoint,
        data=json.dumps(payload).encode("utf-8"),
        headers={"Authorization": f"Bearer {OPENAI_API_KEY}",
                 "Content-Type": "application/json"})
    with urllib.request.urlopen(req, timeout=60) as resp:
        data = json.loads(resp.read().decode("utf-8"))
    return data["choices"][0]["message"]["content"].strip()

def create_notion_page(title: str, url: str, source: str, summary: str, published_iso: str = None):
    notion_endpoint = "https://api.notion.com/v1/pages"
    headers = {
        "Authorization": f"Bearer {NOTION_TOKEN}",
        "Notion-Version": "2022-06-28",
        "Content-Type": "application/json"
    }
    body = {
      "parent": {"database_id": NOTION_DB},
      "properties": {
        "Title": {"title": [{"text": {"content": title}}]},
        "URL": {"url": url},
        "Source": {"rich_text": [{"text": {"content": source}}]},
      },
      "children": [
        {"object":"block","type":"heading_2","heading_2":{"rich_text":[{"type":"text","text":{"content":"الملخص"}}]}},
        {"object":"block","type":"paragraph","paragraph":{"rich_text":[{"type":"text","text":{"content": summary}}]}}
      ]
    }
    if published_iso:
        body["properties"]["Published"] = {"date": {"start": published_iso}}
    resp = requests.post(notion_endpoint, headers=headers, json=body, timeout=60)
    resp.raise_for_status()
    return resp.json()

for e in items:
    title = e.get("title", "بدون عنوان")
    link = e.get("link", "")
    published = None
    if e.get("published_parsed"):
        published = datetime(*e.published_parsed[:6]).isoformat()

    article_text = fetch_article_text(link)
    if not article_text:
        print("لم أستطع استخراج نص:", link)
        continue

    summary = summarize(article_text, title)
    create_notion_page(title, link, feed.feed.get("title","RSS Source"), summary, published)
    print("أُضيف إلى Notion:", title)
    time.sleep(2)  # فاصل بسيط لاحترام المعدلات

🧪 الخطوة 6: الاختبار

  1. بدّل RSS_URL برابط خلاصة حقيقي (مثلاً خلاصة مدوّنة تقنية).
  2. شغّل السكربت: python app.py.
  3. افتح قاعدة بيانات Notion وتحقق من ظهور الصفحات الجديدة بداخلها.

⏱️ خطوة اختيارية: تشغيل تلقائي عبر Zapier

  1. أنشئ Zap بزناد RSS by Zapier لاكتشاف العناصر الجديدة.
  2. أضِف خطوة Webhooks by Zapier (POST) لاستدعاء سكربت مستضاف لديك (أو Cloud Function) وتمرير بيانات المقال كـ JSON.
  3. يمكنك بدلاً من ذلك استدعاء Notion مباشرة من Zap باستخدام خطوة Notion: Create Page وتمرير ملخص جاهز إذا جعلت التلخيص يتم داخل Zap عبر واجهة OpenAI.

🔒 ملاحظات أمان وامتثال

  • خزّن مفاتيح API كمتغيرات بيئية أو أسرار على الخادم—لا تُضمّنها داخل المستودع.
  • راجِع حدود المعدلات (Rate Limits) لواجهة OpenAI قبل تشغيل دفعات كبيرة.
  • لو استخدمت Zapier، احرص على تدوير الرموز السرّية دوريًا والاطلاع على تحديثات الأمان.

🚀 أفكار للتطوير

  • إضافة وسم الموضوع (Topic Tagging) تلقائيًا عبر نموذج تصنيف.
  • إرسال الملخص كبريد أسبوعي.
  • تجميع أكثر من مصدر RSS مع إزالة التكرار.

📚 المصادر

💬 هل لديك سؤال عن هذا الدرس؟ اتركه في التعليقات وسنساعدك خطوة بخطوة.

Share:

Was this tutorial helpful?

What are you looking for?