السرد والجلب
`emails.list` و`emails.list_all` و`emails.iterate` و`emails.get` و`emails.list_events`.
emails.list
filters = {status: ["queued", "scheduled"], from: "[email protected]"} first = client.emails.list(**filters, limit: 50)second = client.emails.list(**filters, limit: 50, cursor: first.next_cursor) if first.next_cursor p first.items.size, second&.items&.sizeالصفحة هي OpenEmail::Page فيها items وhas_more? وnext_cursor. مرّر next_cursor مرة أخرى كـ cursor:، مع المرشِّحات نفسها، للحصول على الصفحة التالية.
emails.iterate وemails.list_all
client.emails.iterate(status: "failed") do |email| warn "#{email[:id]} #{email[:lastError]}"end failures = client.emails.list_all(status: "failed", from: "[email protected]")puts failures.sizeكلاهما يتبع next_cursor نيابةً عنك. ويجلب iterate صفحة فقط عندما يصل المرور إليها، فإن break داخل الكتلة، أو first أو find على الـ Enumerator الذي يعيده دون كتلة، يوقف الطلبات، بينما يمر list_all على كل الصفحات قبل أن يعيد Array واحدة، لذا أعطه مرشِّحًا ينتهي. والترقيم قائم على المفاتيح في الحالتين، فرسالة تصل في أثناء المرور لا يمكنها أن تجعله يتخطى سجلًا كما قد تفعل الإزاحة.
emails.get وemails.list_events
email = client.emails.get("msg_3f9a1c07d2b84e6a9c5b1f20")puts email[:status]p email[:recipients] events = client.emails.list_all_events("msg_3f9a1c07d2b84e6a9c5b1f20")events.each { |event| puts "#{event[:type]} #{event[:createdAt]}" }get هو الاستدعاء الوحيد الذي يعيد recipients، بـ Hash لكل عنوان فيه status وerror وdeliveredAt الخاصة به. فقائمة من خمسين رسالة يحمل كل منها مستلميه صفحة تقرير لم يطلبها أحد.
يقرأ list_events سجل أحداث إرسال واحد، من الأقدم: email.accepted وemail.queued وemail.sent وemail.delivered وemail.bounced وemail.opened وغيرها، لكل منها Hash باسم data يعتمد شكله على type الخاص به. ويمر list_all_events وiterate_events على السجل كله نيابةً عنك. وتسلّم webhooks مجموعة فرعية من الأحداث نفسها لحظة وقوعها، فهذا هو المكان الذي تبحث فيه حين يفوتك webhook.
المعاملات
statusString or Array<String>- حالة واحدة أو عدة حالات (`queued` أو `scheduled` أو `sending` أو `sent` أو `partial` أو `bounced` أو `cancelled` أو `failed`)، وتطابق أيًّا منها. وتعني `bounced` أن كل مستلم ذهبت إليه الرسالة قد ارتدت عنه، بينما الرسالة التي ارتدت عن بعضهم ووصلت إلى الباقين تظهر `partial`. ويرسل الـ gem الـ Array كقيمة واحدة مفصولة بفواصل لأن الخادم يقسّم على الفواصل، وأي قيمة خارج المجموعة تعطي 422 تسمّي القيمة المجهولة.
broadcast_idString- نسخ بث واحد فقط، بمعرّف `brd_` من `broadcasts.send`. فكل شخص يصل إليه البث يتلقى رسالة خاصة به، فهذا يسرد من ذهب إليهم وما حدث لكل نسخة. ويسرد `broadcasts.list_recipients` الأشخاص أنفسهم مع مرات الفتح والنقرات وإلغاءات الاشتراك.
fromString- مطابقة تامة لعنوان الإرسال كما سُجّل، وهو `addr@host` المجرد بأحرف صغيرة. ويُكتب السجل بعد تجريد أي اسم معروض، فعنوان بصيغة الأقواس الزاوية مثل `Acme <[email protected]>` لا يطابق شيئًا. وتُحوَّل قيمتك إلى أحرف صغيرة قبل المقارنة، والمقارنة مساواة لا مطابقة بادئة أو نطاق.
scheduled_fromTime, DateTime or String- الرسائل المجدولة لهذه اللحظة أو بعدها فقط. ومع `scheduled_to:` و`status: ["scheduled", "queued"]` يسرد ما ينتظر الانطلاق في نافذة زمنية، كما يفعل تقويم التطبيق. وتُستبعد الرسالة التي ليس لها `scheduledAt`. مرّر Time أو DateTime أو لحظة ISO 8601 مع إزاحتها الزمنية: فـ Date في Ruby يُرسَل كتاريخ مجرد، وهذان المرشِّحان يرفضانه.
scheduled_toTime, DateTime or String- الرسائل المجدولة لهذه اللحظة أو قبلها فقط. ووقوع `scheduled_from:` بعد `scheduled_to:` يعطي 422 `invalid_parameter`.
limitInteger- الصفوف في هذه الصفحة، من 1 إلى 100، والافتراضي 25. والقيمة خارج هذا المدى تُرفض بـ 422 بدل أن تُقصّ. وفي `list_all` و`iterate` هي حجم كل صفحة يجلبانها.
cursorString- معرّف رسالة (`msg_…`) يبدأ منه الترقيم. قائم على المفاتيح لا على الإزاحة: تعود الصفوف الأقدم تمامًا من `createdAt` الخاص بتلك الرسالة، فالإرسالات التي تصل في منتصف الصفحة لا يمكنها دفع سجل بعيدًا عنك. والمعرّف الذي لا يسمّي أي رسالة في مساحة العمل هذه يعطي 400 `invalid_cursor`.
api_keyString- يسرد بهذا المفتاح بدل مفتاح العميل.
المفتاح المقصور على بعض العناوين لا يقرأ إلا الرسائل المرسلة من العناوين التي يغطيها، وتُقطع الصفحة بعد ذلك الترشيح، فكل صفحة عدا الأخيرة تحمل مع ذلك limit صفًا. وfrom: الذي لا يغطيه المفتاح يعيد صفحة أخيرة فارغة بدل 403.
الاستجابة: OpenEmail::Page
itemsArray<Hash>- صفحة واحدة من الرسائل، الأحدث أولًا حسب `createdAt`، مستخرجة من مُغلَّف `data` الخاص بواجهة API. ولا تحمل سجلات القائمة أبدًا تفصيل `recipients` لكل عنوان. فذلك في `get`.
has_more?Boolean- ما إذا كانت هناك سجلات أخرى تطابق المرشِّح بعد هذه الصفحة. ويُجاب عن ذلك بجلب سجل واحد زيادة على `limit` بدل استعلام عدّ ثانٍ.
next_cursorString or nil- المعرّف الذي تمرّره مرة أخرى كـ `cursor:`، وnil في الصفحة الأخيرة. ويتوقف `iterate` و`list_all` عندما يكون هذا nil أو تكون قيمة `has_more?` هي false، لأن صفحة تدّعي وجود المزيد دون أن تسمي مؤشرًا كانت ستدور إلى ما لا نهاية.
كل عنصر
objectString- دائمًا `email` في صف من هذه القائمة.
idString- المعرّف الخاص بهذه الواجهة، `msg_…`. وهو ما يأخذه كل استدعاء آخر من emails، وما يسمّيه المؤشر.
statusString- أين الرسالة في دورة حياتها. و`partial` حالة قائمة بذاتها لا نكهة من نكهات الفشل: فبعض المستلمين لديهم الرسالة ولا يمكن سحبها منهم، ومن ثَم فإعادة المحاولة خطأ. و`bounced` تعني أن الرسالة ارتدّت عن كل مستلميها بعد خروجها، فلم تصل إلى أحد، وكل مستلم في `get` يذكر السبب.
modeString- `live` أو `test`، مأخوذة من المفتاح الذي أرسل. والإرسال في وضع الاختبار يُسجَّل هنا ولا يُبثّ أبدًا.
fromString- العنوان الذي أُذن بالإرسال تحته، مخزَّنًا مجردًا وبأحرف صغيرة، فالاسم المعروض المعطى في `from` يخرج على الشبكة لكنه لا يُحفظ هنا. وهو String عادي لا Hash لأن هذه هي الهوية التي أُذن بها: فعنوان خارج نطاق إرسال المفتاح، ليس على نطاق يملكه ولا مسمّى عليه، يُرفض بـ 403، ولا يُستبدل بصمت بعنوان مسموح له.
subjectString or nil- الموضوع كما خُزّن. nil على رسالة سُجّلت دون موضوع.
messageIdString or nil- ترويسة Message-ID بحسب RFC 5322، لا معرّفنا. تكون nil إلى أن توجد رسالة MIME، وتعيد خدمة الإرسال كتابتها عند الخروج، فيحمل أي ارتداد أو DSN لاحق معرّفًا مختلفًا ويُربط عبر `id` بدلًا منها.
threadIdString or nil- المحادثة التي تنتمي إليها هذه الرسالة، حين تُعطى أو تُعيَّن. وnil فيما عدا ذلك.
transportString or nil- كيف غادرت البايتات. nil حتى الإرسال الفعلي. وقد تسمّي السجلات المخزَّنة وسائل نقل لم تعد مستخدمة، فعامل القيمة التي لا تعرفها كمعلومة لا كخطأ.
attemptsInteger- كم محاولة إرسال جرت على الرسالة، و0 قبل الأولى.
lastErrorString or nil- أحدث خطأ في الإرسال، مكتوبًا لشخص. nil ما دام لم يفشل شيء.
scheduledAtString or nil- متى يُتوقع أن تنطلق الرسالة، كلحظة ISO 8601. لا تكون nil إلا في إرسال فوري بلا نافذة إلغاء: فالنافذة مجرد تأخير قصير لا أكثر، ولهذا يملأ `cancellableForSeconds` هذا الحقل أيضًا، على صف تكون قيمة `status` فيه `queued` لا `scheduled`.
cancellableUntilString or nil- اللحظة التي يُتوقع أن تنطلق فيها الرسالة، وتحمل القيمة نفسها التي يحملها `scheduledAt` في أي إرسال مؤجَّل وnil في غير المؤجَّل. وهي طابع زمني للعرض لا الاختبار الذي يجريه الخادم: فـ `cancel` يتفرّع على `status`، ولا يوقف رسالة إلا ما دامت `queued` أو `scheduled`.
sentAtString or nil- متى انطلقت. nil حتى يكتمل الإرسال الفعلي، ولهذا فالحقل الذي يُتفرّع عليه هو `status` لا هذا.
tagsHash- الوسوم المعطاة عند الإرسال، تُعاد كما هي ولا تُفسَّر أبدًا. دائمًا Hash، فارغ حين لا يُضبط أي وسم ولا يكون nil أبدًا، ويُعاد فقط: فهذه القائمة ترشّح حسب `status` و`from` و`broadcast_id` ونافذة الجدولة، فالوسم شيء تقرؤه من رسالة لا وسيلة للعثور عليها.
broadcastIdString or nil- البث `brd_` الذي تكون هذه الرسالة نسخة منه، أو nil لرسالة أُرسلت وحدها.
sourceString- أي واجهة طلبت الإرسال: `composer` أو `api` أو `mcp` أو `ai` أو `queue`. و`api` هو هذا العميل.
createdAtString- متى كُتب سجل الإرسال، وهو قبل الإرسال الفعلي. وهذا هو الحقل الذي ترتّب عليه القائمة والحقل الذي يقارن عليه المؤشر.
trackingHash- ملخص التفاعل، ولا يظهر إلا على صف رسالته كانت متتبَّعة ويغيب فيما عدا ذلك. فالغياب هو الجواب عن سؤال «هل تُتبّعت هذه الرسالة»، حيث كانت قيمة `openCount` البالغة 0 ستُقرأ على أنها «لم يفتحها أحد».
translationHash- لا يظهر أبدًا في سجل قائمة: فسجل الترجمة يعيش داخل الطلب المخزَّن، وهو ما لا تجلبه القائمة عمدًا. وغيابه هنا لا يقول شيئًا عما إذا كانت الرسالة قد تُرجمت. اسأل `get`.
تتبّع العنصر
opensBoolean- ما إذا كانت هذه الرسالة قد خرجت ببكسل. وهذا ما طُبّق على هذه الرسالة، لا ما يقوله إعداد الحساب الآن.
clicksBoolean- ما إذا كانت روابط هذه الرسالة قد أُعيدت كتابتها. false حين لا يحتوي المتن على روابط لإعادة كتابتها، لأنه لم يتغيّر شيء عندئذ.
openedBoolean- ما إذا كان قد سُجّل أي فتح محسوب، مشتقة من كون `openCount` أكبر من 0.
clickedBoolean- ما إذا كانت قد سُجّلت أي نقرة محسوبة، مشتقة من كون `clickCount` أكبر من 0.
openCountInteger- عمليات الفتح التي يُعتقد أن إنسانًا سبّبها، مجموعة على كل نسخة من الرسالة. وتُسجَّل الماسحات ووسطاء الخصوصية لكنها تُستثنى، والجلبات المتكررة خلال ثلاثين ثانية تُدمج في واحدة.
clickCountInteger- النقرات المحسوبة، مجموعة على النسخ. وتُزال التكرارات لكل رابط لا لكل رسالة، لأن اتّباع رابطين بفارق ثوانٍ فعلان لا تكرار.
firstOpenAtString or nil- أول فتح محسوب عبر النسخ، وnil ما دام لا يوجد أي منها. والزيارات الآلية لا تحرّكه أبدًا.