السرد والجلب
`emails->list` و`emails->listAll` و`emails->iterate` و`emails->get` و`emails->listEvents`.
emails->list
$filters = ['status' => ['queued', 'scheduled'], 'from' => '[email protected]']; $first = $client->emails->list(...$filters, limit: 50);$second = $first->hasMore ? $client->emails->list(...$filters, limit: 50, cursor: $first->nextCursor) : null; echo count($first), ' ', $second === null ? 0 : count($second), PHP_EOL;الصفحة هي OpenEmail\Result\Page فيها items وhasMore وnextCursor. مرّر nextCursor مرة أخرى كـ cursor:، مع المرشِّحات نفسها، للحصول على الصفحة التالية. ونشر مصفوفة واحدة من المرشِّحات في كل استدعاء، كما يفعل ...$filters، يبقيها هي نفسها.
emails->iterate وemails->listAll
foreach ($client->emails->iterate(status: 'failed') as $email) { error_log($email['id'] . ' ' . ($email['lastError'] ?? ''));} $failures = $client->emails->listAll(status: 'failed', from: '[email protected]');echo count($failures), PHP_EOL;كلاهما يتبع nextCursor نيابةً عنك. ويعيد iterate كائن Generator لا يجلب صفحة إلا عندما يصل المرور إليها، فإن الخروج بـ break من foreach يوقف الطلبات، بينما يمر listAll على كل الصفحات قبل أن يعيد مصفوفة واحدة، لذا أعطه مرشِّحًا ينتهي. والترقيم قائم على المفاتيح في الحالتين، فرسالة تصل في أثناء المرور لا يمكنها أن تجعله يتخطى سجلًا كما قد تفعل الإزاحة.
emails->get وemails->listEvents
$email = $client->emails->get('msg_3f9a1c07d2b84e6a9c5b1f20');echo $email['status'], PHP_EOL;print_r($email['recipients']); $events = $client->emails->listAllEvents('msg_3f9a1c07d2b84e6a9c5b1f20'); foreach ($events as $event) { echo $event['type'], ' ', $event['createdAt'], PHP_EOL;}get هو الاستدعاء الوحيد الذي يعيد recipients، بمصفوفة لكل عنوان فيها status وerror وdeliveredAt الخاصة به. فقائمة من خمسين رسالة يحمل كل منها مستلميه صفحة تقرير لم يطلبها أحد.
يقرأ listEvents سجل أحداث إرسال واحد، من الأقدم: email.accepted وemail.queued وemail.sent وemail.delivered وemail.bounced وemail.opened وغيرها، لكل منها مصفوفة باسم data يعتمد شكله على type الخاص به. ويمر listAllEvents وiterateEvents على السجل كله نيابةً عنك. وتسلّم webhooks مجموعة فرعية من الأحداث نفسها لحظة وقوعها، فهذا هو المكان الذي تبحث فيه حين يفوتك webhook.
المعاملات
statusstring or array- حالة واحدة أو عدة حالات (`queued` أو `scheduled` أو `sending` أو `sent` أو `partial` أو `bounced` أو `cancelled` أو `failed`)، وتطابق أيًّا منها. وتعني `bounced` أن كل مستلم ذهبت إليه الرسالة قد ارتدت عنه، بينما الرسالة التي ارتدت عن بعضهم ووصلت إلى الباقين تظهر `partial`. ويرسل العميل المصفوفة كقيمة واحدة مفصولة بفواصل لأن الخادم يقسّم على الفواصل، وأي قيمة خارج المجموعة تعطي 422 تسمّي القيمة المجهولة.
broadcastIdstring- نسخ بث واحد فقط، بمعرّف `brd_` من `broadcasts->send`. فكل شخص يصل إليه البث يتلقى رسالة خاصة به، فهذا يسرد من ذهب إليهم وما حدث لكل نسخة. ويسرد `broadcasts->listRecipients` الأشخاص أنفسهم مع مرات الفتح والنقرات وإلغاءات الاشتراك.
fromstring- مطابقة تامة لعنوان الإرسال كما سُجّل، وهو `addr@host` المجرد بأحرف صغيرة. ويُكتب السجل بعد تجريد أي اسم معروض، فعنوان بصيغة الأقواس الزاوية مثل `Acme <[email protected]>` لا يطابق شيئًا. وتُحوَّل قيمتك إلى أحرف صغيرة قبل المقارنة، والمقارنة مساواة لا مطابقة بادئة أو نطاق.
scheduledFromDateTimeInterface or string- الرسائل المجدولة لهذه اللحظة أو بعدها فقط. ومع `scheduledTo:` و`status: ['scheduled', 'queued']` يسرد ما ينتظر الانطلاق في نافذة زمنية، كما يفعل تقويم التطبيق. وتُستبعد الرسالة التي ليس لها `scheduledAt`. مرّر `DateTimeInterface`، يُرسَل كلحظة بتوقيت UTC، أو لحظة ISO 8601 مع إزاحتها الزمنية: فسلسلة التاريخ التي لا وقت فيها يرفضها هذان المرشِّحان.
scheduledToDateTimeInterface or string- الرسائل المجدولة لهذه اللحظة أو قبلها فقط. ووقوع `scheduledFrom:` بعد `scheduledTo:` يعطي 422 `invalid_parameter`.
limitint- الصفوف في هذه الصفحة، من 1 إلى 100، والافتراضي 25. والقيمة خارج هذا المدى تُرفض بـ 422 بدل أن تُقصّ. وفي `listAll` و`iterate` هي حجم كل صفحة يجلبانها.
cursorstring- معرّف رسالة (`msg_…`) يبدأ منه الترقيم. قائم على المفاتيح لا على الإزاحة: تعود الصفوف الأقدم تمامًا من `createdAt` الخاص بتلك الرسالة، فالإرسالات التي تصل في منتصف الصفحة لا يمكنها دفع سجل بعيدًا عنك. والمعرّف الذي لا يسمّي أي رسالة في مساحة العمل هذه يعطي 400 `invalid_cursor`.
apiKeystring- يسرد بهذا المفتاح بدل مفتاح العميل.
المفتاح المقصور على بعض العناوين لا يقرأ إلا الرسائل المرسلة من العناوين التي يغطيها، وتُقطع الصفحة بعد ذلك الترشيح، فكل صفحة عدا الأخيرة تحمل مع ذلك limit صفًا. وfrom: الذي لا يغطيه المفتاح يعيد صفحة أخيرة فارغة بدل 403.
الاستجابة: OpenEmail\Result\Page
itemsarray- صفحة واحدة من الرسائل، الأحدث أولًا حسب `createdAt`، مستخرجة من مُغلَّف `data` الخاص بواجهة API. ولا تحمل سجلات القائمة أبدًا تفصيل `recipients` لكل عنوان. فذلك في `get`.
hasMorebool- ما إذا كانت هناك سجلات أخرى تطابق المرشِّح بعد هذه الصفحة. ويُجاب عن ذلك بجلب سجل واحد زيادة على `limit` بدل استعلام عدّ ثانٍ.
nextCursorstring or null- المعرّف الذي تمرّره مرة أخرى كـ `cursor:`، وnull في الصفحة الأخيرة. ويتوقف `iterate` و`listAll` عندما يكون هذا null أو تكون قيمة `hasMore` هي false، لأن صفحة تدّعي وجود المزيد دون أن تسمي مؤشرًا كانت ستدور إلى ما لا نهاية.
كل عنصر
objectstring- دائمًا `email` في صف من هذه القائمة.
idstring- المعرّف الخاص بهذه الواجهة، `msg_…`. وهو ما يأخذه كل استدعاء آخر من emails، وما يسمّيه المؤشر.
statusstring- أين الرسالة في دورة حياتها. و`partial` حالة قائمة بذاتها لا نكهة من نكهات الفشل: فبعض المستلمين لديهم الرسالة ولا يمكن سحبها منهم، ومن ثَم فإعادة المحاولة خطأ. و`bounced` تعني أن الرسالة ارتدّت عن كل مستلميها بعد خروجها، فلم تصل إلى أحد، وكل مستلم في `get` يذكر السبب.
modestring- `live` أو `test`، مأخوذة من المفتاح الذي أرسل. والإرسال في وضع الاختبار يُسجَّل هنا ولا يُبثّ أبدًا.
fromstring- العنوان الذي أُذن بالإرسال تحته، مخزَّنًا مجردًا وبأحرف صغيرة، فالاسم المعروض المعطى في `from` يخرج على الشبكة لكنه لا يُحفظ هنا. وهو سلسلة نصية عادية لا مصفوفة لأن هذه هي الهوية التي أُذن بها: فعنوان خارج نطاق إرسال المفتاح، ليس على نطاق يملكه ولا مسمّى عليه، يُرفض بـ 403، ولا يُستبدل بصمت بعنوان مسموح له.
subjectstring or null- الموضوع كما خُزّن. null على رسالة سُجّلت دون موضوع.
messageIdstring or null- ترويسة Message-ID بحسب RFC 5322، لا معرّفنا. تكون null إلى أن توجد رسالة MIME، وتعيد خدمة الإرسال كتابتها عند الخروج، فيحمل أي ارتداد أو DSN لاحق معرّفًا مختلفًا ويُربط عبر `id` بدلًا منها.
threadIdstring or null- المحادثة التي تنتمي إليها هذه الرسالة، حين تُعطى أو تُعيَّن. وnull فيما عدا ذلك.
transportstring or null- كيف غادرت البايتات. null حتى الإرسال الفعلي. وقد تسمّي السجلات المخزَّنة وسائل نقل لم تعد مستخدمة، فعامل القيمة التي لا تعرفها كمعلومة لا كخطأ.
attemptsint- كم محاولة إرسال جرت على الرسالة، و0 قبل الأولى.
lastErrorstring or null- أحدث خطأ في الإرسال، مكتوبًا لشخص. null ما دام لم يفشل شيء.
scheduledAtstring or null- متى يُتوقع أن تنطلق الرسالة، كلحظة ISO 8601. لا تكون null إلا في إرسال فوري بلا نافذة إلغاء: فالنافذة مجرد تأخير قصير لا أكثر، ولهذا يملأ `cancellableForSeconds` هذا الحقل أيضًا، على صف تكون قيمة `status` فيه `queued` لا `scheduled`.
cancellableUntilstring or null- اللحظة التي يُتوقع أن تنطلق فيها الرسالة، وتحمل القيمة نفسها التي يحملها `scheduledAt` في أي إرسال مؤجَّل وnull في غير المؤجَّل. وهي طابع زمني للعرض لا الاختبار الذي يجريه الخادم: فـ `cancel` يفرّع على `status`، ولا يوقف رسالة إلا ما دامت `queued` أو `scheduled`.
sentAtstring or null- متى انطلقت. null حتى يكتمل الإرسال الفعلي، ولهذا فالحقل الذي يُتفرّع عليه هو `status` لا هذا.
tagsarray- الوسوم المعطاة عند الإرسال، تُعاد كما هي ولا تُفسَّر أبدًا. دائمًا مصفوفة، فارغة حين لا يُضبط أي وسم ولا تكون null أبدًا، ويُعاد فقط: فهذه القائمة ترشّح حسب `status` و`from` و`broadcastId` ونافذة الجدولة، فالوسم شيء تقرؤه من رسالة لا وسيلة للعثور عليها.
broadcastIdstring or null- البث `brd_` الذي هذه الرسالة نسخة منه، أو null لرسالة أُرسلت وحدها.
sourcestring- أي واجهة طلبت الإرسال: `composer` أو `api` أو `mcp` أو `ai` أو `queue`. و`api` هو هذا العميل.
createdAtstring- متى كُتب سجل الإرسال، وهو قبل الإرسال الفعلي. وهذا هو الحقل الذي ترتّب عليه القائمة والحقل الذي يقارن عليه المؤشر.
trackingarray- ملخص التفاعل، ولا يظهر إلا على صف رسالته كانت متتبَّعة ويغيب فيما عدا ذلك. فالغياب هو الجواب عن سؤال «هل تُتبّعت هذه الرسالة»، حيث كانت قيمة `openCount` البالغة 0 ستُقرأ على أنها «لم يفتحها أحد»، فاقرأه بـ `?? null` بدل افتراض وجود المفتاح.
translationarray- لا يظهر أبدًا في سجل قائمة: فسجل الترجمة يعيش داخل الطلب المخزَّن، وهو ما لا تجلبه القائمة عمدًا. وغيابه هنا لا يقول شيئًا عما إذا كانت الرسالة قد تُرجمت. اسأل `get`.
تتبّع العنصر
opensbool- ما إذا كانت هذه الرسالة قد خرجت ببكسل. وهذا ما طُبّق على هذه الرسالة، لا ما يقوله إعداد الحساب الآن.
clicksbool- ما إذا كانت روابط هذه الرسالة قد أُعيدت كتابتها. false حين لا يحتوي المتن على روابط لإعادة كتابتها، لأنه لم يتغيّر شيء عندئذ.
openedbool- ما إذا كان قد سُجّل أي فتح محسوب، مشتقة من كون `openCount` أكبر من 0.
clickedbool- ما إذا كانت قد سُجّلت أي نقرة محسوبة، مشتقة من كون `clickCount` أكبر من 0.
openCountint- عمليات الفتح التي يُعتقد أن إنسانًا سبّبها، مجموعة على كل نسخة من الرسالة. وتُسجَّل الماسحات ووسطاء الخصوصية لكنها تُستثنى، والجلبات المتكررة خلال ثلاثين ثانية تُدمج في واحدة.
clickCountint- النقرات المحسوبة، مجموعة على النسخ. وتُزال التكرارات لكل رابط لا لكل رسالة، لأن اتّباع رابطين بفارق ثوانٍ فعلان لا تكرار.
firstOpenAtstring or null- أول فتح محسوب عبر النسخ، وnull ما دام لا يوجد أي منها. والزيارات الآلية لا تحرّكه أبدًا.