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

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

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

یک پیام

tracking.ts
const report = await openemail.emails.getTracking('msg_…') console.log(report.openCount, 'opens from', report.recipients.length, 'recipients')for (const link of report.links) console.log(link.url, link.clickCount)

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

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

tracking-report.ts
await openemail.tracking.list({ opened: false, days: 7, limit: 100 })await openemail.tracking.getStats({ days: 30, offsetMinutes: -new Date().getTimezoneOffset() })await openemail.tracking.get('msg_…')await openemail.tracking.listOpens('msg_…', { includeMachine: true })await openemail.tracking.listClicks('msg_…')

list، listOpens و listClicks به آرایه‌های ساده حل می‌شوند. get، listOpens و listClicks هم شناسهٔ ارسال msg_… را می‌گیرند و هم شناسهٔ خودِ رکورد ردیابی، tmsg_….

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

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

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

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

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

openedboolean
`true` پیام‌هایی را انتخاب می‌کند که دست‌کم یک open شمرده‌شده دارند، `false` پیام‌های ردیابی‌شده‌ای را که هیچ‌کدام را ندارند. هیچ‌کدام پیش‌فرض نیست، و `false` هرگز به معنای نامهٔ ردیابی‌نشده نیست، که اصلاً در این فهرست نمی‌آید.
clickedboolean
همان فیلتر برای کلیک‌های شمرده‌شده، که مستقل از `opened` اعمال می‌شود. هر دو را می‌شود داد، و آنگاه پیام‌ها باید هر دو را برآورده کنند.
daysnumber
چند روز از اکنون به عقب نگاه شود، 1 تا 365 با پیش‌فرض 30؛ بیرون از این بازه یک 422 است. پنجره بر اساس زمان ساخته‌شدن رکورد ردیابی اندازه گرفته می‌شود، و فقط رکوردهایی فهرست می‌شوند که ارسالشان واقعاً انجام شده است.
limitnumber
حداکثر همین تعداد پیام، 1 تا 200 با پیش‌فرض 50، تازه‌ترین اول. هیچ cursor ای وجود ندارد: این گزارشی روی یک پنجره است نه یک فید، پس با `days` و `limit` کران‌دار می‌شود و یکجا خوانده می‌شود.

پاسخ: TrackingResource

