پرش به مستندات
Python

فهرست و دریافت

`emails.list`، `emails.list_all`، `emails.iterate`، `emails.get` و `emails.list_events`.

emails.list

list_emails.py
from openemail import openemail first = openemail.emails.list(status=['queued', 'scheduled'], from_='[email protected]', limit=50) if first['nextCursor']:    second = openemail.emails.list(        status=['queued', 'scheduled'],        from_='[email protected]',        limit=50,        cursor=first['nextCursor'],    )

هر صفحه {'items': [...], 'hasMore': ..., 'nextCursor': ...} است. nextCursor را با همان فیلترها به‌عنوان cursor پس بدهید تا صفحهٔ بعد از آن را بگیرید.

emails.iterate و emails.list_all

iterate_emails.py
import sys from openemail import openemail for email in openemail.emails.iterate(status='failed'):    print(email['id'], email['lastError'], file=sys.stderr) failures = openemail.emails.list_all(status='failed', from_='[email protected]')

هر دو nextCursor را به‌جای شما دنبال می‌کنند. iterate ژنراتوری است که صفحه را فقط وقتی می‌گیرد که حلقه به آن برسد، پس بیرون‌زدن از حلقه درخواست‌ها را متوقف می‌کند، در حالی که list_all پیش از برگرداندن یک فهرست همهٔ صفحه‌ها را می‌پیماید، پس فیلتری به آن بدهید که تمام شود. در هر دو حالت صفحه‌بندی keyset است، پس پیامی که وسط پیمایش برسد نمی‌تواند باعث شود ردیفی از قلم بیفتد، آن‌طور که با offset می‌افتاد.

emails.get و emails.list_events

get_email.py
from openemail import openemail email = openemail.emails.get('msg_…')print(email['status'], email['recipients']) events = openemail.emails.list_all_events('msg_…')for event in events:    print(event['type'], event['createdAt'])

get تنها فراخوانی‌ای است که recipients را برمی‌گرداند، یک ردیف به ازای هر نشانی. فهرستی از پنجاه پیام که هرکدام گیرندگانش را حمل کند، صفحه‌ای از گزارشی است که کسی نخواسته.

پارامترها

statusEmailStatus | Sequence[EmailStatus]
یک وضعیت یا چند وضعیت (`queued`، `scheduled`، `sending`، `sent`، `partial`، `bounced`، `cancelled`، `failed`)، که با هرکدام از آن‌ها که داده شود مطابقت می‌کند. SDK فهرست را به‌صورت یک مقدار واحدِ جداشده با کاما می‌فرستد چون سرور روی کاما می‌شکند؛ مقداری بیرون از آن مجموعه یک 422 است که مقدار ناشناخته را نام می‌برد.
broadcast_idstr
فقط نسخه‌های یک ارسال گروهی، یک شناسهٔ `brd_` از `broadcasts.send`. هر کسی که ارسال گروهی به او برسد پیام خودش را می‌گیرد، پس این فهرست نشان می‌دهد برای چه کسانی رفته و چه بر سر هر نسخه آمده. `broadcasts.list_recipients` همین افراد را همراه با باز کردن‌ها، کلیک‌ها و لغو اشتراک‌هایشان فهرست می‌کند.
from_str
تطبیق دقیق روی نشانی فرستنده، همان‌طور که ثبت شده، یعنی `addr@host` خام و با حروف کوچک. ردیف با حذف هر نام نمایشی نوشته می‌شود، پس angle-addr ای مانند `Acme <[email protected]>` با هیچ‌چیز مطابقت نمی‌کند. مقدار شما پیش از مقایسه به حروف کوچک تبدیل می‌شود، و مقایسه برابری است نه پیشوند یا تطبیق دامنه. زیرخط پایانی از آن روست که `from` یک کلیدواژهٔ Python است.
limitint
ردیف‌های این صفحه، 1 تا 100 با پیش‌فرض 25. مقداری بیرون از این بازه به‌جای محدود شدن، با 422 رد می‌شود.
cursorstr
شناسهٔ یک پیام (`msg_…`) که صفحه‌بندی از آن آغاز شود. keyset است نه offset: ردیف‌ها اکیداً قدیمی‌تر از `createdAt` آن پیام برمی‌گردند، پس ارسال‌هایی که وسط صفحه می‌رسند نمی‌توانند ردیفی را از جلوی شما رد کنند. شناسه‌ای که در این workspace هیچ پیامی را نام نبرد یک 400 است.
scheduled_fromdatetime | str
فقط پیام‌هایی که برای این لحظه یا پس از آن زمان‌بندی شده‌اند: یک `datetime`، یا یک لحظهٔ ISO-8601 همراه با منطقهٔ زمانی. پیامی که `scheduledAt` نداشته باشد کنار گذاشته می‌شود، پس همراه با `scheduled_to` و `status=['queued', 'scheduled']` این فیلتر آنچه را در یک بازهٔ زمانی منتظر رفتن است فهرست می‌کند.
scheduled_todatetime | str
فقط پیام‌هایی که برای این لحظه یا پیش از آن زمان‌بندی شده‌اند. یک `scheduled_from` دیرتر از آن، یک 422 `invalid_parameter` روی `scheduledTo` است.

