दस्तावेज़ पर जाएँ
Ruby

Open और click tracking

`emails.get_tracking` और पूरा `tracking` namespace।

एक संदेश

tracking.rb
report = client.emails.get_tracking("msg_3f9a1c07d2b84e6a9c5b1f20") puts "#{report[:openCount]} opens from #{report[:recipients].size} recipients"report[:links].each { |link| puts "#{link[:url]} #{link[:clickCount]}" }

जो संदेश कभी ट्रैक नहीं हुआ वह ख़ाली रिपोर्ट नहीं, बल्कि OpenEmail::NotFoundError raise करता है, जिसका not_found? true होता है। “हमने कुछ दर्ज नहीं किया” और “किसी ने नहीं खोला” अलग जवाब हैं और इन्हें एक ही जवाब नहीं बाँटना चाहिए। test कुंजी से भेजा गया संदेश कभी ट्रैक नहीं होता, इसलिए वह हमेशा यही raise करता है।

पूरे मेलबॉक्स में

tracking_report.rb
client.tracking.list(opened: false, days: 7, limit: 100)client.tracking.get_stats(days: 30, offset_minutes: Time.now.utc_offset / 60)client.tracking.get("msg_3f9a1c07d2b84e6a9c5b1f20")client.tracking.list_opens("msg_3f9a1c07d2b84e6a9c5b1f20", include_machine: true)client.tracking.list_clicks("msg_3f9a1c07d2b84e6a9c5b1f20")

list, list_opens और list_clicks एक OpenEmail::Page लौटाते हैं, और list_all, iterate, list_all_opens, iterate_opens, list_all_clicks और iterate_clicks आपके लिए हर पेज पर चलते हैं। get, list_opens और list_clicks या तो msg_… send id लेते हैं या ट्रैकिंग रिकॉर्ड की अपनी tmsg_…।

emails पर मेथड के बजाय एक अलग namespace, और इसका कारण कवरेज है: emails send रिकॉर्ड सूचीबद्ध करता है, जो सिर्फ़ उसी मेल के लिए होते हैं जिसे इस API ने संभाला। composer, MCP टूल और assistant सभी इसके बिना भेजते हैं, इसलिए emails पर बनी रिपोर्ट मेलबॉक्स के बारे में नहीं, आपके API ट्रैफ़िक के बारे में होती।

आंकड़ों को ईमानदारी से पढ़ना

जोड़ीइसका क्या अर्थ है
opens और clicksजो लागू हुआ: संदेश pixel या दोबारा लिखे गए लिंक के साथ गया या नहीं।
opened और clickedजो हुआ।
openCountगिने गए हिट। स्कैनर और प्राइवेसी प्रॉक्सी शामिल नहीं।
openCountRawहर हिट। इसे एंगेजमेंट के तौर पर पेश करने से ही ओपन रेट 100% से ऊपर चला जाता है।
attributableक्या किसी पढ़े जाने को किसी नामित प्राप्तकर्ता से जोड़ा भी जा सकता है।

tracking.get_stats की दरें “ट्रैक किए गए” संदेशों पर होती हैं, भेजी गई हर चीज़ पर कभी नहीं। वरना जो मेलबॉक्स दस में से एक संदेश ट्रैक करता है वह ऐसा दिखता मानो ढह गया हो। openRate और clickRate एक दशमलव स्थान तक पूर्णांकित प्रतिशत हैं, जैसे 42.5, 0 और 1 के बीच के भिन्न नहीं।

पैरामीटर: tracking.list

