إنجازيو

إنجازيو

نجهّز لك تجربة تعليمية ذكية

Developers · الإصدار ١٫٠ · أكتوبر ٢٠٢٦

دليل ربط سبورة إنجازيو للمطوّرين

اربط أي منصة تعليمية أو موقع أو نظام مدرسي بسبورة إنجازيو: الدخول الموحّد، والأدوار، والحصص، والسبورات. أغلب المسارات لا تحتاج سطر كود واحدًا داخل منصتك.

١. نظرة عامة

الأكاديمية على إنجازيو نسختك الخاصة من المنصة: تعمل على نطاق فرعي من موقعك أنت (مثل board.example.com)، وتحمل اسمك وشعارك، ولها مديروها ومعلّموها وطلابها وحصصها وسبوراتها.

يدير مديرُ الأكاديمية كل شيء من لوحة التحكم على هذا النطاق. والربط يجيب عن ثلاثة أسئلة فقط:

  • من هذا الشخص؟ — كيف يدخل المستخدم: بحسابه الموجود في منصتك، أو بجوجل، أو بمايكروسوفت، أو من منصة التعلّم، أو بحساب تنشئه له في إنجازيو.
  • ما دوره؟ — مدير أكاديمية أو معلّم أو طالب، يُستنتج تلقائيًّا من البيانات التي ترجعها منصتك أصلًا.
  • ما حصصه؟ — لتكون لكل حصة سبورتها، يفتحها معلّمها ويدخلها طلابها.
منصتكالمسار المقترحالكود المطلوب عندك
أي موقع، ولا يوجد مطوّرأ · حسابات يديرها المدير (استيراد + روابط دعوة)لا شيء
المستخدمون يدخلون بـ Google Workspace أو Microsoft 365ب · OpenID Connectلا شيء — بضعة إعدادات
Keycloak أو Auth0 أو Okta أو Azure AD B2C أو ووردبريس بإضافة OIDC أو أي خادم OIDCب · OpenID Connectلا شيء — تسجيل تطبيق واحد
Moodle أو Canvas أو Blackboard أو Brightspace أو Schoology أو Sakaiج · LTI 1.3لا شيء — تسجيل أداة واحدة
موقع خاص بكوكي جلسة وواجهة /meد · الدخول بجلسة موقعكغالبًا لا شيء
تريد إنشاء السبورات من صفحات حصصك أنتهـ · واجهة الشركاء البرمجيةنداء واحد من خادمك
تريد مزامنة الأشخاص والحصص تلقائيًّاو · Webhook أو تقويم iCalبلا كود (Zapier أو Make أو n8n)

٢. البدء السريع (١٥ دقيقة)

  1. اشترك في باقة أكاديمية على injazio.com فيصلك حساب مدير.
  2. أضف سجلّ DNS واحدًا: board ← CNAME ← board.injazio.com (القسم ٤). شهادة HTTPS تصدر تلقائيًّا.
  3. افتح https://board.example.com/admin/academy وادخل بحساب المدير.
  4. اختر مسار الدخول من الأكاديمية ← الربط (الأقسام ٥ إلى ٨).
  5. اضبط قواعد الأدوار إن كانت منصتك ترسل الأدوار (القسم ٩).
  6. أضف الحصص، أو دعها تتزامن من منصة التعلّم أو التقويم أو الـWebhook (القسمان ١٠ و١١).
  7. راجع قائمة الإطلاق (القسم ١٦).

٣. المفاهيم الأساسية

الأكاديمية (المستأجر)
مساحتك المعزولة. لا تنتقل بيانات بين أكاديمية وأخرى أبدًا.
نطاق الأكاديمية
نطاقك الفرعي مثل board.example.com، وعليه كل روابط الدخول.
مدير الأكاديمية
يدير الأشخاص والحصص والنطاق والربط. ولا يصير مديرًا لمنصة إنجازيو أبدًا.
المعلّم
يملك السبورات وله كل أدوات الشرح: الرسم والمناهج والألعاب والاختبارات والتسجيل والشهادات. ويُحسب من مقاعد المعلّمين في باقتك.
الطالب
يدخل السبورات المدعوّ إليها، ويرى حصصه وسبوراتها في حصصي.
المعرّف الخارجي
معرّف المستخدم الثابت في منصتك (sub أو id أو uuid…). لا يتغيّر طوال عمر الحساب. البريد ليس معرّفًا.
الحصة
موعد له معلّم وطلاب. تُنشأ سبورتها عند أول فتح من المعلّم، فالحصص التي لا تُفتح لا تستهلك من حصة السبورات.

أولوية الدور. الدور الذي يضبطه المدير يدويًّا يُقفَل، فلا تغيّره أي مزامنة. وإلا فقواعد الأدوار (القسم ٩) هي التي تقرّر، فإن لم تنطبق قاعدة طُبّقت خريطة مدمجة: admin ← مدير أكاديمية، و teacher أو instructor أو trainer ← معلّم، وما عداها ← طالب. ومالك الأكاديمية مدير دائمًا.

