الكتابات/tutorial/2026/08
Tutorial10 أغسطس 2026·25 دقيقة

Activepieces مع TypeScript: بناء أتمتة سير عمل مخصصة للمشاريع العربية والخليجية

تعلم كيف تستضيف Activepieces بنفسك وتبني قطعاً مخصصة بـ TypeScript لأتمتة عمليات شركتك — مع مثال عملي خليجي: تذكير تلقائي بمواعيد تقارير هيئة الزكاة عبر واتساب.

Activepieces منصة أتمتة سير عمل مفتوحة المصدر (رخصة MIT) تنتشر بسرعة بين الفرق التقنية الناطقة بالعربية وشركات منطقة الشرق الأوسط وشمال أفريقيا. على عكس أدوات الأتمتة التي تفرض رسوماً لكل مهمة أو تنفيذ، يمكن تشغيل Activepieces على خادمك الخاص دون أي تكاليف إضافية. وعلى عكس n8n — التي يطغى عليها المحتوى العربي للمبتدئين — تعتمد Activepieces على TypeScript بشكل أصيل، مما يعني أن كل تكامل (يُسمى piece) مبني بنفس TypeScript الذي تكتبه بالفعل.

في هذا الدليل ستتعلم:

  1. استضافة Activepieces باستخدام Docker Compose في أقل من 10 دقائق
  2. بناء أول flow يربط Google Sheets بواتساب
  3. إنشاء قطعة TypeScript مخصصة باستخدام حزمة @activepieces/pieces-framework
  4. تطبيق مثال خليجي حقيقي: حساب موعد تقديم الإقرار الضريبي لهيئة الزكاة وإرسال تذكير عبر واتساب تلقائياً

المتطلبات الأساسية

قبل البدء، تأكد من توفر ما يلي:

  • Docker و Docker Compose مثبتَين
  • Node.js 20 فأعلى مع npm
  • خادم أو جهاز محلي بذاكرة وصول عشوائي لا تقل عن 2 GB
  • حساب واتساب للأعمال أو صلاحية الوصول إلى WhatsApp Cloud API من Meta
  • معرفة أساسية بـ TypeScript (async/await، الواجهات، الأنواع العامة)

ما هو Activepieces؟

Activepieces منصة أتمتة بصرية (drag-and-drop). كل أتمتة تُسمى flow وتتكون من:

  • مُشغِّل (Trigger) — ما يبدأ تشغيل الـ flow (webhook، جدول زمني، أو حدث من تطبيق)
  • إجراءات (Actions) — ما يحدث بعد ذلك (إرسال رسالة، تحديث قاعدة بيانات، استدعاء API)

كل مشغل أو إجراء هو piece — الوحدة الأساسية للتكامل في Activepieces. يوجد أكثر من 400 قطعة جاهزة تغطي Google Workspace وSlack وواتساب وNotion وPostgreSQL وغيرها.

لماذا Activepieces للمطورين في السعودية ودول الخليج؟

الميزةActivepiecesn8nZapier
الرخصةMIT (مجاني للأبد)Fair-code (مقيدة)SaaS فقط
الاستضافة الذاتيةنعمنعملا
لغة SDKTypeScriptJavaScript/TSلا SDK
رسوم لكل مهمةلالانعم
واجهة عربيةنعملالا

Activepieces هو الاختيار العملي عندما تحتاج إلى سيادة كاملة على البيانات (لا تغادر خوادمك)، وتمديد TypeScript-native، وحرية من رسوم الاستخدام.

الخطوة 1: استضافة Activepieces مع Docker

أنشئ مجلد المشروع:

mkdir activepieces-deploy
cd activepieces-deploy

أنشئ ملف docker-compose.yml:

