عنصر الإضافة إلى التقويم
عنصر «أضف هذا إلى تقويمي» بنقرة واحدة، والحل العملي لدعوات المناطق الزمنية المختلفة. لا تملك الرسالة المُرسَلة أي JavaScript لاكتشاف المنطقة الزمنية للمستلم، لذا يرمّز هذا العنصر بداية الفعالية ونهايتها لحظةً زمنية مطلقة بدلًا من نص وقت محلي محسوب مسبقًا. وبذلك يعرضها تطبيق التقويم لدى كل حاضر بشكل صحيح بتوقيته المحلي هو تلقائيًا.
آلية العمل
العنصر محتوى خالص، مثل عنصر المكان: لا شيء يُجاب عنه، لذا لا يظهر أبدًا في لوحة الردود أو تصدير CSV. وتعتمد الروابط الثلاثة التي تعرضها جميعًا على خانة تتبّع النقرات العامة نفسها التي تستخدمها كل العناصر الحاملة لروابط عادية، بدلًا من قدرة مخصّصة.
لا تُعرض الروابط إلا عند وجود startsAt صالح: فالفعالية التي لم يُكتب لها وقت بدء تعرض نص العنوان والوصف فقط، دون روابط معطّلة لا تقود إلى أي مكان. وإذا ضُبط startsAt دون endsAt (أو كانت قيمته تسبق startsAt)، يجعل العنصر المدة الافتراضية ساعة واحدة بعد البدء — إذ يُعامَل ملء «وقت البدء» وحده على أنه الحالة الشائعة، وكل مستهلك لاحق (ملف .ics، وGoogle Calendar، وOutlook.com) يحتاج إلى وجود لحظة انتهاء ما. أما location فحقل حر عادي تملؤه يدويًا من نص عنصر المكان أو رابط الاجتماع لديك؛ فالعناصر الثلاث غير مرتبطة تلقائيًا في هذا الإصدار الأول، لذا حدّثه بنفسك إن تغيّر المكان.
من هذه الخصائص تُعرض ثلاثة روابط، تتشارك blockId واحدًا لأغراض تتبّع النقرات (إذ تُجمِّع الخريطة الحرارية النقرات حسب العنصر لا حسب كل رابط منفرد، وهو الاصطلاح نفسه الذي يتّبعه عنصر روابط التواصل الاجتماعي مع أيقوناتها المتعددة):
- تنزيل ملف .ics — رابط موقّع إلى
GET /api/calendarيبثّ ملف RFC 5545 (iCalendar) مبنيًا يدويًا. لا توجد أي حزمة npm خلفه — فملف.icsنص عادي، يُبنى بطريقة «من الصفر بالكامل» نفسها التي يُبنى بها مرمِّز GIF للعدّاد التنازلي. وتُكتب قيمتاDTSTART/DTENDفي الملف لحظتين مطلقتين بتوقيت UTC (بلاحقةZ، دون الحاجة إلى مكوّنTZID/VTIMEZONE) — وهذا هو الإصلاح الفعلي لمشكلة المناطق الزمنية، لا شيئًا يُحسب لحظة العرض، بل مجرد نتيجة لتخزينstartsAt/endsAtللعنصر بالمللي ثانية منذ بداية حقبة Unix أصلًا. وUIDالفعالية تجزئة sha256 حتمية لعنوانها/وصفها/موقعها/بدايتها/نهايتها، فإعادة تنزيل الرابط الموقّع نفسه تحدّث إدخالًا واحدًا في التقويم بدلًا من إنشاء نسخة مكرّرة. ويُهرَّب النص الحر وفق RFC 5545 §3.3.11 (الشرطات المائلة العكسية، والفواصل، والفواصل المنقوطة، وفواصل الأسطر الحرفية)، وتُطوى الأسطر الطويلة عند حدّ 75 ثمانيًا الذي تشترطه المواصفة، فلا يمكن لوصف طويل يكتبه المنظّم أن ينتج ملفًا غير صالح تقنيًا. أما الرابط نفسه فيُوقَّع بالطريقة نفسها التي تُوقَّع بها نقاط نهاية العدّاد التنازلي والصيغة والمخططات — إذ تُسلسَل حمولة الفعالية كاملة في سلسلة الاستعلام (دون قراءة من Firestore في مسار GET)، مع فصل نطاقها عن كل عائلة روابط موقّعة أخرى في التطبيق عبر بادئة"calendar:"مضمّنة في مدخل HMAC، فلا يمكن للتوقيع المولَّد لنقطة النهاية هذه أن يُتحقَّق منه مقابل أي نقطة أخرى. - إضافة إلى تقويم Google — رابط عميق عادي
calendar.google.com/calendar/render?action=TEMPLATE&...يُبنى لحظة الإخراج، دون رحلة ذهاب وإياب إلى الخادم. - إضافة إلى Outlook.com — رابط عميق عادي
outlook.live.com/calendar/0/action/compose?...، يُبنى أيضًا لحظة الإخراج.
يُقتطع كلٌّ من العنوان والوصف والموقع احترازيًا إلى أطوال قصوى ثابتة (200 / 2,000 / 300 حرف) قبل بناء أيٍّ من الروابط الثلاثة، فلا يمكن لحقل حر طويل جدًا أن ينتج رابط .ics معطّلًا أو سلسلة استعلام ضخمة في رابطَي الويب الآخرين.
الحقول القابلة للضبط:
- عنوان الفعالية.
- الوصف (اختياري).
- وقت البدء — مطلوب لعرض أي روابط.
- وقت الانتهاء (افتراضيًا: 1 ساعة بعد البدء).
- الموقع (اختياري، نص حر).
- لون الخلفية، والحشو، والحدّ، واستدارة الزوايا للبطاقة.
- تجاوزات لون عنوان الفعالية وحجمه، ولون الروابط الثلاثة وخلفيتها المشتركين.
أمثلة
Subject
Save the date: our fall meetup
يبدأ كل مشروع بغرض «فعالية» وفيه عنصر الإضافة إلى التقويم جاهزًا إلى جانب رابط الاجتماع والمكان وتأكيد الحضور — راجع الفعاليات والندوات عبر الإنترنت للنمط الكامل من الدعوة إلى التذكير الذي يشكّل هذا العنصر جزءًا منه. ويعيد نادٍ رياضي استخدام العنصر نفسه أسبوعًا بعد أسبوع لمواعيد التدريبات والمباريات، فيعكس تقويم كل عائلة الجدول بشكل صحيح أيًّا كانت المنطقة الزمنية التي تسافر فيها — راجع الفرق والأندية الرياضية. ويمكن لسلسلة ندوات عبر الإنترنت إدراج هذا العنصر في رسالة تأكيد تُرسَل فور التسجيل، ليضيف المستلم الموعد إلى تقويمه في اللحظة نفسها التي سجّل فيها، بدلًا من الاعتماد على تذكّره لاحقًا.
كيف يبدو البديل الثابت
<div style="margin:12px 0;background-color:transparent">
<p style="margin:0 0 8px;font-weight:600;font-size:16px;color:#111827">Q3 Product Launch</p>
<a href="https://mailinapp.com/api/calendar?d=eyJ0aXRsZSI6...&s=abc123..."
style="display:inline-block;padding:10px 20px;background-color:#4f46e5;color:#ffffff;
border-radius:6px;text-decoration:none;font-size:14px;font-weight:600;margin:0 8px 8px 0">
Download .ics
</a>
<a href="https://calendar.google.com/calendar/render?action=TEMPLATE&text=Q3+Product+Launch&dates=20260901T170000Z%2F20260901T180000Z"
style="display:inline-block;padding:10px 20px;background-color:#4f46e5;color:#ffffff;
border-radius:6px;text-decoration:none;font-size:14px;font-weight:600;margin:0 8px 8px 0">
Add to Google Calendar
</a>
</div>
هذا هو العنصر المُرسَل بأكمله — ثلاثة روابط عادية (حُذف الثالث، Outlook.com، هنا للاختصار) مبنية من تفاصيل الفعالية نفسها، دون أي صورة أو محتوى مقيَّد.