{"id":211,"date":"2017-05-13T00:38:09","date_gmt":"2017-05-13T04:38:09","guid":{"rendered":"http:\/\/unliterate.net\/?p=211"},"modified":"2017-05-13T00:40:03","modified_gmt":"2017-05-13T04:40:03","slug":"email-heick-email","status":"publish","type":"post","link":"https:\/\/www.unliterate.net\/index.php\/2017\/05\/13\/email-heick-email\/","title":{"rendered":"email.heick.email"},"content":{"rendered":"<h1>Yays!<\/h1>\n<p>Today i&#8217;ve done it. I&#8217;ve acquired my email dream!<\/p>\n<p>I&#8217;m talking about a nearly-automated @<em>heick.email<\/em><\/p>\n<h1>&#8230;to explain&#8230;<\/h1>\n<p>For years, if you ever wanted to send me an email I would say:<\/p>\n<blockquote><p>&#8220;Just put your name at the front of @unliterate.net, and i&#8217;ll get it.&#8221;<\/p><\/blockquote>\n<p>Ever since I setup my email @unliterate.net\u00a0<em>wrong<\/em> as a catch-all SPAM domain, I&#8217;ve had to deal with the following rigmarole when getting new email setup:<\/p>\n<ol>\n<li>Get the <span style=\"color: #ff6600;\">name<\/span>@unliterate.net figured out<\/li>\n<li>Setup a folder in\u00a0Thunderbird, my email client<\/li>\n<li>Setup a mail filter rule in my email client to move the received message from my Inbox to that folder<\/li>\n<\/ol>\n<p>Which things have been working for years, and it&#8217;s been a fairly straightforward approach.<\/p>\n<p>Until I got married, and we decided to get the\u00a0<em>heick.email<\/em> domain and have all our mail shared.<\/p>\n<h1>&#8230;how to share the email&#8230;<\/h1>\n<p>So, the @unliterate.net experiment utilized POP3 as the server for me to get all my catch-all. This was easy to configure, and was fairly straightforward.<\/p>\n<p>We needed to be able to share email across computers and devices, though, and still have the flexibility to do the &#8220;folder structure&#8221;-thingy that I&#8217;ve grown comfortable with the @unliterate.net &#8220;mail filter&#8221; rules.<\/p>\n<p>So, the only solution is to go from POP3 to IMAP.<\/p>\n<p>IMAP gives us the flexibility of folders on the\u00a0<em>server<\/em>, not on the client. It also stores all the mail there, and the protocol (after swallowing that it&#8217;s not like POP3) is actually quite orderly and simple.<\/p>\n<p>So, i&#8217;ve employed dovecot as my IMAP server, which was also my POP3 server, and configured it simply to enable IMAP and know where I want my users mailboxes to be stored.<\/p>\n<p>After setting up DNS for mail, i&#8217;ve got email coming into @heick.email, and I&#8217;m happy.<\/p>\n<p>I just need to be able to\u00a0<em>now<\/em> do the mail filtering&#8230;<\/p>\n<h1>How to automate folder-making for IMAP<\/h1>\n<p>This was a basic challenge, and I love challenges.<\/p>\n<p>I had to use my programming language of choice (PHP) with the php-imap module loaded, and fancy up a script that runs on a *\/1 (1 minute) cron task.<\/p>\n<p>The script is as follows:<\/p>\n<pre>&lt;?php\r\n\/**\r\n * The whole purpose of this script is to perform the following:\r\n * 1) Open an IMAP connection to an INBOX\r\n * 2) Look through all the messages\r\n * 3) Grab all messages and look for the first \"To: \" header in each message\r\n * 4) If the person in the \"To: \" is in the allowed domain\r\n * - We grab the user\r\n * - We check to see if their is a mailbox for that user, and move the messge there\r\n * - We delete the message\r\n * 5) If the person is not in the allowed domain\r\n * - We move the message to a default folder\r\n *\/\r\n\r\nfunction get_imap_folders($resource, $config)\r\n{\r\n \/\/ Get a list of mailboxes\r\n $original_folders = imap_listmailbox($resource, \"{\" . $config['server'] . \":\" . $config['port'] . \"}\", \"*\");\r\n \/\/ these come through as {server:port}mailbox, so we just clean them up a bit\r\n $new_folders = array();\r\n $to_remove = \"{\" . $config['server'] . \":\" . $config['port'] . \"}\";\r\n $folders = str_replace($to_remove, \"\", $original_folders);\r\n return $folders;\r\n}\r\n\r\n$config = array(\r\n 'server' =&gt; 'localhost',\r\n 'port' =&gt; '143',\r\n 'username' =&gt; 'redacted',\r\n 'password' =&gt; 'redacted',\r\n 'folder' =&gt; 'INBOX',\r\n 'spam' =&gt; 'SPAM',\r\n 'debug' =&gt; true,\r\n);\r\n$debug_message = \"\";\r\n\r\n$res = imap_open(\"{\" . $config['server'] . \":\" . $config['port'] . \"\/service=imap\/novalidate-cert\" . \"}\" . $config['folder'], $config['username'], $config['password']);\r\nif (!$res)\r\n{\r\n if ($config['debug'])\r\n {\r\n $debug_message = \"IMAP Stream Failure\";\r\n }\r\n die($debug_message);\r\n}\r\n\r\n$folders = get_imap_folders($res, $config);\r\n\r\n\/\/ Lets get all the mail messages in the $config['folder']\r\n$mbox = imap_check($res);\r\n$number_messages = $mbox-&gt;Nmsgs;\r\nif ($number_messages == 0)\r\n{\r\n if ($config['debug'])\r\n {\r\n $debug_message = \"No Messages\";\r\n }\r\n die($debug_message);\r\n}\r\n$range = \"1:\" . $number_messages;\r\n\r\n\/\/ now, we'll get the messages\r\n$messages = imap_fetch_overview($res, $range);\r\nforeach ($messages as $msg)\r\n{\r\n $msgno = $msg-&gt;msgno;\r\n $to = $msg-&gt;to;\r\n\r\necho \"Message: \" . $msg-&gt;subject . \"\\n\";\r\n if (strpos($to, \"@\"))\r\n {\r\n $array_to = explode(\"@\", $to);\r\n $to = $array_to[0];\r\n }\r\n\r\n\/\/ do we need to create a folder to move this message into?\r\n $destination_mbox = \"{\" . $config['server'] . \":\" . $config['port'] . \"}\" . $to;\r\n if (!in_array($to, $folders))\r\n {\r\n if (imap_createmailbox($res, $destination_mbox))\r\n {\r\n echo \"&gt; Created folder [$to]\\n\";\r\n }\r\n else\r\n {\r\n echo \"&gt; Failed to create folder [$to]\\n\";\r\n }\r\n\r\n}\r\n $folders = get_imap_folders($res, $config);\r\n if (imap_mail_move($res, $msgno, $to))\r\n {\r\n echo \"+ Moved successfully\\n\";\r\n }\r\n else\r\n {\r\n echo \"- Failed to move message\\n\";\r\n }\r\n}\r\nimap_expunge($res);\r\nimap_close($res);\r\n?&gt;<\/pre>\n<p>To explain, basically this access my IMAP server, gets all the folders, then gets all the mail. It goes though the &#8220;to:&#8221; portions of the email addresses and sees if I have a folder that matches what&#8217;s in the\u00a0<em>name<\/em> part of the email address in the &#8220;to:&#8221; portion. If it doesn&#8217;t exist, it makes the folder. Then, as a final result, it moves the mail to that folder and aborts.<\/p>\n<p>So, this script now runs every minute, checking for new mail, creating the folders necessary and moving the messages.<\/p>\n<p><strong><em>vivre heick.email!<\/em><\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Yays! Today i&#8217;ve done it. I&#8217;ve acquired my email dream! I&#8217;m talking about a nearly-automated @heick.email &#8230;to explain&#8230; For years, if you ever wanted to send me an email I would say: &#8220;Just put your name at the front of @unliterate.net, and i&#8217;ll get it.&#8221; Ever since I setup my email @unliterate.net\u00a0wrong as a catch-all [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[20,14,17],"tags":[],"class_list":["post-211","post","type-post","status-publish","format-standard","hentry","category-geek-instructions","category-goals","category-linux"],"_links":{"self":[{"href":"https:\/\/www.unliterate.net\/index.php\/wp-json\/wp\/v2\/posts\/211","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.unliterate.net\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.unliterate.net\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.unliterate.net\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.unliterate.net\/index.php\/wp-json\/wp\/v2\/comments?post=211"}],"version-history":[{"count":2,"href":"https:\/\/www.unliterate.net\/index.php\/wp-json\/wp\/v2\/posts\/211\/revisions"}],"predecessor-version":[{"id":213,"href":"https:\/\/www.unliterate.net\/index.php\/wp-json\/wp\/v2\/posts\/211\/revisions\/213"}],"wp:attachment":[{"href":"https:\/\/www.unliterate.net\/index.php\/wp-json\/wp\/v2\/media?parent=211"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.unliterate.net\/index.php\/wp-json\/wp\/v2\/categories?post=211"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.unliterate.net\/index.php\/wp-json\/wp\/v2\/tags?post=211"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}