version: "3"
services:
  activepieces:
    image: activepieces/activepieces:latest
    ports:
      - "8080:80"
    depends_on:
      - postgres
      - redis
    environment:
      - AP_DB_TYPE=POSTGRES
      - AP_POSTGRES_DATABASE=activepieces
      - AP_POSTGRES_HOST=postgres
      - AP_POSTGRES_PORT=5432
      - AP_POSTGRES_USERNAME=activepieces
      - AP_POSTGRES_PASSWORD=كلمة_مرور_قوية_هنا
      - AP_REDIS_URL=redis://redis:6379
      - AP_ENCRYPTION_KEY=مفتاح_تشفير_32_حرف_هنا
      - AP_JWT_SECRET=سر_jwt_هنا
      - AP_FRONTEND_URL=http://localhost:8080
      - AP_SIGN_UP_ENABLED=true
      - AP_TELEMETRY_ENABLED=false
    volumes:
      - activepieces_data:/root/.activepieces
 
  postgres:
    image: postgres:15
    environment:
      - POSTGRES_DB=activepieces
      - POSTGRES_USER=activepieces
      - POSTGRES_PASSWORD=كلمة_مرور_قوية_هنا
    volumes:
      - postgres_data:/var/lib/postgresql/data
 
  redis:
    image: redis:7
    volumes:
      - redis_data:/data
 
volumes:
  activepieces_data:
  postgres_data:
  redis_data:

أنشئ مفتاح تشفير آمن بطول 32 حرفاً:

openssl rand -hex 16

استبدل مفتاح_تشفير_32_حرف_هنا بالناتج وضع قيمة قوية لـ AP_JWT_SECRET. ثم شغّل الحاوية:

docker compose up -d

بعد نحو 60 ثانية، افتح http://localhost:8080 في المتصفح وأنشئ حساب المسؤول.

الخطوة 2: أول Flow — إشعار واتساب عند إضافة صف في Google Sheets

هذا الـ flow يُطلَق عند إضافة صف جديد في جدول Google Sheets (مثل نموذج استفسار عميل) ويرسل رسالة واتساب لفريقك.

في لوحة تحكم Activepieces:

  1. اضغط New Flow وسمّه "إشعار استفسار جديد"
  2. اضغط Trigger ← ابحث عن Google Sheets ← اختر New Row Added
  3. وصّل حساب Google، ثم اختر جدول البيانات والورقة المستهدفة
  4. اضغط زر + لإضافة إجراء
  5. ابحث عن WhatsApp Business Cloud ← اختر Send Text Message
  6. في حقل نص الرسالة، اربط أعمدة الصف — مثال: "استفسار جديد من [الاسم] — الجوال: [الجوال]"
  7. اضغط Test Step على كل خطوة للتأكد من الاتصال
  8. فعّل الـ flow بتحريك المفتاح إلى Active

Flow يعمل الآن. لا كود مكتوب، لا إدارة خوادم إضافية.

الخطوة 3: بناء قطعة TypeScript مخصصة

القطع الجاهزة تغطي معظم حالات الاستخدام، لكن القطع المخصصة تتيح لك ربط أي API خاص بسوقك أو قطاعك. هنا تتألق TypeScript SDK في Activepieces.

إعداد بيئة التطوير

استنسخ مستودع Activepieces الرئيسي:

git clone https://github.com/activepieces/activepieces.git
cd activepieces
npm install

أنشئ قطعة جديدة باستخدام CLI:

npm run create-piece

أدخل zatca-reminder اسماً للقطعة. سيُنشئ الأمر هذه البنية:

packages/pieces/custom/zatca-reminder/
├── src/
│   ├── index.ts
│   └── lib/
│       ├── actions/
│       │   └── get-next-deadline.ts
│       └── triggers/
├── package.json
└── tsconfig.json

نقطة دخول القطعة

افتح src/index.ts:

import { createPiece, PieceAuth } from '@activepieces/pieces-framework';
import { getNextDeadlineAction } from './lib/actions/get-next-deadline';
 
