بناء نظام أتمتة لنشر المقالات من Google Sheets إلى Blogger تلقائياً

دقائق القراءة: 8

بناء نظام أتمتة لنشر المقالات من Google Sheets إلى Blogger تلقائياً

هل سئمت من العمليات اليدوية المتكررة لنشر المقالات؟ هل تحلم بتبسيط سير عملك وتحرير وقتك الثمين للتركيز على إنشاء محتوى عالي الجودة بدلاً من المهام الإدارية؟ إذاً، فإن بناء نظام أتمتة لنشر المقالات من Google Sheets إلى Blogger تلقائياً هو الحل الأمثل لك. في هذا المقال الشامل، سنغوص في أعماق كيفية إنشاء نظام آلي بالكامل ينقل مقالاتك المكتوبة في جداول بيانات Google Sheets مباشرة إلى مدونة Blogger الخاصة بك، مما يوفر عليك ساعات لا تحصى من العمل اليدوي ويضمن اتساق النشر.

لماذا الأتمتة؟ فوائد لا يمكن تجاهلها

في عالم المحتوى الرقمي سريع الخطى، تعد الكفاءة أمراً بالغ الأهمية. الأتمتة ليست مجرد رفاهية، بل ضرورة استراتيجية. إليك أبرز الفوائد التي ستحصل عليها:

  • توفير الوقت والجهد: بدلاً من النسخ واللصق يدوياً، يقوم النظام بالعمل نيابة عنك.
  • تقليل الأخطاء البشرية: تقلل الأتمتة من فرص الأخطاء الإملائية أو التنسيقية التي قد تحدث أثناء النشر اليدوي.
  • اتساق النشر: يمكنك جدولة المقالات أو نشرها فوراً بمجرد جاهزيتها، مما يحافظ على جدول نشر ثابت.
  • التركيز على الإبداع: حرر وقتك للتركيز على كتابة محتوى أفضل وتطوير استراتيجياتك التسويقية.
  • التحكم المركزي: إدارة جميع مقالاتك من مكان واحد (Google Sheet) قبل النشر.

الأدوات الأساسية التي سنستخدمها

لتحقيق هذا النظام الآلي، سنعتمد على ثلاث أدوات قوية ومتكاملة:

  • Google Sheets: لتخزين وتنظيم بيانات المقالات (العنوان، المحتوى، التصنيفات، الحالة).
  • Google Apps Script: بيئة تطوير قائمة على JavaScript تتيح لنا التفاعل مع خدمات Google المختلفة، وهي العقل المدبر لنظام الأتمتة لدينا.
  • Blogger API: الواجهة التي تسمح لـ Google Apps Script بالتفاعل برمجياً مع مدونة Blogger لإنشاء المقالات وتعديلها.

الخطوات التفصيلية لبناء نظام الأتمتة

الخطوة 1: إعداد جدول بيانات Google Sheets

ابدأ بإنشاء جدول بيانات جديد في Google Sheets. يجب أن يحتوي هذا الجدول على الأعمدة التالية كحد أدنى:

  • Title (العنوان): عنوان المقال.
  • Content (المحتوى): نص المقال بصيغة HTML.
  • Labels (التصنيفات): تصنيفات المقال مفصولة بفاصلة (مثال: SEO, أتمتة, برمجة).
  • Status (الحالة): لتتبع حالة النشر (مثال: جاهز للنشر، تم النشر، خطأ).
  • Post URL (رابط المقال): ليتم تحديثه برابط المقال بعد النشر.
💡 ملاحظة فنية: تأكد من أن محتوى المقال في عمود Content مكتوب بصيغة HTML لضمان التنسيق الصحيح عند النشر في Blogger. يمكنك استخدام أدوات تحويل النص إلى HTML إذا لزم الأمر.

الخطوة 2: تفعيل Blogger API وإنشاء بيانات الاعتماد