پاسخ: Page[EmailResource]

itemslist[EmailResource]
یک صفحه از پیام‌ها، تازه‌ترین اول بر اساس `createdAt`، که از پاکت `data` مربوط به API بیرون کشیده شده است. ردیف‌های فهرست هرگز تفکیکِ به‌ازای‌نشانیِ `recipients` را حمل نمی‌کنند. آن روی `get` است.
hasMorebool
اینکه آیا فراتر از این صفحه ردیف‌های دیگری با فیلتر می‌خوانند یا نه. پاسخش با گرفتن یکی بیش از `limit` به دست می‌آید، نه با کوئری شمارش دوم.
nextCursorstr | None
شناسه‌ای که باید به‌عنوان `cursor` پس بدهید، و روی آخرین صفحه null است. `iterate` و `list_all` وقتی این null باشد یا `hasMore` برابر false باشد می‌ایستند، چون صفحه‌ای که ادعای ادامه کند اما هیچ cursor ای را نام نبرد تا ابد حلقه می‌زد.
items[].objectLiteral['email']
روی یک ردیف از این فهرست همیشه `'email'`.
items[].idstr
شناسهٔ خودِ این API، `msg_…`. همان چیزی است که هر endpoint دیگر emails می‌گیرد، و همان چیزی که cursor نام می‌برد.
items[].statusEmailStatus
پیام کجای زندگی‌اش است. `partial` وضعیتی از آنِ خودش است نه گونه‌ای از failed: بعضی گیرندگان آن را دارند و نمی‌شود پس گرفت، پس تلاش دوباره اشتباه است. و `bounced` یعنی پیام پس از رفتن از همه‌ی گیرندگان برگشت خورد، پس دست هیچ‌کس نیست، و هر گیرنده در `get` دلیلش را می‌گوید.
items[].modeApiKeyMode
`live` یا `test`، برگرفته از کلیدی که آن را فرستاده. ارسال در حالت test همین‌جا ثبت می‌شود و هرگز منتقل نمی‌شود.
items[].fromstr
نشانی‌ای که ارسال زیر آن مجاز شمرده شد، که خام و با حروف کوچک ذخیره می‌شود، پس نام نمایشی‌ای که روی `from` داده شده باشد باز هم روی سیم بیرون می‌رود اما اینجا نگه داشته نمی‌شود. یک رشتهٔ ساده است نه یک دیکشنری، چون این همان هویتی است که مجاز شمرده شد: نشانی‌ای بیرون از اسکوپ ارسالِ یک کلید، که نه روی دامنه‌ای است که آن کلید دارد و نه روی آن نام برده شده، با یک 403 رد می‌شود و هرگز بی‌سروصدا با نشانی مجاز عوض نمی‌شود.
items[].subjectstr | None
موضوع همان‌طور که ذخیره شده. روی پیامی که بدون موضوع ثبت شده null است.
items[].messageIdstr | None
همان Message-ID مربوط به RFC 5322، نه شناسهٔ ما. تا وقتی MIME وجود نداشته باشد null است، و سرویس ارسال در مسیر خروج آن را بازنویسی می‌کند، پس bounce یا DSN بعدی شناسهٔ دیگری حمل می‌کند و به‌جای آن روی `items[].id` همبسته می‌شود.
items[].threadIdstr | None
thread ای که این پیام به آن تعلق دارد، در جایی که یکی داده یا تخصیص داده شده باشد. در غیر این صورت null.
items[].transportEmailTransport | str | None
بایت‌ها چگونه رفتند. تا پیش از ارسال null است، و نوعش باز گذاشته شده تا حمل‌ونقلی که این SDK هنوز نامش را نمی‌برد تغییری شکننده نباشد: رکوردهای ذخیره‌شده می‌توانند هنوز حمل‌ونقل‌هایی را نام ببرند که دیگر به کار نمی‌روند.
items[].attemptsint
پیام چند بار تلاش برای ارسال داشته است؛ پیش از نخستین تلاش 0.
items[].lastErrorstr | None
تازه‌ترین خطای ارسال، نوشته‌شده برای آدم. تا وقتی چیزی شکست نخورده null است.
items[].scheduledAtstr | None
زمانی که پیام باید برود، به شکل یک لحظهٔ ISO-8601. فقط روی ارسال فوریِ بدون پنجرهٔ لغو null است: پنجره چیزی جز تأخیری کوتاه نیست، پس `cancellableForSeconds` هم این را پر می‌کند، روی ردیفی که `status` آن `queued` است نه `scheduled`.
items[].cancellableUntilstr | None
لحظه‌ای که پیام باید برود، که روی هر ارسال به‌تعویق‌افتاده همان مقدار `scheduledAt` را حمل می‌کند و روی ارسالی که به تعویق نیفتاده null است. این زمانی است برای نمایش، نه آزمونی که سرور انجام می‌دهد: `cancel` روی `status` شاخه می‌زند و پیام را فقط تا وقتی هنوز `queued` یا `scheduled` است متوقف می‌کند.
items[].sentAtstr | None
زمانی که رفت. تا کامل‌شدن ارسال null است، و به همین دلیل باید روی `status` شاخه بزنید نه روی این.
items[].tagsdict[str, str]
برچسب‌هایی که هنگام ارسال داده شده‌اند، همان‌طور بازگردانده می‌شوند و هرگز تفسیر نمی‌شوند. همیشه یک دیکشنری (`{}` وقتی چیزی تنظیم نشده، هرگز null) و فقط بازگردانده می‌شوند: این فراخوانی بر اساس `status`، `from_`، `broadcast_id`، `scheduled_from` و `scheduled_to` فیلتر می‌کند، پس برچسب چیزی است که از روی پیام خوانده می‌شود، نه راهی برای یافتن آن.
items[].broadcastIdstr | None
ارسال گروهیِ `brd_` که این پیام نسخه‌ای از آن است، یا null برای پیامی که تنها فرستاده شده.
items[].sourceEmailSource | str
کدام سطح درخواست ارسال را داده است: `composer`، `api`، `mcp`، `ai`، `oauth` یا `form`. `api` همین کلاینت با کلید API است، و `oauth` همین کلاینت با توکن دسترسی.
items[].createdAtstr
زمانی که رکورد ارسال نوشته شد، که پیش از ارسال واقعی است. فهرست بر اساس همین فیلد مرتب می‌شود و cursor با همین فیلد مقایسه می‌شود.
items[].trackingNotRequired[EmailTrackingSummary]
خلاصهٔ تعامل، که فقط روی ردیفی حاضر است که پیامش ردیابی شده و در غیر این صورت غایب است. پاسخِ «آیا این ردیابی شد؟» همین غیاب است، جایی که `openCount: 0` به معنای «کسی بازش نکرد» خوانده می‌شد.
items[].tracking.opensbool
اینکه آیا این پیام با یک pixel بیرون رفت یا نه. آنچه بر همین پیام اعمال شد، نه آنچه تنظیم حساب اکنون می‌گوید.
items[].tracking.clicksbool
اینکه آیا پیوندهای این پیام بازنویسی شدند یا نه. وقتی بدنه هیچ پیوندی برای بازنویسی نداشته false است، چون آنگاه چیزی تغییر نکرده.
items[].tracking.openedbool
اینکه آیا هیچ open شمرده‌شده‌ای ثبت شده است یا نه، که از `openCount > 0` مشتق می‌شود.
items[].tracking.clickedbool
اینکه آیا هیچ click شمرده‌شده‌ای ثبت شده است یا نه، که از `clickCount > 0` مشتق می‌شود.
items[].tracking.openCountint
باز شدن‌هایی که گمان می‌رود کار یک آدم بوده‌اند، جمع‌زده روی هر نسخه از پیام. اسکنرها و پروکسی‌های حریم خصوصی ثبت می‌شوند اما کنار گذاشته می‌شوند، و واکشی‌های تکراری در سی ثانیه در یکی جمع می‌شوند.
items[].tracking.clickCountint
کلیک‌های شمرده‌شده، جمع‌زده روی نسخه‌ها. به ازای هر پیوند یکتاسازی می‌شود نه به ازای هر پیام، چون دنبال‌کردن دو پیوند با چند ثانیه فاصله دو کنش است نه یک تکرار.
items[].tracking.firstOpenAtstr | None
نخستین باز شدنِ شمرده‌شده در میان نسخه‌ها، و تا وقتی هیچ‌کدام نباشد null. بازدیدهای ماشینی هرگز آن را جابه‌جا نمی‌کنند.
items[].translationNotRequired[EmailTranslationResource]
هرگز روی یک ردیف فهرست حاضر نیست: رکورد ترجمه در درخواست ذخیره‌شده زندگی می‌کند، که فهرست عمداً آن را نمی‌گیرد. غیابش اینجا هیچ نمی‌گوید که پیام ترجمه شده یا نه. از `get` بپرسید.

مرجع