[{"data":1,"prerenderedAt":2926},["ShallowReactive",2],{"navigation":3,"\u002Fdocs\u002Fguides\u002Fimap-pop3\u002F":121,"\u002Fdocs\u002Fguides\u002Fimap-pop3\u002F-surround":2921},[4,8,22,26,43,104],{"title":5,"path":6,"stem":7},"Getting Started","\u002Fdocs\u002Fgetting-started","1.docs\u002F1.getting-started",{"title":9,"path":10,"stem":11,"children":12,"page":21},"Setup","\u002Fdocs\u002Fsetup","1.docs\u002F2.setup",[13,17],{"title":14,"path":15,"stem":16},"Domain","\u002Fdocs\u002Fsetup\u002Fdomain","1.docs\u002F2.setup\u002F2.domain",{"title":18,"path":19,"stem":20},"Email","\u002Fdocs\u002Fsetup\u002Faccount","1.docs\u002F2.setup\u002F3.account",false,{"title":23,"path":24,"stem":25},"Email Testing API","\u002Fdocs\u002Fapi","1.docs\u002F3.api",{"title":27,"path":28,"stem":29,"children":30,"page":21},"Features","\u002Fdocs\u002Ffeatures","1.docs\u002F4.features",[31,35,39],{"title":32,"path":33,"stem":34},"Account","\u002Fdocs\u002Ffeatures\u002Faccount","1.docs\u002F4.features\u002F1.account",{"title":36,"path":37,"stem":38},"Mailbox","\u002Fdocs\u002Ffeatures\u002Fmailbox","1.docs\u002F4.features\u002F2.mailbox",{"title":40,"path":41,"stem":42},"Messages","\u002Fdocs\u002Ffeatures\u002Fmessage","1.docs\u002F4.features\u002F3.message",{"title":44,"path":45,"stem":46,"children":47,"page":21},"Guides","\u002Fdocs\u002Fguides","1.docs\u002F5.guides",[48,52,56,60,64,68,72,76,80,84,88,92,96,100],{"title":49,"path":50,"stem":51},"SMTP Test","\u002Fdocs\u002Fguides\u002Fsend-test-email","1.docs\u002F5.guides\u002F01.send-test-email",{"title":53,"path":54,"stem":55},"API Quickstart","\u002Fdocs\u002Fguides\u002Femail-testing-api","1.docs\u002F5.guides\u002F02.email-testing-api",{"title":57,"path":58,"stem":59},"CI","\u002Fdocs\u002Fguides\u002Fci","1.docs\u002F5.guides\u002F03.ci",{"title":61,"path":62,"stem":63},"Catch-All","\u002Fdocs\u002Fguides\u002Fcatch-all","1.docs\u002F5.guides\u002F04.catch-all",{"title":65,"path":66,"stem":67},"SPF, DKIM, DMARC","\u002Fdocs\u002Fguides\u002Fspf-dkim-dmarc","1.docs\u002F5.guides\u002F05.spf-dkim-dmarc",{"title":69,"path":70,"stem":71},"Playwright","\u002Fdocs\u002Fguides\u002Fe2e","1.docs\u002F5.guides\u002F06.e2e",{"title":73,"path":74,"stem":75},"Cypress","\u002Fdocs\u002Fguides\u002Fcypress","1.docs\u002F5.guides\u002F07.cypress",{"title":77,"path":78,"stem":79},"Email Clients","\u002Fdocs\u002Fguides\u002Femail-clients","1.docs\u002F5.guides\u002F08.email-clients",{"title":81,"path":82,"stem":83},"AI Agents","\u002Fdocs\u002Fguides\u002Fagents","1.docs\u002F5.guides\u002F09.agents",{"title":85,"path":86,"stem":87},"Local Development","\u002Fdocs\u002Fguides\u002Flocal-development","1.docs\u002F5.guides\u002F10.local-development",{"title":89,"path":90,"stem":91},"Size Limits","\u002Fdocs\u002Fguides\u002Femail-size-limits","1.docs\u002F5.guides\u002F11.email-size-limits",{"title":93,"path":94,"stem":95},"OTP & Magic Links","\u002Fdocs\u002Fguides\u002Fotp-magic-links","1.docs\u002F5.guides\u002F12.otp-magic-links",{"title":97,"path":98,"stem":99},"IMAP & POP3","\u002Fdocs\u002Fguides\u002Fimap-pop3","1.docs\u002F5.guides\u002F13.imap-pop3",{"title":101,"path":102,"stem":103},"Nodemailer","\u002Fdocs\u002Fguides\u002Fnodemailer","1.docs\u002F5.guides\u002F14.nodemailer",{"title":105,"path":106,"stem":107,"children":108,"page":21},"Alternatives","\u002Fdocs\u002Falternatives","1.docs\u002F6.alternatives",[109,113,117],{"title":110,"path":111,"stem":112},"Mailtrap","\u002Fdocs\u002Falternatives\u002Fmailtrap","1.docs\u002F6.alternatives\u002F1.mailtrap",{"title":114,"path":115,"stem":116},"Mailosaur","\u002Fdocs\u002Falternatives\u002Fmailosaur","1.docs\u002F6.alternatives\u002F2.mailosaur",{"title":118,"path":119,"stem":120},"Mailinator","\u002Fdocs\u002Falternatives\u002Fmailinator","1.docs\u002F6.alternatives\u002F3.mailinator",{"id":122,"title":123,"body":124,"description":2915,"extension":2916,"meta":2917,"navigation":2918,"path":98,"seo":2919,"stem":99,"__hash__":2920},"docs\u002F1.docs\u002F5.guides\u002F13.imap-pop3.md","IMAP vs POP3 for Developers: Ports, Commands, and Test Scripts",{"type":125,"value":126,"toc":2901},"minimark",[127,131,134,139,230,233,236,291,300,304,435,439,470,474,477,482,516,519,527,634,652,658,684,688,708,729,735,809,818,822,825,1011,1018,1022,1031,1624,1633,1649,1656,1735,1741,2184,2188,2195,2635,2641,2651,2766,2770,2773,2836,2840,2891,2897],[128,129,130],"p",{},"IMAP and POP3 both fetch mail from a server. IMAP works on the server's copy: folders, read flags, and search live there, and every client sees the same state. POP3 downloads the inbox and can delete it afterwards. It has no folders, no flags, and no search.",[128,132,133],{},"Every sandbox account speaks both, so you can read one test message each way and see the difference.",[135,136,138],"h2",{"id":137},"imap-pop3-and-smtp-ports","IMAP, POP3, and SMTP Ports",[140,141,142,158],"table",{},[143,144,145],"thead",{},[146,147,148,152,155],"tr",{},[149,150,151],"th",{},"Protocol",[149,153,154],{},"Port",[149,156,157],{},"Encryption",[159,160,161,173,187,197,209,221],"tbody",{},[146,162,163,167,170],{},[164,165,166],"td",{},"IMAP",[164,168,169],{},"993",[164,171,172],{},"TLS from the first byte",[146,174,175,177,180],{},[164,176,166],{},[164,178,179],{},"143",[164,181,182,183],{},"Plain text, upgraded with ",[184,185,186],"code",{},"STARTTLS",[146,188,189,192,195],{},[164,190,191],{},"POP3",[164,193,194],{},"995",[164,196,172],{},[146,198,199,201,204],{},[164,200,191],{},[164,202,203],{},"110",[164,205,182,206],{},[184,207,208],{},"STLS",[146,210,211,214,217],{},[164,212,213],{},"SMTP submission",[164,215,216],{},"587",[164,218,182,219],{},[184,220,186],{},[146,222,223,225,228],{},[164,224,213],{},[164,226,227],{},"465",[164,229,172],{},[128,231,232],{},"Those are the standard assignments. RFC 8314 recommends the TLS-first ports for mail clients.",[128,234,235],{},"The sandbox listens on these:",[140,237,238,249],{},[143,239,240],{},[146,241,242,244,247],{},[149,243,151],{},[149,245,246],{},"Host",[149,248,154],{},[159,250,251,265,276],{},[146,252,253,255,260],{},[164,254,166],{},[164,256,257],{},[184,258,259],{},"imap.smtp.dev",[164,261,262,263],{},"993, or 143 with ",[184,264,186],{},[146,266,267,269,274],{},[164,268,191],{},[164,270,271],{},[184,272,273],{},"pop.smtp.dev",[164,275,194],{},[146,277,278,281,286],{},[164,279,280],{},"SMTP",[164,282,283],{},[184,284,285],{},"send.smtp.dev",[164,287,288,289],{},"587 with ",[184,290,186],{},[128,292,293,294,299],{},"The username is the account's full address and the password is the account's password, on all three (",[295,296,298],"a",{"href":297},"\u002Fdocs\u002Fsetup\u002Faccount\u002F","connection settings",").",[135,301,303],{"id":302},"imap-vs-pop3-at-a-glance","IMAP vs POP3 at a Glance",[140,305,306,316],{},[143,307,308],{},[146,309,310,312,314],{},[149,311],{},[149,313,166],{},[149,315,191],{},[159,317,318,329,343,354,368,383,397,411],{},[146,319,320,323,326],{},[164,321,322],{},"Where mail lives",[164,324,325],{},"On the server. Clients cache it",[164,327,328],{},"Downloaded. Keeping the server copy is optional",[146,330,331,334,340],{},[164,332,333],{},"Folders",[164,335,336,337],{},"Any number, plus ",[184,338,339],{},"INBOX",[164,341,342],{},"The inbox only",[146,344,345,348,351],{},[164,346,347],{},"Read and flagged state",[164,349,350],{},"Stored on the server, shared by every client",[164,352,353],{},"None",[146,355,356,359,365],{},[164,357,358],{},"Search",[164,360,361,362],{},"On the server, with ",[184,363,364],{},"SEARCH",[164,366,367],{},"None. Download, then filter",[146,369,370,373,376],{},[164,371,372],{},"Message ids",[164,374,375],{},"A UID per message, stable within a mailbox",[164,377,378,379,382],{},"A unique id from ",[184,380,381],{},"UIDL",". Message numbers change between sessions",[146,384,385,388,394],{},[164,386,387],{},"New mail",[164,389,390,391],{},"Pushed while the client waits in ",[184,392,393],{},"IDLE",[164,395,396],{},"Seen at the next login. A session sees the inbox as it was",[146,398,399,402,405],{},[164,400,401],{},"Part of a message",[164,403,404],{},"Any header or MIME part",[164,406,407,408],{},"Headers plus the first n lines, with ",[184,409,410],{},"TOP",[146,412,413,416,426],{},[164,414,415],{},"Deleting",[164,417,418,419,422,423],{},"Flag ",[184,420,421],{},"\\Deleted",", then ",[184,424,425],{},"EXPUNGE",[164,427,428,431,432],{},[184,429,430],{},"DELE",", applied at ",[184,433,434],{},"QUIT",[135,436,438],{"id":437},"which-one-for-a-test","Which One for a Test",[440,441,442,455,465],"ul",{},[443,444,445,449,450,454],"li",{},[446,447,448],"strong",{},"Usually neither."," To assert on a message, the ",[295,451,453],{"href":452},"\u002Fdocs\u002Fguides\u002Femail-testing-api\u002F","REST API"," returns it as JSON with the parts already decoded. There's no MIME to parse and no connection to keep open.",[443,456,457,459,460,464],{},[446,458,166],{}," when the code under test is an IMAP client, or to open the message in a ",[295,461,463],{"href":462},"\u002Fdocs\u002Fguides\u002Femail-clients\u002F","desktop client",".",[443,466,467,469],{},[446,468,191],{}," when your product pulls mail over POP3: a helpdesk importing a support inbox, or a \"check mail from another account\" feature.",[135,471,473],{"id":472},"by-hand-with-openssl","By Hand with openssl",[128,475,476],{},"Typing the commands shows exactly what a client library does for you. Both sessions need a TLS connection, so use openssl instead of telnet.",[478,479,481],"h3",{"id":480},"imap-commands","IMAP Commands",[483,484,489],"pre",{"className":485,"code":486,"language":487,"meta":488,"style":488},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","openssl s_client -connect imap.smtp.dev:993 -crlf -quiet\n","bash","",[184,490,491],{"__ignoreMap":488},[492,493,496,500,504,507,510,513],"span",{"class":494,"line":495},"line",1,[492,497,499],{"class":498},"sBMFI","openssl",[492,501,503],{"class":502},"sfazB"," s_client",[492,505,506],{"class":502}," -connect",[492,508,509],{"class":502}," imap.smtp.dev:993",[492,511,512],{"class":502}," -crlf",[492,514,515],{"class":502}," -quiet\n",[128,517,518],{},"Every command starts with a tag you choose, and the server repeats the tag on the line that ends its reply. Type one line at a time:",[483,520,525],{"className":521,"code":523,"language":524,"meta":488},[522],"language-text","a1 LOGIN qa@test.example.com your-password\na2 LIST \"\" \"*\"\na3 SELECT INBOX\na4 UID SEARCH UNSEEN\na5 UID FETCH 1 (FLAGS BODY.PEEK[HEADER.FIELDS (FROM TO SUBJECT DATE)])\na6 UID FETCH 1 BODY[]\na7 UID STORE 1 +FLAGS (\\Deleted)\na8 EXPUNGE\na9 LOGOUT\n","text",[184,526,523],{"__ignoreMap":488},[140,528,529,539],{},[143,530,531],{},[146,532,533,536],{},[149,534,535],{},"Command",[149,537,538],{},"Does",[159,540,541,551,561,578,602,612,622],{},[146,542,543,548],{},[164,544,545],{},[184,546,547],{},"LOGIN",[164,549,550],{},"Logs in. Put the password in double quotes if it has spaces or punctuation",[146,552,553,558],{},[164,554,555],{},[184,556,557],{},"LIST \"\" \"*\"",[164,559,560],{},"Lists every mailbox",[146,562,563,568],{},[164,564,565],{},[184,566,567],{},"SELECT INBOX",[164,569,570,571,574,575],{},"Opens a mailbox. The reply has the message count as ",[184,572,573],{},"EXISTS",", and ",[184,576,577],{},"UIDVALIDITY",[146,579,580,585],{},[164,581,582],{},[184,583,584],{},"UID SEARCH UNSEEN",[164,586,587,588,591,592,591,595,574,598,601],{},"Returns the UIDs of unread messages. ",[184,589,590],{},"ALL",", ",[184,593,594],{},"FROM",[184,596,597],{},"TO",[184,599,600],{},"SUBJECT"," are other keys",[146,603,604,609],{},[164,605,606],{},[184,607,608],{},"UID FETCH 1 (… BODY.PEEK[…])",[164,610,611],{},"Reads flags and four headers of UID 1 without marking it read",[146,613,614,619],{},[164,615,616],{},[184,617,618],{},"UID FETCH 1 BODY[]",[164,620,621],{},"Returns the whole raw message and marks it read",[146,623,624,631],{},[164,625,626,591,629],{},[184,627,628],{},"UID STORE … (\\Deleted)",[184,630,425],{},[164,632,633],{},"Deletes it",[128,635,636,637,640,641,591,644,647,648,651],{},"Replace ",[184,638,639],{},"1"," with a UID from the search. The server ends each reply with ",[184,642,643],{},"OK",[184,645,646],{},"NO"," when it refuses, or ",[184,649,650],{},"BAD"," when it can't parse the command.",[128,653,654,655,657],{},"Port 143 starts in plain text. To test the ",[184,656,186],{}," path instead:",[483,659,661],{"className":485,"code":660,"language":487,"meta":488,"style":488},"openssl s_client -starttls imap -connect imap.smtp.dev:143 -crlf -quiet\n",[184,662,663],{"__ignoreMap":488},[492,664,665,667,669,672,675,677,680,682],{"class":494,"line":495},[492,666,499],{"class":498},[492,668,503],{"class":502},[492,670,671],{"class":502}," -starttls",[492,673,674],{"class":502}," imap",[492,676,506],{"class":502},[492,678,679],{"class":502}," imap.smtp.dev:143",[492,681,512],{"class":502},[492,683,515],{"class":502},[478,685,687],{"id":686},"pop3-commands","POP3 Commands",[483,689,691],{"className":485,"code":690,"language":487,"meta":488,"style":488},"openssl s_client -connect pop.smtp.dev:995 -crlf -quiet\n",[184,692,693],{"__ignoreMap":488},[492,694,695,697,699,701,704,706],{"class":494,"line":495},[492,696,499],{"class":498},[492,698,503],{"class":502},[492,700,506],{"class":502},[492,702,703],{"class":502}," pop.smtp.dev:995",[492,705,512],{"class":502},[492,707,515],{"class":502},[128,709,710,713,714,717,718,721,722,724,725,728],{},[184,711,712],{},"-quiet"," matters here. Without it, openssl treats a line that starts with ",[184,715,716],{},"Q"," or ",[184,719,720],{},"R"," as one of its own commands, and ",[184,723,434],{}," and ",[184,726,727],{},"RETR"," never reach the server.",[483,730,733],{"className":731,"code":732,"language":524,"meta":488},[522],"USER qa@test.example.com\nPASS your-password\nSTAT\nLIST\nUIDL\nTOP 1 0\nRETR 1\nDELE 1\nQUIT\n",[184,734,732],{"__ignoreMap":488},[140,736,737,745],{},[143,738,739],{},[146,740,741,743],{},[149,742,535],{},[149,744,538],{},[159,746,747,757,767,776,786,796],{},[146,748,749,754],{},[164,750,751],{},[184,752,753],{},"STAT",[164,755,756],{},"Returns the message count and total size in bytes",[146,758,759,764],{},[164,760,761],{},[184,762,763],{},"LIST",[164,765,766],{},"Returns the number and size of each message",[146,768,769,773],{},[164,770,771],{},[184,772,381],{},[164,774,775],{},"Returns the number and unique id of each message. The ids persist, the numbers don't",[146,777,778,783],{},[164,779,780],{},[184,781,782],{},"TOP 1 0",[164,784,785],{},"Returns the headers of message 1 and no body lines",[146,787,788,793],{},[164,789,790],{},[184,791,792],{},"RETR 1",[164,794,795],{},"Returns the whole message",[146,797,798,803],{},[164,799,800],{},[184,801,802],{},"DELE 1",[164,804,805,806,808],{},"Marks it. Nothing is deleted until ",[184,807,434],{},", and a dropped connection deletes nothing",[128,810,811,812,717,815,464],{},"Replies start with ",[184,813,814],{},"+OK",[184,816,817],{},"-ERR",[135,819,821],{"id":820},"with-curl","With curl",[128,823,824],{},"curl speaks both protocols:",[483,826,828],{"className":485,"code":827,"language":487,"meta":488,"style":488},"# IMAP: UIDs of unread messages\ncurl \"imaps:\u002F\u002Fimap.smtp.dev\u002FINBOX\" --request \"UID SEARCH UNSEEN\" \\\n  --user \"qa@test.example.com:$QA_PASSWORD\"\n\n# IMAP: the message with UID 1, raw\ncurl \"imaps:\u002F\u002Fimap.smtp.dev\u002FINBOX;UID=1\" --user \"qa@test.example.com:$QA_PASSWORD\"\n\n# IMAP: only its headers\ncurl \"imaps:\u002F\u002Fimap.smtp.dev\u002FINBOX;UID=1;SECTION=HEADER\" \\\n  --user \"qa@test.example.com:$QA_PASSWORD\"\n\n# POP3: list the messages, then fetch the first\ncurl \"pop3s:\u002F\u002Fpop.smtp.dev\u002F\" --user \"qa@test.example.com:$QA_PASSWORD\"\ncurl \"pop3s:\u002F\u002Fpop.smtp.dev\u002F1\" --user \"qa@test.example.com:$QA_PASSWORD\"\n",[184,829,830,836,865,882,889,895,918,923,929,943,956,961,967,989],{"__ignoreMap":488},[492,831,832],{"class":494,"line":495},[492,833,835],{"class":834},"sHwdD","# IMAP: UIDs of unread messages\n",[492,837,839,842,846,849,852,855,857,859,861],{"class":494,"line":838},2,[492,840,841],{"class":498},"curl",[492,843,845],{"class":844},"sMK4o"," \"",[492,847,848],{"class":502},"imaps:\u002F\u002Fimap.smtp.dev\u002FINBOX",[492,850,851],{"class":844},"\"",[492,853,854],{"class":502}," --request",[492,856,845],{"class":844},[492,858,584],{"class":502},[492,860,851],{"class":844},[492,862,864],{"class":863},"sTEyZ"," \\\n",[492,866,868,871,873,876,879],{"class":494,"line":867},3,[492,869,870],{"class":502},"  --user",[492,872,845],{"class":844},[492,874,875],{"class":502},"qa@test.example.com:",[492,877,878],{"class":863},"$QA_PASSWORD",[492,880,881],{"class":844},"\"\n",[492,883,885],{"class":494,"line":884},4,[492,886,888],{"emptyLinePlaceholder":887},true,"\n",[492,890,892],{"class":494,"line":891},5,[492,893,894],{"class":834},"# IMAP: the message with UID 1, raw\n",[492,896,898,900,902,905,907,910,912,914,916],{"class":494,"line":897},6,[492,899,841],{"class":498},[492,901,845],{"class":844},[492,903,904],{"class":502},"imaps:\u002F\u002Fimap.smtp.dev\u002FINBOX;UID=1",[492,906,851],{"class":844},[492,908,909],{"class":502}," --user",[492,911,845],{"class":844},[492,913,875],{"class":502},[492,915,878],{"class":863},[492,917,881],{"class":844},[492,919,921],{"class":494,"line":920},7,[492,922,888],{"emptyLinePlaceholder":887},[492,924,926],{"class":494,"line":925},8,[492,927,928],{"class":834},"# IMAP: only its headers\n",[492,930,932,934,936,939,941],{"class":494,"line":931},9,[492,933,841],{"class":498},[492,935,845],{"class":844},[492,937,938],{"class":502},"imaps:\u002F\u002Fimap.smtp.dev\u002FINBOX;UID=1;SECTION=HEADER",[492,940,851],{"class":844},[492,942,864],{"class":863},[492,944,946,948,950,952,954],{"class":494,"line":945},10,[492,947,870],{"class":502},[492,949,845],{"class":844},[492,951,875],{"class":502},[492,953,878],{"class":863},[492,955,881],{"class":844},[492,957,959],{"class":494,"line":958},11,[492,960,888],{"emptyLinePlaceholder":887},[492,962,964],{"class":494,"line":963},12,[492,965,966],{"class":834},"# POP3: list the messages, then fetch the first\n",[492,968,970,972,974,977,979,981,983,985,987],{"class":494,"line":969},13,[492,971,841],{"class":498},[492,973,845],{"class":844},[492,975,976],{"class":502},"pop3s:\u002F\u002Fpop.smtp.dev\u002F",[492,978,851],{"class":844},[492,980,909],{"class":502},[492,982,845],{"class":844},[492,984,875],{"class":502},[492,986,878],{"class":863},[492,988,881],{"class":844},[492,990,992,994,996,999,1001,1003,1005,1007,1009],{"class":494,"line":991},14,[492,993,841],{"class":498},[492,995,845],{"class":844},[492,997,998],{"class":502},"pop3s:\u002F\u002Fpop.smtp.dev\u002F1",[492,1000,851],{"class":844},[492,1002,909],{"class":502},[492,1004,845],{"class":844},[492,1006,875],{"class":502},[492,1008,878],{"class":863},[492,1010,881],{"class":844},[128,1012,1013,1014,1017],{},"Add ",[184,1015,1016],{},"-v"," to see every command and reply.",[135,1019,1021],{"id":1020},"from-python","From Python",[128,1023,1024,724,1027,1030],{},[184,1025,1026],{},"imaplib",[184,1028,1029],{},"poplib"," are in the standard library. Waiting for a message over IMAP:",[483,1032,1036],{"className":1033,"code":1034,"language":1035,"meta":488,"style":488},"language-python shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import email\nimport imaplib\nimport os\nimport ssl\nimport time\nfrom email import policy\n\n\ndef wait_for_message(to, timeout=30):\n    with imaplib.IMAP4_SSL(\"imap.smtp.dev\", ssl_context=ssl.create_default_context()) as imap:\n        imap.login(\"qa@test.example.com\", os.environ[\"QA_PASSWORD\"])\n        imap.select(\"INBOX\", readonly=True)\n        deadline = time.monotonic() + timeout\n        while time.monotonic() \u003C deadline:\n            _, data = imap.uid(\"SEARCH\", \"TO\", f'\"{to}\"')\n            uids = data[0].split()\n            if uids:\n                _, parts = imap.uid(\"FETCH\", uids[-1], \"(BODY.PEEK[])\")\n                return email.message_from_bytes(parts[0][1], policy=policy.default)\n            time.sleep(2)\n    raise TimeoutError(f\"no message to {to} after {timeout}s\")\n\n\nmessage = wait_for_message(\"qa+run42@test.example.com\")\nprint(message[\"Subject\"])\nprint(message.get_body(preferencelist=(\"plain\",)).get_content())\n","python",[184,1037,1038,1047,1054,1061,1068,1075,1088,1092,1096,1129,1176,1219,1244,1268,1289,1347,1372,1383,1432,1477,1495,1533,1538,1543,1564,1586],{"__ignoreMap":488},[492,1039,1040,1044],{"class":494,"line":495},[492,1041,1043],{"class":1042},"s7zQu","import",[492,1045,1046],{"class":863}," email\n",[492,1048,1049,1051],{"class":494,"line":838},[492,1050,1043],{"class":1042},[492,1052,1053],{"class":863}," imaplib\n",[492,1055,1056,1058],{"class":494,"line":867},[492,1057,1043],{"class":1042},[492,1059,1060],{"class":863}," os\n",[492,1062,1063,1065],{"class":494,"line":884},[492,1064,1043],{"class":1042},[492,1066,1067],{"class":863}," ssl\n",[492,1069,1070,1072],{"class":494,"line":891},[492,1071,1043],{"class":1042},[492,1073,1074],{"class":863}," time\n",[492,1076,1077,1080,1083,1085],{"class":494,"line":897},[492,1078,1079],{"class":1042},"from",[492,1081,1082],{"class":863}," email ",[492,1084,1043],{"class":1042},[492,1086,1087],{"class":863}," policy\n",[492,1089,1090],{"class":494,"line":920},[492,1091,888],{"emptyLinePlaceholder":887},[492,1093,1094],{"class":494,"line":925},[492,1095,888],{"emptyLinePlaceholder":887},[492,1097,1098,1102,1106,1109,1113,1116,1119,1122,1126],{"class":494,"line":931},[492,1099,1101],{"class":1100},"spNyl","def",[492,1103,1105],{"class":1104},"s2Zo4"," wait_for_message",[492,1107,1108],{"class":844},"(",[492,1110,1112],{"class":1111},"sHdIc","to",[492,1114,1115],{"class":844},",",[492,1117,1118],{"class":1111}," timeout",[492,1120,1121],{"class":844},"=",[492,1123,1125],{"class":1124},"sbssI","30",[492,1127,1128],{"class":844},"):\n",[492,1130,1131,1134,1137,1139,1142,1144,1146,1148,1150,1152,1155,1157,1160,1162,1165,1168,1171,1173],{"class":494,"line":945},[492,1132,1133],{"class":1042},"    with",[492,1135,1136],{"class":863}," imaplib",[492,1138,464],{"class":844},[492,1140,1141],{"class":1104},"IMAP4_SSL",[492,1143,1108],{"class":844},[492,1145,851],{"class":844},[492,1147,259],{"class":502},[492,1149,851],{"class":844},[492,1151,1115],{"class":844},[492,1153,1154],{"class":1111}," ssl_context",[492,1156,1121],{"class":844},[492,1158,1159],{"class":1104},"ssl",[492,1161,464],{"class":844},[492,1163,1164],{"class":1104},"create_default_context",[492,1166,1167],{"class":844},"())",[492,1169,1170],{"class":1042}," as",[492,1172,674],{"class":863},[492,1174,1175],{"class":844},":\n",[492,1177,1178,1181,1183,1186,1188,1190,1193,1195,1197,1200,1202,1206,1209,1211,1214,1216],{"class":494,"line":958},[492,1179,1180],{"class":863},"        imap",[492,1182,464],{"class":844},[492,1184,1185],{"class":1104},"login",[492,1187,1108],{"class":844},[492,1189,851],{"class":844},[492,1191,1192],{"class":502},"qa@test.example.com",[492,1194,851],{"class":844},[492,1196,1115],{"class":844},[492,1198,1199],{"class":1104}," os",[492,1201,464],{"class":844},[492,1203,1205],{"class":1204},"swJcz","environ",[492,1207,1208],{"class":844},"[",[492,1210,851],{"class":844},[492,1212,1213],{"class":502},"QA_PASSWORD",[492,1215,851],{"class":844},[492,1217,1218],{"class":844},"])\n",[492,1220,1221,1223,1225,1228,1230,1232,1234,1236,1238,1241],{"class":494,"line":963},[492,1222,1180],{"class":863},[492,1224,464],{"class":844},[492,1226,1227],{"class":1104},"select",[492,1229,1108],{"class":844},[492,1231,851],{"class":844},[492,1233,339],{"class":502},[492,1235,851],{"class":844},[492,1237,1115],{"class":844},[492,1239,1240],{"class":1111}," readonly",[492,1242,1243],{"class":844},"=True)\n",[492,1245,1246,1249,1251,1254,1256,1259,1262,1265],{"class":494,"line":969},[492,1247,1248],{"class":863},"        deadline ",[492,1250,1121],{"class":844},[492,1252,1253],{"class":863}," time",[492,1255,464],{"class":844},[492,1257,1258],{"class":1104},"monotonic",[492,1260,1261],{"class":844},"()",[492,1263,1264],{"class":844}," +",[492,1266,1267],{"class":863}," timeout\n",[492,1269,1270,1273,1275,1277,1279,1281,1284,1287],{"class":494,"line":991},[492,1271,1272],{"class":1042},"        while",[492,1274,1253],{"class":863},[492,1276,464],{"class":844},[492,1278,1258],{"class":1104},[492,1280,1261],{"class":844},[492,1282,1283],{"class":844}," \u003C",[492,1285,1286],{"class":863}," deadline",[492,1288,1175],{"class":844},[492,1290,1292,1295,1297,1300,1302,1304,1306,1309,1311,1313,1315,1317,1319,1321,1323,1325,1327,1330,1333,1336,1338,1341,1344],{"class":494,"line":1291},15,[492,1293,1294],{"class":863},"            _",[492,1296,1115],{"class":844},[492,1298,1299],{"class":863}," data ",[492,1301,1121],{"class":844},[492,1303,674],{"class":863},[492,1305,464],{"class":844},[492,1307,1308],{"class":1104},"uid",[492,1310,1108],{"class":844},[492,1312,851],{"class":844},[492,1314,364],{"class":502},[492,1316,851],{"class":844},[492,1318,1115],{"class":844},[492,1320,845],{"class":844},[492,1322,597],{"class":502},[492,1324,851],{"class":844},[492,1326,1115],{"class":844},[492,1328,1329],{"class":1100}," f",[492,1331,1332],{"class":502},"'\"",[492,1334,1335],{"class":1124},"{",[492,1337,1112],{"class":1104},[492,1339,1340],{"class":1124},"}",[492,1342,1343],{"class":502},"\"'",[492,1345,1346],{"class":844},")\n",[492,1348,1350,1353,1355,1358,1360,1363,1366,1369],{"class":494,"line":1349},16,[492,1351,1352],{"class":863},"            uids ",[492,1354,1121],{"class":844},[492,1356,1357],{"class":863}," data",[492,1359,1208],{"class":844},[492,1361,1362],{"class":1124},"0",[492,1364,1365],{"class":844},"].",[492,1367,1368],{"class":1104},"split",[492,1370,1371],{"class":844},"()\n",[492,1373,1375,1378,1381],{"class":494,"line":1374},17,[492,1376,1377],{"class":1042},"            if",[492,1379,1380],{"class":863}," uids",[492,1382,1175],{"class":844},[492,1384,1386,1389,1391,1394,1396,1398,1400,1402,1404,1406,1409,1411,1413,1415,1418,1420,1423,1425,1428,1430],{"class":494,"line":1385},18,[492,1387,1388],{"class":863},"                _",[492,1390,1115],{"class":844},[492,1392,1393],{"class":863}," parts ",[492,1395,1121],{"class":844},[492,1397,674],{"class":863},[492,1399,464],{"class":844},[492,1401,1308],{"class":1104},[492,1403,1108],{"class":844},[492,1405,851],{"class":844},[492,1407,1408],{"class":502},"FETCH",[492,1410,851],{"class":844},[492,1412,1115],{"class":844},[492,1414,1380],{"class":1104},[492,1416,1417],{"class":844},"[-",[492,1419,639],{"class":1124},[492,1421,1422],{"class":844},"],",[492,1424,845],{"class":844},[492,1426,1427],{"class":502},"(BODY.PEEK[])",[492,1429,851],{"class":844},[492,1431,1346],{"class":844},[492,1433,1435,1438,1441,1443,1446,1448,1451,1453,1455,1458,1460,1462,1465,1467,1470,1472,1475],{"class":494,"line":1434},19,[492,1436,1437],{"class":1042},"                return",[492,1439,1440],{"class":863}," email",[492,1442,464],{"class":844},[492,1444,1445],{"class":1104},"message_from_bytes",[492,1447,1108],{"class":844},[492,1449,1450],{"class":1104},"parts",[492,1452,1208],{"class":844},[492,1454,1362],{"class":1124},[492,1456,1457],{"class":844},"][",[492,1459,639],{"class":1124},[492,1461,1422],{"class":844},[492,1463,1464],{"class":1111}," policy",[492,1466,1121],{"class":844},[492,1468,1469],{"class":1104},"policy",[492,1471,464],{"class":844},[492,1473,1474],{"class":1204},"default",[492,1476,1346],{"class":844},[492,1478,1480,1483,1485,1488,1490,1493],{"class":494,"line":1479},20,[492,1481,1482],{"class":863},"            time",[492,1484,464],{"class":844},[492,1486,1487],{"class":1104},"sleep",[492,1489,1108],{"class":844},[492,1491,1492],{"class":1124},"2",[492,1494,1346],{"class":844},[492,1496,1498,1501,1504,1506,1509,1512,1514,1516,1518,1521,1523,1526,1528,1531],{"class":494,"line":1497},21,[492,1499,1500],{"class":1042},"    raise",[492,1502,1503],{"class":498}," TimeoutError",[492,1505,1108],{"class":844},[492,1507,1508],{"class":1100},"f",[492,1510,1511],{"class":502},"\"no message to ",[492,1513,1335],{"class":1124},[492,1515,1112],{"class":1104},[492,1517,1340],{"class":1124},[492,1519,1520],{"class":502}," after ",[492,1522,1335],{"class":1124},[492,1524,1525],{"class":1104},"timeout",[492,1527,1340],{"class":1124},[492,1529,1530],{"class":502},"s\"",[492,1532,1346],{"class":844},[492,1534,1536],{"class":494,"line":1535},22,[492,1537,888],{"emptyLinePlaceholder":887},[492,1539,1541],{"class":494,"line":1540},23,[492,1542,888],{"emptyLinePlaceholder":887},[492,1544,1546,1549,1551,1553,1555,1557,1560,1562],{"class":494,"line":1545},24,[492,1547,1548],{"class":863},"message ",[492,1550,1121],{"class":844},[492,1552,1105],{"class":1104},[492,1554,1108],{"class":844},[492,1556,851],{"class":844},[492,1558,1559],{"class":502},"qa+run42@test.example.com",[492,1561,851],{"class":844},[492,1563,1346],{"class":844},[492,1565,1567,1570,1572,1575,1577,1579,1582,1584],{"class":494,"line":1566},25,[492,1568,1569],{"class":1104},"print",[492,1571,1108],{"class":844},[492,1573,1574],{"class":1104},"message",[492,1576,1208],{"class":844},[492,1578,851],{"class":844},[492,1580,1581],{"class":502},"Subject",[492,1583,851],{"class":844},[492,1585,1218],{"class":844},[492,1587,1589,1591,1593,1595,1597,1600,1602,1605,1608,1610,1613,1615,1618,1621],{"class":494,"line":1588},26,[492,1590,1569],{"class":1104},[492,1592,1108],{"class":844},[492,1594,1574],{"class":1104},[492,1596,464],{"class":844},[492,1598,1599],{"class":1104},"get_body",[492,1601,1108],{"class":844},[492,1603,1604],{"class":1111},"preferencelist",[492,1606,1607],{"class":844},"=(",[492,1609,851],{"class":844},[492,1611,1612],{"class":502},"plain",[492,1614,851],{"class":844},[492,1616,1617],{"class":844},",)).",[492,1619,1620],{"class":1104},"get_content",[492,1622,1623],{"class":844},"())\n",[128,1625,1626,724,1629,1632],{},[184,1627,1628],{},"readonly=True",[184,1630,1631],{},"BODY.PEEK"," leave the message unread, so a test doesn't change what the next one finds.",[1634,1635,1636],"warning",{},[128,1637,1638,724,1641,1644,1645,1648],{},[184,1639,1640],{},"imaplib.IMAP4_SSL",[184,1642,1643],{},"poplib.POP3_SSL"," don't verify the server's certificate unless you pass a context. ",[184,1646,1647],{},"ssl.create_default_context()"," turns verification on.",[128,1650,1651,1652,1655],{},"Python 3.14 added ",[184,1653,1654],{},"idle()",", which waits for the server to announce a message instead of polling:",[483,1657,1659],{"className":1033,"code":1658,"language":1035,"meta":488,"style":488},"with imap.idle(duration=30) as idler:\n    for kind, data in idler:\n        if kind == \"EXISTS\":\n            break\n",[184,1660,1661,1692,1711,1730],{"__ignoreMap":488},[492,1662,1663,1666,1668,1670,1673,1675,1678,1680,1682,1685,1687,1690],{"class":494,"line":495},[492,1664,1665],{"class":1042},"with",[492,1667,674],{"class":863},[492,1669,464],{"class":844},[492,1671,1672],{"class":1104},"idle",[492,1674,1108],{"class":844},[492,1676,1677],{"class":1111},"duration",[492,1679,1121],{"class":844},[492,1681,1125],{"class":1124},[492,1683,1684],{"class":844},")",[492,1686,1170],{"class":1042},[492,1688,1689],{"class":863}," idler",[492,1691,1175],{"class":844},[492,1693,1694,1697,1700,1702,1704,1707,1709],{"class":494,"line":838},[492,1695,1696],{"class":1042},"    for",[492,1698,1699],{"class":863}," kind",[492,1701,1115],{"class":844},[492,1703,1299],{"class":863},[492,1705,1706],{"class":1042},"in",[492,1708,1689],{"class":863},[492,1710,1175],{"class":844},[492,1712,1713,1716,1719,1722,1724,1726,1728],{"class":494,"line":867},[492,1714,1715],{"class":1042},"        if",[492,1717,1718],{"class":863}," kind ",[492,1720,1721],{"class":844},"==",[492,1723,845],{"class":844},[492,1725,573],{"class":502},[492,1727,851],{"class":844},[492,1729,1175],{"class":844},[492,1731,1732],{"class":494,"line":884},[492,1733,1734],{"class":1042},"            break\n",[128,1736,1737,1738,1740],{},"POP3 can't search, so the script reads each message's headers with ",[184,1739,410],{}," and downloads the one it wants:",[483,1742,1744],{"className":1033,"code":1743,"language":1035,"meta":488,"style":488},"import os\nimport poplib\nimport ssl\nfrom email import message_from_bytes, policy\n\npop = poplib.POP3_SSL(\"pop.smtp.dev\", context=ssl.create_default_context())\npop.user(\"qa@test.example.com\")\npop.pass_(os.environ[\"QA_PASSWORD\"])\n\ncount, size = pop.stat()\nfor number in range(1, count + 1):\n    _, lines, _ = pop.top(number, 0)\n    headers = message_from_bytes(b\"\\r\\n\".join(lines), policy=policy.default)\n    if \"qa+run42@test.example.com\" in headers.get(\"To\", \"\"):\n        _, lines, _ = pop.retr(number)\n        message = message_from_bytes(b\"\\r\\n\".join(lines), policy=policy.default)\n        print(message[\"Subject\"])\n        print(message.get_body(preferencelist=(\"plain\",)).get_content())\n        break\n\npop.quit()\n",[184,1745,1746,1752,1759,1765,1780,1784,1822,1842,1870,1874,1896,1926,1962,2008,2046,2074,2115,2134,2164,2169,2173],{"__ignoreMap":488},[492,1747,1748,1750],{"class":494,"line":495},[492,1749,1043],{"class":1042},[492,1751,1060],{"class":863},[492,1753,1754,1756],{"class":494,"line":838},[492,1755,1043],{"class":1042},[492,1757,1758],{"class":863}," poplib\n",[492,1760,1761,1763],{"class":494,"line":867},[492,1762,1043],{"class":1042},[492,1764,1067],{"class":863},[492,1766,1767,1769,1771,1773,1776,1778],{"class":494,"line":884},[492,1768,1079],{"class":1042},[492,1770,1082],{"class":863},[492,1772,1043],{"class":1042},[492,1774,1775],{"class":863}," message_from_bytes",[492,1777,1115],{"class":844},[492,1779,1087],{"class":863},[492,1781,1782],{"class":494,"line":891},[492,1783,888],{"emptyLinePlaceholder":887},[492,1785,1786,1789,1791,1794,1796,1799,1801,1803,1805,1807,1809,1812,1814,1816,1818,1820],{"class":494,"line":897},[492,1787,1788],{"class":863},"pop ",[492,1790,1121],{"class":844},[492,1792,1793],{"class":863}," poplib",[492,1795,464],{"class":844},[492,1797,1798],{"class":1104},"POP3_SSL",[492,1800,1108],{"class":844},[492,1802,851],{"class":844},[492,1804,273],{"class":502},[492,1806,851],{"class":844},[492,1808,1115],{"class":844},[492,1810,1811],{"class":1111}," context",[492,1813,1121],{"class":844},[492,1815,1159],{"class":1104},[492,1817,464],{"class":844},[492,1819,1164],{"class":1104},[492,1821,1623],{"class":844},[492,1823,1824,1827,1829,1832,1834,1836,1838,1840],{"class":494,"line":920},[492,1825,1826],{"class":863},"pop",[492,1828,464],{"class":844},[492,1830,1831],{"class":1104},"user",[492,1833,1108],{"class":844},[492,1835,851],{"class":844},[492,1837,1192],{"class":502},[492,1839,851],{"class":844},[492,1841,1346],{"class":844},[492,1843,1844,1846,1848,1851,1853,1856,1858,1860,1862,1864,1866,1868],{"class":494,"line":925},[492,1845,1826],{"class":863},[492,1847,464],{"class":844},[492,1849,1850],{"class":1104},"pass_",[492,1852,1108],{"class":844},[492,1854,1855],{"class":1104},"os",[492,1857,464],{"class":844},[492,1859,1205],{"class":1204},[492,1861,1208],{"class":844},[492,1863,851],{"class":844},[492,1865,1213],{"class":502},[492,1867,851],{"class":844},[492,1869,1218],{"class":844},[492,1871,1872],{"class":494,"line":931},[492,1873,888],{"emptyLinePlaceholder":887},[492,1875,1876,1879,1881,1884,1886,1889,1891,1894],{"class":494,"line":945},[492,1877,1878],{"class":863},"count",[492,1880,1115],{"class":844},[492,1882,1883],{"class":863}," size ",[492,1885,1121],{"class":844},[492,1887,1888],{"class":863}," pop",[492,1890,464],{"class":844},[492,1892,1893],{"class":1104},"stat",[492,1895,1371],{"class":844},[492,1897,1898,1901,1904,1906,1909,1911,1913,1915,1918,1921,1924],{"class":494,"line":958},[492,1899,1900],{"class":1042},"for",[492,1902,1903],{"class":863}," number ",[492,1905,1706],{"class":1042},[492,1907,1908],{"class":1104}," range",[492,1910,1108],{"class":844},[492,1912,639],{"class":1124},[492,1914,1115],{"class":844},[492,1916,1917],{"class":1104}," count ",[492,1919,1920],{"class":844},"+",[492,1922,1923],{"class":1124}," 1",[492,1925,1128],{"class":844},[492,1927,1928,1931,1933,1936,1938,1941,1943,1945,1947,1950,1952,1955,1957,1960],{"class":494,"line":963},[492,1929,1930],{"class":863},"    _",[492,1932,1115],{"class":844},[492,1934,1935],{"class":863}," lines",[492,1937,1115],{"class":844},[492,1939,1940],{"class":863}," _ ",[492,1942,1121],{"class":844},[492,1944,1888],{"class":863},[492,1946,464],{"class":844},[492,1948,1949],{"class":1104},"top",[492,1951,1108],{"class":844},[492,1953,1954],{"class":1104},"number",[492,1956,1115],{"class":844},[492,1958,1959],{"class":1124}," 0",[492,1961,1346],{"class":844},[492,1963,1964,1967,1969,1971,1973,1976,1978,1981,1983,1985,1988,1990,1993,1996,1998,2000,2002,2004,2006],{"class":494,"line":969},[492,1965,1966],{"class":863},"    headers ",[492,1968,1121],{"class":844},[492,1970,1775],{"class":1104},[492,1972,1108],{"class":844},[492,1974,1975],{"class":1100},"b",[492,1977,851],{"class":844},[492,1979,1980],{"class":863},"\\r\\n",[492,1982,851],{"class":844},[492,1984,464],{"class":844},[492,1986,1987],{"class":1104},"join",[492,1989,1108],{"class":844},[492,1991,1992],{"class":1104},"lines",[492,1994,1995],{"class":844},"),",[492,1997,1464],{"class":1111},[492,1999,1121],{"class":844},[492,2001,1469],{"class":1104},[492,2003,464],{"class":844},[492,2005,1474],{"class":1204},[492,2007,1346],{"class":844},[492,2009,2010,2013,2015,2017,2019,2022,2025,2027,2030,2032,2034,2037,2039,2041,2044],{"class":494,"line":991},[492,2011,2012],{"class":1042},"    if",[492,2014,845],{"class":844},[492,2016,1559],{"class":502},[492,2018,851],{"class":844},[492,2020,2021],{"class":844}," in",[492,2023,2024],{"class":863}," headers",[492,2026,464],{"class":844},[492,2028,2029],{"class":1104},"get",[492,2031,1108],{"class":844},[492,2033,851],{"class":844},[492,2035,2036],{"class":502},"To",[492,2038,851],{"class":844},[492,2040,1115],{"class":844},[492,2042,2043],{"class":844}," \"\"",[492,2045,1128],{"class":844},[492,2047,2048,2051,2053,2055,2057,2059,2061,2063,2065,2068,2070,2072],{"class":494,"line":1291},[492,2049,2050],{"class":863},"        _",[492,2052,1115],{"class":844},[492,2054,1935],{"class":863},[492,2056,1115],{"class":844},[492,2058,1940],{"class":863},[492,2060,1121],{"class":844},[492,2062,1888],{"class":863},[492,2064,464],{"class":844},[492,2066,2067],{"class":1104},"retr",[492,2069,1108],{"class":844},[492,2071,1954],{"class":1104},[492,2073,1346],{"class":844},[492,2075,2076,2079,2081,2083,2085,2087,2089,2091,2093,2095,2097,2099,2101,2103,2105,2107,2109,2111,2113],{"class":494,"line":1349},[492,2077,2078],{"class":863},"        message ",[492,2080,1121],{"class":844},[492,2082,1775],{"class":1104},[492,2084,1108],{"class":844},[492,2086,1975],{"class":1100},[492,2088,851],{"class":844},[492,2090,1980],{"class":863},[492,2092,851],{"class":844},[492,2094,464],{"class":844},[492,2096,1987],{"class":1104},[492,2098,1108],{"class":844},[492,2100,1992],{"class":1104},[492,2102,1995],{"class":844},[492,2104,1464],{"class":1111},[492,2106,1121],{"class":844},[492,2108,1469],{"class":1104},[492,2110,464],{"class":844},[492,2112,1474],{"class":1204},[492,2114,1346],{"class":844},[492,2116,2117,2120,2122,2124,2126,2128,2130,2132],{"class":494,"line":1374},[492,2118,2119],{"class":1104},"        print",[492,2121,1108],{"class":844},[492,2123,1574],{"class":1104},[492,2125,1208],{"class":844},[492,2127,851],{"class":844},[492,2129,1581],{"class":502},[492,2131,851],{"class":844},[492,2133,1218],{"class":844},[492,2135,2136,2138,2140,2142,2144,2146,2148,2150,2152,2154,2156,2158,2160,2162],{"class":494,"line":1385},[492,2137,2119],{"class":1104},[492,2139,1108],{"class":844},[492,2141,1574],{"class":1104},[492,2143,464],{"class":844},[492,2145,1599],{"class":1104},[492,2147,1108],{"class":844},[492,2149,1604],{"class":1111},[492,2151,1607],{"class":844},[492,2153,851],{"class":844},[492,2155,1612],{"class":502},[492,2157,851],{"class":844},[492,2159,1617],{"class":844},[492,2161,1620],{"class":1104},[492,2163,1623],{"class":844},[492,2165,2166],{"class":494,"line":1434},[492,2167,2168],{"class":1042},"        break\n",[492,2170,2171],{"class":494,"line":1479},[492,2172,888],{"emptyLinePlaceholder":887},[492,2174,2175,2177,2179,2182],{"class":494,"line":1497},[492,2176,1826],{"class":863},[492,2178,464],{"class":844},[492,2180,2181],{"class":1104},"quit",[492,2183,1371],{"class":844},[135,2185,2187],{"id":2186},"from-node","From Node",[128,2189,2190,2191,2194],{},"With ImapFlow, and ",[184,2192,2193],{},"mailparser"," to decode the raw message:",[483,2196,2200],{"className":2197,"code":2198,"language":2199,"meta":488,"style":488},"language-js shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { ImapFlow } from 'imapflow'\nimport { simpleParser } from 'mailparser'\n\nconst client = new ImapFlow({\n  host: 'imap.smtp.dev',\n  port: 993,\n  secure: true,\n  auth: { user: 'qa@test.example.com', pass: process.env.QA_PASSWORD },\n  logger: false,\n})\n\nawait client.connect()\nconst lock = await client.getMailboxLock('INBOX')\ntry {\n  const uids = await client.search({ to: 'qa+run42@test.example.com' }, { uid: true })\n  const { source } = await client.fetchOne(uids.at(-1), { source: true }, { uid: true })\n  const message = await simpleParser(source)\n  console.log(message.subject, message.text)\n}\nfinally {\n  lock.release()\n}\nawait client.logout()\n","js",[184,2201,2202,2227,2246,2250,2270,2288,2300,2313,2356,2368,2374,2378,2393,2422,2430,2480,2545,2565,2594,2599,2606,2618,2622],{"__ignoreMap":488},[492,2203,2204,2206,2209,2212,2215,2218,2221,2224],{"class":494,"line":495},[492,2205,1043],{"class":1042},[492,2207,2208],{"class":844}," {",[492,2210,2211],{"class":863}," ImapFlow",[492,2213,2214],{"class":844}," }",[492,2216,2217],{"class":1042}," from",[492,2219,2220],{"class":844}," '",[492,2222,2223],{"class":502},"imapflow",[492,2225,2226],{"class":844},"'\n",[492,2228,2229,2231,2233,2236,2238,2240,2242,2244],{"class":494,"line":838},[492,2230,1043],{"class":1042},[492,2232,2208],{"class":844},[492,2234,2235],{"class":863}," simpleParser",[492,2237,2214],{"class":844},[492,2239,2217],{"class":1042},[492,2241,2220],{"class":844},[492,2243,2193],{"class":502},[492,2245,2226],{"class":844},[492,2247,2248],{"class":494,"line":867},[492,2249,888],{"emptyLinePlaceholder":887},[492,2251,2252,2255,2258,2260,2263,2265,2267],{"class":494,"line":884},[492,2253,2254],{"class":1100},"const",[492,2256,2257],{"class":863}," client ",[492,2259,1121],{"class":844},[492,2261,2262],{"class":844}," new",[492,2264,2211],{"class":1104},[492,2266,1108],{"class":863},[492,2268,2269],{"class":844},"{\n",[492,2271,2272,2275,2278,2280,2282,2285],{"class":494,"line":891},[492,2273,2274],{"class":1204},"  host",[492,2276,2277],{"class":844},":",[492,2279,2220],{"class":844},[492,2281,259],{"class":502},[492,2283,2284],{"class":844},"'",[492,2286,2287],{"class":844},",\n",[492,2289,2290,2293,2295,2298],{"class":494,"line":897},[492,2291,2292],{"class":1204},"  port",[492,2294,2277],{"class":844},[492,2296,2297],{"class":1124}," 993",[492,2299,2287],{"class":844},[492,2301,2302,2305,2307,2311],{"class":494,"line":920},[492,2303,2304],{"class":1204},"  secure",[492,2306,2277],{"class":844},[492,2308,2310],{"class":2309},"sfNiH"," true",[492,2312,2287],{"class":844},[492,2314,2315,2318,2320,2322,2325,2327,2329,2331,2333,2335,2338,2340,2343,2345,2348,2350,2353],{"class":494,"line":925},[492,2316,2317],{"class":1204},"  auth",[492,2319,2277],{"class":844},[492,2321,2208],{"class":844},[492,2323,2324],{"class":1204}," user",[492,2326,2277],{"class":844},[492,2328,2220],{"class":844},[492,2330,1192],{"class":502},[492,2332,2284],{"class":844},[492,2334,1115],{"class":844},[492,2336,2337],{"class":1204}," pass",[492,2339,2277],{"class":844},[492,2341,2342],{"class":863}," process",[492,2344,464],{"class":844},[492,2346,2347],{"class":863},"env",[492,2349,464],{"class":844},[492,2351,2352],{"class":863},"QA_PASSWORD ",[492,2354,2355],{"class":844},"},\n",[492,2357,2358,2361,2363,2366],{"class":494,"line":931},[492,2359,2360],{"class":1204},"  logger",[492,2362,2277],{"class":844},[492,2364,2365],{"class":2309}," false",[492,2367,2287],{"class":844},[492,2369,2370,2372],{"class":494,"line":945},[492,2371,1340],{"class":844},[492,2373,1346],{"class":863},[492,2375,2376],{"class":494,"line":958},[492,2377,888],{"emptyLinePlaceholder":887},[492,2379,2380,2383,2386,2388,2391],{"class":494,"line":963},[492,2381,2382],{"class":1042},"await",[492,2384,2385],{"class":863}," client",[492,2387,464],{"class":844},[492,2389,2390],{"class":1104},"connect",[492,2392,1371],{"class":863},[492,2394,2395,2397,2400,2402,2405,2407,2409,2412,2414,2416,2418,2420],{"class":494,"line":969},[492,2396,2254],{"class":1100},[492,2398,2399],{"class":863}," lock ",[492,2401,1121],{"class":844},[492,2403,2404],{"class":1042}," await",[492,2406,2385],{"class":863},[492,2408,464],{"class":844},[492,2410,2411],{"class":1104},"getMailboxLock",[492,2413,1108],{"class":863},[492,2415,2284],{"class":844},[492,2417,339],{"class":502},[492,2419,2284],{"class":844},[492,2421,1346],{"class":863},[492,2423,2424,2427],{"class":494,"line":991},[492,2425,2426],{"class":1042},"try",[492,2428,2429],{"class":844}," {\n",[492,2431,2432,2435,2437,2440,2442,2444,2446,2449,2451,2453,2456,2458,2460,2462,2464,2467,2469,2472,2474,2476,2478],{"class":494,"line":1291},[492,2433,2434],{"class":1100},"  const",[492,2436,1380],{"class":863},[492,2438,2439],{"class":844}," =",[492,2441,2404],{"class":1042},[492,2443,2385],{"class":863},[492,2445,464],{"class":844},[492,2447,2448],{"class":1104},"search",[492,2450,1108],{"class":1204},[492,2452,1335],{"class":844},[492,2454,2455],{"class":1204}," to",[492,2457,2277],{"class":844},[492,2459,2220],{"class":844},[492,2461,1559],{"class":502},[492,2463,2284],{"class":844},[492,2465,2466],{"class":844}," },",[492,2468,2208],{"class":844},[492,2470,2471],{"class":1204}," uid",[492,2473,2277],{"class":844},[492,2475,2310],{"class":2309},[492,2477,2214],{"class":844},[492,2479,1346],{"class":1204},[492,2481,2482,2484,2486,2489,2491,2493,2495,2497,2499,2502,2504,2507,2509,2512,2514,2517,2519,2521,2523,2525,2527,2529,2531,2533,2535,2537,2539,2541,2543],{"class":494,"line":1349},[492,2483,2434],{"class":1100},[492,2485,2208],{"class":844},[492,2487,2488],{"class":863}," source",[492,2490,2214],{"class":844},[492,2492,2439],{"class":844},[492,2494,2404],{"class":1042},[492,2496,2385],{"class":863},[492,2498,464],{"class":844},[492,2500,2501],{"class":1104},"fetchOne",[492,2503,1108],{"class":1204},[492,2505,2506],{"class":863},"uids",[492,2508,464],{"class":844},[492,2510,2511],{"class":1104},"at",[492,2513,1108],{"class":1204},[492,2515,2516],{"class":844},"-",[492,2518,639],{"class":1124},[492,2520,1684],{"class":1204},[492,2522,1115],{"class":844},[492,2524,2208],{"class":844},[492,2526,2488],{"class":1204},[492,2528,2277],{"class":844},[492,2530,2310],{"class":2309},[492,2532,2466],{"class":844},[492,2534,2208],{"class":844},[492,2536,2471],{"class":1204},[492,2538,2277],{"class":844},[492,2540,2310],{"class":2309},[492,2542,2214],{"class":844},[492,2544,1346],{"class":1204},[492,2546,2547,2549,2552,2554,2556,2558,2560,2563],{"class":494,"line":1374},[492,2548,2434],{"class":1100},[492,2550,2551],{"class":863}," message",[492,2553,2439],{"class":844},[492,2555,2404],{"class":1042},[492,2557,2235],{"class":1104},[492,2559,1108],{"class":1204},[492,2561,2562],{"class":863},"source",[492,2564,1346],{"class":1204},[492,2566,2567,2570,2572,2575,2577,2579,2581,2584,2586,2588,2590,2592],{"class":494,"line":1385},[492,2568,2569],{"class":863},"  console",[492,2571,464],{"class":844},[492,2573,2574],{"class":1104},"log",[492,2576,1108],{"class":1204},[492,2578,1574],{"class":863},[492,2580,464],{"class":844},[492,2582,2583],{"class":863},"subject",[492,2585,1115],{"class":844},[492,2587,2551],{"class":863},[492,2589,464],{"class":844},[492,2591,524],{"class":863},[492,2593,1346],{"class":1204},[492,2595,2596],{"class":494,"line":1434},[492,2597,2598],{"class":844},"}\n",[492,2600,2601,2604],{"class":494,"line":1479},[492,2602,2603],{"class":1042},"finally",[492,2605,2429],{"class":844},[492,2607,2608,2611,2613,2616],{"class":494,"line":1497},[492,2609,2610],{"class":863},"  lock",[492,2612,464],{"class":844},[492,2614,2615],{"class":1104},"release",[492,2617,1371],{"class":1204},[492,2619,2620],{"class":494,"line":1535},[492,2621,2598],{"class":844},[492,2623,2624,2626,2628,2630,2633],{"class":494,"line":1540},[492,2625,2382],{"class":1042},[492,2627,2385],{"class":863},[492,2629,464],{"class":844},[492,2631,2632],{"class":1104},"logout",[492,2634,1371],{"class":863},[128,2636,2637,2638,2640],{},"The script assumes the message has already arrived. When nothing matches, ",[184,2639,2448],{}," returns an empty array and there is nothing to fetch.",[128,2642,2643,2644,2646,2647,2650],{},"ImapFlow sits in ",[184,2645,393],{}," whenever no command is running, and emits ",[184,2648,2649],{},"exists"," when the server announces new mail:",[483,2652,2654],{"className":2197,"code":2653,"language":2199,"meta":488,"style":488},"await client.mailboxOpen('INBOX')\n\nclient.on('exists', ({ count, prevCount }) => {\n  console.log(`${count - prevCount} new, ${count} in the inbox`)\n})\n",[184,2655,2656,2677,2681,2720,2760],{"__ignoreMap":488},[492,2657,2658,2660,2662,2664,2667,2669,2671,2673,2675],{"class":494,"line":495},[492,2659,2382],{"class":1042},[492,2661,2385],{"class":863},[492,2663,464],{"class":844},[492,2665,2666],{"class":1104},"mailboxOpen",[492,2668,1108],{"class":863},[492,2670,2284],{"class":844},[492,2672,339],{"class":502},[492,2674,2284],{"class":844},[492,2676,1346],{"class":863},[492,2678,2679],{"class":494,"line":838},[492,2680,888],{"emptyLinePlaceholder":887},[492,2682,2683,2686,2688,2691,2693,2695,2697,2699,2701,2704,2707,2709,2712,2715,2718],{"class":494,"line":867},[492,2684,2685],{"class":863},"client",[492,2687,464],{"class":844},[492,2689,2690],{"class":1104},"on",[492,2692,1108],{"class":863},[492,2694,2284],{"class":844},[492,2696,2649],{"class":502},[492,2698,2284],{"class":844},[492,2700,1115],{"class":844},[492,2702,2703],{"class":844}," ({",[492,2705,2706],{"class":1111}," count",[492,2708,1115],{"class":844},[492,2710,2711],{"class":1111}," prevCount",[492,2713,2714],{"class":844}," })",[492,2716,2717],{"class":1100}," =>",[492,2719,2429],{"class":844},[492,2721,2722,2724,2726,2728,2730,2733,2736,2738,2740,2742,2745,2748,2750,2752,2755,2758],{"class":494,"line":884},[492,2723,2569],{"class":863},[492,2725,464],{"class":844},[492,2727,2574],{"class":1104},[492,2729,1108],{"class":1204},[492,2731,2732],{"class":844},"`${",[492,2734,2735],{"class":863},"count ",[492,2737,2516],{"class":844},[492,2739,2711],{"class":863},[492,2741,1340],{"class":844},[492,2743,2744],{"class":502}," new, ",[492,2746,2747],{"class":844},"${",[492,2749,1878],{"class":863},[492,2751,1340],{"class":844},[492,2753,2754],{"class":502}," in the inbox",[492,2756,2757],{"class":844},"`",[492,2759,1346],{"class":1204},[492,2761,2762,2764],{"class":494,"line":891},[492,2763,1340],{"class":844},[492,2765,1346],{"class":863},[135,2767,2769],{"id":2768},"what-to-test-in-a-mail-client","What to Test in a Mail Client",[128,2771,2772],{},"If your product reads mail, these are the cases that break in production:",[440,2774,2775,2793,2804,2813,2825],{},[443,2776,2777,2780,2781,2785,2786,2792],{},[446,2778,2779],{},"Flags changed elsewhere."," Mark a message read in ",[295,2782,2784],{"href":2783},"\u002Fmail\u002Faccounts\u002F","Mail"," or with a ",[295,2787,2789],{"href":2788},"\u002Fdocs\u002Fapi\u002F#update-a-message",[184,2790,2791],{},"PATCH",", and check your IMAP client picks the change up.",[443,2794,2795,2798,2799,2803],{},[446,2796,2797],{},"Folders."," ",[295,2800,2802],{"href":2801},"\u002Fdocs\u002Ffeatures\u002Fmailbox\u002F","Create a mailbox",", move a message into it, and check the client lists both.",[443,2805,2806,2809,2810,2812],{},[446,2807,2808],{},"The same message twice."," Run a POP3 import twice without deleting. ",[184,2811,381],{}," is what stops the second run from storing duplicates.",[443,2814,2815,2818,2819,2821,2822,2824],{},[446,2816,2817],{},"A delete that didn't happen."," POP3 applies ",[184,2820,430],{}," at ",[184,2823,434],{},". Drop the connection mid-session and check the importer doesn't assume the message is gone.",[443,2826,2827,2830,2831,2835],{},[446,2828,2829],{},"A large message."," Send one near the ",[295,2832,2834],{"href":2833},"\u002Fdocs\u002Fguides\u002Femail-size-limits\u002F","size limit"," and check the client doesn't time out or load it all into memory.",[135,2837,2839],{"id":2838},"when-it-fails","When It Fails",[140,2841,2842,2852],{},[143,2843,2844],{},[146,2845,2846,2849],{},[149,2847,2848],{},"Reply",[149,2850,2851],{},"Cause",[159,2853,2854,2864,2874,2883],{},[146,2855,2856,2861],{},[164,2857,2858],{},[184,2859,2860],{},"NO [AUTHENTICATIONFAILED] Invalid credentials",[164,2862,2863],{},"IMAP login failed: a wrong password, or the username isn't the full address",[146,2865,2866,2871],{},[164,2867,2868],{},[184,2869,2870],{},"-ERR [AUTH] Username and password not accepted",[164,2872,2873],{},"The same, over POP3",[146,2875,2876,2880],{},[164,2877,2878],{},[184,2879,650],{},[164,2881,2882],{},"IMAP couldn't parse the command: a missing tag, or an unquoted argument with a space",[146,2884,2885,2888],{},[164,2886,2887],{},"Nothing after connecting",[164,2889,2890],{},"Plain text sent to a TLS port. 993 and 995 need TLS from the first byte",[128,2892,2893,2894,464],{},"To send the message these examples read, see ",[295,2895,49],{"href":2896},"\u002Fdocs\u002Fguides\u002Fsend-test-email\u002F",[2898,2899,2900],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}",{"title":488,"searchDepth":838,"depth":838,"links":2902},[2903,2904,2905,2906,2910,2911,2912,2913,2914],{"id":137,"depth":838,"text":138},{"id":302,"depth":838,"text":303},{"id":437,"depth":838,"text":438},{"id":472,"depth":838,"text":473,"children":2907},[2908,2909],{"id":480,"depth":867,"text":481},{"id":686,"depth":867,"text":687},{"id":820,"depth":838,"text":821},{"id":1020,"depth":838,"text":1021},{"id":2186,"depth":838,"text":2187},{"id":2768,"depth":838,"text":2769},{"id":2838,"depth":838,"text":2839},"IMAP works on the server's copy of a mailbox, POP3 downloads it. Ports, the commands to type into openssl, and curl, Python, and Node scripts for both.","md",{},{"title":97},{"title":123,"description":2915},"CpSOAPIMWFNOr7lyizB5DHuPnkpKg_KPKMBcr5cNUfo",[2922,2924],{"title":93,"path":94,"stem":95,"description":2923,"children":-1},"Read one-time codes and magic links from the real email over a REST API, then test resend, reuse, and single-use links. Playwright specs you can copy.",{"title":101,"path":102,"stem":103,"description":2925,"children":-1},"Point Nodemailer at a sandbox SMTP server, send from a test, and assert on links, headers, and attachments over REST. Compared with mocks and Ethereal.",1794400214126]