openedBoolean
`true` उन संदेशों को चुनता है जिनमें कम से कम एक गिना गया ओपन है, `false` उन ट्रैक किए गए संदेशों को चुनता है जिनमें एक भी नहीं। इनमें से कोई डिफ़ॉल्ट नहीं है, और `false` का मतलब कभी भी बिना ट्रैकिंग वाला मेल नहीं होता, जो इस सूची में आता ही नहीं।
clickedBoolean
गिने गए क्लिक के लिए वही फ़िल्टर, `opened` से स्वतंत्र रूप से लागू। दोनों दिए जा सकते हैं, और संदेशों को दोनों शर्तें पूरी करनी होंगी।
daysInteger
अभी से कितने दिन पीछे देखना है, 1 से 365, डिफ़ॉल्ट 30, और उस सीमा से बाहर 422 है। विंडो ट्रैकिंग रिकॉर्ड बनने के समय से मापी जाती है, और सिर्फ़ वे रिकॉर्ड सूचीबद्ध होते हैं जिनका send सच में बाहर गया।
minutesInteger
इसकी जगह मिनटों में विंडो, 1 से 527040, जो दोनों सेट होने पर `days` पर भारी पड़ती है। एक दिन से छोटी विंडो को बारीक `grain` चाहिए।
grainString
`minute`, `hour` या `day`, डिफ़ॉल्ट `day`। यह सिर्फ़ विंडो की शुरुआत को नीचे की ओर पूर्णांकित करता है, ताकि यह सूची उसी grain पर पढ़े गए `get_stats` से मेल खाए, और जवाब में किसी चीज़ का आकार नहीं बदलता।
limitInteger
हर पेज पर रिपोर्ट, 1 से 200, डिफ़ॉल्ट 50, सबसे नई पहले। अगले पेज के लिए पेज का `next_cursor` उन्हीं फ़िल्टरों के साथ `cursor:` के रूप में वापस भेजें, या `list_all` और `iterate` को पूरी विंडो पर चलने दें।
cursorString
पिछले पेज का `next_cursor`, एक `tmsg_` id।
api_keyString
क्लाइंट की कुंजी के बजाय इस कुंजी से सूची लेता है।

जवाब: ट्रैकिंग रिपोर्ट

emails.get_tracking और tracking.get एक रिपोर्ट Symbol कुंजियों वाले Hash के रूप में लौटाते हैं, और tracking.list उनका एक पेज लौटाता है।

