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

ردیابی بازشدن و کلیک

`emails.get_tracking` و کل منبع `tracking`.

یک پیام

tracking.py
from openemail import openemail report = openemail.emails.get_tracking('msg_…') print(report['openCount'], 'opens from', len(report['recipients']), 'recipients')for link in report['links']:    print(link['url'], link['clickCount'])

پیامی که هرگز ردیابی نشده، به‌جای گزارشی خالی، یک OpenEmailApiError را raise می‌کند که is_not_found آن true است. «چیزی ثبت نکردیم» و «کسی بازش نکرد» دو پاسخ متفاوت‌اند و نباید یک پاسخ مشترک داشته باشند.

در سراسر صندوق

tracking_report.py
import time from openemail import openemail openemail.tracking.list(opened=False, days=7, limit=100)openemail.tracking.get_stats(days=30, offset_minutes=time.localtime().tm_gmtoff // 60)openemail.tracking.get('msg_…')openemail.tracking.list_opens('msg_…', include_machine=True)openemail.tracking.list_clicks('msg_…')

list، list_opens و list_clicks یک صفحه برمی‌گردانند، {'items': [...], 'hasMore': ..., 'nextCursor': ...}، و list_all، iterate، list_all_opens، iterate_opens، list_all_clicks و iterate_clicks همهٔ صفحه‌ها را برایتان می‌پیمایند. get، list_opens و list_clicks هم شناسهٔ ارسال msg_… را می‌گیرند و هم شناسهٔ خودِ رکورد ردیابی، tmsg_….

منبعی از آنِ خودش است نه چند فیلد روی emails، و دلیلش پوشش است: emails رکوردهای ارسال را فهرست می‌کند، که فقط برای نامه‌ای وجود دارند که همین API فرستاده باشد. composer، ابزارهای MCP و دستیار همه بدون آن می‌فرستند، پس گزارشی که روی emails ساخته شود گزارشی دربارهٔ ترافیک API شما می‌شد، نه دربارهٔ صندوق.

خواندن صادقانهٔ اعداد

جفتمعنایش چیست
opens / clicksآنچه اعمال شد: اینکه پیام با pixel یا با پیوندهای بازنویسی‌شده بیرون رفت یا نه.
opened / clickedآنچه رخ داد.
openCountبازدیدهای شمرده‌شده. اسکنرها و پروکسی‌های حریم خصوصی کنار گذاشته شده‌اند.
openCountRawهمهٔ بازدیدها. نقل‌کردن این عدد به‌عنوان تعامل، همان راهی است که نرخ باز شدن از 100% بالاتر می‌رود.
attributableاینکه آیا یک خوانده‌شدن اصلاً می‌تواند به گیرنده‌ای نام‌برده نسبت داده شود یا نه.

نرخ‌های tracking.get_stats روی پیام‌های TRACKED محاسبه می‌شوند، هرگز روی همهٔ آنچه فرستاده شده. وگرنه صندوقی که از هر ده پیام یکی را ردیابی می‌کند چنان به نظر می‌رسید که انگار فروپاشیده است.

پارامترها: tracking.list

openedbool
`True` پیام‌هایی را انتخاب می‌کند که دست‌کم یک open شمرده‌شده دارند، `False` پیام‌های ردیابی‌شده‌ای را که هیچ‌کدام را ندارند. هیچ‌کدام پیش‌فرض نیست، و `False` هرگز به معنای نامهٔ ردیابی‌نشده نیست، که اصلاً در این فهرست نمی‌آید.
clickedbool
همان فیلتر برای کلیک‌های شمرده‌شده، که مستقل از `opened` اعمال می‌شود. هر دو را می‌شود داد، و آنگاه پیام‌ها باید هر دو را برآورده کنند.
daysint
چند روز از اکنون به عقب نگاه شود، 1 تا 365 با پیش‌فرض 30؛ بیرون از این بازه یک 422 است. پنجره بر اساس زمان ساخته‌شدن رکورد ردیابی اندازه گرفته می‌شود، و فقط رکوردهایی فهرست می‌شوند که ارسالشان واقعاً انجام شده است.
limitint
تعداد گزارش در هر صفحه، 1 تا 200 با پیش‌فرض 50، تازه‌ترین اول. `nextCursor` صفحه را با همان فیلترها به‌عنوان `cursor` برگردانید تا صفحهٔ بعد بیاید، یا بگذارید `list_all` و `iterate` کل پنجره را بپیمایند.

پاسخ: TrackingResource

objectLiteral['tracking']
روی گزارشی که به‌خودی‌خود گرفته شود (از راه `tracking.get`، `tracking.list` یا `emails.get_tracking`) همیشه `'tracking'`. همان گزارش وقتی به شکل `email['tracking']` درون پیامی گرفته‌شده تو در تو بیاید، این کلید را ندارد، چون آنجا بخشی از همان object است نه چیزی که گرفته شده باشد.
idstr
شناسهٔ خودِ رکورد ردیابی، `tmsg_…`. فراخوانی‌های به‌ازای‌هر‌بازدید، یعنی `list_opens` و `list_clicks`، بر همین کلید می‌نشینند؛ یک `msg_…` که به آن‌ها داده شود اول به همین حل می‌شود.
sendIdstr | None
ارسال `msg_…` که این رکورد با آن متناظر است، و هر جا رکورد ارسالی نوشته نشده باشد null. کامپوزر، `sendEmail` در MCP و دستیار، همگی بدون آن ارسال می‌کنند. ردیابی کل صندوق پستی را پوشش می‌دهد، نه فقط ترافیک API را.
threadIdstr | None
پس از ارسال پر می‌شود تا یک رابط خواندن بتواند دوباره پیام را پیدا کند، و هر جا درایور چیزی گزارش نکرده باشد null است. باربر نیست: رکوردی که این فیلدش null است هم شمرده می‌شود.
messageIdstr | None
همان Message-ID مطابق RFC 5322، نه شناسهٔ ما. این هم پس از ارسال پر می‌شود، و هر جا لایهٔ انتقال چیزی برای پر کردنش برنگردانده باشد null است.
subjectstr | None
موضوع، همان‌گونه که هنگام ارسال بوده. روی پیامی که بدون موضوع ثبت شده null است.
fromstr
آدرس فرستنده، که روی خودِ رکورد کپی می‌شود نه اینکه از ارسال join شود. گزارش‌ها مدت‌ها بعد خوانده می‌شوند و آدرسی که از آن زمان اصلاح یا حذف شده باشد در غیر این صورت تاریخ را بازنویسی می‌کرد.
sourceEmailSource | str
کدام سطح آن را فرستاده است: `composer`، `api`، `mcp`، `ai`، `oauth` یا `form`. تایپش باز است تا سطحی که این SDK هنوز نامش را نمی‌برد تغییری شکننده نباشد.
sentAtstr | None
زمانی که پیام رفته است، به‌صورت یک لحظهٔ ISO-8601. روی رکوردی که ارسالش هرگز کامل نشده null است. `tracking.list` این‌ها را کنار می‌گذارد، `get` نه.
opensbool
اینکه آیا روی این پیام پیکسل اعمال شده است یا نه. این همان کاری است که انجام شده، نه آنچه تنظیم حساب اکنون می‌گوید.
clicksbool
اینکه آیا پیوندهای این پیام بازنویسی شدند یا نه. وقتی بدنه هیچ پیوندی نداشته False است، چون آنگاه چیزی تغییر نکرده و رکوردی که خلافش را ادعا کند با بایت‌ها جور درنمی‌آمد.
openedbool
اینکه آیا در میان نسخه‌ها هیچ open شمرده‌شده‌ای ثبت شده است یا نه. آن را در کنار `opens` بخوانید: نبودِ داده به‌دلیل جمع‌نشدنش، با نخواندنِ پیام از سوی هیچ‌کس، دو واقعیت متفاوت است.
clickedbool
اینکه آیا هیچ click شمرده‌شده‌ای ثبت شده است یا نه. شاهدی قوی‌تر از یک open است، چون تصویرها بسیار بیشتر از آنکه پیوندها دنبال‌نشده بمانند مسدود می‌شوند.
attributablebool
اینکه آیا هر خوانده‌شدنِ اینجا می‌تواند به گیرنده‌ای نام‌برده نسبت داده شود یا نه. همان لحظه که نسخه‌ای نسبت‌داده‌نشده فعالیت شمرده‌شده نشان دهد False می‌شود، که همان حالت چندگیرنده‌ای است که یک بدنه زیر یک توکن به کل فهرست می‌رود؛ پس پیش از نوشتن «Bob این را باز نکرده است» آن را بررسی کنید.
openCountint
باز شدن‌هایی که گمان می‌رود کار یک آدم بوده‌اند، جمع‌زده روی نسخه‌ها. بازدیدهای ماشینی کنار گذاشته می‌شوند و تکرارها در سی ثانیه در یکی جمع می‌شوند، پس این همان عددی است که باید جلوی چشم خواننده گذاشت.
clickCountint
کلیک‌های شمرده‌شده، جمع‌زده روی نسخه‌ها. به ازای هر پیوند یکتاسازی می‌شود نه به ازای هر پیام، پس دو پیوند متفاوت که با چند ثانیه فاصله دنبال شوند دو کلیک‌اند.
openCountRawint
هر واکشی pixel، با احتساب اسکنرها و پروکسی‌های حریم خصوصی. `openCountRaw - openCount` نشان می‌دهد دسته‌بند چند تا را کنار گذاشته، و تنها شاهد موجود بر این است که این پالایش اصلاً رخ داده.
clickCountRawint
هر بازدید از یک پیوند بازنویسی‌شده، با احتساب بازدیدهای ماشینی و تکرارها.
firstOpenAtstr | None
نخستین باز شدنِ شمرده‌شده در میان نسخه‌ها، و تا وقتی هیچ‌کدام نباشد null. بازدیدهای ماشینی هرگز آن را جابه‌جا نمی‌کنند.
lastOpenAtstr | None
تازه‌ترین باز شدنِ شمرده‌شده در میان نسخه‌ها، و تا وقتی هیچ‌کدام نباشد null.
firstClickAtstr | None
نخستین کلیکِ شمرده‌شده در میان نسخه‌ها، و تا وقتی هیچ‌کدام نباشد null.
lastClickAtstr | None
تازه‌ترین کلیکِ شمرده‌شده در میان نسخه‌ها، و تا وقتی هیچ‌کدام نباشد null.
recipientslist[TrackingRecipientResource]
برای هر نسخهٔ ردیابی‌شده یک ورودی: در جایی که لایهٔ انتقال اجازه می‌دهد بایت‌ها برای هر فرد متفاوت باشد، به ازای هر گیرنده، و جایی که چنین نیست، یک ورودی مشترکِ واحد. ورودی مشترک حذف می‌شود مگر آنکه واقعاً چیزی روی آن ثبت شده باشد، پس یک ردیف دست‌نخوردهٔ «کسی» هرگز کنار نام‌های واقعی نمی‌نشیند.
recipients[].emailstr | None
این نسخه به چه کسی رفته است، با حروف کوچک و همان‌گونه که هنگام ارسال بوده. دقیقاً وقتی null است که `attributed` برابر false باشد.
recipients[].kindRecipientKind | None
آدرس روی کدام هدر آمده بود، تا گزارش همان‌طور خوانده شود که خودِ پیام خوانده می‌شد. روی نسخهٔ مشترک null است، چون به هیچ آدرسی تعلق ندارد.
recipients[].attributedbool
اینکه این ردیف فردی را نام می‌برد یا نه. پیش از `email` آن را بخوانید: مقدار false یعنی نسخهٔ مشترک، که به محض ثبت هر بازدیدی روی آن فهرست می‌شود، و نسبت دادن نامی به آن بازدید، حتی در پیامی با یک گیرندهٔ واحد، همان یک واقعیتی را از خود می‌سازد که این سازوکار نمی‌تواند تأمینش کند.
recipients[].openCountint
باز شدن‌های شمرده‌شده تنها روی همین نسخه، با همان استثناهای مجموع پیام: بازدیدهای ماشینی کنار گذاشته می‌شوند و تکرارها در فاصلهٔ سی ثانیه در یکی ادغام می‌شوند.
recipients[].clickCountint
کلیک‌های شمرده‌شده تنها روی همین نسخه، که به‌جای هر نسخه، به ازای هر پیوند یکتاسازی می‌شود.
recipients[].firstOpenAtstr | None
نخستین باز شدنِ شمرده‌شده روی این نسخه، و تا وقتی هیچ‌کدام نباشد null.
recipients[].lastOpenAtstr | None
تازه‌ترین باز شدنِ شمرده‌شده روی این نسخه، و تا وقتی هیچ‌کدام نباشد null.
recipients[].firstClickAtstr | None
نخستین کلیکِ شمرده‌شده روی این نسخه، و تا وقتی هیچ‌کدام نباشد null.
recipients[].lastClickAtstr | None
تازه‌ترین کلیکِ شمرده‌شده روی این نسخه، و تا وقتی هیچ‌کدام نباشد null.
linkslist[TrackingLinkResource]
هر پیوندی که در این پیام بازنویسی شده است، به ترتیب جایی که در بدنه نشسته بود. جایی که پیوندی نبوده خالی است: پیامی که با `clicks` خاموش ارسال شده، یا پیامی که بدنه‌اش اصلاً پیوندی نداشته.
links[].idstr
شناسهٔ خودِ پیوند، `lnk_…`. همان مقداری است که `linkId` در یک ردیف کلیک نام می‌برد، پس یک بازدید از `list_clicks` را می‌توان به ورودی اینجا بازگرداند.
links[].urlstr
مقصد واقعی پیوند، همان‌گونه که پیش از بازنویسی در پیام بوده است. بازهدایت‌کننده یک شناسه را به همین مقدار بازمی‌گرداند و بازدیدکننده را روانه می‌کند.
links[].labelstr | None
متن لنگر همان‌گونه که در پیام آمده بود، یا هر جا پیوند متنی نداشته null، مثل یک تصویر یا یک URL خام. برای این است که گزارش بتواند بگوید «پیوند صفحهٔ قیمت‌ها» به‌جای نقل یک URL با سه پارامتر ردیابی روی آن، و هرگز جانشین `url` نمی‌شود.
links[].clickCountint
بازدیدهای شمرده‌شدهٔ این پیوند، جمع‌بسته روی همهٔ نسخه‌ها. همان پنجرهٔ سی‌ثانیه‌ای به‌ازای هر پیوند که برای `clickCount` روی پیام به کار می‌رود.
links[].clickCountRawint
هر بازدید از این پیوند، شامل بازدیدهای ماشینی و تکرارها.

مرجع