export const zatcaReminder = createPiece({
  displayName: 'ZATCA Reminder',
  auth: PieceAuth.None(),
  minimumSupportedRelease: '0.20.0',
  logoUrl: 'https://your-cdn.com/zatca-logo.png',
  authors: ['your-name'],
  actions: [getNextDeadlineAction],
  triggers: [],
});

لا نحتاج مصادقة هنا لأن القطعة تُجري حسابات تاريخية محلية فقط. للقطع التي تستدعي APIs خارجية، استخدم PieceAuth.SecretText() أو PieceAuth.CustomAuth().

بناء الإجراء: حساب موعد إقرار ZATCA

استبدل محتوى src/lib/actions/get-next-deadline.ts:

import {
  createAction,
  Property,
} from '@activepieces/pieces-framework';
 
export const getNextDeadlineAction = createAction({
  name: 'get_next_deadline',
  displayName: 'حساب موعد إقرار ZATCA التالي',
  description: 'يحسب الموعد النهائي التالي لتقديم الإقرار الضريبي أو الفاتورة الإلكترونية لدى هيئة الزكاة.',
  props: {
    filingPeriod: Property.StaticDropdown({
      displayName: 'دورة الإقرار',
      description: 'هل الشركة مُقِرّة شهرياً أم ربع سنوياً؟',
      required: true,
      options: {
        options: [
          { label: 'شهري', value: 'monthly' },
          { label: 'ربع سنوي', value: 'quarterly' },
        ],
      },
    }),
    referenceDate: Property.ShortText({
      displayName: 'تاريخ المرجع (YYYY-MM-DD)',
      description: 'تاريخ بداية الحساب. اتركه فارغاً لاستخدام اليوم.',
      required: false,
    }),
  },
 
  async run(context) {
    const { filingPeriod, referenceDate } = context.propsValue;
 
    const base = referenceDate ? new Date(referenceDate) : new Date();
    const year = base.getFullYear();
    const month = base.getMonth(); // 0-indexed
 
    let deadlineDate: Date;
 
    if (filingPeriod === 'monthly') {
      // المُقِرّون الشهريون: يقدمون بحلول نهاية الشهر التالي
      deadlineDate = new Date(year, month + 2, 0);
    } else {
      // المُقِرّون ربع سنوياً: الربع الأول (يناير-مارس) موعده 30 أبريل، وهكذا
      const quarter = Math.floor(month / 3);
      const deadlineMonth = (quarter + 1) * 3;
      deadlineDate = new Date(year, deadlineMonth + 1, 0);
    }
 
    const formatted = deadlineDate.toISOString().split('T')[0];
    const msPerDay = 1000 * 60 * 60 * 24;
    const daysRemaining = Math.ceil(
      (deadlineDate.getTime() - base.getTime()) / msPerDay
    );
 
    const arabicMessage =
      filingPeriod === 'monthly'
        ? `تذكير ZATCA: موعد الإقرار الشهري ${formatted} — بعد ${daysRemaining} يوم`
        : `تذكير ZATCA: موعد الإقرار الفصلي ${formatted} — بعد ${daysRemaining} يوم`;
 
    return {
      deadlineDate: formatted,
      daysRemaining,
      arabicMessage,
      isUrgent: daysRemaining <= 7,
    };
  },
});

ما تُعيده هذه الدالة:

  • deadlineDate — تاريخ الموعد النهائي بصيغة ISO
  • daysRemaining — عدد الأيام المتبقية
  • arabicMessage — نص رسالة واتساب جاهز بالعربية
  • isUrgent — قيمة منطقية تصبح true إذا كان الموعد خلال 7 أيام أو أقل

الخطوة 4: اختبار القطعة محلياً

بناء القطعة:

npm run build -- --filter=@activepieces/piece-zatca-reminder

تشغيل خادم التطوير مع تحميل قطعتك:

AP_DEV_PIECES=zatca-reminder npm run start

افتح http://localhost:4200. ستجد قطعتك في محرك البحث بلوحة بناء الـ flows — ابحث عن "ZATCA".

