ما هي التطبيقات؟
تتيح لك التطبيقات إنشاء وإدارة تخصيصات Twenty ككود. بدلًا من تكوين كل شيء عبر واجهة المستخدم، تُعرِّف نموذج بياناتك ووظائف المنطق في الكود — مما يجعل البناء والصيانة والنشر إلى مساحات عمل متعددة أسرع. ما الذي يمكنك فعله اليوم:- عرِّف كائنات وحقولًا مخصصة على شكل كود (نموذج بيانات مُدار)
- أنشئ وظائف منطقية مع مشغلات مخصصة
- حدد المهارات لوكلاء الذكاء الاصطناعي
- انشر التطبيق نفسه عبر مساحات عمل متعددة
المتطلبات الأساسية
- Node.js 24+ وYarn 4
- مساحة عمل Twenty ومفتاح واجهة برمجة التطبيقات (أنشئ واحدًا على https://app.twenty.com/settings/api-webhooks)
البدء
أنشئ تطبيقًا جديدًا باستخدام المُهيئ الرسمي، ثم قم بالمصادقة وابدأ التطوير:هيكل المشروع (مُنشأ بالقالب)
عند تشغيلnpx create-twenty-app@latest my-twenty-app، يقوم المُهيئ بما يلي:
- ينسخ تطبيقًا أساسيًا مصغّرًا إلى
my-twenty-app/ - يضيف اعتمادًا محليًا
twenty-sdkوتهيئة Yarn 4 - ينشئ ملفات ضبط ونصوصًا مرتبطة بـ
twentyCLI - يُنشئ الملفات الأساسية (تهيئة التطبيق، دور الدالة الافتراضي، دالة ما بعد التثبيت) بالإضافة إلى ملفات الأمثلة بحسب وضع الإنشاء
--exhaustive كما يلي:
--minimal، سيتم إنشاء الملفات الأساسية فقط (application-config.ts وroles/default-role.ts وlogic-functions/post-install.ts). مع --interactive، تختار ملفات الأمثلة التي تريد تضمينها.
بشكل عام:
- package.json: يصرّح باسم التطبيق والإصدار والمحرّكات (Node 24+، Yarn 4)، ويضيف
twenty-sdkبالإضافة إلى نص برمجيtwentyيفوِّض إلىtwentyCLI المحلي. شغِّلyarn twenty helpلعرض جميع الأوامر المتاحة. - .gitignore: يتجاهل العناصر الشائعة مثل
node_modulesو.yarnوgenerated/(عميل مضبوط الأنواع) وdist/وbuild/ومجلدات التغطية وملفات السجلات وملفات.env*. - yarn.lock، .yarnrc.yml، .yarn/: تقوم بقفل وتكوين حزمة أدوات Yarn 4 المستخدمة في المشروع.
- .nvmrc: يثبّت إصدار Node.js المتوقع للمشروع.
- eslint.config.mjs وtsconfig.json: يقدّمان إعدادات الفحص والتهيئة لـ TypeScript لمصادر TypeScript في تطبيقك.
- README.md: ملف README قصير في جذر التطبيق يتضمن تعليمات أساسية.
- public/: مجلد لتخزين الأصول العامة (صور، خطوط، ملفات ثابتة) التي سيتم تقديمها مع تطبيقك. الملفات الموضوعة هنا تُرفع أثناء المزامنة وتكون متاحة أثناء وقت التشغيل.
- src/: المكان الرئيسي حيث تعرّف تطبيقك ككود
اكتشاف الكيانات
يكتشف SDK الكيانات عبر تحليل ملفات TypeScript الخاصة بك بحثًا عن استدعاءاتexport default define<Entity>({...}). يحتوي كل نوع كيان على دالة مساعدة مقابلة يتم تصديرها من twenty-sdk:
| دالة مساعدة | نوع الكيان |
|---|---|
defineObject() | تعريفات كائنات مخصصة |
defineLogicFunction() | تعريفات الوظائف المنطقية |
defineFrontComponent() | Front component definitions |
defineRole() | تعريفات الأدوار |
defineField() | امتدادات الحقول للكائنات الموجودة |
defineView() | تعريفات العروض المحفوظة |
defineNavigationMenuItem() | تعريفات عناصر قائمة التنقل |
defineSkill() | تعريفات مهارات وكيل الذكاء الاصطناعي |
تسمية الملفات مرنة. يعتمد اكتشاف الكيانات على بنية الشجرة المجردة (AST) — إذ يقوم SDK بفحص ملفات المصدر لديك بحثًا عن النمط
export default define<Entity>({...}). يمكنك تنظيم ملفاتك ومجلداتك كيفما تشاء. التجميع حسب نوع الكيان (مثلًا، logic-functions/ وroles/) هو مجرد عرف لتنظيم الشيفرة، وليس مطلبًا إلزاميًا.yarn twenty app:devسيولّد تلقائيًا عميل API مضبوط الأنواع فيnode_modules/twenty-sdk/generated(عميل Twenty مضبوط الأنواع + أنواع مساحة العمل).yarn twenty entity:addسيضيف ملفات تعريف الكيانات ضمنsrc/لكائناتك المخصّصة، والوظائف، ومكوّنات الواجهة الأمامية، والأدوار، والمهارات، وغير ذلك.
المصادقة
في المرة الأولى التي تشغّل فيهاyarn twenty auth:login، سيُطلب منك إدخال:
- عنوان URL لواجهة برمجة التطبيقات (الافتراضي http://localhost:3000 أو ملف تعريف مساحة العمل الحالية لديك)
- مفتاح واجهة برمجة التطبيقات
~/.twenty/config.json. You can maintain multiple profiles and switch between them.
Managing workspaces
yarn twenty auth:switch، ستستخدم جميع الأوامر اللاحقة تلك المساحة افتراضيًا. You can still override it temporarily with --workspace <name>.
استخدم موارد SDK (الأنواع والتكوين)
يوفّر twenty-sdk كتلَ بناءٍ مضبوطة الأنواع ودوال مساعدة تستخدمها داخل تطبيقك. فيما يلي الأجزاء الأساسية التي ستتعامل معها غالبًا.دوال مساعدة
يوفّر SDK دوالًا مساعدة لتعريف كيانات تطبيقك. كما هو موضح في اكتشاف الكيانات، يجب استخدامexport default define<Entity>({...}) كي يتم اكتشاف كياناتك:
| دالة | الغرض |
|---|---|
defineApplication() | تهيئة بيانات التعريف للتطبيق (مطلوب، واحد لكل تطبيق) |
defineObject() | تعريف كائنات مخصصة مع حقول |
defineLogicFunction() | تعريف وظائف منطقية مع معالجات |
defineFrontComponent() | عرِّف مكوّنات أمامية لواجهة مستخدم مخصّصة |
defineRole() | تهيئة صلاحيات الدور والوصول إلى الكائنات |
defineField() | وسّع الكائنات الموجودة بحقول إضافية |
defineView() | تعريف العروض المحفوظة للكائنات |
defineNavigationMenuItem() | تعريف روابط التنقل في الشريط الجانبي |
defineSkill() | عرّف مهارات وكيل الذكاء الاصطناعي |
تعريف الكائنات
تصف الكائنات المخصصة كلًا من المخطط والسلوك للسجلات في مساحة عملك. استخدمdefineObject() لتعريف كائنات مع تحقق مدمج:
- استخدم
defineObject()للحصول على تحقق مدمج ودعم أفضل من IDE. universalIdentifierيجب أن يكون فريدًا وثابتًا عبر عمليات النشر.- يتطلب كل حقل
nameوtypeوlabelومعرّفuniversalIdentifierثابتًا خاصًا به. - المصفوفة
fieldsاختيارية — يمكنك تعريف كائنات بدون حقول مخصصة. - يمكنك إنشاء كائنات جديدة باستخدام
yarn twenty entity:add، والذي يرشدك خلال التسمية والحقول والعلاقات.
يتم إنشاء الحقول الأساسية تلقائيًا. عند تعريف كائن مخصص، يضيف Twenty تلقائيًا حقولًا قياسية
مثل
id وname وcreatedAt وupdatedAt وcreatedBy وupdatedBy وdeletedAt.
لا تحتاج إلى تعريف هذه في مصفوفة fields — أضف فقط حقولك المخصصة.
يمكنك تجاوز الحقول الافتراضية من خلال تعريف حقل بالاسم نفسه في مصفوفة fields الخاصة بك،
لكن هذا غير مستحسن.تكوين التطبيق (application-config.ts)
كل تطبيق لديه ملف واحدapplication-config.ts يصف:
- هوية التطبيق: المعرفات، اسم العرض، والوصف.
- كيفية تشغيل وظائفه: الدور الذي تستخدمه للأذونات.
- متغيرات (اختياري): أزواج مفتاح-قيمة تُعرض لوظائفك كمتغيرات بيئة.
- (Optional) post-install function: a logic function that runs after the app is installed.
defineApplication() to define your application configuration:
- حقول
universalIdentifierهي معرّفات حتمية تخصك؛ أنشئها مرة واحدة واحتفظ بها ثابتة عبر عمليات المزامنة. applicationVariablesتصبح متغيرات بيئة لوظائفك (على سبيل المثال،DEFAULT_RECIPIENT_NAMEمتاح كـprocess.env.DEFAULT_RECIPIENT_NAME).defaultRoleUniversalIdentifierيجب أن يطابق ملف الدور (انظر أدناه).postInstallLogicFunctionUniversalIdentifier(optional) points to a logic function that runs automatically after the app is installed. See Post-install functions.
الأدوار والصلاحيات
يمكن للتطبيقات تعريف أدوار تُغلّف الصلاحيات على كائنات وإجراءات مساحة العمل لديك. يعين الحقلdefaultRoleUniversalIdentifier في application-config.ts الدور الافتراضي الذي تستخدمه وظائف المنطق في تطبيقك.
- مفتاح واجهة البرمجة في وقت التشغيل المحقون باسم
TWENTY_API_KEYمستمد من دور الوظيفة الافتراضي هذا. - سيُقيَّد العميل مضبوط الأنواع بالأذونات الممنوحة لذلك الدور.
- اتبع مبدأ أقل الامتياز: أنشئ دورًا مخصصًا بالأذونات التي تحتاجها وظائفك فقط، ثم أشِر إلى معرّفه الشامل.
الدور الافتراضي للوظيفة (*.role.ts)
عند توليد تطبيق جديد بالقالب، ينشئ CLI أيضًا ملف دور افتراضي. استخدمdefineRole() لتعريف أدوار مع تحقق مدمج:
universalIdentifier لهذا الدور في application-config.ts باسم defaultRoleUniversalIdentifier. بعبارة أخرى:
- \*.role.ts يحدد ما يمكن أن يفعله الدور الافتراضي للوظيفة.
- application-config.ts يشير إلى ذلك الدور بحيث ترث وظائفك أذوناته.
- ابدأ من الدور المُنشأ بالقالب، ثم قيّده تدريجيًا باتباع مبدأ أقل الامتياز.
- استبدل
objectPermissionsوfieldPermissionsبالكائنات/الحقول التي تحتاجها وظائفك. permissionFlagsتتحكم في الوصول إلى القدرات على مستوى المنصة. اجعلها في الحد الأدنى؛ أضف فقط ما تحتاجه.- اطّلع على مثال عملي في تطبيق Hello World:
packages/twenty-apps/hello-world/src/roles/function-role.ts.
تكوين الوظيفة المنطقية ونقطة الدخول
كل ملف وظيفة يستخدمdefineLogicFunction() لتصدير تكوين مع معالج ومشغّلات اختيارية.
- route: يعرِض وظيفتك على مسار وطريقة HTTP تحت نقطة النهاية
/s/:
مثال:path: '/post-card/create',-> الاستدعاء على<APP_URL>/s/post-card/create
- cron: يشغّل وظيفتك على جدول باستخدام تعبير CRON.
- databaseEvent: يعمل على أحداث دورة حياة كائنات مساحة العمل. عندما تكون عملية الحدث هي
updated، يمكن تحديد الحقول المحددة المراد الاستماع إليها في مصفوفةupdatedFields. إذا تُركت غير معرّفة أو فارغة، فسيؤدي أي تحديث إلى تشغيل الدالة.
مثال: person.updated
الملاحظات:
- المصفوفة
triggersاختيارية. يمكن استخدام الوظائف بدون مشغلات كوظائف مساعدة تُستدعى بواسطة وظائف أخرى. - يمكنك مزج أنواع متعددة من المشغلات في وظيفة واحدة.
Post-install functions
A post-install function is a logic function that runs automatically after your app is installed on a workspace. This is useful for one-time setup tasks such as seeding default data, creating initial records, or configuring workspace settings. عند إنشاء هيكل تطبيق جديد باستخدامcreate-twenty-app، يتم إنشاء دالة ما بعد التثبيت لك في src/logic-functions/post-install.ts:
application-config.ts:
- دوال ما بعد التثبيت هي دوال منطقية قياسية — فهي تستخدم
defineLogicFunction()مثل أي دالة أخرى. - حقل
postInstallLogicFunctionUniversalIdentifierفيdefineApplication()اختياري. إذا تم تجاهله، لن يتم تشغيل أي دالة بعد التثبيت. - تم تعيين مهلة افتراضية إلى 300 ثانية (5 دقائق) للسماح بمهام الإعداد الأطول مثل تهيئة البيانات.
- لا تحتاج دوال ما بعد التثبيت إلى مُشغِّلات — حيث يستدعيها النظام الأساسي أثناء التثبيت أو يدويًا عبر
function:execute --postInstall.
حمولة مشغل المسار
عندما يستدعي مشغّل المسار وظيفتك المنطقية، يتلقى كائنًا من النوعRoutePayload يتبع تنسيق AWS HTTP API v2. استورد النوع من twenty-sdk:
RoutePayload على البنية التالية:
| الخاصية | النوع | الوصف |
|---|---|---|
headers | Record<string, string | undefined> | رؤوس HTTP (فقط تلك المدرجة في forwardedRequestHeaders) |
queryStringParameters | Record<string, string | undefined> | معلمات سلسلة الاستعلام (تُضمّ القيم المتعددة باستخدام فواصل) |
pathParameters | Record<string, string | undefined> | معلمات المسار المستخرجة من نمط المسار (على سبيل المثال، /users/:id → { id: '123' }) |
المحتوى | object | null | جسم الطلب المُحلَّل (JSON) |
isBase64Encoded | قيمة منطقية | ما إذا كان جسم الطلب مُرمَّزًا بترميز base64 |
requestContext.http.method | string | طريقة HTTP (GET, POST, PUT, PATCH, DELETE) |
requestContext.http.path | string | المسار الخام للطلب |
تمرير رؤوس HTTP
افتراضيًا، لا تُمرَّر رؤوس HTTP من الطلبات الواردة إلى وظيفتك المنطقية لأسباب أمنية. للوصول إلى رؤوس محددة، قم بإدراجها صراحةً في مصفوفةforwardedRequestHeaders:
تُحوَّل أسماء الرؤوس إلى أحرف صغيرة. يمكنك الوصول إليها باستخدام مفاتيح بأحرف صغيرة (على سبيل المثال،
event.headers['content-type']).- مُنشأ بالقالب: شغّل
yarn twenty entity:addواختر خيار إضافة وظيفة منطقية جديدة. يُولّد هذا ملفًا مبدئيًا مع معالج وتكوين. - يدوي: أنشئ ملفًا جديدًا
*.logic-function.tsواستخدمdefineLogicFunction()مع اتباع النمط نفسه.
تمييز دالة منطقية كأداة
يمكن إتاحة الدوال المنطقية بوصفها أدوات لوكلاء الذكاء الاصطناعي وسير العمل. عندما يتم تمييز دالة كأداة، تصبح قابلة للاكتشاف بواسطة ميزات الذكاء الاصطناعي الخاصة بـ Twenty ويمكن اختيارها كخطوة في أتمتة سير العمل. لتمييز دالة منطقية كأداة، عيّنisTool: true وقدّم toolInputSchema يصف معاملات الإدخال المتوقعة باستخدام مخطط JSON:
isTool(boolean, الافتراضي:false): عند ضبطه علىtrue، يتم تسجيل الدالة كأداة وتصبح متاحة لوكلاء الذكاء الاصطناعي ولأتمتة سير العمل.toolInputSchema(object, اختياري): كائن JSON Schema يصف المعلمات التي تقبلها دالتك. يستخدم وكلاء الذكاء الاصطناعي هذا المخطط لفهم المدخلات التي تتوقعها الأداة وللتحقق من صحة الاستدعاءات. إذا تم إغفاله، فالقيمة الافتراضية للمخطط هي{ type: 'object', properties: {} }(من دون معلمات).- الدوال التي لديها
isTool: false(أو غير معيَّنة) غير معروضة كأدوات. لا يزال بالإمكان تنفيذها مباشرةً أو استدعاؤها بواسطة دوال أخرى، لكنها لن تظهر في اكتشاف الأدوات. - تسمية الأداة: عند كشفها كأداة، يتم تطبيع اسم الدالة تلقائيًا إلى
logic_function_<name>(تحويله إلى أحرف صغيرة، واستبدال المحارف غير الأبجدية الرقمية بشرطات سفلية). على سبيل المثال،enrich-companyتصبحlogic_function_enrich_company. - يمكنك دمج
isToolمع المشغِّلات — إذ يمكن للدالة أن تكون أداة (قابلة للاستدعاء من قِبل وكلاء الذكاء الاصطناعي) وأن تُشغَّل بواسطة أحداث (cron، وأحداث قاعدة البيانات، والمسارات) في الوقت نفسه.
اكتب
description جيدًا. يعتمد وكلاء الذكاء الاصطناعي على حقل description الخاص بالدالة لتحديد وقت استخدام الأداة. كن محددًا بشأن ما تفعله الأداة ومتى ينبغي استدعاؤها.المكوّنات الأمامية
تتيح لك المكوّنات الأمامية إنشاء مكوّنات React مخصّصة تُعرَض داخل واجهة مستخدم Twenty. استخدمdefineFrontComponent() لتعريف مكوّنات مع تحقّق مدمج:
- المكوّنات الأمامية هي مكوّنات React تُعرَض ضمن سياقات معزولة داخل Twenty.
- استخدم لاحقة الملف
*.front-component.tsxللاكتشاف التلقائي. - يشير الحقل
componentإلى مكوّن React الخاص بك. - يتم بناء المكوّنات ومزامنتها تلقائيًا أثناء
yarn twenty app:dev.
- مُنشأ بالقالب: شغّل
yarn twenty entity:addواختر خيار إضافة مكوّن أمامي جديد. - يدوي: أنشئ ملفًا جديدًا
*.front-component.tsxواستخدمdefineFrontComponent().
المهارات
تُحدِّد المهارات تعليمات وإمكانات قابلة لإعادة الاستخدام يمكن لوكلاء الذكاء الاصطناعي استخدامها داخل مساحة العمل لديك. استخدمdefineSkill() لتعريف مهارات مع تحقّق مدمج:
nameهي سلسلة معرّف فريدة للمهارة (يُنصَح باستخدام kebab-case).labelهو اسم العرض المقروء للبشر الظاهر في واجهة المستخدم.contentيحتوي على تعليمات المهارة — وهو النص الذي يستخدمه وكيل الذكاء الاصطناعي.icon(اختياري) يحدّد الأيقونة المعروضة في واجهة المستخدم.description(اختياري) يوفّر سياقًا إضافيًا حول غرض المهارة.
- مُنشأ بالقالب: شغِّل
yarn twenty entity:addواختر خيار إضافة مهارة جديدة. - يدوي: أنشئ ملفًا جديدًا واستخدم
defineSkill()مع اتباع النمط نفسه.
عميل مُولَّد مضبوط الأنواع
يُولَّد العميل مضبوط الأنواع تلقائيًا بواسطةyarn twenty app:dev ويُخزَّن في node_modules/twenty-sdk/generated استنادًا إلى مخطط مساحة العمل لديك. استخدمه في وظائفك:
yarn twenty app:dev كلما تغيّرت كائناتك أو حقولك.
بيانات الاعتماد وقت التشغيل في الوظائف المنطقية
عندما تعمل وظيفتك على Twenty، يقوم النظام الأساسي بحقن بيانات الاعتماد كمتغيرات بيئة قبل تنفيذ كودك:TWENTY_API_URL: عنوان URL الأساسي لواجهة Twenty البرمجية التي يستهدفها تطبيقك.TWENTY_API_KEY: مفتاح قصير العمر ذو نطاق يقتصر على الدور الافتراضي لوظيفة تطبيقك.
- لا تحتاج إلى تمرير عنوان URL أو مفتاح واجهة برمجة التطبيقات إلى العميل المُولَّد. يقوم بقراءة
TWENTY_API_URLوTWENTY_API_KEYمن process.env وقت التشغيل. - تُحدَّد أذونات مفتاح واجهة برمجة التطبيقات بواسطة الدور المشار إليه في
application-config.tsعبرdefaultRoleUniversalIdentifier. هذا هو الدور الافتراضي الذي تستخدمه الوظائف المنطقية في تطبيقك. - يمكن للتطبيقات تعريف أدوار لاتباع مبدأ أقل الامتياز. امنح فقط الأذونات التي تحتاجها وظائفك، ثم وجّه
defaultRoleUniversalIdentifierإلى المعرّف الشامل لذلك الدور.
مثال Hello World
استكشف مثالًا بسيطًا شاملًا من البداية إلى النهاية يوضح الكائنات والوظائف المنطقية والمكوّنات الأمامية ومشغّلات متعددة هنا:إعداد يدوي (بدون المهيئ)
بينما نوصي باستخدامcreate-twenty-app للحصول على أفضل تجربة للبدء، يمكنك أيضًا إعداد مشروع يدويًا. لا تثبّت CLI عالميًا. بدل ذلك، أضف twenty-sdk كاعتماد محلي واربط سكربتًا واحدًا في ملف package.json لديك:
twenty:
yarn twenty <command>، مثلًا: yarn twenty app:dev، yarn twenty help، إلخ.
استكشاف الأخطاء وإصلاحها
- أخطاء المصادقة: شغّل
yarn twenty auth:loginوتأكد من أن مفتاح واجهة برمجة التطبيقات لديك يمتلك الأذونات المطلوبة. - يتعذّر الاتصال بالخادم: تحقق من عنوان URL لواجهة البرمجة وأن خادم Twenty قابل للوصول.
- الأنواع أو العميل مفقود/قديم: أعد تشغيل
yarn twenty app:dev— فهو ينشئ العميل مضبوط الأنواع بشكل تلقائي. - وضع التطوير لا يزامن: تأكد من أن
yarn twenty app:devقيد التشغيل وأن التغييرات ليست متجاهلة من بيئتك.