دليل · ١٦ دقيقة للقراءة
ملخص تقني يومي متعدد المصادر مع ترتيب AI وتوصيل Slack في n8n
سير n8n يسحب Hacker News و Dev.to و GitHub Trending بالتوازي كل صباح، يُلخص كل عنصر في جملة واحدة بالذكاء الاصطناعي، ثم يُرسل رسالة Slack بصيغة Block Kit بروابط قابلة للنقر. مُشغّل بجدول، يدمج ثلاثة أشكال بيانات، ويستخدم `gpt-5-mini` عبر الأرصدة المجانية.
بُني واستورد وحُفظ مباشرة على nerdleveltech.app.n8n.cloud · gpt-5-mini + أرصدة مجانية
جدول المحتويات
١٢ عقدة، ٣ مصادر بيانات متوازية، خطوة تلخيص AI واحدة، حمولة Slack Block Kit واحدة — وُصلت وحُفظت على n8n cloud. استورد، بدّل رابط Slack webhook العام (الخطوة ٦)، وجدول. لقطات التنفيذ أدناه تعرض البيانات تتدفق عبر مُلخص AI.
⚠️ قبل التفعيل: عقدة Post to Slack Webhook تأتي برابط placeholder (
https://hooks.slack.com/services/REPLACE/WITH/YOUR_WEBHOOK). أول تشغيل مجدول سيفشل بـ ٤٠٤ إذا لم تستبدله. انظر الخطوة ٦ لإجراء الاستبدال الدقيق.
ما الذي ستبنيه
سير n8n مُشغّل بجدول يومي:
- يعمل كل صباح الساعة ٨ (UTC افتراضياً، قابل للضبط)
- يجلب أهم ٥ عناصر بالتوازي من ثلاثة مصادر: صفحة Hacker News الأولى، أفضل مقالات Dev.to، مستودعات GitHub المُنشأة في آخر ٤٨ ساعة مرتبة بالنجوم
- يُطبّع كل شكل إلى كائن مشترك
{ source, title, url, score, summary_seed } - يستخدم Summarization Chain من LangChain لكتابة ملخص جملة واحدة لكل عنصر
- يبني رسالة Slack Block Kit بأقسام مُجمّعة وروابط قابلة للنقر وفواصل
- يُرسل POST إلى Slack Incoming Webhook — بدون OAuth
تخطَّ البناء — استورد السير
المتطلبات المسبقة
| المتطلب | التفاصيل |
|---|---|
| حساب n8n | تجربة مجانية ١٤ يوماً |
| أرصدة OpenAI | ١٠٠ مجانية تغطي شهور من التشغيلات اليومية |
| مساحة عمل Slack | تحتاج صلاحيات admin لتثبيت Incoming Webhook |
| الوقت | حوالي ٢٠ دقيقة |
الخطوة ١ — استيراد السير
أنشئ سير جديد، ألصق JSON على اللوحة الفارغة. يُحمل n8n 12 عقدة. يبدو هكذا:
Schedule ──┬─→ HN Fetch ─→ Normalize HN
├─→ Dev.to ─→ Normalize Dev.to ──┐
└─→ GitHub ─→ Normalize GitHub ──┼─→ Merge → Summarize Each → Combine → Format Slack → POST
──┘
انقر نقراً مزدوجاً على OpenAI Chat Model، وتحقق من بيانات n8n المجانية و gpt-5-mini بدرجة حرارة 0.3 (منخفضة — نريد مخرجات جملة واحدة متسقة).
الخطوة ٢ — فهم المصادر الثلاثة
| المصدر | نقطة النهاية | المصادقة | يُعيد |
|---|---|---|---|
| Hacker News | hn.algolia.com/api/v1/search?tags=front_page&hitsPerPage=5 | بدون | hits[] مع title و url و points |
| Dev.to | dev.to/api/articles?top=1&per_page=5 | بدون | مصفوفة عادية مع title و url و positive_reactions_count |
| GitHub | api.github.com/search/repositories?q=created:>{date}&sort=stars&order=desc&per_page=5 | بدون (محدود) | items[] مع full_name و html_url و stargazers_count و description |
رابط GitHub يستخدم تعبير n8n: {{ $now.minus({days: 2}).toFormat('yyyy-MM-dd') }} — يبني سلسلة تاريخ لـ"قبل يومين" في وقت التشغيل لتحصل دائماً على أحدث المستودعات.
الخطوة ٣ — تطبيع كل مصدر
ثلاث عقد Code تحول كل مصدر إلى نفس شكل الكائن. مثلاً Normalize HN:
const hits = $input.first().json.hits || [];
return hits.map(h => ({
json: {
source: 'Hacker News',
title: h.title,
url: h.url || `https://news.ycombinator.com/item?id=${h.objectID}`,
score: h.points || 0,
summary_seed: (h.story_text || '').slice(0, 400)
}
}));
summary_seed يُعطي AI سياقاً للعناصر التي تفتقد لجسم URL (Show HN أو Ask HN). URL الاحتياطي (news.ycombinator.com/item?id=...) يضمن أن عناصر Ask HN لا تزال قابلة للنقر.
Normalize Dev.to يقرأ description إلى summary_seed. Normalize GitHub يقرأ description السطر الواحد للمستودع.
بعد هذه الخطوة، كل العناصر الـ ١٥ (٥ × ٣) لها بنية متطابقة — لا عقدة لاحقة تحتاج لمعرفة من أي مصدر جاءت.
الخطوة ٤ — الدمج والتلخيص
عقدة Merge
مضبوطة على mode: append. تأخذ ٣ تدفقات مدخلة (عقد Normalize الثلاث) وتُخرج قائمة مُجمعة واحدة من ١٥ عنصراً بترتيب المصدر.
Summarization Chain
السلسلة تشتغل مرة لكل عنصر. المطالبة مُدمجة في combineMapPrompt للعقدة:
⚠️ اختلاف نحوي مهم: مطالبة Summarization Chain تستخدم متغير قالب LangChain
{text}وليس تعبيرات n8n{{ $json.x }}. السلسلة الافتراضية تُغذي محتوى كل عنصر مدخل تلقائياً كـ{text}في المطالبة. إذا احتجت الوصول لحقول أخرى ($json.titleو$json.url)، أنظف حل هو استبدال Summarization Chain بـ Basic LLM Chain (chainLlm) — تلك العقدة تُبدل تعبيرات n8n مثل ما يفعل دليل ١. واجهنا هذا في اختبارنا الحقيقي: مع{{ $json.title }}حرفياً في مطالبة Summarization Chain، أعاد النموذج placeholders بأسلوب القوالب الخاصة به بدلاً من ملخص حقيقي. استخدم Basic LLM Chain إلا إذا احتجت تحديداً map-reduce على مستندات طويلة جداً.
Source: {{ $json.source }}
Title: {{ $json.title }}
URL: {{ $json.url }}
Score/engagement: {{ $json.score }}
Context: "{{ $json.summary_seed }}"
Write ONE crisp sentence (≤ 25 words) that tells a busy developer what this
is and why it matters TODAY. Lead with the concrete thing, not with "This
story is about...". If it is a GitHub repo, mention the language or primary
domain. No hedging.
كل عنصر يحصل على استدعاء API واحد إلى gpt-5-mini. التكلفة اليومية الإجمالية: ~٠٫٠٠٥$ (أقل بكثير من ١٠٠ رصيد مجاني).
أعلاه: عقدة Summarize Each مفتوحة بعد تنفيذ حقيقي — اللوحة اليسرى المُدخل المدموج من المصادر الثلاثة، اللوحة اليمنى ملخصات الجملة الواحدة التي أنتجتها gpt-5-mini.
Combine Items
عقدة Code تُجمِّع العناصر المُلخصة حسب المصدر:
const bySource = {};
items.forEach(it => {
const src = it.json.source || 'Other';
bySource[src] = bySource[src] || [];
bySource[src].push({
summary: (it.json.output || it.json.response?.text || it.json.text || '').trim(),
url: it.json.url,
title: it.json.title,
score: it.json.score
});
});
الاحتياطي الثلاثي it.json.output || it.json.response?.text || it.json.text يتعامل مع أشكال مخرجات التلخيص لثلاث إصدارات n8n. احتفظ به — التكلفة مقارنة حرف واحد، والفائدة توافق مستقبلي.
الخطوة ٥ — تنسيق Slack Block Kit
انقر نقراً مزدوجاً على Format Slack Blocks. عقدة Code تبني حمولة Block Kit الرسمية من Slack — JSON منظم يعرض كبطاقات غنية، ليس نصاً عادياً.
const blocks = [
{ type: 'header', text: { type: 'plain_text', text: `🧠 Daily Tech Digest — ${date}` } },
{ type: 'context', elements: [{ type: 'mrkdwn', text: `Merged from ${Object.keys(bySource).length} sources` }] },
{ type: 'divider' }
];
Object.entries(bySource).forEach(([src, items]) => {
blocks.push({ type: 'section', text: { type: 'mrkdwn', text: `*${src}*` } });
items.forEach(i => {
const scoreStr = i.score ? ` _(${i.score})_` : '';
blocks.push({ type: 'section', text: { type: 'mrkdwn', text: `• <${i.url}|${i.title}>${scoreStr}\n${i.summary}` } });
});
blocks.push({ type: 'divider' });
});
النتيجة: رأس قسم بالخط العريض لكل مصدر، كل عنصر على سطر خاص به بعنوان قابل للنقر وملخص AI أسفله. النقاط تُعرض بالخط المائل _(312)_.
لماذا Block Kit مقابل النص العادي؟ رسائل النص العادي تقطع العناوين عند الروابط الطويلة ولا تُعرض قابلة للنقر. صيغة
<url|text>في Block Kit تُعطيك تسميات روابط قابلة للنقر وتجميع وفواصل وتذييلات سياق.
الخطوة ٦ — توصيل Slack Webhook
٦أ. إنشاء webhook في Slack
- افتح Slack في متصفح ← اضغط اسم مساحة العمل أعلى اليسار ← Settings & administration ← Manage apps
- ابحث "Incoming Webhooks" ← Add to Slack
- اختر القناة التي تريد نشر الملخص عليها (مثلاً
#ai-digest) - اضغط Add Incoming WebHooks integration — Slack يُعطيك رابطاً مثل
https://hooks.slack.com/services/T01.../B02.../abc123 - انسخ الرابط
٦ب. اللصق في السير
انقر نقراً مزدوجاً على Post to Slack Webhook في n8n. استبدل placeholder الـ URL:
https://hooks.slack.com/services/REPLACE/WITH/YOUR_WEBHOOK
…برابط webhook الحقيقي. احفظ السير.
٦ج. اختبره
اضغط Execute workflow على اللوحة. السير يشتغل عبر العقد الـ ١٢ وينشر على قناة Slack. إذا كان كل شيء صحيحاً، تحصل على رسالة غنية تبدو كنشرة مُنسقة — المصادر مفصولة، الروابط قابلة للنقر، ملخصات AI تحت كل عنصر.
إذا لم تصل رسالة Slack:
- افتح سجل التنفيذ ← اضغط عقدة Post to Slack Webhook ← افحص رمز استجابة HTTP.
200= نجاح.400= JSON تالف (عادة حقلtextاحتياطي مفقود). - تحقق من القناة التي تم تثبيت webhook عليها — لا يمكنك إعادة توجيه webhook بدون تثبيت واحد جديد.
التوسعات: البريد و Teams و Discord والتخصيص
البريد الإلكتروني بدلاً من Slack
استبدل Post to Slack Webhook بعقدة Gmail (تحتاج OAuth لحساب Google). اعمل خريطة:
- To ← بريدك الإلكتروني
- Subject ←
🧠 Daily Tech Digest — {{ $json.text }} - Body (HTML) ← حوّل blocks من Slack إلى HTML بعقدة Code صغيرة قبل هذه الخطوة
Microsoft Teams
Teams يقبل Adaptive Cards بدلاً من Block Kit. أنشئ عقدة Code جديدة تُترجم كائن bySource إلى JSON بتنسيق Adaptive Card (المخطط هنا). أرسل POST إلى رابط webhook الوارد لقناة Teams.
Discord
Discord يقبل webhooks لكن بشكل مختلف — مصفوفة embeds مع title و description و url و fields. سهل الترجمة من bySource.
التخصيص بتفضيلات المستخدم
أضف عقدة Read From Database قبل الجلب. استعلم عن جدول { user_id, topics[], min_score, slack_webhook } ووزع لكل مستخدم. كل مستخدم يحصل على ملخص مُصفى لمواضيعه مع webhook شخصي.
ضبط المصادر لكل يوم
أضف عقدة Switch بعد Schedule توجه إلى مجموعات fetch مختلفة حسب يوم الأسبوع. الإثنين = Hacker News + Dev.to؛ الجمعة = GitHub Trending + Product Hunt. يُبقي الملخص طازجاً.
ما التالي
ادمج هذا مع يوتيوب إلى تدوينة AI لتحويل مستودع GitHub لليوم إلى مقال شرح كامل، أو مع إثراء العملاء المحتملين بالـAI لتحديد الشركات المُوظِّفة من منشورات Dev.to وتوليد outreach.
الأسئلة الشائعة
لماذا نستخدم ٣ عقد HTTP Request منفصلة بدلاً من واحدة بمتغيرات؟
كل مصدر يعيد شكل استجابة مختلف: HN يُعيد `hits[]` من Algolia، Dev.to يُعيد مصفوفة عادية، GitHub يُعيد `items[]`. تطبيع ثلاثة أشكال في عقدة Code واحدة يصبح spaghetti. ثلاثة أزواج Fetch → Normalize تعطيك معالجة أخطاء لكل مصدر، وإعادة محاولة لكل مصدر، وتصحيح أنظف عندما تنكسر واجهة واحدة. عقدة Merge تخيطها معاً.
كيف أحصل على رابط Slack webhook؟
في Slack، اذهب إلى مساحة عملك ← Apps ← ابحث عن 'Incoming Webhooks' ← Add to Slack ← اختر قناة ← انسخ رابط الـwebhook. ألصقه في حقل URL لعقدة **Post to Slack Webhook**، مُستبدلاً placeholder الـ `REPLACE/WITH/YOUR_WEBHOOK`. بدون نطاقات OAuth ولا bot token — فقط رابط واحد يقبل POST مع Block Kit JSON.
هل أستطيع استبدال Dev.to بـ Product Hunt أو Medium أو تغذية RSS؟
نعم. كرّر زوج Fetch + Normalize لمصدرك ووصل مخرجات Normalize إلى عقدة Merge. Product Hunt لديه واجهة GraphQL (تحتاج مفتاح مطور مجاني)، Medium يعرض RSS على `https://medium.com/feed/@<user>` أو `/<publication>`، وأي RSS لمدونة يعمل مع عقدة RSS Feed Read من n8n. القاعدة الوحيدة: عقدة Normalize يجب أن تُخرج `{ source, title, url, score, summary_seed }` — نفس شكل العقد الثلاث الأخرى.
الملخص يصل لكن ملخصات الذكاء الاصطناعي مفقودة — لماذا؟
افحص عقدة Combine Items Code. تقرأ من `j.output || j.response?.text || j.text` — هذه أسماء الحقول الثلاثة المحتملة حسب إصدار n8n لديك. إذا كانت عقدة Summarize Each تستخدم حقلاً مختلفاً (شائع مع الإصدارات الأقدم)، افتح التنفيذ، افحص مخرجات التلخيص، وحدّث سلسلة الاحتياطية لتشمل اسم الحقل.
ماذا عن حدود المعدل؟ هل ستحظرني واجهة GitHub؟
واجهة بحث GitHub غير المُصادق عليها تسمح بـ ١٠ طلبات/دقيقة. تشغيل سير واحد يقوم بطلب واحد بالضبط، فالتشغيلات اليومية تستخدم 1/10 من حد الدقيقة — آمن. إذا ضاعفت المصادر (مثلاً ٥ استعلامات GitHub مختلفة)، صادق بإضافة `Authorization: Bearer ghp_<your_token>` في رؤوس عقدة HTTP. هذا يرفع الحد إلى 30/دقيقة. HN و Dev.to ليس لهما متطلب مصادقة عند هذا الحجم.
مقالات ذات صلة
داخل وكلاء الذكاء الاصطناعي للبرمجة: كيف تتطور مسارات التطوير الذاتية
نظرة واقعية ومفصلة عن وكلاء الذكاء الاصطناعي للبرمجة — كيف تعمل، ما الذي يجعلها مختلفة عن الكوبيلوتات التقليدية، وكيف تعيد السيرورات الوكلائية تشكيل تطوير البرمجيات.
بناء الذكاء الاصطناعي الموثوق: ضوابط LLM في تطبيقات العالم الحقيقي
اكتشف كيف تجعل الضوابط النماذج اللغوية الكبيرة (LLMs) آمنة، أخلاقية، ومطابقة—من الرعاية الصحية إلى المالية—وتعلم كيفية تصميم ومراقبة ونشر AI بمسؤولية.
المزيد من الأدلّة
دليل · ١٥ دقيقة للقراءة
إثراء العملاء المحتملين بالـ AI ورسائل مُخصصة في n8n — ٦ عقد ونموذج واحد
ضع بريد العميل المحتمل ورابط شركته في نموذج n8n. السير يحلل الموقع، يستكشف stack التقني، يُشير لإشارات التوظيف والأسعار والامتثال، ثم يطلب من gpt-5-mini درجة ملاءمة وثلاثة أسباب وبريد بارد مُخصص. مخرجات JSON مُحققة المخطط جاهزة لـCRM.
دليل · ١٦ دقيقة للقراءة
مراقب صفحة المنافس بالذكاء الاصطناعي مع diff وتنبيهات Slack في n8n
سير n8n مجدول يومياً يجلب صفحات تسعير وميزات منافسيك، يُجري hash مقابل snapshot الأمس في static data لـn8n، يحسب diff على مستوى الجمل، ويُرسل التغييرات المهمة فقط إلى Slack — مدعوم بـgpt-5-mini. سير متفرع كامل بمنطق IF.
للوكلاء الآليين:/for-agents/llms.txt/ar/guides/n8n-multisource-news-digest.md