الجدولة والإلغاء
`scheduledAt` و`emails.reschedule` و`emails.update` و`emails.cancel`.
الإرسال لاحقًا
message = {from: "[email protected]", to: "[email protected]", subject: "Your September invoice", text: "Invoice attached."} client.emails.send(message, scheduledAt: "PT1H")client.emails.send(message, scheduledAt: Time.utc(2027, 1, 1, 9))client.emails.send(message, scheduledAt: "2027-01-01T09:00:00.000Z")Time أو DateTime، أو لحظة ISO 8601 في صورة String، أو مدة مثل PT1H أو P2D. حتى سنة واحدة إلى الأمام، ولا يكون في الماضي أبدًا. والوسيط المسمّى إلى جانب الـ Hash يضيف الحقل إلى رسالة بنيتها سابقًا.
يُرسَل Date في Ruby كتاريخ مجرد مثل 2027-01-01، تقرؤه API على أنه منتصف الليل UTC في ذلك اليوم. مرّر Time، مثل Time.utc(2027, 1, 1, 9)، حين تهمّ الساعة.
النقل والإيقاف
message = {from: "[email protected]", to: "[email protected]", subject: "Your September invoice", text: "Invoice attached."} queued = client.emails.send(message, scheduledAt: "PT1H") client.emails.reschedule(queued[:id], Time.now + 86_400)client.emails.cancel(queued[:id])لا يمكن إيقاف سوى الرسائل queued وscheduled. وأي رسالة تجاوزت ذلك ترفع OpenEmail::ConflictError، لأن جزءًا منها صار بالفعل في صندوق بريد أحدهم. وإلغاء رسالة ملغاة أصلًا ينجح ولا يغيّر شيئًا.
للعثور على ما ينتظر الانطلاق في نافذة زمنية، اعرض القائمة مع status: ["scheduled", "queued"] وscheduled_from: وscheduled_to:، كما يفعل تقويم التطبيق.
تغييرها قبل أن تنطلق
يغيّر emails.update رسالة لم تنطلق بعد: موعد انطلاقها عبر scheduledAt، وما تقوله عبر subject وhtml وtext، والعنوان الذي تخرج منه عبر from، ومن تذهب إليهم عبر to وcc وbcc. أرسل أيًّا منها معًا، والحقل الذي تتركه يحتفظ بقيمته. وقائمة المستلمين تستبدل القائمة المخزَّنة كاملة. وهذا ما يفعله تعديل رسالة مجدولة في تقويم التطبيق.
updated = client.emails.update( "msg_3f9a1c07d2b84e6a9c5b1f20", subject: "Your September invoice, corrected", to: ["[email protected]", "[email protected]"], scheduledAt: Time.utc(2026, 10, 5, 8)) puts updated[:status], updated[:subject], updated[:scheduledAt]يُفحص from كما يُفحص عند الإرسال، فيجب أن يكون عنوانًا يجوز للمفتاح الإرسال باسمه. والرسالة التي تُرجمت عند قبولها تحتفظ بصياغتها المعتمدة، فأي subject أو html أو text جديد عليها يعطي 409 translation_locked، والرسالة التي شُفّرت قبل جدولتها تحتفظ بصياغتها ومستلميها. ألغِ هذه وأرسلها من جديد بدلًا من ذلك.
نافذة تراجع بدلًا من ذلك
message = {from: "[email protected]", to: "[email protected]", subject: "Your September invoice", text: "Invoice attached."} held = client.emails.send(message, cancellableForSeconds: 30) puts held[:status], held[:cancellableUntil]الرسالة المجدولة قابلة للإلغاء أصلًا حتى تنطلق، فلا يمكن الجمع بين الاثنين، والخادم يرفض ذلك. استخدم هذا الخيار لنافذة تراجع عن الإرسال في رسالة فورية.
المعاملات: الجدولة
scheduledAtTime, DateTime or String- متى تُرسل الرسالة، في `emails.send`: Time أو DateTime، أو لحظة ISO 8601 في صورة String، أو مدة مثل `PT1H` أو `P2D`. ويُرسَل Time أو DateTime كلحظة UTC، وString كما هو، وDate في Ruby كتاريخ مجرد يعني منتصف الليل UTC. على الأقل بعد ثانية من الآن وبحد أقصى 365 يومًا، وكلا الحدين يعطي `validation_error` على `scheduledAt`، واللغة الطبيعية غير مقبولة، لأن تحليل «الثلاثاء القادم» تحليلًا خاطئًا يرسل رسالة في وقت لا يمكن التراجع عنه.
cancellableForSecondsInteger- نافذة تراجع عن الإرسال على إرسال فوري: Integer من 0 إلى 900، والافتراضي 0. وأي قيمة فوق 0 تُرفض مع `scheduledAt`، الذي يكون قابلًا للإلغاء أصلًا حتى ينطلق، والرسالة المحتجزة بهذه الطريقة تبقى عند `queued` لا `scheduled`. فهي آلية التأجيل نفسها بتأخير قصير.
idStringمطلوب- المعرّف `msg_`، وهو الوسيط الأول لـ `emails.cancel` و`emails.reschedule` و`emails.update`. وتحتاج هذه إلى `emails:send` لا إلى نطاق خاص بها، وتبحث عن المعرّف داخل مساحة عمل المفتاح نفسها، فمعرّف يخص مساحة أخرى يعطي `not_found_error` تمامًا كمعرّف لم يوجد قط.
scheduled_atTime, DateTime or Stringمطلوب- الوقت الجديد، كوسيط ثانٍ لـ `emails.reschedule`، يُقرأ بالقواعد نفسها وفي نافذة السنة نفسها. وهو الشيء الوحيد الذي يغيّره `reschedule`، ولا يرسل العميل شيئًا غيره. والمدة نسبية إلى لحظة قراءة الخادم لها، فإعادة الجدولة المُعادة تحط بعد الأولى بقليل: بعدها لا قبلها أبدًا.
api_keyString- يعمل بهذا المفتاح بدل مفتاح العميل، في أيٍّ من الاستدعاءات الثلاثة.
الاستجابة
يعيد كلٌّ من cancel وreschedule وupdate الرسالة كاملة في صورة Hash بمفاتيح من نوع Symbol.
objectString- دائمًا `email`. تجيب هذه الاستدعاءات بالرسالة كاملة لا بمجرد إقرار، فلا حاجة إلى جلب شيء مجددًا لمعرفة ما تغيّر. ويعيد `emails.send` الشكل نفسه مع `replayed`.
idString- المقبض `msg_`. ثابت طوال عمر الرسالة، وهو المعرّف الذي يأخذه كل استدعاء آخر عليها.
statusString- تكون `cancelled` بعد الإلغاء و`scheduled` بعد إعادة الجدولة، بما في ذلك رسالة كانت `queued` فقط خلف نافذة تراجع، فإعادة الجدولة تحوّلها إلى جدولة حقيقية. ولا يمكن نقل أو إيقاف سوى الرسائل في الحالتين `queued` و`scheduled`. وأي شيء تجاوز ذلك يعطي `conflict_error` برمز `email_not_cancellable`، لأن جزءًا منه صار في صندوق بريد أحدهم بالفعل.
scheduledAtString or nil- لحظة ISO 8601 المقرر أن تُرسل فيها الرسالة. تُضبط لنافذة التراجع كما تُضبط لإرسال `scheduledAt`، لأنهما آلية واحدة، وتكون nil في الإرسال الفوري العادي.
cancellableUntilString or nil- متى يتوقف الإلغاء عن العمل، وهي اللحظة نفسها التي تحملها `scheduledAt` في كلا المسارين المؤجَّلين. وتكون nil في إرسال فوري يكون قد انطلق بالفعل قبل أن يعود الاستدعاء.
sentAtString or nil- متى غادرت الرسالة فعلًا. nil ما دامت تنتظر، وnil إلى الأبد على الرسالة الملغاة.
messageIdString or nil- ترويسة Message-ID بحسب RFC 5322، وتكون nil إلى أن توجد رسالة MIME، فهي دائمًا nil على الرسائل التي يمكن لهذه الاستدعاءات أن تعمل عليها. وليست شيئًا تخاطب به API، ولا ما يعود به أي ارتداد لاحق أيضًا: فخدمة الإرسال تعيد كتابة الترويسة عند الخروج.
threadIdString or nil- المحادثة التي تنتمي إليها هذه الرسالة، مأخوذة من الطلب ومُعاد كتابتها بما يبلّغ عنه النقل بمجرد الإرسال. وتكون nil عندما لا تكون الرسالة ردًا.
transportString or nil- كيف غادرت البايتات، وnil حتى الإرسال الفعلي، فهي nil على كل رسالة يمكن أن يعيدها إلغاء أو إعادة جدولة. والإرسال في وضع الاختبار يسجّل `test`، وقد تظهر وسيلة نقل لا يسمّيها هذا الـ gem بعد، فعامل القيمة المجهولة كمعلومة لا كخطأ.
attemptsInteger- كم مرة طالب الإرسال بهذا السجل. تزداد مع كل مطالبة لا مع إرسال ناجح، وتكون 0 لأي شيء ما زال ينتظر.
lastErrorString or nil- آخر فشل سُجّل على الرسالة، وnil ما دام لم يفشل شيء. والإرسال المؤجَّل الذي تعذّر إدراج مهمته في الطابور يُكتب هنا بالشكل `Could not schedule: …` ويُنقل إلى `failed`، وهو السبيل الوحيد الذي تتوقف به رسالة مجدولة عن كونها قابلة للإلغاء دون أن يطلب أحد ذلك.
fromString- العنوان الذي أُذن للرسالة أن تخرج منه: `from` الذي أُرسل، مخزَّنًا مجردًا بأحرف صغيرة. ويُحذف أي اسم معروض هنا، لأن مرشِّح `from:` في `emails.list` يقارن بالمساواة.