defineLogicFunction
عرّف الدوال المنطقية ومشغّلاتها
defineLogicFunction
عرّف الدوال المنطقية ومشغّلاتها
كل ملف وظيفة يستخدم أنواع المشغّلات المتاحة:يحتوي نوع في معالجك، يمكنك الوصول إلى الرؤوس المُمرَّرة بهذه الطريقة:لأسباب أمنية، يتم تقييد ترويسات الاستجابة بقائمة مسموح بها. يتم إسقاط أي ترويسة ليست في القائمة (مثل يمكن الوصول إلى نقطة النهاية عند:المعرّف هو يصل التحدي في يستبدل عقد الـ Resolver. يفرض نوع تتضمن الحمولة ما يلي:مثال على حدث الإنشاء:مثال على حدث التحديث:تشغيل المشغّل فقط عند تحديثات البريد الإلكتروني:مثال على حدث الحذف:أنشئ كليهما مرة واحدة، في نطاق الوحدة، ثم يحدد كل موضع استدعاء أذونات الوصول التي يستخدمها من خلال العميل الذي يستدعيه. يأخذ تستخدم مساعدات SDK التي تصل إلى موارد تطبيقك الخاصة أذونات الوصول الخاصة به دائمًا وتتجاهل النقاط الرئيسية:للتصريح بمعاملاتك مرة واحدة وخدمة كلتا الواجهتين، عرّف مخطط JSON واحد (بمجرد تثبيت التطبيق، سيظهر Enrich Company في منتقّي الإجراءات في منشئ سير العمل. يعرض المُنشئ
defineLogicFunction() لتصدير تكوين مع معالج ومشغّلات اختيارية.src/logic-functions/createPostCard.logic-function.ts
- httpRoute: يعرِض وظيفتك على مسار وطريقة HTTP. في شيفرة التطبيق، أضف البادئة
/s/إلى مسار التوجيه عند استخدامRestApiClient؛ يستخدم عنوان URL المنشور قاعدةTWENTY_FUNCTIONS_URLالمُحدَّدة (أو\<server-url>/sإذا لم تُحدَّد).
لاستدعاء دالة منطقية يتم تشغيلها بواسطة مسار من مكون واجهة (بدون واجهة رسومية)، راجع قسم استدعاء دالة منطقية.
- cron: يشغّل وظيفتك على جدول باستخدام تعبير CRON.
- databaseEvent: يعمل على أحداث دورة حياة كائنات مساحة العمل. عندما تكون عملية الحدث هي
updated، يمكن تحديد الحقول المحددة المراد الاستماع إليها في مصفوفةupdatedFields. إذا تُركت غير معرّفة أو فارغة، فسيؤدي أي تحديث إلى تشغيل الدالة.
مثال:person.updated،*.created،company.*
- serverRoute: يوفّر مسار HTTP واحدًا بنطاق التسجيل. تعمل دالة resolver (المُعلَنة باستخدام
serverRouteTriggerSettings) في مساحة عمل المالك وتُرجِع إمّا كائنResponseمتزامنًا أو كلاً من مساحة العمل المستهدفة ودالة المنطق المطلوب إدراجها في قائمة الانتظار؛ في مسار الإدراج في قائمة الانتظار يؤكّد النظام الأساسي تلقّي الطلب برمز202ويُشغِّل ذلك الهدف في طابور العامل (worker queue). راجع مشغّل مسار الخادم.
يمكنك أيضًا تنفيذ دالة يدويًا باستخدام CLI:يمكنك متابعة السجلات باستخدام:
حمولة مشغل المسار
عندما يستدعي مُشغِّل المسار وظيفتك المنطقية، فإنها تتلقّى كائنRoutePayload الذي يتبع صيغة AWS HTTP API v2.
استورد نوع RoutePayload من twenty-sdk/logic-function:RoutePayload على البنية التالية:forwardedRequestHeaders
افتراضيًا، لا تُمرَّر رؤوس HTTP من الطلبات الواردة إلى دالتك المنطقية لأسباب أمنية. للوصول إلى رؤوس محددة، أدرِجها في مصفوفةforwardedRequestHeaders:تُحوَّل أسماء الرؤوس إلى أحرف صغيرة. يمكنك الوصول إليها باستخدام مفاتيح بأحرف صغيرة (على سبيل المثال،
event.headers['content-type']).استجابة HTTP مخصصة
بشكل افتراضي، فإن إرجاع قيمة بسيطة من المعالج الخاص بك يعيدها كاستجابة200 (بصيغة JSON للكائنات وtext/plain للسلاسل النصية). للتحكم في رمز الحالة ورؤوس الاستجابة، أعد كائن Response من twenty-sdk/logic-function:Set-Cookie، وترويسات CORS مثل Access-Control-Allow-Origin، أو ترويسات X-* المخصصة) بصمت قبل إرسال الاستجابة. ترويسات الاستجابة المسموح بها هي:content-typecontent-languagecontent-dispositioncache-controlretry-after
يجب أن يكون رمز الحالة رمز حالة HTTP صالحًا (بين 100 و599). تتم مطابقة أسماء ترويسات الاستجابة دون حساسية لحالة الأحرف.
استجابات أخطاء المنصة
إلى جانب استجابات المعالج لديك، تتعامل المنصة مع استدعاءات المسارات مباشرة في بعض الحالات:404 عندما لا يكون المسار موجودًا أو لا تكون الدالة موجودة، و403 عندما يكون التطبيق متوقفًا، و429 عند بلوغ حد معدل التنفيذ، و422 عندما تكون dependencies الخاصة بالإنتاج للتطبيق كبيرة جدًا بحيث يتعذر تثبيتها — راجع حدود حجم dependencies.مشغّل مسار الخادم
httpRouteTriggerSettings يوفّر دالة تحت /s/ ويحل مساحة العمل من مضيف الطلب — وهذا يعمل عندما تكون لكل مساحة عمل نطاقها الخاص. لكن المزوّدين من جهات خارجية يرسلون أحداث كل مستأجر إلى عنوان URL واحد. في هذه الحالة، استخدم serverRouteTriggerSettings.يتكوّن المشغّل من جزأين:-
دالة منطق resolver — يتم التصريح عنها باستخدام
serverRouteTriggerSettings— تعمل في مساحة العمل المالكة (مساحة العمل التي تمتلك تسجيل التطبيق). تفحص الطلب الوارد وتُرجِع إمّا:{ workspaceId, targetLogicFunctionUniversalIdentifier, payload? }— يضع النظام الأساسي ذلك الهدف في قائمة الانتظار في مساحة العمل المُحدَّدة ويؤكّد تلقّي الطلب برمز202 { queued: true }، أوResponseمنtwenty-sdk/logic-function— تُعيد المنصّة إرسال تلك الاستجابة عبر HTTP بشكل متزامن ولا تُدرِج هدفًا في قائمة الانتظار (استخدم هذا لمصافحات التحدّي مثل Slackurl_verification).
rawBodyالأصلي والرؤوس المُمرَّرة، ويمكنه رفض الطلب دون لمس الهدف مطلقًا. - دالة منطق target — دالة منطق عادية لكل مساحة عمل — تعمل بعد ذلك في مساحة العمل التي تم حلّها باستخدام الحمولة التي أعادها الـ resolver (أو حمولة الطلب الأصلية إذا لم يقم الـ resolver بتحويلها). قيمة الإرجاع الخاصة به لا يطّلع عليها مستدعي HTTP عندما يختار الـ resolver مسار الإضافة إلى الطابور (enqueue path).
src/logic-functions/resolve-server-route.logic-function.ts
src/logic-functions/handle-invoice-paid.logic-function.ts
universalIdentifier الخاص بالـ resolver من ملف manifest لديك. سجّل عنوان URL هذا لدى المزوّد.الرد على طلب GET للتحقق. يتحقق بعض الموفّرين من نقطة نهاية قبل أن يرسلوا إليها، وذلك بإرسال طلب GET يحمل تحديًا إلى عنوان URL نفسه الذي سيرسلون إليه الأحداث لاحقًا عبر POST — وتُعد WhatsApp Cloud API من Meta أحدهم. لا يستجيب مسار الخادم إلا لطلبات POST ما لم تحدد خلاف ذلك، لذا أعلن الطريقتين معًا:event.queryStringParameters، وتؤدي إعادة Response إلى إرجاعه إلى الموفّر ضمن الطلب نفسه. يُرسل نص سلسلة كـ text/plain، وهذا ما يتوقعه هؤلاء الموفّرون:httpMethods الإعداد الافتراضي بدلاً من الإضافة إليه، لذا فإن ['GET'] وحده يجعل المسار يرفض POST. يتم دعم GET وPOST فقط. اتركه غير معيّن ما لم يكن المزوّد يحتاج إلى الفعل الثاني: فالمسار الذي يعلن GET سيُنفَّذ محلّله بواسطة أي مستدعٍ غير موثَّق، بما في ذلك برامج الزحف وأدوات توسيع الروابط التي ترسل GET دون طلب مسبق. يُستجاب لكل ما لا تتوفر للمنصة طريقة له بالرمز 405 دون أن يُشغَّل المحلّل مطلقًا.يجب أن يتم المطالبة بالتطبيق وتثبيته في مساحة عمل المالك الخاصة به. نظرًا لأن محلِّل الاستدعاء يعمل في مساحة عمل المالك (مساحة العمل التي تمتلك تسجيل التطبيق)، فإن مشغّل مسار الخادم يعمل فقط بمجرد أن يكون قد تم المطالبة بالتطبيق — أي أصبح لديه مساحة عمل مالكة — و تم تثبيت هذا التطبيق في مساحة عمل المالك. إلى أن يتحقق الشرطان معًا، فلن يكون لدى محلِّل الاستدعاء مكان يعمل فيه، وبالتالي لا يمكن إرسال المسار. لذلك لا يمكن إدراج أي تطبيق يعرِّض دالة منطقية
serverRouteTriggerSettings في السوق حتى تتم المطالبة به وتثبيته في مساحة عمل المالك الخاصة به.LogicFunctionConfig في حزمة SDK هذا في وقت الترجمة: بمجرد تعيينك لـ serverRouteTriggerSettings، يُقيَّد الـ handler الخاص بك بأن يُرجِع إما Response، أو { workspaceId: string; targetLogicFunctionUniversalIdentifier: string; payload?: object } (أو Promise لأيٍّ منهما). على مسار الإرسال (dispatch path)، يجب أن يكون workspaceId لمساحة عمل تكون الدالة المستهدفة مثبّتة فيها، وإلا فسيتم رفض الطلب مع 404. أي نتيجة لا تطابق أياً من البنيتين — بما في ذلك تلك التي لا تكون معرّفاتها UUIDs — تُرفَض مع رمز الحالة 502.بالنسبة لتواقيع الطلبات، يستخدم معظم المزوّدين HMAC-SHA256 للتوقيع؛ الأجزاء التي تختلف هي اسم الرأس وترميز الملخّص وسلسلة الحمولة الموقّعة. بعض الأمثلة:
يُظهِر مثال الـ resolver أعلاه بالفعل تدفّق GitHub HMAC-SHA256 — عدِّل اسم الرأس وترميز الملخّص وسلسلة الحمولة الموقّعة بحسب المزوّد الذي تدمجه.
عندما يُرجِع الـ resolver كائن إرسال (dispatch object)، يستجيب المسار بـ
202 { queued: true } وتعمل الدالة المستهدفة على طابور العامل (worker queue) — المتصل لا يطّلع أبدًا على زمن استجابة الدالة المستهدفة أو نتيجتها أو حالات الفشل الخاصة بها (تُسجَّل هذه في سجلات التنفيذ). هذا يمنع عمليات إعادة الإرسال من جهة المرسِل من تضخيم تباطؤ المعالجة، وهو ما تريده عند استيعاب خطافات الويب.عندما يجب على المتصل قراءة جسم الاستجابة في نفس الطلب (مثل challenge handshakes أو interactive acknowledgements)، أرجِع Response من الـ resolver بدلًا من ذلك. تعيد المنصّة إرجاعها بشكل متزامن وتتجاوز الطابور؛ تمر ترويساتها (headers) عبر نفس قائمة السماح (allow-list) الخاصة باستجابات مسارات HTTP. احرص على أن تكون دالة resolver سريعة — بعض المزوّدين (مثل Slack) تنتهي مهلة طلباتهم خلال بضع ثوانٍ. نظرًا لأن الـ resolver يمكن الوصول إليه كنقطة نهاية عامة، قم بحمايته من خلال تحديد المعدّل (rate limiting) على الحافة لديك.حمولة مُحفِّز حدث قاعدة البيانات
عندما يستدعي مُحفِّز حدث قاعدة البيانات دالة المنطق الخاصة بك، فإنه يستقبل كائنDatabaseEventPayload واحدًا لكل سجل تم تغييره. تجمع الحمولة بين البيانات الوصفية حول مساحة العمل والكائن المصدر وبين الحدث على مستوى السجل.في عمليات الحذف اللين (soft deletes)، يتبع
.deleted بنية نمط التحديث لأن حقل deletedAt في السجل يتغيّر.
في عمليات الحذف الدائم، استخدم .destroyed.databaseEventTriggerSettings.updatedFields يرشّح أيّ أحداث التحديث التي تُشغِّل الدالة.
event.properties.updatedFields يوضّح لك أي الحقول تغيّرت فعليًا في الحدث الحالي.سياق التنفيذ
يتلقى كل معالج وسيطًا ثانيًا يصف عملية التشغيل نفسها، بغض النظر عما شغّلها. بينما يتغير شكل الوسيط الأول بحسب المُشغِّل، لا يتغير شكل هذا الوسيط:يكون
userWorkspaceId وworkspaceMemberId بقيمة null عندما لا يشغّل أحد عملية التشغيل: فلا توجد جهة خلف جداول cron وخطافات التثبيت وخطافات الويب غير الموثقة. ويكونان أيضًا بقيمة null عندما لا يكون لدى الشخص سجل عضو في مساحة العمل، أو عندما يكون سجله قد حُذف.يخبرك السياق بمن شغّل عملية التشغيل. أما ما قد تفعله عملية التشغيل فهو تعريف منفصل أدناه.
أذونات الوصول التي تستخدمها المكالمة
يتصرف كل عميل —CoreApiClient وMetadataApiClient وRestApiClient — بصفته الشخص الذي شغّل عملية التشغيل: إذ يتقاطع دوره مع دور تطبيقك، لذا لا يمكن للمكالمة أبدًا أن تفعل أكثر مما يسمح به أيّ منكما. هذا هو السلوك الافتراضي، ويعني أنه لا يمكن للشخص أبدًا استخدام تطبيقك لتجاوز أذوناته الخاصة.عندما لا يشغّل أحد عملية التشغيل، لا يوجد شخص للتصرف بصفته، لذا يعود العميل نفسه إلى أذونات الوصول الخاصة بتطبيقك: لا تحتاج جداول cron وخطافات التثبيت وخطافات الويب غير الموثقة إلى معالجة خاصة.تحتاج بعض المكالمات بصورة مشروعة إلى أذونات الوصول الخاصة بالتطبيق حتى عندما يكون هناك شخص خلف عملية التشغيل — مثل قراءة سجلات إعدادات تطبيقك، أو تنفيذ عمل لا يستطيع ذلك الشخص تنفيذه بنفسه. أنشئ عميلاً ثانيًا لهذه الحالات:RestApiClient الخيار نفسه:عملية التشغيل التي لم يشغّلها أحد تتصرف بصفتها تطبيقك. لا يوجد شخص خلف جداول cron وخطافات التثبيت وخطافات الويب غير الموثقة، لذا يعود العميل الافتراضي إلى أذونات الوصول الخاصة بتطبيقك ويستمر في العمل. لا يلزم استخدام
runAs: 'application' إلا عندما تريد أذونات الوصول تلك في عملية تشغيل شغّلها شخص بالفعل.تحقق من context.workspaceMemberId عندما تتصرف دالة بشكل مختلف بناءً على وجود شخص خلفها، على سبيل المثال لإسناد سجل.runAs: وهي مخزن المفتاح-القيمة والاتصالات وrunAgent وgetPublicAssetUrl وفرض رسوم الأرصدة.إتاحة دالة كأداة ذكاء اصطناعي أو كإجراء ضمن سير العمل
يمكن إتاحة دوال المنطق على واجهتين، ولكلٍ منهما مشغِّل خاص به:toolTriggerSettings— يجعل الدالة قابلة للاكتشاف عبر ميزات الذكاء الاصطناعي الخاصة بـ Twenty (الدردشة، MCP، استدعاء الدوال). يستخدم JSON Schema القياسي، وهو التنسيق الذي تفهمه LLMs أصلاً.workflowActionTriggerSettings— يجعل الدالة تظهر كخطوة في منشئ سير العمل المرئي. يستخدمInputSchemaالغني الخاص بـ Twenty لكي يتمكن المُنشئ من عرض محرّرات الحقول المناسبة، وأدوات انتقاء المتغيّرات، والتسميات.
cronTriggerSettings وdatabaseEventTriggerSettings وhttpRouteTriggerSettings — النمط نفسه، والشكل نفسه.العلاقة بإجراء Code الخاص بسير العمل. يُعَد إجراء Code المضمَّن في منشئ سير العمل دالة منطقية بحد ذاته — حيث ينشئ Twenty واحدًا لكل خطوة Code ويعرض محرره مضمّنًا. تُستخدَم
workflowActionTriggerSettings لتحويل هذا الكود المضمَّن لمرة واحدة إلى إجراء قابل لإعادة الاستخدام: عرِّف الدالة مرة واحدة في تطبيقك وستصبح قابلة للاختيار في أي سير عمل، بدلاً من نسخها ولصقها في كل خطوة Code. راجع إجراء Code في دليل المستخدم لعرض منظور المستخدم النهائي.src/logic-functions/enrich-company.logic-function.ts
- يمكن للدالة مزج الواجهات — صرِّح بكلٍ من
toolTriggerSettingsوworkflowActionTriggerSettingsلإتاحتها في الدردشة وفي منشئ سير العمل. toolTriggerSettings.inputSchemaوworkflowActionTriggerSettings.inputSchemaكلاهما اختياري. عند الإغفال، يستنتج مُنشئ البيان هذه المخططات من الشيفرة المصدرية للمعالج (JSON Schema لأداة الذكاء الاصطناعي، وInputSchemaالخاصة بـ Twenty لإجراء سير العمل). قدّم واحدًا صراحةً عندما ترغب في أنواع أكثر ثراءً — على سبيل المثال، مع حقول واعية بـFieldMetadataTypeمثلCURRENCYأوRELATIONلمنشئ سير العمل، أو مع حقولdescriptionالتي يمكن لوكيل الذكاء الاصطناعي قراءتها:
InputJsonSchema) وحوِّله لاستخدامه في إجراء سير العمل باستخدام jsonSchemaToInputSchema من twenty-sdk/logic-function. toolTriggerSettings.inputSchema يستخدم مخطط JSON مباشرة، بينما workflowActionTriggerSettings.inputSchema يتوقّع InputSchema الخاص بـ Twenty:مثال كامل لإجراء سير عمل
تقبلworkflowActionTriggerSettings أربعة حقول:تجميع ذلك معًا — دالّة معروضة كإجراء سير عمل، مع مخرَج مُعلَن بحيث يمكن للخطوات اللاحقة الرجوع إلى
taskId:src/logic-functions/enrich-company.logic-function.ts
companyName وdomain كحقول إدخال (كلٌّ منهما قادر على سحب القيم من الخطوات السابقة)، ويمكن للخطوات اللاحقة الرجوع إلى مخرجات الخطوة taskId وenriched.اكتب
description جيدًا. يعتمد وكلاء الذكاء الاصطناعي على حقل description الخاص بالدالة لتحديد وقت استخدام الأداة. كن محددًا بشأن ما تفعله الأداة ومتى ينبغي استدعاؤها.مساعدات وقت التشغيل. يقوم
twenty-sdk/utils بإعادة تصدير مساعدات صغيرة لوقت التشغيل حتى لا تستورد المعالجات مباشرةً من twenty-shared. على سبيل المثال، تُرجِع isDefined(value) القيمة false لكلٍّ من null وundefined — استخدمها لتضييق نطاق مُدخلات المعالِجات الاختيارية بأمان، والتي يمكن أن تصل كقيمة null أثناء وقت التشغيل حتى عندما تكون مكتوبة كـ T | undefined:خطافات التثبيت — معالجات ما قبل التثبيت وما بعد التثبيت وإلغاء التثبيت — تشترك في وقت التشغيل نفسه، ولكن يُصرَّح عنها بدوال تعريف خاصة بها ولا تأخذ إعدادات المشغّلات. راجع خطافات التثبيت (Install Hooks) لمعرفة
definePreInstallLogicFunction و definePostInstallLogicFunction و defineUninstallLogicFunction.إنشاء نشاط في المخطط الزمني
استخدمcreateTimelineActivity() لنشر حدث مجال صريح من دالة منطقية. عرّف الحدث أولاً باعتباره نوع نشاط في المخطط الزمني، ثم عالج النوع والكائنات باستخدام معرفاتها العامة الثابتة:
timelineActivityTypeUniversalIdentifier وtargetObjectUniversalIdentifier وtargetRecordId. يمكنك أيضاً توفير happensAt وproperties وworkspaceMemberId. يتحكم happensAt في موضع الحدث ووقته المعروض في المخطط الزمني؛ ويكون افتراضياً وقت الإنشاء.
لربط سجل آخر بالحدث، وفّر linkedRecordId وlinkedObjectMetadataUniversalIdentifier معاً. يمكنك بالإضافة إلى ذلك توفير linkedRecordCachedName كخيار احتياطي للعرض التاريخي:
timelineActivity القياسي. أبقِ أنواع الأحداث الصريحة غير مرتبطة بـaction؛ إذ إن النوع المرتبط بإجراء يتلقى بالفعل أحداث تدقيق تلقائية، وإلا فسينتج صفوفاً مكررة.
عملاء واجهة برمجة تطبيقات مضبوطة الأنواع (twenty-client-sdk)
توفر حزمة twenty-client-sdk عميلين لـ GraphQL ذوي أنواع ثابتة للتفاعل مع واجهة Twenty البرمجية من وظائفك المنطقية ومكوّنات الواجهة الأمامية.
CoreApiClient
استعلام وتعديل بيانات مساحة العمل (السجلات، الكائنات)
CoreApiClient
استعلام وتعديل بيانات مساحة العمل (السجلات، الكائنات)
CoreApiClient هو العميل الرئيسي للاستعلام وتعديل بيانات مساحة العمل. يُولَّد من مخطط مساحة العمل لديك أثناء yarn twenty dev أو yarn twenty dev:build، لذا فهو مضبوط الأنواع بالكامل ليتوافق مع كائناتك وحقولك.true لتضمين حقل، واستخدم __args للوسيطات، وعشّش الكائنات للعلاقات. ستحصل على إكمال تلقائي كامل وفحص للأنواع يعتمد على مخطط مساحة العمل لديك.يتم توليد CoreApiClient في وقت التطوير/البناء. إذا استخدمته دون تشغيل
yarn twenty dev أو yarn twenty dev:build أولًا، فسيؤدي ذلك إلى خطأ. تحدث عملية التوليد تلقائيًا — إذ يستطلع CLI مخطط GraphQL لمساحة عملك وينشئ عميلًا مضبوط الأنواع باستخدام @genql/cli.استخدام CoreSchema للتعليقات التوضيحية للأنواع
CoreSchema يوفّر أنواع TypeScript المطابقة لكائنات مساحة العمل لديك — مفيد لتعيين أنواع حالة المكوّن أو معاملات الدوال:MetadataApiClient
إعدادات مساحة العمل، والتطبيقات، ورفع الملفات
MetadataApiClient
إعدادات مساحة العمل، والتطبيقات، ورفع الملفات
يأتي
MetadataApiClient مُجهّزًا مسبقًا مع SDK (لا حاجة للتوليد). يستعلم عن نقطة النهاية /metadata للحصول على تكوين مساحة العمل والتطبيقات ورفع الملفات. يأخذ خيار runAs نفسه الذي يأخذه CoreApiClient — راجع أذونات الوصول التي تستخدمها المكالمة.رفع الملفات
يتضمنMetadataApiClient طريقة uploadFile لإرفاق الملفات بالحقول من نوع الملف:النقاط الرئيسية:
- يستخدم
universalIdentifierالخاص بالحقل (وليس معرّفه الخاص بمساحة العمل)، بحيث يعمل كود الرفع لديك عبر أي مساحة عمل مُثبَّت فيها تطبيقك. - العنوان
urlالمُعاد هو عنوان URL موقّع يمكنك استخدامه للوصول إلى الملف المرفوع.
عند تشغيل كودك على Twenty (وظائف منطقية أو مكوّنات أمامية)، يقوم النظام الأساسي بحقن بيانات الاعتماد كمتغيرات بيئية:
TWENTY_API_URL— عنوان URL الأساسي لواجهة Twenty البرمجيةTWENTY_APP_ACCESS_TOKEN— مفتاح قصير العمر لأذونات الوصول الافتراضية: دور الشخص متقاطعًا مع دور تطبيقك عندما يكون هناك شخص خلف عملية التشغيل، ودور تطبيقك الخاص عندما لا يكون هناك أحد. الشخص هو من شغّل عملية التشغيل في دالة منطقية، أو من ينظر إلى الصفحة في مكوّن أمامي.TWENTY_APP_APPLICATION_ACCESS_TOKEN— مفتاح قصير العمر يقتصر نطاقه على دور تطبيقك الخاص وحده. للدوال المنطقية فقط، ويُحقن فيها دائمًا، وهو ما يستخدمهrunAs: 'application'.
process.env تلقائيًا، ويغطي أذونات الوصول التي تستخدمها المكالمة الاختيار بينها. تُحدَّد أذونات تطبيقك الخاصة بواسطة الدور المُعلن باستخدام defineApplicationRole() (أو المشار إليه عبر defaultRoleUniversalIdentifier في application-config.ts)؛ ولا يمكن لعملية تشغيل تتصرف بصفة شخص أن تتجاوز ذلك الدور أو دوره.