objectString
अपने आप में लाई गई रिपोर्ट पर हमेशा `tracking`, चाहे `tracking.get`, `tracking.list` या `emails.get_tracking` से। वही रिपोर्ट जब `emails.get` से आए संदेश पर `tracking` के रूप में भीतर आती है तो यह कुंजी नहीं होती, क्योंकि वहाँ वह उस संदेश का हिस्सा है, अलग से लाई गई चीज़ नहीं।
idString
ट्रैकिंग रिकॉर्ड की अपनी id, `tmsg_…`। `list_opens` और `list_clicks` इसी पर आधारित हैं, और उन्हें दी गई `msg_…` को पहले इसी के रूप में खोजा जाता है।
sendIdString or nil
वह `msg_…` send जिससे यह जुड़ा है, और जहाँ कोई send रिकॉर्ड नहीं लिखा गया वहाँ nil। composer, MCP का `sendEmail` और assistant सभी इसके बिना भेजते हैं। ट्रैकिंग पूरे मेलबॉक्स को कवर करती है, सिर्फ़ API ट्रैफ़िक को नहीं।
threadIdString or nil
भेजे जाने के बाद भरा जाता है ताकि पढ़ने वाला UI संदेश फिर से ढूँढ सके, और जहाँ driver ने कुछ नहीं बताया वहाँ nil। यह ज़रूरी नहीं है: जिस रिकॉर्ड में यह nil हो वह भी गिना जाता है।
messageIdString or nil
RFC 5322 Message-ID, हमारी id नहीं। यह भी भेजे जाने के बाद भरा जाता है, और जहाँ transport ने भरने को कुछ नहीं लौटाया वहाँ nil।
subjectString or nil
विषय, जैसा भेजते समय था। बिना विषय के दर्ज संदेश पर nil।
fromString
भेजने वाला पता, जो send से जोड़कर लाने के बजाय रिकॉर्ड पर ही कॉपी कर दिया जाता है। रिपोर्टें घटना के बहुत बाद पढ़ी जाती हैं, और तब से सुधारा या हटाया गया कोई पता अन्यथा इतिहास को दोबारा लिख देता।
sourceString
इसे किस सतह ने भेजा: `composer`, `api`, `mcp`, `ai` या `queue`। ऐसी सतह भी दिख सकती है जिसका नाम यह gem अभी नहीं लेता, इसलिए अज्ञात मान को error नहीं, जानकारी मानें।
sentAtString or nil
संदेश कब गया, ISO 8601 क्षण के रूप में। जिस रिकॉर्ड का send कभी पूरा नहीं हुआ उस पर nil। `tracking.list` उन्हें छोड़ देता है, `get` नहीं।
opensBoolean
क्या इस संदेश पर pixel लगाया गया था। यह बताता है कि क्या किया गया, न कि अभी अकाउंट सेटिंग क्या कहती है।
clicksBoolean
क्या इस संदेश के लिंक दोबारा लिखे गए। जब बॉडी में कोई लिंक न हो तो false, क्योंकि तब कुछ बदला ही नहीं और इसके उलट दावा करने वाला रिकॉर्ड बाइट्स से मेल नहीं खा सकता।
openedBoolean
क्या सभी कॉपियों में कहीं भी कोई गिना गया ओपन दर्ज हुआ। इसे `opens` के साथ मिलाकर पढ़ें: डेटा इसलिए न होना कि कुछ इकट्ठा ही नहीं हुआ, इस बात से अलग तथ्य है कि संदेश किसी ने पढ़ा ही नहीं।
clickedBoolean
क्या कोई गिना गया क्लिक दर्ज हुआ। ओपन से ज़्यादा मज़बूत सबूत, क्योंकि लिंक पर न जाने की तुलना में इमेज कहीं ज़्यादा बार ब्लॉक होती हैं।
attributableBoolean
क्या यहाँ का हर पढ़ा जाना किसी नामित प्राप्तकर्ता से जोड़ा जा सकता है। जैसे ही किसी बिना-श्रेय वाली कॉपी पर गिनी गई गतिविधि दिखती है, यह False हो जाता है। यही वह बहु-प्राप्तकर्ता स्थिति है जहाँ एक ही बॉडी एक ही token के तहत पूरी सूची को जाती है, इसलिए "Bob ने इसे नहीं खोला" लिखने से पहले इसे जाँच लें।
openCountInteger
वे ओपन जिन्हें किसी व्यक्ति द्वारा किया गया माना जाता है, सभी कॉपियों को जोड़कर। मशीनी हिट छोड़ दिए जाते हैं और तीस सेकंड के भीतर के दोहराव एक में मिला दिए जाते हैं, इसलिए पाठक के सामने यही आँकड़ा रखना चाहिए।
clickCountInteger
गिने गए क्लिक, सभी कॉपियों को जोड़कर। डुप्लिकेट हटाना प्रति संदेश नहीं बल्कि प्रति लिंक होता है, इसलिए कुछ सेकंड के अंतर पर खोले गए दो अलग लिंक दो क्लिक हैं।
openCountRawInteger
हर pixel fetch, स्कैनर और प्राइवेसी प्रॉक्सी समेत। `openCountRaw` में से `openCount` घटाने पर पता चलता है कि कितने अलग रखे गए, मशीनी fetch और तीस सेकंड के भीतर के दोहराव मिलाकर, और यही इकलौता उपलब्ध सबूत है कि छँटाई हुई भी।
clickCountRawInteger
दोबारा लिखे गए लिंक पर हर विज़िट, मशीनी हिट और दोहराव समेत।
firstOpenAtString or nil
कॉपियों में सबसे पहला गिना गया open, और जब तक कोई न हो तब तक nil। मशीनी hits इसे कभी नहीं खिसकाते।
lastOpenAtString or nil
कॉपियों में सबसे हाल का गिना गया open, जब तक कोई न हो तब तक nil।
firstClickAtString or nil
कॉपियों में सबसे पहला गिना गया click, जब तक कोई न हो तब तक nil।
lastClickAtString or nil
कॉपियों में सबसे हाल का गिना गया click, जब तक कोई न हो तब तक nil।
recipientsArray<Hash>
प्रत्येक ट्रैक की गई प्रति के लिए एक प्रविष्टि: जहाँ ट्रांसपोर्ट बाइट्स को हर व्यक्ति के लिए अलग होने देता है वहाँ प्रति प्राप्तकर्ता एक, और जहाँ नहीं देता वहाँ एक साझा प्रविष्टि। साझा प्रविष्टि तब तक हटा दी जाती है जब तक उस पर वास्तव में कुछ दर्ज न हुआ हो, इसलिए बिना किसी हिट वाली "कोई" पंक्ति असली नामों के बगल में कभी नहीं बैठती।
linksArray<Hash>
इस संदेश में फिर से लिखा गया हर लिंक, उसी क्रम में जिसमें वह body में बैठा था। जहाँ कोई नहीं था वहाँ खाली: `clicks` बंद रखकर भेजा गया संदेश, या वह जिसकी body में कोई लिंक था ही नहीं।

