CI कोड चलाने में बहुत अच्छा है, लेकिन एक चीज़ में यह बुरी तरह असफल है जिस पर आपका product शायद निर्भर करता है: email। यदि आपके tests signups, password resets, magic links, या inbound notifications को cover करते हैं, तो आपको अभी भी CI में emails देखने का एक तरीका चाहिए (1) shared mailbox में login किए बिना, (2) HTML scraping के बिना, या (3) sensitive content को job logs में dump किए बिना।
अच्छी बात यह है कि आप email को किसी भी अन्य test artifact की तरह treat कर सकते हैं: इसे run के अनुसार provision करें, deterministically wait करें, structured fields पर assert करें, और results को CI output से attach करें।
“मेलबॉक्स में लॉग इन” क्यों CI को तोड़ता है
एक पारंपरिक mailbox (Gmail, Outlook, IMAP) long lived identity के चारों ओर wrapped human UX है। CI को इसका उल्टा चाहिए: short lived, isolated, machine readable state।
जब आप pipelines में real mailbox पर भरोसा करते हैं तो सामान्य failure modes:
- Parallel runs collide होते हैं: multiple jobs एक ही inbox पढ़ते हैं, गलत message pick करते हैं, या एक-दूसरे की state delete कर देते हैं।
- Auth और MFA का CI में कोई स्थान नहीं: OAuth refresh tokens expire हो जाते हैं, MFA challenges runs को block करते हैं, और permissions बहुत broad होती हैं।
- Observability backwards है: आप “हमें कौन सा email मिला?” को build artifact के रूप में आसानी से store नहीं कर सकते।
- Security खराब हो जाती है: teams debug करने के लिए logs में OTPs और magic links paste करना शुरू कर देते हैं।
यदि आप चाहते हैं कि emails testable हों, तो उन्हें events की तरह consumable होना चाहिए।
💡 अपनी CI Pipeline में Email से लड़ना बंद करें
Mailbox login की headaches और parallel run collisions को छोड़ें। Mailhook disposable inboxes बनाता है जो proper test resources की तरह behave करते हैं - API के माध्यम से run के अनुसार provisioned और structured JSON के रूप में consumed।
CI में emails देखने के तीन practical तरीके
Email testing के बहुत सारे tricks हैं, लेकिन 2026 में अधिकांश teams इनमें से किसी एक पर converge करती हैं, यह इस पर निर्भर करता है कि वे क्या validate कर रहे हैं।
Option 1: Local SMTP capture (तेज़, dev और कुछ CI के लिए बेहतरीन)
यदि आपका goal “क्या हमारे app ने email send करने की कोशिश की?” है तो local SMTP capture tool सबसे simple approach है।
यह कैसे काम करता है:
- आपका app CI network के अंदर local server को SMTP के माध्यम से भेजता है।
- Server messages store करता है और उन्हें एक छोटी API/UI के माध्यम से expose करता है।
फायदे:
- बहुत तेज़
- कोई external dependency नहीं
- Unit tests और integration tests के लिए बेहतरीन
नुकसान:
- Real inbound routing का true end to end test नहीं
- Production email infrastructure में होने वाली deliverability और routing issues को catch नहीं करता
यह developer workflows के लिए अच्छा default है, लेकिन यह अक्सर E2E flows के लिए कम पड़ता है जो production की तरह behave करना चाहिए।
Option 2: एक disposable inbox API (E2E और verification flows के लिए सबसे अच्छा)
End to end tests के लिए जहां आपको real inbound email receive करना है और OTP या link extract करना है, programmable disposable inboxes सबसे reliable pattern हैं:
- Run या attempt के अनुसार API के माध्यम से fresh inbox बनाएं।
- Test के अंतर्गत flow में इसके email address का उपयोग करें।
- Arrival के लिए deterministically wait करें।
- Message को structured JSON के रूप में retrieve करें।
- केवल आवश्यक artifact पर assert और extract करें।
यह mailbox logins से पूरी तरह बचता है। CI केवल data fetch करता है।
Mailhook बिल्कुल इसी model के लिए built है: API के माध्यम से disposable inbox creation, JSON के रूप में delivered email, webhook notifications, polling retrieval, shared domains, custom domain support, signed payloads, और batch processing। Canonical integration details के लिए, published contract का उपयोग करें: Mailhook llms.txt।
Option 3: Provider specific event streams (उपयोगी, लेकिन अक्सर inbox shaped नहीं)
कुछ email sending providers delivery events (accepted, bounced, delivered) और कभी-कभी message previews expose करते हैं। यह deliverability telemetry के लिए helpful हो सकता है, लेकिन “इस magic link पर click करें” style tests के लिए हमेशा पर्याप्त नहीं होता।
अधिकांश orgs में, teams को deterministic verification flows के लिए अभी भी inbox shaped abstraction (address, messages, retrieval) की आवश्यकता होती है।
Quick decision table
| CI में goal | सबसे अच्छा approach | आप वास्तव में किस पर assert करते हैं |
|---|---|---|
| “हमने सही email content generate किया” | Local SMTP capture | Subject/from/to, text body, templates |
| “एक user signup verification complete कर सकता है” | Disposable inbox API | Timeout के अंदर arrival, extracted OTP या link |
| “Deliverability और provider behavior” | Provider events + targeted tests | Delivery events, bounces, complaint signals |
यदि आपकी pipeline को emails को “देखना” है जैसे user उन्हें experience करेगा, तो disposable inboxes जीतते हैं।
Deterministic pattern: inbox per run, wait, parse JSON
Key यह है कि “mailbox search करने” के terms में सोचना बंद करें। CI में आप explicit contract चाहते हैं:
- Isolation: प्रत्येक run को अपना inbox मिलता है।
- Delivery: आपके test harness के पास messages के लिए wait करने का reliable तरीका है (webhook first, polling fallback)।
- Consumption: आप stable JSON fields पर assert करते हैं, rendered HTML पर नहीं।