بناء الـ flow الكامل للتذكير:

  1. المشغل: جدول زمني (Schedule) → اضبطه ليعمل في اليوم العشرين من كل شهر
  2. الإجراء 1: ZATCA Reminder → حساب موعد ZATCA → دورة الإقرار: شهري
  3. الإجراء 2: فلتر — أكمل فقط إذا كانت قيمة isUrgent تساوي true
  4. الإجراء 3: WhatsApp Business Cloud → إرسال رسالة نصية → النص: ناتج arabicMessage من الإجراء الأول

فريق المالية يتلقى الآن تذكيراً تلقائياً عبر واتساب في كل مرة يقترب فيها موعد إقرار ZATCA.

الخطوة 5: إضافة القطعة إلى بيئة الإنتاج

بعد الاختبار، احزم القطعة لنشرها على نسخة Activepieces الإنتاجية.

أنشئ Dockerfile مخصصاً يمتد من الصورة الرسمية:

FROM activepieces/activepieces:latest
COPY packages/pieces/custom/zatca-reminder/dist /root/custom-pieces/zatca-reminder

أضف مسار القطعة المخصصة في Docker Compose:

environment:
  - AP_CUSTOM_PIECES_PATH=/root/custom-pieces

أعد البناء وأعد التشغيل:

docker compose build
docker compose up -d

قطعة ZATCA Reminder متاحة الآن في لوحة بناء الـ flows الإنتاجية إلى جانب جميع القطع الجاهزة.

استكشاف الأخطاء وإصلاحها

الحاوية لا تبدأ: شغّل docker compose logs activepieces لقراءة سجل البدء. أشيع الأسباب: AP_ENCRYPTION_KEY غير صحيح أو منقوص — يجب أن يكون 32 حرفاً هكساديسيمياً (ناتج openssl rand -hex 16).

القطعة المخصصة لا تظهر في البحث: بعد البناء، أعد تشغيل الحاوية وامسح كاش المتصفح. تأكد أن قيمة AP_DEV_PIECES تطابق اسم الحزمة في package.json وليس displayName.

رسائل واتساب لا تصل: رموز التوكن المؤقتة من Meta تنتهي صلاحيتها خلال 24 ساعة. في بيئة الإنتاج، أنشئ رمز مستخدم نظام دائماً من Meta Business Manager ضمن Business Settings → System Users.

أخطاء TypeScript في قطعتك: شغّل npx tsc --noEmit داخل مجلد القطعة. أنواع الإطار صارمة — جميع قيم Property تُعيد unknown بشكل افتراضي، فحوّلها صراحةً أو استخدم النوع المساعد PiecePropValueSchema.

الخطوات التالية

نمط القطعة المخصصة نفسه ينطبق على أي API خاص بمنطقة MENA:

  • مراقبة نطاقات Qiwa — استعلم عن نطاقات الامتثال دورياً وأرسل تنبيهاً لمدير الموارد البشرية عبر واتساب عند تغير النطاق
  • مشغّل مدفوعات Moyasar — استقبل webhook من Moyasar وابدأ flow يُحدّث CRM تلقائياً
  • استعلام حالة مطالبات NPHIES — تحقق من حالة المطالبات الصحية يومياً وأرسل تنبيهاً لفريق الفوترة عند أي تغيير

لمزيد من الخلفية التجارية، اطلع على دليل أتمتة سير العمل بالذكاء الاصطناعي للشركات الصغيرة وتحليل تكاليف أتمتة سير العمل في السعودية.

إذا كان فريقك يعتمد واتساب كقناة تواصل رئيسية مع العملاء، فاطلع على دليل وكيل واتساب بـ TypeScript لمعالجة الرسائل الواردة بذكاء.


هل تريد أتمتة عمليات شركتك السعودية أو الخليجية باستخدام Activepieces؟ فريقنا متخصص في تكامل API وحلول الأتمتة المخصصة لأسواق الشرق الأوسط وشمال أفريقيا. تواصل معنا لمناقشة مشروعك.