recipients में हर प्रविष्टि

emailString or nil
यह कॉपी किसे गई, छोटे अक्षरों में और भेजते समय जैसा था। ठीक तब nil जब `attributed` false हो।
kindString or nil
`to`, `cc` या `bcc`: पता किस हेडर पर था, ताकि रिपोर्ट वैसे ही पढ़ी जाए जैसे संदेश पढ़ा गया। साझा कॉपी पर nil, जो किसी एक पते की नहीं है।
attributedBoolean
क्या यह पंक्ति किसी व्यक्ति का नाम बताती है। इसे `email` से पहले पढ़ें: false का अर्थ है साझा प्रति, जो किसी भी हिट के उस पर आते ही सूचीबद्ध हो जाती है, और उस हिट पर नाम चिपकाना, एकमात्र प्राप्तकर्ता वाले संदेश पर भी, ठीक वही तथ्य गढ़ना होगा जो यह तंत्र दे ही नहीं सकता।
openCountInteger
केवल इसी प्रति पर गिने गए ओपन, संदेश के कुल योग जैसी ही छूटों के साथ: मशीन हिट हटा दी जाती हैं, और तीस सेकंड के भीतर की पुनरावृत्तियाँ एक में समेट दी जाती हैं।
clickCountInteger
केवल इसी प्रति पर गिने गए क्लिक, जिनका दोहराव प्रति प्रति नहीं बल्कि प्रति लिंक हटाया जाता है।
firstOpenAtString or nil
इस कॉपी पर सबसे पहला गिना गया open, जब तक कोई न हो तब तक nil।
lastOpenAtString or nil
इस कॉपी पर सबसे हाल का गिना गया open, जब तक कोई न हो तब तक nil।
firstClickAtString or nil
इस कॉपी पर सबसे पहला गिना गया click, जब तक कोई न हो तब तक nil।
lastClickAtString or nil
इस कॉपी पर सबसे हाल का गिना गया click, जब तक कोई न हो तब तक nil।

links में हर प्रविष्टि

idString
लिंक की अपनी id, `lnk_…`। यही वह मान है जिसका नाम click पंक्ति का `linkId` लेता है, ताकि `list_clicks` से आए hit को यहाँ की प्रविष्टि से मिलाया जा सके।
urlString
लिंक असल में कहाँ जाता है, जैसा दोबारा लिखे जाने से पहले संदेश में था। redirector id से इसे खोजता है और विज़िटर को आगे भेज देता है।
labelString or nil
anchor टेक्स्ट जैसा संदेश में दिखा, या nil जहाँ लिंक में कोई टेक्स्ट न था, जैसे कोई चित्र या सादा URL। यह इसलिए है ताकि रिपोर्ट तीन ट्रैकिंग पैरामीटर वाला URL उद्धृत करने के बजाय “कीमतों वाला लिंक” कह सके, और यह कभी `url` की जगह नहीं लेता।
clickCountInteger
इस लिंक पर गिनी गई विज़िट, सभी प्रतियों पर जोड़कर। संदेश के `clickCount` जैसी ही प्रति-लिंक तीस-सेकंड की विंडो।
clickCountRawInteger
इस लिंक पर हर विज़िट, मशीन हिट और पुनरावृत्तियाँ सहित।