مقاعد المعلّمين. إن امتلأت مقاعد باقتك رُفضت الترقية اليدوية بالرمز teachers_limit_reached، ومن يصل بالدخول الموحّد معلّمًا يدخل طالبًا مع تنبيه، حتى يفرغ مقعد.

٤. الخطوة الأولى — ربط نطاقك

من الأكاديمية ← النطاق اكتب النطاق الفرعي الذي تريده (مثل board.example.com)، ثم أنشئ هذا السجلّ عند مزوّد DNS (Cloudflare أو GoDaddy أو Namecheap أو Route 53…):

dns
board.example.com.   CNAME   board.injazio.com.
  • إن لم يسمح مزوّدك بـCNAME على هذا الاسم فاستعمل سجلّ A الظاهر في اللوحة.
  • في Cloudflare اجعل السجلّ DNS only (السحابة الرمادية) حتى تصدر الشهادة.
  • لا تستطيع توجيه الاسم الآن؟ أثبت الملكية بسجلّ TXT: _injazio-verify.board.example.com بالقيمة الظاهرة في اللوحة، ثم حوّل الـCNAME لاحقًا.
  • اضغط تحقّق، فتنتقل الحالة من waiting_dns إلى ready. شهادة HTTPS تصدر وتتجدّد تلقائيًّا.
  • بعد صدور الشهادة يمكنك جعل النطاق أساسيًّا. والحدّ ثلاثة نطاقات لكل أكاديمية.

٥. المسار أ — حسابات يديرها المدير (بلا كود)

ينشئ المدير الحسابات من الأكاديمية ← الأشخاص: واحدًا واحدًا، أو باستيراد ملف، أو بمشاركة رابط دعوة. مناسب إن لم يكن في منصتك دخول موحّد، أو لتبدأ اليوم.

استيراد جدول

ارفع ملف .xlsx أو .csv (بترميز UTF-8 أو UTF-16، والفاصل فاصلة أو فاصلة منقوطة أو Tab)، حتى ٥٬٠٠٠ صف. العناوين تُفهم بالعربية والإنجليزية. ابدأ دائمًا بـالمعاينة: تعرض نتيجة كل صف دون أن تكتب شيئًا.

العمودالعناوين المقبولةملاحظات
الاسم *الاسم، name، full nameإلزامي
البريدالبريد، البريد الإلكتروني، emailالبريد أو اسم المستخدم — أحدهما إلزامي
اسم المستخدماسم المستخدم، username، loginحروف وأرقام و _ . -
الدورالدور، النوع، roleمدير · معلم · طالب (أو admin · teacher · student). الأصل: طالب
كلمة المروركلمة المرور، passwordإن تُركت فارغة تُولَّد كلمة سهلة القراءة من ٨ أحرف وتظهر مرة واحدة
الجوالالجوال، الهاتف، phoneاختياري
المعرّفالمعرف، رقم الحساب، external_idمعرّفه في منصتك — ليجد الدخول الموحّد الحساب نفسه لاحقًا
csv
الاسم,البريد,الدور,المعرف
سارة علي,sara@example.com,معلم,1042
عمر خالد,omar@example.com,طالب,2210

روابط الدعوة

أنشئ رابطًا لدور معيّن، مع وصف ومدة صلاحية وحدّ استعمال اختيارية. من يفتحه ينشئ حسابه بنفسه بهذا الدور:

url
https://board.example.com/join/inv_8fJ2kQ…(٣٢ حرفًا)
  • يمكن إبطال الرابط في أي وقت، والرابط المستنفَد أو المنتهي أو المُبطَل يتوقّف فورًا.
  • دعوات المعلّمين تحترم مقاعد المعلّمين.
  • لا نخزّن إلا بصمة الرمز — انسخ الرابط لحظة إنشائه.

٦. المسار ب — OpenID Connect (جوجل، مايكروسوفت، وأي مزوّد OIDC)

يظهر زر الدخول بـ… في صفحة دخول أكاديميتك. يصادق المستخدم عند مزوّد هويته، ثم تتحقّق إنجازيو من توقيع رمز الهوية وتُدخله. يعمل مع كل مزوّد OIDC قياسي.

القيم التي تسجّلها عند المزوّد

نوع التطبيق
تطبيق ويب (عميل سرّي)
رابط إعادة التوجيه
https://board.example.com/sso/oidc/callback
النطاقات (Scopes)
openid email profile (وأضف groups أو roles إن استعملتها في قواعد الأدوار)
نوع المنح
Authorization Code مع PKCE (S256)

القيم التي تُدخلها في الأكاديمية ← الربط ← OIDC