💡 Deterministic Email Pattern को Minutes में Working बनाएं
Inbox isolation और JSON parsing को rebuild क्यों करें जब आप तुरंत testing शुरू कर सकते हैं? Mailhook आपको webhooks, polling, और structured email data out of the box देता है - बिल्कुल वही जिसकी इस pattern को जरूरत है।
Step 1: एक inbox provision करें
Test start में inbox बनाएं और दोनों keep करें:
- email address (जिसका आपका app उपयोग करता है)
- inbox handle (जिसका आपका test harness messages fetch करने के लिए उपयोग करता है)
Mailhook के साथ, exact request और response fields llms.txt में documented हैं। Code reviews में उस file को source of truth के रूप में treat करें।
Step 2: Email trigger करें
Test के अंतर्गत action चलाएं, उदाहरण के लिए:
- signup
- password reset
- email sign in
Determinism के लिए, अपने application में एक correlation value pass करें जिसे आप control करते हैं (उदाहरण के लिए, एक run ID) ताकि यह email में end up हो। Common places:
- verification link के अंदर query param
- custom header जो आपका mailer add करता है
- email text में reference token
Step 3: Arrival के लिए wait करें (CI के अंदर polling सबसे simple है)
Webhooks तब बेहतरीन होते हैं जब आपके पास पहले से public endpoint हो। CI में, polling अक्सर आसान होता है और अगर आप timeouts और backoff implement करते हैं तो अभी भी deterministic होता है।
Provider agnostic polling pseudocode:
async function waitForEmail({ inboxId, matcher, timeoutMs }) {
const started = Date.now();
let delay = 250;
while (Date.now() - started < timeoutMs) {
const messages = await listMessages(inboxId); // provider API call
const match = messages.find(matcher);
if (match) return match;
await sleep(delay);
delay = Math.min(delay * 1.5, 2000);
}
throw new Error(`Timed out waiting for email in inbox ${inboxId}`);
}
Important part matcher है: इसे इतना narrow बनाएं कि parallel runs एक-दूसरे के mail को match न कर सकें।
Step 4: JSON पर assert करें, केवल आवश्यक चीज़ extract करें
एक बार जब आप structured JSON representation retrieve कर लें, तो assertions prefer करें जैसे:
- From domain correct है
- Recipient expected address से match करता है
- Subject में expected intent है
- Text body में OTP pattern है
Brittle behaviors से बचें:
- HTML markup scraping करना
- Exact formatting या CSS पर depend करना
- LLM को “पूरा email पढ़ने” देना जब आपको केवल OTP चाहिए
Example extraction (OTP):
import re
def extract_otp(text: str) -> str:
m = re.search(r"\b(\d{6})\b", text)
if not m:
raise ValueError("OTP not found")
return m.group(1)
Step 5: Email JSON को CI artifact के रूप में attach करें (print करने के बजाय)
Secrets leak किए बिना failures को debug करने के लिए:
- received message JSON को file में write करें
- इसे artifact के रूप में upload करें
- जहां appropriate हो sensitive fields को redact या omit करें
GitHub Actions में, artifact upload straightforward है:
- name: Save inbound email JSON
run: node scripts/save-email.js > email.json
- name: Upload email artifact
uses: actions/upload-artifact@v4
with:
name: inbound-email
path: email.json
यही “manual mailbox debugging” और “CI grade email visibility” के बीच सबसे बड़ा practical difference है। आपको run से tied durable artifact मिलता है।
CI में webhooks: कब ये sense बनाते हैं
Webhooks ideal हैं जब:
- आप stable public URL के साथ long lived test environment चलाते हैं
- आपको lowest latency चाहिए
- आप पहले से छोटी receiver service operate करते हैं
यदि आप webhooks का उपयोग करते हैं, तो webhook request को untrusted input channel के रूप में treat करें:
- signatures verify करें
- timestamp tolerance enforce करें
- deliveries को dedupe करें (retries होती हैं)
Mailhook signed payloads support करता है, जो यहां correct primitive है। फिर से, exact signature और header format Mailhook llms.txt में described है।
“Emails देखने” के लिए CI reliability checklist
ये guardrails हैं जो अधिकांश flakiness को remove कर देते हैं:
Run के अनुसार unique inbox का उपयोग करें (या attempt के अनुसार)
यदि आप inboxes share करते हैं, तो आप eventually गलत message match करेंगे। Isolation debugging से सस्ता है।
Fixed sleeps की जगह deterministic waiting prefer करें
sleep(10) को “matching email arrive होने या timeout तक wait करें” से replace करें। यह speed और stability improve करता है।
सही level पर dedupe करें
Email pipelines retries के कारण legitimately duplicates deliver कर सकती हैं। आपका harness robust होना चाहिए:
- latest matching message select करके
- seen message IDs track करके
- consumption को idempotent बनाकर
Email content को hostile input के रूप में treat करें
Test environments में भी, email में हो सकता है:
- unexpected HTML
- tracking links
- attachments
यदि agent involved है, तो constrain करें कि वह email के साथ क्या कर सकता है। Minimal artifact (OTP या URL) extract करें, इसे validate करें, फिर proceed करें।
Secrets को logs से बाहर रखें
यदि आपको कुछ log करना है, तो identifiers log करें:
- run ID
- inbox ID
- message ID
फिर full message content को appropriate access controls के साथ artifacts में store करें।
Minimal “CI में emails देखने” की implementation plan
यदि आप flaky shared mailbox setup से शुरू कर रहे हैं, तो इस order में migrate करें:
Phase 1: Mailboxes में logging बंद करें
- Mailbox UI steps को API retrieval से replace करें।
- Received message को artifact के रूप में store करें।
Phase 2: Isolate करें
- Run के अनुसार inbox बनाएं (या verification flows के लिए attempt के अनुसार)।
- Email content में correlation token add करें।
Phase 3: इसे secure और scalable बनाएं
- यदि आप webhooks का उपयोग करते हैं तो webhook signature verification add करें।
- Timeouts, dedupe, और clear error messages add करें।
- यदि आपको allowlisting या stricter control की जरूरत है तो custom domain consider करें।
Mailhook instant shared domains और custom domain support दोनों support करता है, ताकि आप fast start कर सकें और बाद में control को tighten कर सकें।
Mailhook कहां fit करता है
यदि आपका goal CI में mailbox में कभी login किए बिना emails देखना है, तो आपको एक inbox चाहिए जो test resource की तरह behave करे:
- API के माध्यम से on demand provisioned
- structured JSON के रूप में consumed
- webhooks के माध्यम से delivered या polling के माध्यम से fetched
- parallel में चलाने के लिए safe
यही core workflow है जिसके लिए Mailhook designed है। Exact calls और payload formats implement करने के लिए canonical integration reference का उपयोग करें: Mailhook llms.txt। आप Mailhook पर product overview से भी शुरू कर सकते हैं।