تخطَّ إلى المستندات
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 تكون 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 يسرد سجلات الإرسال، وهي لا توجد إلا للبريد الذي تولّته هذه الواجهة. أما محرّر الرسائل وأدوات MCP والمساعد فكلها ترسل دون سجل كهذا، فتقرير مبني على emails كان سيكون تقريرًا عن حركة واجهتك لا عن صندوق البريد.

قراءة الأرقام بأمانة

الزوجما الذي يعنيه
opens / clicksما طُبّق: أي ما إذا كانت الرسالة قد خرجت ببكسل أو بروابط مُعاد كتابتها.
opened / clickedما الذي حدث.
openCountالزيارات المحتسَبة. تُستبعَد أدوات الفحص ووكلاء الخصوصية.
openCountRawكل زيارة. الاستشهاد بهذا الرقم كمقياس للتفاعل هو ما يجعل معدل الفتح يتجاوز 100%.
attributableما إذا كان بالإمكان أصلًا نسب عملية قراءة إلى مستلم بعينه.

النسب الواردة من tracking.get_stats محسوبة على الرسائل المتتبَّعة، لا على كل ما أُرسل. ولولا ذلك لبدا صندوق بريد يتتبّع رسالة واحدة من كل عشر وكأنه انهار.

المعاملات: tracking.list

openedbool
تختار القيمة `True` الرسائل التي سُجّلت لها عملية فتح محتسَبة واحدة على الأقل، وتختار `False` الرسائل المتتبَّعة التي لم تُسجَّل لها أي عملية. ولا يُعدّ أيٌّ منهما قيمة افتراضية، كما أن `False` لا تعني قط البريد غير المتتبَّع، فهو لا يظهر في هذه القائمة إطلاقًا.
clickedbool
المرشّح نفسه لكن للنقرات المحتسَبة، ويُطبَّق باستقلال عن `opened`. ويمكن تمرير كليهما معًا، وعندئذٍ يجب أن تستوفي الرسائل الشرطين معًا.
daysint
عدد الأيام التي يُنظر فيها إلى الوراء اعتبارًا من الآن، من 1 إلى 365 وقيمته الافتراضية 30؛ وأي قيمة خارج هذا المدى تُعيد 422. تُقاس النافذة بوقت إنشاء سجل التتبّع، ولا تُدرج إلا السجلات التي خرج إرسالها فعليًا.
limitint
عدد التقارير في الصفحة، من 1 إلى 200 وقيمته الافتراضية 50، من الأحدث إلى الأقدم. أعد `nextCursor` الخاصة بالصفحة بوصفها `cursor`، مع المرشّحات نفسها، للصفحة التالية، أو دع `list_all` و`iterate` يتصفّحان النافذة كلها.

الاستجابة: TrackingResource

objectLiteral['tracking']
تساوي دائمًا `'tracking'` في التقرير الذي يُجلب بذاته، عبر `tracking.get` أو `tracking.list` أو `emails.get_tracking`. أما التقرير نفسه حين يأتي مضمَّنًا باسم `email['tracking']` داخل رسالة مُسترجَعة فيصل دون هذا المفتاح، لأنه هناك جزء من ذلك الكائن لا شيء جرى جلبه.
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
عنوان الإرسال، منسوخًا على السجل بدل ضمّه من عملية الإرسال. فالتقارير تُقرأ بعد وقت طويل، وعنوان صُحّح أو أُزيل منذ ذلك الحين كان سيعيد كتابة التاريخ لولا ذلك.
sourceEmailSource | str
الواجهة التي أرسلتها: `composer` أو `api` أو `mcp` أو `ai` أو `oauth` أو `form`. والنوع مفتوح كي لا تكون واجهة لم يسمّها هذا SDK بعدُ تغييرًا كاسرًا.
sentAtstr | None
وقت ذهاب الرسالة، كلحظة بصيغة ISO-8601. ويكون null في سجل لم تكتمل عملية إرساله. و`tracking.list` يستبعد تلك السجلات، بينما `get` لا يستبعدها.
opensbool
ما إذا كانت بكسل قد طُبِّقت على هذه الرسالة. هذا ما جرى فعلًا، لا ما يقوله إعداد الحساب الآن.
clicksbool
ما إذا كانت روابط هذه الرسالة قد أُعيدت كتابتها. تكون False عندما لا يحمل متن الرسالة أي رابط، إذ لم يُغيَّر حينها شيء، وسجلٌّ يدّعي خلاف ذلك لا يمكن التوفيق بينه وبين البايتات الفعلية.
openedbool
ما إذا كانت قد سُجّلت أي عملية فتح محتسَبة عبر النسخ. اقرأها مقابل `opens`: فغياب البيانات لأنه لم يُجمع منها شيء حقيقةٌ مختلفة عن ألا يكون أحد قد قرأ الرسالة.
clickedbool
ما إذا كانت قد سُجّلت أي نقرة محتسَبة. وهي دليل أقوى من عملية الفتح، لأن حجب الصور أكثر شيوعًا بكثير من ترك الروابط دون اتّباع.
attributablebool
ما إذا كان بالإمكان نسب كل عملية قراءة هنا إلى مستلم بعينه. تصبح False في اللحظة التي تُظهر فيها نسخة غير منسوبة نشاطًا محتسَبًا، وهي حالة تعدّد المستلمين حيث يذهب متن واحد إلى القائمة كلها برمز واحد، فتحقّق منها قبل أن تكتب «لم يفتح Bob هذه الرسالة».
openCountint
عمليات الفتح التي يُرجَّح أن إنسانًا هو من تسبّب بها، مجموعةً عبر النسخ. تُستبعَد زيارات الآلات، وتُدمج التكرارات خلال ثلاثين ثانية في واحدة، ولذلك فهذا هو الرقم الذي يُعرض على القارئ.
clickCountint
النقرات المحتسَبة، مجموعةً عبر النسخ. وتُزال التكرارات لكل رابط لا لكل رسالة، فاتّباع رابطين مختلفين بفارق ثوانٍ يُعدّ نقرتين.
openCountRawint
كل جلب للبكسل، بما في ذلك أدوات الفحص ووكلاء الخصوصية. والفرق `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
كل زيارة لهذا الرابط، بما فيها الزيارات الآلية والتكرارات.

المرجع