الحقلGoogleMicrosoft Entra IDغيرهما (Keycloak و Auth0 و Okta…)
المُصدِر (Issuer)https://accounts.google.comhttps://login.microsoftonline.com/{tenant-id}/v2.0 (أو common)رابط المُصدِر عندك، مثل https://sso.example.com/realms/school
Client IDمن Google Cloud ← CredentialsApplication (client) IDمن مزوّدك
Client secretمن Google CloudCertificates & secretsمن مزوّدك
حقل المعرّفsubsub (أو oid)sub إلا إن فضّلت حقلًا ثابتًا آخر

اضغط اختبار: تجلب إنجازيو /.well-known/openid-configuration وتؤكّد أن المزوّد متاح.

من يُسمح له بالدخول

allow_modeالسلوك
existing (الأصل)من له حساب في أكاديميتك فقط (يُطابَق بالبريد الموثَّق أو بدخول OIDC سابق). الأكثر أمانًا.
domainsكل من بريده الموثّق في النطاقات المذكورة، مثل school.edu, staff.school.edu. الجدد طلاب ما لم تقل قاعدة دور غير ذلك.
anyأي حساب عند المزوّد. لا تستعمله إلا مع مزوّد خاص (Keycloak أو Entra الخاص بك).
  • يُربط الحساب أول مرة بالبريد الموثَّق، ثم بالمعرّف الثابت عند المزوّد.
  • الحسابات الموقوفة تُرفض (account_suspended).
  • السرّ يُخزَّن مشفّرًا ولا تعيده الواجهة أبدًا.
  • الأمان: state و nonce و PKCE في كل دخول، والتوقيع يُتحقَّق منه بمفاتيح المزوّد العامة (RS*/ES* فقط)، مع فحص iss و aud والصلاحية.

ملاحظات لكل مزوّد

  • Google Workspace — Google Cloud Console ← APIs & Services ← Credentials ← OAuth client ID ← Web. أضف رابط إعادة التوجيه. واجعل شاشة الموافقة *Internal* لتقصرها على مؤسستك.
  • Microsoft 365 / Entra ID — Entra admin center ← App registrations ← New ← Web ← رابط إعادة التوجيه. أضف Client secret. ضع معرّف مؤسستك في المُصدِر لتقصره عليها. وأضف حقل groups من *Token configuration* إن كنت تستنتج الأدوار من المجموعات.
  • Keycloak — Clients ← Create ← OpenID Connect، مع تفعيل *Client authentication*، ورابط إعادة التوجيه كما سبق. أضف mapper لـ*realm roles* في رمز الهوية لتستعمل الأدوار.
  • ووردبريس — ثبّت إضافة خادم OpenID Connect (مثل *OpenID Connect Server* أو *miniOrange OAuth Server*)، وسجّل إنجازيو عميلًا برابط إعادة التوجيه السابق.
  • Auth0 / Okta / OneLogin / Cognito — أنشئ *Regular Web Application* وانسخ المُصدِر و Client ID والسرّ.

٧. المسار ج — LTI 1.3 (Moodle، Canvas، Blackboard، Brightspace…)

أضف سبورة إنجازيو أداةً خارجية في منصة التعلّم. يضيفها المعلّم نشاطًا داخل المقرّر، فإذا ضغطه المستخدم دخل بدوره الصحيح وفُتحت سبورة هذا النشاط — السبورة نفسها كل مرة. وطلاب المقرّر ينضمّون إليها تلقائيًّا.

قيم الأداة (انسخها من الأكاديمية ← الربط ← LTI)

إصدار LTI
LTI 1.3
Tool URL / Target link URI
https://board.example.com/lti/launch
Initiate login URL
https://board.example.com/lti/login
Redirect URI(s)
https://board.example.com/lti/launch
Public keyset (JWKS) URL
https://api.injazio.com/api/lti/jwks
المفتاح العام
يظهر أيضًا بصيغة PEM في اللوحة للمنصات التي تطلب مفتاحًا لا رابطًا
طريقة الفتح
نافذة جديدة (مستحسن — المتصفّحات تقيّد الكوكي داخل الإطارات)
الرسائل
LtiResourceLinkRequest
الخصوصية
شارك اسم المستخدم وبريده

ثم سجّل منصة التعلّم في إنجازيو

بعد حفظ الأداة تعرض منصتك قيمها. أدخلها في إضافة منصة:

الحقل في إنجازيوMoodleCanvasBlackboard Learn
Issuerرابط Moodle عندك، مثل https://lms.example.comhttps://canvas.instructure.comhttps://blackboard.com
Client IDيظهر في *Tool configuration details*Developer Key IDApplication ID
Auth login URL…/mod/lti/auth.phphttps://sso.canvaslms.com/api/lti/authorize_redirecthttps://developer.blackboard.com/api/v1/gateway/oidcauth
Keyset URL…/mod/lti/certs.phphttps://sso.canvaslms.com/api/lti/security/jwkshttps://developer.blackboard.com/api/v1/management/applications/{id}/jwks.json
Access token URL…/mod/lti/token.phphttps://sso.canvaslms.com/login/oauth2/tokenhttps://developer.blackboard.com/api/v1/gateway/oauth2/jwttoken
Deployment IDيعرضه Moodle (اختياري — يُحفظ عند أول تشغيل)من *Deployment ID* للتطبيقمن النشر