للسماح لـ Google Apps Script بالتفاعل مع مدونتك، تحتاج إلى تفعيل Blogger API وإنشاء بيانات اعتماد OAuth 2.0.

  1. انتقل إلى Google Cloud Console.
  2. أنشئ مشروعاً جديداً أو اختر مشروعاً موجوداً.
  3. من قائمة التنقل، اختر APIs & Services > Library.
  4. ابحث عن Blogger API v3 وقم بتفعيله.
  5. من قائمة التنقل، اختر APIs & Services > Credentials.
  6. انقر على CREATE CREDENTIALS > OAuth client ID.
  7. اختر Web application كنوع التطبيق.
  8. في حقل Authorized redirect URIs، أضف https://script.google.com/macros/d/[YOUR_SCRIPT_ID]/usercallback. ستحصل على [YOUR_SCRIPT_ID] لاحقاً عند نشر Google Apps Script كتطبيق ويب. في الوقت الحالي، يمكنك استخدام https://developers.google.com/oauthplayground كبديل مؤقت إذا كنت تختبر يدوياً، ولكن الأفضل هو استخدام Google Apps Script مباشرة.
  9. انقر على CREATE وستحصل على Client ID و Client Secret. احتفظ بهما بأمان.
💡 ملاحظة فنية: عند تشغيل Google Apps Script لأول مرة الذي يتفاعل مع Blogger API، سيطلب منك Google تفويض الوصول. تأكد من منح الأذونات اللازمة.

الخطوة 3: كتابة كود Google Apps Script

الآن نأتي إلى الجزء الأهم: كتابة الكود الذي سيربط كل شيء معاً.

  1. افتح جدول بيانات Google Sheets الذي أنشأته.
  2. من القائمة العلوية، اختر Extensions > Apps Script. سيفتح محرر Google Apps Script في علامة تبويب جديدة.
  3. الصق الكود التالي في ملف Code.gs. تأكد من استبدال YOUR_BLOG_ID بمعرف مدونتك على Blogger (يمكنك العثور عليه في رابط لوحة تحكم مدونتك، بعد blogID=).

const BLOG_ID = 'YOUR_BLOG_ID'; // استبدل هذا بمعرف مدونتك على Blogger
const SHEET_NAME = 'Sheet1'; // اسم الورقة التي تحتوي على بيانات المقالات
const STATUS_COLUMN_INDEX = 4; // العمود E (مؤشر 4) لحالة النشر
const POST_URL_COLUMN_INDEX = 5; // العمود F (مؤشر 5) لرابط المقال

/**
 * تنشر المقالات الجاهزة من Google Sheet إلى Blogger.
 */
function publishArticlesFromSheet() {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(SHEET_NAME);
  if (!sheet) {
    Logger.log('الورقة غير موجودة: ' + SHEET_NAME);
    return;
  }

  const dataRange = sheet.getDataRange();
  const values = dataRange.getValues();

  // تخطي الصف الأول (العناوين)
  for (let i = 1; i < values.length; i++) {
    const row = values[i];
    const title = row[0]; // العمود A
    const content = row[1]; // العمود B
    const labels = row[2] ? row[2].split(',').map(label => label.trim()) : []; // العمود C
    const status = row[3]; // العمود D

    if (status === 'جاهز للنشر') {
      try {
        const post = {
          kind: 'blogger#post',
          blog: { id: BLOG_ID },
          title: title,
          content: content,
          labels: labels,
          // يمكنك إضافة 'published': 'YYYY-MM-DDTHH:MM:SS-HH:MM' لجدولة النشر
          // أو 'published': new Date().toISOString() للنشر الفوري
        };

        const url = `https://www.googleapis.com/blogger/v3/blogs/${BLOG_ID}/posts/`;
        const options = {
          method: 'POST',
          contentType: 'application/json',
          payload: JSON.stringify(post),
          headers: {
            Authorization: 'Bearer ' + ScriptApp.getOAuthToken()
          },
          muteHttpExceptions: true
        };

        const response = UrlFetchApp.fetch(url, options);
        const responseCode = response.getResponseCode();
        const responseBody = response.getContentText();

        if (responseCode === 200) {
          const publishedPost = JSON.parse(responseBody);
          const postUrl = publishedPost.url;
          sheet.getRange(i + 1, STATUS_COLUMN_INDEX + 1).setValue('تم النشر');
          sheet.getRange(i + 1, POST_URL_COLUMN_INDEX + 1).setValue(postUrl);
          Logger.log('تم نشر المقال: ' + title + ' الرابط: ' + postUrl);
        } else {
          sheet.getRange(i + 1, STATUS_COLUMN_INDEX + 1).setValue('خطأ في النشر');
          Logger.log('خطأ في نشر المقال: ' + title + ' الكود: ' + responseCode + ' الاستجابة: ' + responseBody);
        }
      } catch (error) {
        sheet.getRange(i + 1, STATUS_COLUMN_INDEX + 1).setValue('خطأ في السكريبت');
        Logger.log('خطأ غير متوقع أثناء معالجة المقال: ' + title + ' الخطأ: ' + error.toString());
      }
    }
  }
}

