<div data-theme-toc="true"> </div>
# مزامنة بيانات مستكشف بيانات Discourse إلى جداول بيانات Google
> :bookmark: يشرح هذا الدليل الإرشادي كيفية أتمتة استيراد نتائج استعلامات مستكشف بيانات Discourse إلى جداول بيانات Google باستخدام Google Apps Script.
>
> :person_raising_hand: مستوى المستخدم المطلوب: مسؤول (Administrator)
## نظرة عامة
من خلال ربط جداول بيانات Google بمكون "مستكشف البيانات" (Data Explorer) الخاص بموقع Discourse الخاص بك، يمكنك سحب نتائج الاستعلام تلقائيًا وفقًا لجدول زمني. هذا مفيد لإنشاء لوحات معلومات، أو تتبع المقاييس، أو مشاركة التقارير مع أعضاء الفريق الذين ليس لديهم وصول إداري إلى Discourse.
## المتطلبات الأساسية
قبل البدء، تأكد من توفر ما يلي:
* تم تمكين مكون [مستكشف البيانات](https://meta.discourse.org/t/32566) (Data Explorer) على موقع Discourse الخاص بك
* استعلام محفوظ في مستكشف البيانات تريد مزامنته
* وصول إداري إلى موقع Discourse الخاص بك
* حساب Google لديه إمكانية الوصول إلى جداول بيانات Google
## الخطوة 1: إعداد Discourse
### الحصول على معرّف الاستعلام (Query ID)
1. انتقل إلى لوحة تحكم المسؤول (Admin panel) في موقع Discourse الخاص بك
2. انتقل إلى **المكونات الإضافية (Plugins)** ← مستكشف البيانات (Data Explorer)
3. افتح الاستعلام الذي تريد مزامنته
4. انظر إلى عنوان URL في شريط عناوين متصفحك - سيبدو كـ `.../queries/123`. الرقم الموجود في النهاية هو **معرّف الاستعلام (query ID)** الخاص بك
### إنشاء مفتاح API
1. انتقل إلى **مسؤول (Admin) ← متقدم (Advanced) ← مفاتيح API (API Keys)**
2. انقر على **مفتاح API جديد (New API Key)**
3. قم بتكوين المفتاح:
* **الوصف (Description):** أدخل شيئًا وصفيًا مثل "مزامنة جداول بيانات Google" (Google Sheets Sync)
* **مستوى المستخدم (User Level):** حدد "مستخدم واحد" (Single User) واختر مستخدمًا مسؤولًا، أو حدد "جميع المستخدمين" (All Users)
* **النطاق (Scope):** حدد "مفصل" (Granular)، ثم حدد **تشغيل الاستعلامات (run queries)** ضمن قسم مستكشف البيانات (Data Explorer)
> :information_source: استخدام النطاق المفصل "تشغيل الاستعلامات" يقتصر هذا المفتاح API على تشغيل استعلامات مستكشف البيانات فقط، وهو أكثر أمانًا من استخدام مفتاح عام.
4. انقر على **حفظ (Save)** و **انسخ مفتاح API فورًا** - لن تتمكن من رؤيته مرة أخرى
لمزيد من التفاصيل حول مفاتيح API، راجع: [إنشاء مفتاح API وتكوينه](https://meta.discourse.org/t/create-and-configure-an-api-key/230124)
## الخطوة 2: إعداد Google Apps Script
يتضمن Google Apps Script خدمة مدمجة تسمى `UrlFetchApp` - لا تحتاج إلى تثبيت أي شيء. ما عليك سوى كتابتها في محرر التعليمات البرمجية وسيتعرف عليها محرك البرمجة النصية تلقائيًا.
1. افتح جدول بيانات Google الخاص بك
2. انتقل إلى **الإضافات (Extensions)** ← **برنامج Apps Script (Apps Script)**
3. احذف أي تعليمات برمجية موجودة في `Code.gs` والصق ما يلي:
```javascript
function syncDiscourseData() {
// ============ CONFIGURATION ============
const DISCOURSE_URL = "https://your-forum.com"; // عنوان URL الخاص بـ Discourse الخاص بك (بدون شرطة مائلة لاحقة)
const QUERY_ID = "123"; // معرّف مستكشف البيانات (Data Explorer query ID) الخاص بك
const API_KEY = "your_api_key_here"; // مفتاح API الخاص بك
const API_USERNAME = "system"; // اسم المستخدم لطلبات API
// =======================================
const url = `${DISCOURSE_URL}/admin/plugins/discourse-data-explorer/queries/${QUERY_ID}/run.csv`;
const options = {
"method": "post",
"headers": {
"Api-Key": API_KEY,
"Api-Username": API_USERNAME
}
};
try {
const response = UrlFetchApp.fetch(url, options);
const csvData = response.getContentText();
const data = Utilities.parseCsv(csvData);
const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
// مسح البيانات الموجودة وكتابة البيانات الجديدة
sheet.clear();
sheet.getRange(1, 1, data.length, data[0].length).setValues(data);
// إضافة طابع زمني "آخر تحديث" في عمودين بعد البيانات
const timestampCell = sheet.getRange(1, data[0].length + 2);
const now = new Date();
timestampCell.setValue("Last Updated: " + Utilities.formatDate(now, Session.getScriptTimeZone(), "yyyy-MM-dd HH:mm:ss"));
timestampCell.setFontWeight("bold");
Logger.log("Successfully synced " + (data.length - 1) + " rows");
} catch (e) {
Logger.log("Error: " + e.toString());
}
}
- قم بتحديث قيم التكوين في الجزء العلوي من البرنامج النصي:
- استبدل
https://your-forum.comبعنوان URL الخاص بـ Discourse - استبدل
123بمعرّف الاستعلام الخاص بك - استبدل
your_api_key_hereبمفتاح API الخاص بك
- استبدل
الخطوة 3: تشغيل البرنامج النصي وتفويضه
-
انقر على أيقونة حفظ (Save) (
) وقم بتسمية مشروعك (على سبيل المثال: “مزامنة Discourse”) -
انقر على زر تشغيل (Run) (
) -
ستظهر نافذة منبثقة تطلب التفويض:
- انقر على مراجعة الأذونات (Review Permissions)
- حدد حساب Google الخاص بك
- إذا رأيت “لم يتم التحقق من هذا التطبيق بواسطة Google”، فانقر على متقدم (Advanced) ← الانتقال إلى [اسم المشروع] (غير آمن)
- انقر على السماح (Allow)
-
تحقق من جدول بيانات Google الخاص بك - يجب أن تظهر البيانات الآن
إذا واجهت أخطاء، فانقر على عرض (View) ← السجلات (Logs) في محرر Apps Script للاطلاع على رسائل الخطأ التفصيلية.
الخطوة 4: إعداد المزامنة التلقائية (اختياري)
لتشغيل المزامنة تلقائيًا وفقًا لجدول زمني:
-
في محرر Apps Script، انقر على أيقونة المشغلات (Triggers) (
) في الشريط الجانبي الأيسر -
انقر على + إضافة مشغل (+ Add Trigger) (أسفل اليمين)
-
قم بتكوين المشغل:
- الدالة المراد تشغيلها (Function to run):
syncDiscourseData - مصدر الحدث (Event source): مدفوع بالوقت (Time-driven)
- نوع المشغل المستند إلى الوقت (Type of time based trigger): اختر التكرار المفضل لديك (على سبيل المثال، مؤقت يومي، مؤقت ساعي)
- الوقت من اليوم/الفاصل الزمني (Time of day/interval): حدد متى تريد تشغيل المزامنة
- الدالة المراد تشغيلها (Function to run):
-
انقر على حفظ (Save)
التعامل مع الاستعلامات ذات المعلمات
إذا كان استعلام مستكشف البيانات الخاص بك يستخدم معلمات، فأضفها إلى حمولة الطلب (request payload):
const options = {
"method": "post",
"headers": {
"Api-Key": API_KEY,
"Api-Username": API_USERNAME
},
"payload": {
"params": JSON.stringify({
"start_date": "2024-01-01",
"category_id": "5"
})
}
};
يجب أن تكون جميع قيم المعلمات سلاسل نصية (strings)، حتى بالنسبة للمعلمات الرقمية.
لمزيد من التفاصيل حول تشغيل الاستعلامات ذات المعلمات، راجع: تشغيل استعلامات مستكشف البيانات باستخدام API الخاص بـ Discourse
التعامل مع مجموعات البيانات الكبيرة
يقتصر تصدير CSV افتراضيًا على 10000 صف كحد أقصى. بالنسبة لمجموعات البيانات الأكبر، قم بتطبيق التصفح (pagination) في الاستعلام الخاص بك باستخدام معلمات LIMIT و OFFSET:
--[params]
-- integer :limit = 1000
-- integer :page = 0
SELECT *
FROM your_table
OFFSET :page * :limit
LIMIT :limit
ثم قم بتعديل البرنامج النصي الخاص بك للتكرار عبر الصفحات حتى لا يتم إرجاع المزيد من النتائج.
استكشاف الأخطاء وإصلاحها
| المشكلة | الحل |
|---|---|
| خطأ 403 Forbidden (محظور) | تحقق من أن مفتاح API الخاص بك يحتوي على نطاق “تشغيل الاستعلامات” وأن اسم المستخدم لديه وصول إداري |
| خطأ 404 Not Found (غير موجود) | تحقق من أن معرّف الاستعلام صحيح وأن الاستعلام موجود |
| نتائج فارغة | تحقق من أن الاستعلام يُرجع بيانات عند تشغيله مباشرة في مستكشف البيانات |
| أخطاء تحديد المعدل (Rate limiting errors) | يحد Discourse من طلبات API الخاصة بمستكشف البيانات إلى طلبين كل 10 ثوانٍ افتراضيًا. أضف تأخيرات بين الطلبات إذا لزم الأمر |
موارد إضافية
- مستكشف بيانات Discourse
- تشغيل استعلامات مستكشف بيانات Discourse باستخدام API الخاص بـ Discourse
- إنشاء مفتاح API وتكوينه
- توثيق Google Apps Script UrlFetchApp