Moodle خطوة بخطوة

  1. Site administration ← Plugins ← Activity modules ← External tool ← Manage tools ← *configure a tool manually*.
  2. Tool name: *Injazio Board*. و Tool URL: رابط launch السابق. و LTI version: LTI 1.3.
  3. Public key type: Keyset URL ← رابط JWKS السابق. و Initiate login URL و Redirection URI(s) كما سبق.
  4. Default launch container: New window. والخصوصية: مشاركة الاسم والبريد *Always*. ثم احفظ.
  5. اضغط أيقونة القائمة بجوار الأداة، وانسخ *Platform ID و Client ID و Deployment ID* والروابط الثلاثة إلى إنجازيو ← إضافة منصة.
  6. في المقرّر: Add an activity ← External tool ← *Injazio Board*. افتحه مرة بصفتك معلّمًا فتُنشأ السبورة.

Canvas خطوة بخطوة

  1. Admin ← Developer Keys ← + Developer Key ← LTI Key، واختر *Manual Entry*.
  2. Redirect URIs: رابط launch. و Target Link URI: رابط launch. و OpenID Connect Initiation URL: رابط login. و JWK Method: *Public JWK URL* ← رابط JWKS.
  3. Placements: *Course Navigation* و/أو *Link Selection*. و Privacy level: Public. احفظ وفعّل المفتاح ON.
  4. Admin ← Settings ← Apps ← + App ← *By Client ID* ← الصق معرّف المفتاح، وانسخ Deployment ID.
  5. في إنجازيو ← إضافة منصة: المُصدِر https://canvas.instructure.com، و Client ID هو معرّف المفتاح، وروابط Canvas من الجدول.

ماذا يحدث عند التشغيل

  • الأدوار: Instructor و ContentDeveloper و Mentor و TeachingAssistant و Administrator ← معلّم، وما عداها ← طالب (وقواعد أدوارك مقدَّمة).
  • المستخدم يُعرَف بـiss + sub، فالشخص في مقرّرين حساب واحد.
  • كل رابط مورد (نشاط) = حصة واحدة وسبورة واحدة. أول معلّم يملكها، والمعلّمون الآخرون يدخلونها مشاركين في التدريس.
  • الطلاب الذين يفتحون النشاط يصيرون مشاركين. وإن لم يفتح المعلّم السبورة بعد يرى الطالب شاشة *انتظار*.
  • الأمان: state و nonce لمرة واحدة، والتوقيع يُتحقَّق منه بمفاتيح المنصة، مع فحص iss و aud و azp و deployment_id، ورفض التشغيل المكرّر.

٨. المسار د — الدخول بجلسة موقعك

للمواقع الخاصة. لأن السبورة على نطاق فرعي من موقعك، يرسل المتصفّح كوكي جلستك إليها تلقائيًّا. يقرؤها خادمنا ويسأل واجهتك عن صاحبها. لا نستلم مفتاح التوقيع ولا كلمات مرور مستخدميك أبدًا.

المطلوب

  1. رمز الجلسة في كوكي على النطاق الأم: Domain=.example.com; Secure; SameSite=Lax (و HttpOnly مقبول). أما localStorage فلا يصلح.
  2. واجهة ترجع المستخدم الحالي مع Authorization: Bearer <الرمز>، مثل GET https://example.com/api/me.
  3. ترجع 200 مع JSON للرمز الصالح، و 401 أو 403 للمنتهي أو غير الصالح أو الموقوف — لا 200 بجسم فارغ أبدًا.
  4. تستجيب في أقل من ٦ ثوانٍ، وفيها حقل معرّف ثابت (id أو uuid).
json
{
  "id": 2481,
  "name": "سارة علي",
  "email": "sara@example.com",
  "role": "trainer",
  "capabilities": { "trainer": true, "admin": false }
}

من الأكاديمية ← الربط ← الدخول بالجلسة اضبط اسم الكوكي ورابط /me ومسارات المعرّف والاسم والبريد والدور ومن يُسمح له. وزر فحص برمز حقيقي يعرض البيانات المقروءة والدور الذي سيأخذه. وإن لم يُضبط شيء لا يدخل أحد (يفشل مغلقًا).

الخروج من موقعك يحذف الكوكي، وإيقاف المستخدم يجعل /me تفشل — وكلاهما يسري عند أول تنقّل له في السبورة. العقد الكامل في docs/sso-partner-integration.md.

٩. قواعد الأدوار

القواعد تحوّل ما ترجعه منصتك (رمز هوية OIDC، أو ردّ /me، أو حقول LTI) إلى دور في الأكاديمية. تُفحص بالترتيب مدير ← معلّم ← طالب، وأول شرط ينطبق يفوز.

json
{
  "admin":   [ { "path": "groups", "op": "contains", "value": "academy-admins" } ],
  "teacher": [ { "path": "role",   "op": "in",       "value": ["teacher", "trainer", "instructor"] },
               { "path": "capabilities.trainer", "op": "truthy" } ],
  "student": [ { "path": "role",   "op": "equals",   "value": "learner" } ]
}
opينطبق حين
equalsالقيمة في path تساوي value (دون اعتبار حالة الأحرف)
inالقيمة في path إحدى قيم القائمة value
containsالمصفوفة (أو النص) في path تحتوي value
truthyالقيمة في path صحيحة أو غير فارغة
existsالمفتاح path موجود
  • path يستعمل النقطة للتداخل: user.profile.type. وحتى ٢٠ شرطًا لكل دور.
  • استعمل المعاينة في اللوحة: الصق ردًّا تجريبيًّا وانظر أي قاعدة تنطبق.
  • الدور الذي يضبطه المدير يدويًّا مقفَل ويتقدّم على القواعد. افتح القفل لتعود المزامنة تقرّر.

١٠. الحصص والسبورات

لكل حصة معلّم وموعد اختياري وطلاب وصلاحية للطلاب (view مشاهدة أو edit تحرير). وتأتي الحصص من أي مصدر من هذه، ويمكن الجمع بينها:

المصدرالطريقةالمفتاح
اللوحةينشئها المدير أو المعلّم، مع تكرار أسبوعي اختياري (حتى ٥٢ أسبوعًا)—
جدولالأكاديمية ← الحصص ← استيراد (العنوان، المعلم، البداية، النهاية، الطلاب)الصف
LTIكل نشاط في منصة التعلّمiss + deployment + resource link
Webhookحدث lesson.upsertمعرّف حصتك id
تقويم iCalرابط اشتراك تقويم، يُزامَن كل ساعةUID الحدث (+ التاريخ للتكرار)
واجهة الشركاءPOST /partner/boards/resolvecontext_type + context_id
  • السبورة تُنشأ حين يفتح المعلّم الحصة أول مرة — لا قبل ذلك، حفاظًا على حصة السبورات.
  • يرى الطلاب حصصهم في حصصي ويدخلون بضغطة، وقبل أن يفتحها المعلّم يرون *في انتظار المعلّم*.
  • داخل السبورة للمعلّم الأدوات كاملة: المناهج والألعاب والاختبارات والواجبات والتسجيل والشهادات والتحكّم في المشاركين.
  • إلغاء الحصة يخفيها عن الطلاب، وتبقى السبورات ومحتواها.

١١. المسار و — الأتمتة: Webhook وتقويم iCal

Webhook وارد (Zapier أو Make أو n8n أو Power Automate أو خادمك)

من الأكاديمية ← الربط ← Webhook اضغط توليد، فيظهر رابط سرّي مرة واحدة:

url
POST https://api.injazio.com/api/hooks/academy/injwh_{academy-id}_{40 characters}

أو أرسل الرمز في ترويسة X-Injazio-Webhook-Token إلى POST /hooks/academy. والجسم حدث واحد {event, data} أو دفعة {events: [...]} حتى ١٠٠ حدث.

bash
curl -X POST "https://api.injazio.com/api/hooks/academy/injwh_124_…" \
  -H "Content-Type: application/json" \
  -d '{
    "events": [
      { "event": "person.upsert", "data": { "external_id": "1042", "name": "سارة علي", "email": "sara@example.com", "role": "teacher" } },
      { "event": "person.upsert", "data": { "external_id": "2210", "name": "عمر خالد", "email": "omar@example.com", "role": "student" } },
      { "event": "lesson.upsert", "data": {
          "id": "L-5531", "title": "الجبر — الأسبوع الثالث",
          "starts_at": "2026-11-02T16:00:00+03:00", "ends_at": "2026-11-02T17:00:00+03:00",
          "teacher_external_id": "1042",
          "students": ["2210", "lina@example.com"]
      } }
    ]
  }'
الحدثالحقولالأثر
person.upsertexternal_id أو email (أحدهما إلزامي)، و name، و roleينشئ الشخص أو يحدّثه. والأدوار اليدوية تبقى مقفلة.
person.removeexternal_id أو emailيوقف الحساب (ويبقى المحتوى). والمالك محميّ.
lesson.upsertid* و title* و starts_at و ends_at و teacher_external_id أو teacher_email و students (مصفوفة معرّفات أو بريد أو {external_id|email}، أو نص مفصول بفواصل) و replace_students (الأصل true) و cancelledينشئ الحصة أو يحدّثها بمفتاح id الخاص بك.
lesson.cancelidيلغي الحصة.
json
{ "success": true, "data": { "results": [
  { "event": "person.upsert", "ok": true, "user_id": 812 },
  { "event": "person.upsert", "ok": true, "user_id": 813, "created": true },
  { "event": "lesson.upsert", "ok": true, "lesson_id": 77, "students": 2, "teacher_found": true }
] } }
  • كل حدث يردّ ok و reason الخاصين به، فالصف الخاطئ لا يوقف الدفعة. أرسل الأشخاص قبل الحصص التي تذكرهم.
  • تكرار الإرسال نفسه ينتج الحالة نفسها (idempotent).
  • جدّد الرابط متى شئت فيتوقّف القديم فورًا، أو عطّله لإيقاف الـWebhook.
  • Zapier: المُشغّل من تطبيقك (مثل *صف جديد في Google Sheets*) ← الإجراء *Webhooks by Zapier ← POST* ← الرابط السابق، ونوع الحمولة JSON. Make: وحدة HTTP ← *Make a request*، الطريقة POST، والجسم raw JSON.

رابط تقويم (iCal / ICS)

الصق رابط اشتراك تقويم (في Google Calendar: *العنوان السرّي بتنسيق iCal*، وفي Outlook: *رابط ICS للتقويم المنشور*، أو تصدير منصة التعلّم). و webcal:// مقبول. تُزامِن إنجازيو كل ساعة وعند الطلب، من ٧ أيام مضت إلى ١٢٠ يومًا قادمة.

  • SUMMARY ← عنوان الحصة، و DTSTART/DTEND (مع احترام المنطقة الزمنية) ← الموعد، و UID ← الهوية.
  • بريد ORGANIZER ← المعلّم (إن كان موجودًا)، وإلا فالمعلّم الافتراضي الذي تختاره.
  • بريد ATTENDEE المطابق لحسابات الأكاديمية ← طلاب.
  • التكرار اليومي والأسبوعي RRULE يُفكّ، و STATUS:CANCELLED يلغي الحصة.

١٢. المسار هـ — واجهة الشركاء البرمجية

للمنصات التي تحتفظ بصفحات حصصها وتريد زر «افتح السبورة». خادمك ينادي نقطة واحدة بمعرّف الحصة ومعرّف المعلّم، فترجع رابط السبورة — تنشئها أول مرة وترجع السبورة نفسها بعد ذلك.

المصادقة

  • الرابط الأساسي: https://api.injazio.com/api
  • الترويسة: X-Api-Key: injk_{academy-id}_{48 characters} — تُصدَر من الأكاديمية ← الربط ← مفاتيح API.
  • الصلاحيات: boards:write (إنشاء السبورات وإدارة الوصول) و subscription:read (قراءة الباقة والاستهلاك). استعمل مفتاحين منفصلين.
  • من الخادم فقط. لا نرسل ترويسات CORS، فلا تضع المفتاح في كود المتصفّح ولا في متغيّر NEXT_PUBLIC_*.
  • الحدود: ٣٠ في الدقيقة لـresolve، و١٢٠ لمنح الوصول، و٦٠ لما عداها.

إنشاء السبورة أو فتحها — POST /partner/boards/resolve

http
POST /api/partner/boards/resolve
Host: api.injazio.com
X-Api-Key: injk_124_…
Content-Type: application/json