/**
 * دالة مساعدة لإنشاء قائمة Blogger ID
 * يمكن تشغيلها مرة واحدة للحصول على ID المدونة
 */
function getBloggerBlogs() {
  const url = 'https://www.googleapis.com/blogger/v3/users/self/blogs';
  const options = {
    method: 'GET',
    headers: {
      Authorization: 'Bearer ' + ScriptApp.getOAuthToken()
    },
    muteHttpExceptions: true
  };

  try {
    const response = UrlFetchApp.fetch(url, options);
    const responseCode = response.getResponseCode();
    const responseBody = response.getContentText();

    if (responseCode === 200) {
      const blogs = JSON.parse(responseBody).items;
      if (blogs && blogs.length > 0) {
        Logger.log('مدوناتك على Blogger:');
        blogs.forEach(blog => {
          Logger.log(`الاسم: ${blog.name}, ID: ${blog.id}`);
        });
      } else {
        Logger.log('لم يتم العثور على مدونات Blogger.');
      }
    } else {
      Logger.log('خطأ في جلب المدونات: ' + responseCode + ' ' + responseBody);
    }
  } catch (error) {
    Logger.log('خطأ غير متوقع أثناء جلب المدونات: ' + error.toString());
  }
}
    

شرح الكود:

  • BLOG_ID: يجب استبداله بمعرف مدونتك.
  • SHEET_NAME: اسم الورقة التي تحتوي على بيانات المقالات.
  • STATUS_COLUMN_INDEX و POST_URL_COLUMN_INDEX: مؤشرات الأعمدة لتحديث حالة النشر ورابط المقال. (تذكر أن المؤشرات تبدأ من 0، لذا العمود E هو 4).
  • دالة publishArticlesFromSheet(): هي الدالة الرئيسية التي تقرأ البيانات من الورقة، وتتحقق من حالة 'جاهز للنشر'، ثم تستخدم Blogger API لنشر المقال.
  • UrlFetchApp.fetch(): تستخدم لإرسال طلبات HTTP إلى Blogger API.
  • ScriptApp.getOAuthToken(): للحصول على رمز الوصول OAuth اللازم للمصادقة مع Google API.
  • JSON.stringify() و JSON.parse(): لتحويل كائنات JavaScript إلى سلاسل JSON والعكس.
  • دالة getBloggerBlogs(): دالة مساعدة مفيدة يمكنك تشغيلها مرة واحدة من محرر Apps Script للحصول على معرفات جميع مدوناتك على Blogger، مما يسهل عليك تحديد BLOG_ID الصحيح.

الخطوة 4: إعداد المشغلات (Triggers)

