إرفاق ملف بسجل من داخل سكربت
الهدف
السماح لمستدعٍ خارجي — بوابة، أو نظام شريك — بإرفاق ملف بسجل عبر Custom API، بحيث يقرر سكربتك على أي سجل يستقر الملف وما إذا كان المستدعي مسموحاً له أصلاً.
لماذا يوجد هذا
عمودا File وImage في السجل لهما نقاط نهاية خاصة بهما، والنموذج يستخدمها. أما البوابة
فلا تستطيع: البوابة تخاطب المنصة عبر Custom APIs ولا شيء غيرها، لأن الفحص الذي يُبعد عميلاً عن
سجلات عميل آخر يجب أن يقع في السكربت بجانب portalCustomerId()، لا في بانِي الطلبات في موقع
ويب.
لذا صار بإمكان السكربت أن يضع ملفاً في حقل سجل ويقرأه مجدداً. تنتقل البايتات كنص base64، لأن السكربت لا يملك طريقة أخرى لحملها — المستدعي يُرمِّز، والمنصة تفكّ الترميز، والسكربت يمرّر السلسلة فحسب.
ما يستطيع السكربت فعله
putRecordFile(table, id, field, fileName, contentType, contentBase64) | يخزّن الملف في حقل السجل. يجيب بـtrue، أو false إن لم يستطع |
getRecordFile(table, id, field) | الملف ككائن — fileName وcontentType وsizeBytes وcontentBase64 — أو لا شيء إن كان الحقل فارغاً |
كلاهما يعمل باسم المستدعي: التخزين يحتاج Update على السجل والقراءة تحتاج Read، تماماً كما تفعل نقاط نهاية ملفات السجل نفسها. سقف حجم الحقل وقاعدة «صور فقط» من شأن المنصة، لا السكربت.
الخطوات
-
أعطِ الجدول عموداً من نوع File —
par_attachment— وإن كان على القائمة أن تُظهر الاسم دون جلب الملف، فعموداً من نوع Text بجانبه للاسم. -
في request schema الخاص بـCustom API، استقبل الملف كثلاث خصائص:
"attachmentName": { "type": "string", "maxLength": 260 },"attachmentType": { "type": "string", "maxLength": 200 },"attachmentBase64": { "type": "string", "maxLength": 5600000 }أو، منذ جولة البوابات ١٠، كـ كائن واحد — وهو ما يرسله منتقي الملفات في شاشة مرسومة، وهو الشكل الذي يعيده
getRecordFile:"par_document": {"type": "object","additionalProperties": false,"required": ["fileName", "contentType", "contentBase64"],"properties": {"fileName": { "type": "string", "maxLength": 260 },"contentType": { "type": "string", "maxLength": 200 },"sizeBytes": { "type": "integer" },"contentBase64": { "type": "string", "maxLength": 5600000 }}}عندئذٍ يسلّم
getInput('par_document')الكائن كاملًا للسكربت، ويقرأfile.fileNameعضوًا منه. وإن كان المتصل شاشة بوابة بارسوير، فاستخدم هذا الشكل — انظر دع الزوّار يرفقون ملفًا. -
في السكربت، أنشئ السجل أولاً ثم الملف — فملف السجل يتبع سجلاً:
var id = createRecord('par_request', {par_name: getInput('subject'),par_attachment_name: getInput('attachmentName')});if (!isEmpty(getInput('attachmentBase64'))) {putRecordFile('par_request', id, 'par_attachment',getInput('attachmentName'), getInput('attachmentType'), getInput('attachmentBase64'));} -
لإعادة ملف، تحقق أولاً من أن السجل يخص المستدعي، ثم اقرأه:
var file = getRecordFile('par_request', id, 'par_attachment');if (isEmpty(file)) {setStatus(404);} else {setOutput('fileName', file.fileName);setOutput('contentType', file.contentType);setOutput('contentBase64', file.contentBase64);}
ثلاثة أمور توقع الناس
- تحقق من الملكية قبل القراءة. يعمل
getRecordFileباسم التطبيق المستدعي، الذي قد يكون مسموحاً له بقراءة كل سجلات الجدول. سؤال «هل هذا السجل يخص هذا المستدعي؟» سؤال سكربتك، ويُجاب عنه بقراءة السجل والمقارنة. - الاسم على الصف لقطة. صف الملف يحتفظ بالاسم الحقيقي؛ وعمود Text بجانبه يتيح للقائمة أن تقول «📎 report.pdf» دون استدعاء ملف لكل صف. اكتبه عند تخزين الملف، ويبقى صحيحاً حتى يستبدل أحدهم الملف من باب آخر.
- الملفات الكبيرة لا تمر عبر السكربت. الملف الذي يتجاوز سقف الحقل يُخزَّن في object storage
وتبثّه نقطة نهاية السجل؛ ويرفضه
getRecordFileبدلاً من تجسيد مئات الميغابايتات داخل مفسّر.
تأكد من نجاحه
افتح السجل في تطبيقه: يُظهر عمود File الملف، وتنزيله يعيد ما أرسله المستدعي. يسجّل تاريخ التدقيق التغيير مع اسم الملف وبصمته.