{
  "context_type": "lesson",
  "context_id": 4821,
  "owner_external_id": "77",
  "owner_name": "د. محمد أحمد",
  "owner_email": "m@example.com",
  "title": "المحاضرة الثالثة — النحو التطبيقي",
  "student_permission": "view",
  "teacher_permission": "edit",
  "meta": { "course_id": 310 }
}
json
{
  "success": true,
  "data": {
    "uuid": "c67G7zwALS7",
    "url": "https://board.example.com/waraqa/c67G7zwALS7",
    "title": "المحاضرة الثالثة — النحو التطبيقي",
    "created": true,
    "owner_id": 5120
  }
}
الحقلإلزاميالمعنى
context_typeنعمlesson · course · consultation · live_class · session · workshop · assignment
context_idنعممعرّفك الرقمي للحصة أو الحجز
owner_external_idنعممعرّف المعلّم في منصتك — المعرّف نفسه الذي يرجعه دخولك الموحّد
owner_name و owner_emailلايُستعملان عند إنشاء حساب المعلّم أول مرة
title و descriptionلاعنوان السبورة (الأصل: *سبورة الحصة #المعرّف*)
student_permissionلاview (الأصل) أو edit
teacher_permissionلاedit (الأصل) أو view
metaلاأي JSON تريد حفظه مع السبورة

created: true تعني أن السبورة أُنشئت الآن وحُسبت من حصتك، و false أنها كانت موجودة. نادِ هذه النقطة من زر افتح السبورة، لا عند حفظ الحصة.

النقاط الأخرى

الطريقة والمسارالجسم / الاستعلامالغرض
GET /partner/boards?context_type=&context_id=هل لهذه الحصة سبورة؟ data: null إن لم تكن. لا تنشئ شيئًا.
POST /partner/boards/accesscontext_type, context_id, viewer_external_id, viewer_name?, viewer_email?, viewer_role?, permission? (view|edit)منح طالب الوصول إلى السبورة
DELETE /partner/boards/accesscontext_type, context_id, viewer_external_idسحب وصول هذا الطالب
PATCH /partner/boards/access-policycontext_type, context_id, participant_permission (view|edit)تغيير صلاحية كل المشاركين دفعة واحدة
GET /partner/subscription—الباقة والحدود والاستهلاك الحالي (مفتاح subscription:read)

أمثلة

php
// Laravel
$res = Http::timeout(10)
    ->withHeaders(['X-Api-Key' => config('services.injazio.board_key')])
    ->acceptJson()
    ->post('https://api.injazio.com/api/partner/boards/resolve', [
        'context_type'      => 'lesson',
        'context_id'        => $lesson->id,
        'owner_external_id' => (string) $lesson->teacher_id,
        'owner_name'        => $lesson->teacher->name,
        'title'             => $lesson->title,
    ]);

if ($res->status() === 409) {
    return back()->with('error', 'انتهت حصة السبورات لهذه الفترة.');
}

$lesson->update(['board_url' => $res->json('data.url')]);
return redirect()->away($res->json('data.url'));
javascript
// Node.js (18+)
const res = await fetch("https://api.injazio.com/api/partner/boards/resolve", {
  method: "POST",
  headers: {
    "X-Api-Key": process.env.INJAZIO_BOARD_KEY,
    "Content-Type": "application/json",
    Accept: "application/json",
  },
  body: JSON.stringify({
    context_type: "lesson",
    context_id: lesson.id,
    owner_external_id: String(lesson.teacherId),
    title: lesson.title,
  }),
});
const { data } = await res.json();
res.redirect(data.url);
python
# Python / Django
import os, requests

r = requests.post(
    "https://api.injazio.com/api/partner/boards/resolve",
    headers={"X-Api-Key": os.environ["INJAZIO_BOARD_KEY"], "Accept": "application/json"},
    json={
        "context_type": "lesson",
        "context_id": lesson.id,
        "owner_external_id": str(lesson.teacher_id),
        "title": lesson.title,
    },
    timeout=10,
)
r.raise_for_status()
return redirect(r.json()["data"]["url"])

١٣. واجهة الإدارة البرمجية (أتمتة اللوحة)

كل ما في لوحة الأكاديمية متاح بصيغة JSON. صادِق بحساب مدير الأكاديمية (Authorization: Bearer <access_token>) وحدّد الأكاديمية بـX-Tenant-Domain: board.example.com. الأساس: https://api.injazio.com/api/tenant.

الطريقةالمسارالغرض
GET/admin/overviewالأعداد والمقاعد وحالة النطاق والربط
GET · POST/admin/peopleالقائمة (مرشّحات: role و status و search و per_page) · إضافة شخص
PATCH · DELETE/admin/people/{id}تعديل (الاسم والبريد والدور والحالة و role_locked) · حذف
POST/admin/people/{id}/reset-passwordتوليد كلمة مرور جديدة
POST/admin/people/importملف file متعدد الأجزاء، و dry_run=1 للمعاينة
GET · POST · DELETE/admin/invites[/{id}]روابط الدعوة
GET · POST/admin/domainحالة النطاق · إضافة نطاق
POST/admin/domain/{id}/verify · /primaryالتحقّق من DNS · جعله أساسيًّا
GET/admin/loginكل إعدادات الدخول (الأسرار لا تُرجع)
PUT · POST/admin/login/roles · /roles/previewحفظ قواعد الأدوار · تجربتها على ردّ نموذجي
PUT · POST/admin/login/sso · /sso/probeإعدادات الدخول بالجلسة · فحصها برمز
PUT · POST/admin/login/oidc · /oidc/testإعدادات OIDC · اختبار الاكتشاف
POST · PUT · DELETE/admin/login/lti[/{id}]منصات LTI
POST · DELETE/admin/login/webhookتجديد · تعطيل الـWebhook
PUT · POST/admin/login/ical · /ical/syncرابط التقويم · المزامنة الآن
POST · DELETE/admin/login/api-keys[/{id}]إصدار · إبطال مفاتيح الشركاء
POST/admin/lessons/importاستيراد الحصص من ملف
GET · POST/lessonsالحصص (المدير: الكل، والمعلّم: حصصه، والطالب: حصصه) · إنشاء
PATCH · DELETE/lessons/{id}تعديل · إلغاء
POST/lessons/{id}/openفتح سبورة الحصة ← { url } أو { waiting: true }

١٤. مرجع الأخطاء

الأخطاء بصيغة JSON: { "success": false, "message": "<code>" }. وأخطاء التحقّق (422) فيها أيضًا كائن errors لكل حقل.

الرمزHTTPالمعنى / الحلّ
invalid_or_unscoped_key401المفتاح خاطئ أو مُبطَل أو بلا الصلاحية المطلوبة
invalid_webhook_token401رابط الـWebhook جُدّد أو عُطّل
boards_limit_reached409انتهت حصة السبورات للفترة، و data فيه الحدّ والاستهلاك وموعد التجديد
active_boards_limit_reached409عدد السبورات الموجودة معًا بلغ الحدّ؛ أرشِف القديم
teachers_limit_reached422كل مقاعد المعلّمين مشغولة
email_taken · username_taken422حساب آخر في الأكاديمية يستعمله
owner_protected422مالك الأكاديمية لا يُخفَّض ولا يُوقف ولا يُحذف
invite_not_found · invite_revoked · invite_expired · invite_full404/422رابط الدعوة لم يعد صالحًا
domain_taken · domains_limit · invalid_domain · platform_domain422النطاق مستعمل، أو تجاوزت ٣، أو صيغته خاطئة، أو هو نطاق لإنجازيو
oidc_not_configured · discovery_failed422أكمل إعدادات OIDC / المُصدِر غير متاح
invalid_state · nonce_mismatch403انتهت مهلة الدخول (١٠ دقائق) أو تكرّر — ابدأ من جديد
issuer_mismatch · audience_mismatch403المُصدِر أو Client ID في إنجازيو يخالف الرمز
email_domain_not_allowed · not_registered_in_academy403منعه إعداد allow_mode
account_suspended403الحساب موقوف في الأكاديمية
platform_not_registered · deployment_not_registered403أضف منصة التعلّم (المُصدِر + Client ID) في إنجازيو، وراجع Deployment ID
replayed_launch · unsupported_lti_version · unsupported_message_type403لا يُقبل إلا تشغيل LTI 1.3 جديد لرابط مورد
not_a_participant403الطالب ليس في هذه الحصة
unknown_event · id_and_title_required · external_id_or_email_required200 (لكل حدث)صحّح حمولة الحدث
ical_fetch_failed · ical_invalid422رابط التقويم غير متاح أو ليس تقويمًا صحيحًا
429429تجاوزت الحدّ — تمهّل وأعد المحاولة

١٥. الأمان والخصوصية

  • العزل — كل طلب محصور في أكاديمية واحدة بنطاقها، ومدير الأكاديمية لا يصل إلى أكاديمية أخرى ولا إلى المنصة أبدًا.
  • لا أسرار تندم على مشاركتها — لا نطلب مفتاح توقيع JWT ولا الوصول إلى قاعدة بياناتك ولا كلمات المرور. و OIDC و LTI يعتمدان التوقيع بالمفتاح العام.
  • الإعداد الافتراضي مغلق — OIDC يُدخل أصحاب الحسابات الموجودة فقط، والدخول بالجلسة لا يُدخل أحدًا حتى تُضبط القواعد.
  • الأسرار مخزّنة بأمان — سرّ OIDC مشفّر، ومفاتيح API ورموز الـWebhook والدعوات تُخزَّن بصمةً بـSHA-256 وتظهر مرة واحدة.
  • الطلبات الصادرة — نداءاتنا إلى /me و JWKS والاكتشاف و iCal عبر HTTPS فقط، وترفض العناوين الداخلية والخاصة (حماية من SSRF).
  • نظافة الرموز — state و nonce و PKCE في كل دخول OIDC، و nonce الخاص بـLTI لمرة واحدة، ورمز الجلسة يضعه خادمنا في كوكي ولا يمرّ في الروابط.
  • الإبطال فوري — جدّد الـWebhook، أو أبطل مفتاحًا أو دعوة، أو أوقف شخصًا: يسري في الحال.
  • البيانات — نخزّن الاسم والبريد والدور ومعرّفك الخارجي. حذف الشخص يوقفه ويُبقي سبوراته، وطلبات الحذف من injazio.com/data-deletion.

١٦. قائمة الإطلاق

  • ☐ حالة النطاق ready، ويفتح HTTPS بلا تحذيرات.
  • ☐ مسار دخول واحد مضبوط ومجرَّب بحساب معلّم وحساب طالب.
  • ☐ قواعد الأدوار جُرّبت ببيانات حقيقية، وحساب المدير مقفَل على دور المدير.
  • ☐ مقاعد المعلّمين في باقتك تكفي معلّميك.
  • ☐ حصة تجريبية: المعلّم يفتح السبورة، والطالب يراها في حصصي ويدخلها.
  • ☐ لـLTI: التشغيل يفتح في نافذة جديدة، وطالب من المقرّر يصل إلى السبورة نفسها.
  • ☐ للـWebhook والواجهة: المفاتيح في الخادم فقط، وتكرار الحمولة نفسها لا يغيّر شيئًا.
  • ☐ أوقف مستخدمًا تجريبيًّا في منصتك وتأكّد أنه لم يعد يدخل.

تحتاج مساعدة؟ راسلنا من injazio.com/contact أو واتساب ‎+20 155 544 9654 مع نطاق أكاديميتك ورمز الخطأ.

↑ المحتويات
دليل ربط سبورة إنجازيو للمطوّرين — Integration Guide | منصة إنجازيو