لجعل النظام آلياً بالكامل، تحتاج إلى إعداد مشغل (Trigger) لتشغيل دالة publishArticlesFromSheet() تلقائياً.

  1. في محرر Google Apps Script، انقر على أيقونة الساعة (Triggers) في الشريط الجانبي الأيسر.
  2. انقر على Add Trigger (إضافة مشغل).
  3. في نافذة Add Trigger:
    • اختر publishArticlesFromSheet للدالة المراد تشغيلها.
    • اختر Head لإصدار النشر.
    • اختر Time-driven كنوع حدث (Event type).
    • اختر تكراراً مناسباً، على سبيل المثال، Every hour (كل ساعة) أو Every 30 minutes (كل 30 دقيقة) حسب احتياجاتك.
  4. انقر على Save.
💡 ملاحظة فنية: عند حفظ المشغل لأول مرة، سيطلب منك Google مراجعة الأذونات ومنحها للسكريبت. تأكد من الموافقة على جميع الأذونات المطلوبة لكي يعمل السكريبت بشكل صحيح.

اعتبارات متقدمة

  • التعامل مع الصور: يمكن تضمين الصور في محتوى HTML باستخدام روابط URL مباشرة للصور المستضافة. إذا كنت ترغب في تحميل الصور إلى Blogger مباشرة، فسيتطلب ذلك استخدام Blogger API لرفع الصور أولاً، وهو أكثر تعقيداً.
  • جدولة النشر: يمكن لـ Blogger API قبول حقل published لتحديد تاريخ ووقت النشر المستقبلي، مما يتيح لك جدولة المقالات بدقة.
  • تحديث المقالات: بدلاً من النشر فقط، يمكنك تعديل الكود لتحديث المقالات الموجودة باستخدام طلبات PUT إلى Blogger API إذا كان لديك معرف المقال.
  • نشر مسودات: يمكنك تعيين isDraft: true في كائن المقال لإرسال المقال كمسودة بدلاً من نشره مباشرة.

الخاتمة

لقد قمت الآن ببناء نظام أتمتة قوي وفعال لنشر المقالات من Google Sheets إلى Blogger تلقائياً. هذا النظام لن يوفر عليك الوقت والجهد فحسب، بل سيحسن أيضاً من كفاءة سير عملك ويسمح لك بالتركيز بشكل أكبر على جوهر عملك: إنشاء محتوى قيم. استثمر في الأتمتة، وشاهد إنتاجيتك ترتفع!

الأسئلة الشائعة (FAQ)

س1: هل يمكنني استخدام هذا النظام مع منصات تدوين أخرى غير Blogger؟

ج1: المفهوم الأساسي للأتمتة من Google Sheets باستخدام Google Apps Script يمكن تطبيقه على منصات أخرى. ومع ذلك، ستحتاج إلى تعديل الكود للتفاعل مع API الخاص بتلك المنصة (مثل WordPress REST API أو Medium API)، حيث تختلف متطلبات المصادقة وهياكل البيانات.

س2: ما هي حدود عدد المقالات التي يمكن نشرها يومياً باستخدام Blogger API؟

ج2: Blogger API، مثل معظم Google APIs، لديها حصص استخدام (quotas) لضمان الاستخدام العادل ومنع إساءة الاستخدام. عادةً ما تكون هذه الحصص سخية بما يكفي للمدونين الأفراد والشركات الصغيرة. يمكنك مراجعة صفحة حصص Blogger API في Google Cloud Console لمشاهدة حدودك الحالية واستخدامك.

س3: هل يمكنني تضمين صور في المقالات المنشورة تلقائياً؟

ج3: نعم، يمكنك تضمين صور في المقالات المنشورة تلقائياً عن طريق تضمين وسوم <img> مع روابط URL مباشرة للصور المستضافة مسبقاً (على سبيل المثال، على Google Photos أو خدمة استضافة صور أخرى) ضمن محتوى HTML في عمود Content في Google Sheets. رفع الصور مباشرة إلى Blogger عبر API يتطلب خطوات إضافية وأكثر تعقيداً.

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *