Disposable Email
Обновена на: March 24, 2022Много често ми се налага да ползвам временни имейли за работа. Най-вече като се тества email delivery etc.
Една от най-яките услуги, които ползвам, е guerrillamail.com. Имат множество домейни и всичко работи чудничко. Getnada.com също са яки. Честно, погледнете ги, спасяват животи.
Но понеже аз съм аз, от известно време имах желанието да се хвана да направя нещо подобно, селф-хостед. Мисля си “колко пък да е филм – дърпаш месиджи, триеш ги, като умрат”. Но с всеки подобен проект най-трудната част е визуализирането на решението, на workflow-а.
Дали правим нов адрес за всеки temporary mailbox? Едва ли. Сигурно има по-елегантен вариант. Може би един генерален адрес – catch-all – и в него папки за всеки временен? Да, но пък ти трябва филтър, за да попадат от временните адреси в папките. Зор – вдигаш и триеш филтри за всеки временен адрес. Не е това решението.
И после се сетих – че защо са ми папки? Правим catch-all, сендърът може да адресира писмото до който си пожелае адрес към домейна и и той ще попадне в кеч-ола. После е въпрос на дърпане на писма, адресирани то специфичен адрес (които са в същия бокс).
Ако стартираме сесийка и генерираме някакъв рендъм стринг (в моя случай – substr(md5(rand()),0,15) за 15-символна поща), и кажем на потребителя “Пращай писма до този адрес”, скриптът ни ще направи imap_search конкретно за този адрес. Тогава, след като получи масив с идентификаторите на писмата, пратени до този адрес, ще ги изплюе в даден формат. Реално не ги четем тези писма, така че прецених, че <pre>-нати изглеждат най-адекватно.
Дотук – детска работа; четеш imap reference @ PHP.net и пишеш сърч и плюене. Обаче, казвам си, не искам мейлбоксът да се пълни до полуда – трябва ни нещо за почистване. Първа идея – трием по подразбиране всички писма по-стари от един ден. Пак лесно – пускаме imap_search BEFORE today (форматиран d-m-Y). Ама можем и по-добре. Защо да не трием всички писма изпратени до пощата, използвана преди новата ни сесия? Обяснявам: ползваш нещото, сесията ти изтича след 30 минути. Стартираш нова сесия; защо да не затрием всички писма, които са ти пратени до старата сесия? Ами, преди да стартираме новата, взимаме идентификатора от старата, после пускаме imap_search TO Staroto_ID. Трият се.
Ще кажеш “да, ама ако някой просто не го ползва, ще останат писмата там”. Така е – докато не се изтрият от първото правило. А ако никой изобщо не ги ползва, най-адекватно е да имаш cron на сървъра, който да прави чистенето. А ако ли не – така или иначе слагаш един лимит на кутията. Десетина мегабайта са предостатъчни.
Приключвам само със контрол на сесиите. Хубаво е да се знае, че по подразбиране РНР не е супер адекватно в garbage collection на сесии. Всъщност, session.gc_maxlifetime е INI стойност за това колко време един сесиен файл е жив, но гербидж колектора се пуска на база вероятност. Тази верояност се определя както от още няколко константи, така и на база колко често се пускат рекуести до скрипта. Най-сигурно ни е да си напишем прост сешън контрол сами. В частност: взимаме сегашното време, проверяваме дали сесията носи променлива за живота си. Ако да и е по-малка от сегашното време, спираме сесията, ако не – даваме й променливата със стойност “сега” плюс еди-колко си.
Съвсем кратко сумиране на забавлението – ако искаме рендъм пощенски адреси за проба, тест, избягване на очевиден спам (бе най-често затова се рекламират), правим голяма кеч-ол кутия, казваме на потребителя как би следвало да адресира писмото, после вадим само тези писма, адресирани към това, което сме казали. Когато остареят или са ненужни, ги трием. Всичко това се побира в кажи-речи 50 реда РНР.