object'tracking'
روی گزارشی که به‌خودی‌خود گرفته شود — از راه `tracking.get`، `tracking.list` یا `emails.getTracking` — همیشه `'tracking'`. همان گزارش وقتی به شکل `email.tracking` درون پیامی گرفته‌شده تو در تو بیاید، این کلید را ندارد، چون آنجا بخشی از همان object است نه چیزی که گرفته شده باشد.
idstring
شناسهٔ خودِ رکورد ردیابی، `tmsg_…`. فراخوانی‌های به‌ازای‌هر‌بازدید، یعنی `listOpens` و `listClicks`، بر همین کلید می‌نشینند؛ یک `msg_…` که به آن‌ها داده شود اول به همین حل می‌شود.
sendIdstring | null
ارسال `msg_…` که این رکورد با آن متناظر است، و هر جا رکورد ارسالی نوشته نشده باشد null. کامپوزر، `sendEmail` در MCP و دستیار، همگی بدون آن ارسال می‌کنند. ردیابی کل صندوق پستی را پوشش می‌دهد، نه فقط ترافیک API را.
threadIdstring | null
پس از ارسال پر می‌شود تا یک رابط خواندن بتواند دوباره پیام را پیدا کند، و هر جا درایور چیزی گزارش نکرده باشد null است. باربر نیست: رکوردی که این فیلدش null است هم شمرده می‌شود.
messageIdstring | null
همان Message-ID مطابق RFC 5322، نه شناسهٔ ما. این هم پس از ارسال پر می‌شود، و هر جا لایهٔ انتقال چیزی برای پر کردنش برنگردانده باشد null است.
subjectstring | null
موضوع، همان‌گونه که هنگام ارسال بوده. روی پیامی که بدون موضوع ثبت شده null است.
fromstring
آدرس فرستنده، که روی خودِ رکورد کپی می‌شود نه اینکه از ارسال join شود. گزارش‌ها مدت‌ها بعد خوانده می‌شوند و آدرسی که از آن زمان اصلاح یا حذف شده باشد در غیر این صورت تاریخ را بازنویسی می‌کرد.
sourceEmailSource | (string & {})
کدام سطح آن را فرستاده است: `composer`، `api`، `mcp`، `ai` یا `queue`. تایپش باز است تا سطحی که این SDK هنوز نامش را نمی‌برد تغییر شکنندهٔ نباشد.
sentAtstring | null
زمانی که پیام رفته است، به‌صورت یک لحظهٔ ISO-8601. روی رکوردی که ارسالش هرگز کامل نشده null است. `tracking.list` این‌ها را کنار می‌گذارد، `get` نه.
opensboolean
اینکه آیا روی این پیام پیکسل اعمال شده است یا نه. این همان کاری است که انجام شده، نه آنچه تنظیم حساب اکنون می‌گوید.
clicksboolean
اینکه آیا پیوندهای این پیام بازنویسی شدند یا نه. وقتی بدنه هیچ پیوندی نداشته false است، چون آنگاه چیزی تغییر نکرده و رکوردی که خلافش را ادعا کند با بایت‌ها جور درنمی‌آمد.
openedboolean
اینکه آیا در میان نسخه‌ها هیچ open شمرده‌شده‌ای ثبت شده است یا نه. آن را در کنار `opens` بخوانید: نبودِ داده به‌دلیل جمع‌نشدنش، با نخواندنِ پیام از سوی هیچ‌کس، دو واقعیت متفاوت است.
clickedboolean
اینکه آیا هیچ click شمرده‌شده‌ای ثبت شده است یا نه. شاهدی قوی‌تر از یک open است، چون تصویرها بسیار بیشتر از آنکه پیوندها دنبال‌نشده بمانند مسدود می‌شوند.
attributableboolean
اینکه آیا هر خوانده‌شدنِ اینجا می‌تواند به گیرنده‌ای نام‌برده نسبت داده شود یا نه. همان لحظه که نسخه‌ای نسبت‌داده‌نشده فعالیت شمرده‌شده نشان دهد false می‌شود، که همان حالت چندگیرنده‌ای است که یک بدنه زیر یک توکن به کل فهرست می‌رود؛ پس پیش از نوشتن «باب این را باز نکرده است» آن را بررسی کنید.
openCountnumber
باز شدن‌هایی که گمان می‌رود کار یک آدم بوده‌اند، جمع‌زده روی نسخه‌ها. بازدیدهای ماشینی کنار گذاشته می‌شوند و تکرارها در سی ثانیه در یکی جمع می‌شوند، پس این همان عددی است که باید جلوی چشم خواننده گذاشت.
clickCountnumber
کلیک‌های شمرده‌شده، جمع‌زده روی نسخه‌ها. به ازای هر پیوند یکتاسازی می‌شود نه به ازای هر پیام، پس دو پیوند متفاوت که با چند ثانیه فاصله دنبال شوند دو کلیک‌اند.
openCountRawnumber
هر واکشی pixel، با احتساب اسکنرها و پروکسی‌های حریم خصوصی. `openCountRaw - openCount` نشان می‌دهد دسته‌بند چند تا را کنار گذاشته، و تنها شاهد موجود بر این است که این پالایش اصلاً رخ داده.
clickCountRawnumber
هر بازدید از یک پیوند بازنویسی‌شده، با احتساب بازدیدهای ماشینی و تکرارها.
firstOpenAtstring | null
نخستین باز شدنِ شمرده‌شده در میان نسخه‌ها، و تا وقتی هیچ‌کدام نباشد null است. بازدیدهای ماشینی هرگز آن را جابه‌جا نمی‌کنند.
lastOpenAtstring | null
تازه‌ترین باز شدنِ شمرده‌شده در میان نسخه‌ها، و تا وقتی هیچ‌کدام نباشد null.
firstClickAtstring | null
نخستین کلیکِ شمرده‌شده در میان نسخه‌ها، و تا وقتی هیچ‌کدام نباشد null.
lastClickAtstring | null
تازه‌ترین کلیکِ شمرده‌شده در میان نسخه‌ها، و تا وقتی هیچ‌کدام نباشد null.
recipientsTrackingRecipientResource[]
برای هر نسخهٔ ردیابی‌شده یک ورودی: در جایی که لایهٔ انتقال اجازه می‌دهد بایت‌ها برای هر فرد متفاوت باشد، به ازای هر گیرنده، و جایی که چنین نیست، یک ورودی مشترکِ واحد. ورودی مشترک حذف می‌شود مگر آنکه واقعاً چیزی روی آن ثبت شده باشد، پس یک ردیف دست‌نخوردهٔ «کسی» هرگز کنار نام‌های واقعی نمی‌نشیند.
recipients[].emailstring | null
این نسخه به چه کسی رفته است، با حروف کوچک و همان‌گونه که هنگام ارسال بوده. دقیقاً وقتی null است که `attributed` برابر false باشد.
recipients[].kind'to' | 'cc' | 'bcc' | null
آدرس روی کدام هدر آمده بود، تا گزارش همان‌طور خوانده شود که خودِ پیام خوانده می‌شد. روی نسخهٔ مشترک null است، چون به هیچ آدرسی تعلق ندارد.
recipients[].attributedboolean
اینکه این ردیف فردی را نام می‌برد یا نه. پیش از `email` آن را بخوانید: مقدار false یعنی نسخهٔ مشترک، که به محض ثبت هر بازدیدی روی آن فهرست می‌شود، و نسبت دادن نامی به آن بازدید، حتی در پیامی با یک گیرندهٔ واحد، همان یک واقعیتی را از خود می‌سازد که این سازوکار نمی‌تواند تأمینش کند.
recipients[].openCountnumber
باز شدن‌های شمرده‌شده تنها روی همین نسخه، با همان استثناهای مجموع پیام: بازدیدهای ماشینی کنار گذاشته می‌شوند و تکرارها در فاصلهٔ سی ثانیه در یکی ادغام می‌شوند.
recipients[].clickCountnumber
کلیک‌های شمرده‌شده تنها روی همین نسخه، که به‌جای هر نسخه، به ازای هر پیوند یکتاسازی می‌شود.
recipients[].firstOpenAtstring | null
نخستین باز شدنِ شمرده‌شده روی این نسخه، و تا وقتی هیچ‌کدام نباشد null.
recipients[].lastOpenAtstring | null
تازه‌ترین باز شدنِ شمرده‌شده روی این نسخه، و تا وقتی هیچ‌کدام نباشد null.
recipients[].firstClickAtstring | null
نخستین کلیکِ شمرده‌شده روی این نسخه، و تا وقتی هیچ‌کدام نباشد null.
recipients[].lastClickAtstring | null
تازه‌ترین کلیکِ شمرده‌شده روی این نسخه، و تا وقتی هیچ‌کدام نباشد null.
linksTrackingLinkResource[]
هر پیوندی که در این پیام بازنویسی شده است، به ترتیب جایی که در بدنه نشسته بود. جایی که پیوندی نبوده خالی است: پیامی که با `clicks` خاموش ارسال شده، یا پیامی که بدنه‌اش اصلاً پیوندی نداشته.
links[].idstring
شناسهٔ خودِ پیوند، `lnk_…`. همان مقداری است که `linkId` در یک ردیف کلیک نام می‌برد، پس یک بازدید از `listClicks` را می‌توان به ورودی اینجا بازگرداند.
links[].urlstring
مقصد واقعی پیوند، همان‌گونه که پیش از بازنویسی در پیام بوده است. بازهدایت‌کننده یک شناسه را به همین مقدار بازمی‌گرداند و بازدیدکننده را روانه می‌کند.
links[].labelstring | null
متن لنگر همان‌گونه که در پیام آمده بود، یا هر جا پیوند متنی نداشته null، مثل یک تصویر یا یک URL خام. برای این است که گزارش بتواند بگوید «پیوند صفحهٔ قیمت‌ها» به‌جای نقل یک URL با سه پارامتر ردیابی روی آن، و هرگز جانشین `url` نمی‌شود.
links[].clickCountnumber
بازدیدهای شمرده‌شدهٔ این پیوند، جمع‌بسته روی همهٔ نسخه‌ها. همان پنجرهٔ سی‌ثانیه‌ای به‌ازای هر پیوند که برای `clickCount` روی پیام به کار می‌رود.
links[].clickCountRawnumber
هر بازدید از این پیوند، شامل بازدیدهای ماشینی و تکرارها.