{"id":475,"date":"2012-07-09T01:43:32","date_gmt":"2012-07-08T23:43:32","guid":{"rendered":"https:\/\/www.npcglib.org\/~stathis\/blog\/?p=475"},"modified":"2013-09-18T04:58:04","modified_gmt":"2013-09-18T02:58:04","slug":"linux-task-sorting-mail-with-imapfilter","status":"publish","type":"post","link":"https:\/\/www.npcglib.org\/~stathis\/blog\/2012\/07\/09\/linux-task-sorting-mail-with-imapfilter\/","title":{"rendered":"linux task: sorting mail with imapfilter"},"content":{"rendered":"<p>Marking the 10th birthday of my e-mail server I decided it is time to share with the world my simple solution to sorting the massive amounts of incoming mail, including spam. Over the years I have accumulated a good number of different email accounts that are difficult to track, thus I have setup a central IMAP server where I fetch all mail into and read exclusively what I choose to. I use several methods to fetch and sort mail, but maybe the most useful utility for sorting mail is <a href=\"https:\/\/github.com\/lefcha\/imapfilter\" title=\"imapfilter\" target=\"_blank\">imapfilter<\/a>. imapfilter is written in <a href=\"http:\/\/www.lua.org\/\" title=\"Lua Programming Language\" target=\"_blank\">Lua<\/a> and relies on configuration files written in Lua to process emails. I&#8217;m not a Lua expert, but I managed to setup a simple and scalable method for filtering my mail.<\/p>\n<p>I use three types of filter tables that I can add filters to as I see it fit:<\/p>\n<ol>\n<li><strong>pre_filters<\/strong>: filters applied before any other sorting rules. These rules are great for getting rid of abusive mail, spam, or ban any hosts from filling your mailbox.<\/li>\n<li><strong>filters<\/strong>: filters that do the bulk of message processing and sorting.<\/li>\n<li><strong>post_filters<\/strong>: filters applied after all message processing has been completed. This is useful if for instance you decide to get rid of any messages that are marked as spam, but they were not sorted due to any of the previous rules (so they are most likely spam). This also allows you to place messages that matched no rules to special folders, etc.<\/li>\n<\/ol>\n<p>Filter tables are simple Lua tables, of which every filter is another table that contains the details of that particular filter:<\/p>\n<pre>\r\nfilter_table_name = {\r\n  { filter1 },\r\n  { filter2 },\r\n}\r\n<\/pre>\n<p>Individual filters are tables with index keys (<em>header<\/em>, <em>p<\/em> and <em>moveto<\/em>):<\/p>\n<pre>\r\nfilter_table_name = {\r\n  { <em>header<\/em> = \"Header_String\" , <em>p<\/em> = \"Pattern_String\", <em>moveto<\/em> = account['folder'] },\r\n  { <em>header<\/em> = \"Other_Header_String\" , <em>p<\/em> = \"Other_Pattern_String\", <em>moveto<\/em> = account['folder'] },\r\n}\r\n<\/pre>\n<p>In the order they appear, filters are applied on a table of email messages, e.g. those messages present in the INBOX of an IMAP account. To apply these filters, I wrote a very simple Lua function (see below <em>parseRules<\/em>) that takes a table of email messages and a table of filters to apply to them. Bear in mind, that to avoid losing any email, I typically just sort unwanted email in the Trash or a Junk folder that I clean up later, either manually or at certain intervals with imapfilter functionality (not shown here).<\/p>\n<p>Putting altogether in an imapfilter configuration file (e.g. ~\/.imapfilter\/config.lua) it should look similar to the following:<\/p>\n<pre>\r\n----------------------\r\n--  Global Options  --\r\n----------------------\r\n\r\noptions.timeout = 120\r\noptions.subscribe = true\r\n\r\n----------------\r\n--  Accounts  --\r\n----------------\r\n-- For every account create an account entry and check() its status\r\n\r\nacc1 = IMAP {\r\n        server = 'collector.server.com',\r\n        username = 'stathis-user',\r\n        password = 'secret',\r\n        ssl = 'ssl3',\r\n}\r\n\r\nacc1.INBOX:check_status()\r\n\r\n----------------\r\n\r\nacc2 = IMAP {\r\n        server = 'imap.gmail.com',\r\n        username = 'stathis-user',\r\n        password = 'secret',\r\n        ssl = 'ssl3',\r\n}\r\n\r\nacc2.INBOX:check_status()\r\n\r\n----------------\r\n\r\nacc3 = IMAP {\r\n        server = 'imap.work.com',\r\n        username = 'stathis-user',\r\n        password = 'secret',\r\n        ssl = 'ssl3',\r\n}\r\n\r\nacc3.INBOX:check_status()\r\n\r\n----------------\r\n\r\n-- select all messages from all INBOXes and construct a single table of messages\r\nresults = acc1.INBOX:select_all() + acc2.INBOX:select_all() + acc3.INBOX:select_all()\r\n\r\n-----------------\r\n--  Functions  --\r\n-----------------\r\n-- parseRules is used to filter message results using a table of rules (see below)\r\n\r\n-- @param res         the table of messages to filter\r\n-- @param ruleTable   the table of rules to match messages against\r\nparseRules = function ( res, ruleTable )\r\nlocal subresults = {}\r\n  for _,entry in pairs(ruleTable) do\r\n    -- don't use match_field, it downloads part of the msg (slow)\r\n    subresults = res:contain_field(entry[\"header\"], entry[\"p\"])\r\n    if subresults:move_messages( entry[\"moveto\"] ) == false then\r\n      print(\"Cannot move messages!\")\r\n    end\r\n  end\r\nend\r\n\r\n---------------\r\n--  Filters  --\r\n---------------\r\n\r\npre_filters = {\r\n  -- Banned IPs typically sending me spam\r\n  { header = \"Received\" , p = \"85.31.186.26\", moveto = acc1['Trash'] },\r\n  { header = \"Received\" , p = \"176.251.35.146\", moveto = acc1['Trash'] },\r\n}\r\n\r\nfilters = {\r\n  \r\n  -- Google Alerts\r\n  { header = \"From\", p = \"googlealerts@google.com\", moveto = acc1['Misc\/Google_Alerts'] },\r\n  \r\n  -- Intel\r\n  { header = \"From\", p = \"isd@intel-dispatch.com\", moveto = acc1['Misc\/Intel'] },\r\n  { header = \"From\", p = \"@softwaredispatch.intel.com\", moveto = acc1['Misc\/Intel'] },\r\n  { header = \"From\", p = \"@software-dispatch.intel.com\", moveto = acc1['Misc\/Intel'] },\r\n  \r\n  -- Boost\r\n  { header = \"Sender\", p = \"@lists.boost.org\", moveto = acc1['Mailing_Lists\/Boost'] },\r\n  { header = \"To\", p = \"users@lists.boost.org\", moveto = acc1['Mailing_Lists\/Boost'] },\r\n  \r\n  -- OpenCV\r\n  { header = \"Subject\", p = \"[OpenCV]\", moveto = acc1['Mailing_Lists\/OpenCV'] },\r\n  { header = \"Subject\", p = \"[OpenCV - Bug #\", moveto = acc1['Misc\/Bugs\/OpenCV'] },\r\n  \r\n}\r\n\r\npost_filters = {\r\n  \r\n  -- Any remaining mail having in the subject SPAM? goes in Junk\r\n  { header = \"Subject\" , p = \"[SPAM?] \", moveto = acc1['Junk'] },\r\n  \r\n}\r\n\r\n---------------------\r\n--  Parse messages --\r\n---------------------\r\n\r\n-- pre filter messages\r\nparseRules(results, pre_filters)\r\n\r\n-- sort messages\r\nparseRules(results, filters)\r\n\r\n-- post filter messages\r\nparseRules(results, post_filters)\r\n\r\n----------------\r\n<\/pre>\n<hr\/>\n<h3>Software used<\/h3>\n<ul>\n<li><a href=\"https:\/\/github.com\/lefcha\/imapfilter\" title=\"imapfilter\" target=\"_blank\">imapfilter<\/a> [v2.5.2]<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Marking the 10th birthday of my e-mail server I decided it is time to share with the world my simple solution to sorting the massive amounts of incoming mail, including spam. Over the years I have accumulated a good number of different email accounts that are difficult to track, thus I have setup a central [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[5],"tags":[26,24,23,25],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v17.9 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<meta name=\"description\" content=\"Find here a working code example for advanced filtering with imapfilter.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.npcglib.org\/~stathis\/blog\/2012\/07\/09\/linux-task-sorting-mail-with-imapfilter\/\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"stathis\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.npcglib.org\/~stathis\/blog\/#website\",\"url\":\"https:\/\/www.npcglib.org\/~stathis\/blog\/\",\"name\":\"sigmoid\",\"description\":\"..oo..oo..oo..oo..oo..oo..\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.npcglib.org\/~stathis\/blog\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.npcglib.org\/~stathis\/blog\/2012\/07\/09\/linux-task-sorting-mail-with-imapfilter\/#webpage\",\"url\":\"https:\/\/www.npcglib.org\/~stathis\/blog\/2012\/07\/09\/linux-task-sorting-mail-with-imapfilter\/\",\"name\":\"linux task: sorting mail with imapfilter - sigmoid\",\"isPartOf\":{\"@id\":\"https:\/\/www.npcglib.org\/~stathis\/blog\/#website\"},\"datePublished\":\"2012-07-08T23:43:32+00:00\",\"dateModified\":\"2013-09-18T02:58:04+00:00\",\"author\":{\"@id\":\"https:\/\/www.npcglib.org\/~stathis\/blog\/#\/schema\/person\/508363c4ebd1fd6066edf00c94e37e41\"},\"description\":\"Find here a working code example for advanced filtering with imapfilter.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.npcglib.org\/~stathis\/blog\/2012\/07\/09\/linux-task-sorting-mail-with-imapfilter\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.npcglib.org\/~stathis\/blog\/2012\/07\/09\/linux-task-sorting-mail-with-imapfilter\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.npcglib.org\/~stathis\/blog\/2012\/07\/09\/linux-task-sorting-mail-with-imapfilter\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.npcglib.org\/~stathis\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"linux task: sorting mail with imapfilter\"}]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.npcglib.org\/~stathis\/blog\/#\/schema\/person\/508363c4ebd1fd6066edf00c94e37e41\",\"name\":\"stathis\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\/\/www.npcglib.org\/~stathis\/blog\/#personlogo\",\"inLanguage\":\"en-US\",\"url\":\"http:\/\/2.gravatar.com\/avatar\/214f29f604ec7d8d2f1345c5fa617c09?s=96&d=mm&r=g\",\"contentUrl\":\"http:\/\/2.gravatar.com\/avatar\/214f29f604ec7d8d2f1345c5fa617c09?s=96&d=mm&r=g\",\"caption\":\"stathis\"},\"url\":\"https:\/\/www.npcglib.org\/~stathis\/blog\/author\/stathis\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"description":"Find here a working code example for advanced filtering with imapfilter.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.npcglib.org\/~stathis\/blog\/2012\/07\/09\/linux-task-sorting-mail-with-imapfilter\/","twitter_misc":{"Written by":"stathis","Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebSite","@id":"https:\/\/www.npcglib.org\/~stathis\/blog\/#website","url":"https:\/\/www.npcglib.org\/~stathis\/blog\/","name":"sigmoid","description":"..oo..oo..oo..oo..oo..oo..","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.npcglib.org\/~stathis\/blog\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.npcglib.org\/~stathis\/blog\/2012\/07\/09\/linux-task-sorting-mail-with-imapfilter\/#webpage","url":"https:\/\/www.npcglib.org\/~stathis\/blog\/2012\/07\/09\/linux-task-sorting-mail-with-imapfilter\/","name":"linux task: sorting mail with imapfilter - sigmoid","isPartOf":{"@id":"https:\/\/www.npcglib.org\/~stathis\/blog\/#website"},"datePublished":"2012-07-08T23:43:32+00:00","dateModified":"2013-09-18T02:58:04+00:00","author":{"@id":"https:\/\/www.npcglib.org\/~stathis\/blog\/#\/schema\/person\/508363c4ebd1fd6066edf00c94e37e41"},"description":"Find here a working code example for advanced filtering with imapfilter.","breadcrumb":{"@id":"https:\/\/www.npcglib.org\/~stathis\/blog\/2012\/07\/09\/linux-task-sorting-mail-with-imapfilter\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.npcglib.org\/~stathis\/blog\/2012\/07\/09\/linux-task-sorting-mail-with-imapfilter\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.npcglib.org\/~stathis\/blog\/2012\/07\/09\/linux-task-sorting-mail-with-imapfilter\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.npcglib.org\/~stathis\/blog\/"},{"@type":"ListItem","position":2,"name":"linux task: sorting mail with imapfilter"}]},{"@type":"Person","@id":"https:\/\/www.npcglib.org\/~stathis\/blog\/#\/schema\/person\/508363c4ebd1fd6066edf00c94e37e41","name":"stathis","image":{"@type":"ImageObject","@id":"https:\/\/www.npcglib.org\/~stathis\/blog\/#personlogo","inLanguage":"en-US","url":"http:\/\/2.gravatar.com\/avatar\/214f29f604ec7d8d2f1345c5fa617c09?s=96&d=mm&r=g","contentUrl":"http:\/\/2.gravatar.com\/avatar\/214f29f604ec7d8d2f1345c5fa617c09?s=96&d=mm&r=g","caption":"stathis"},"url":"https:\/\/www.npcglib.org\/~stathis\/blog\/author\/stathis\/"}]}},"_links":{"self":[{"href":"https:\/\/www.npcglib.org\/~stathis\/blog\/wp-json\/wp\/v2\/posts\/475"}],"collection":[{"href":"https:\/\/www.npcglib.org\/~stathis\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.npcglib.org\/~stathis\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.npcglib.org\/~stathis\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.npcglib.org\/~stathis\/blog\/wp-json\/wp\/v2\/comments?post=475"}],"version-history":[{"count":22,"href":"https:\/\/www.npcglib.org\/~stathis\/blog\/wp-json\/wp\/v2\/posts\/475\/revisions"}],"predecessor-version":[{"id":904,"href":"https:\/\/www.npcglib.org\/~stathis\/blog\/wp-json\/wp\/v2\/posts\/475\/revisions\/904"}],"wp:attachment":[{"href":"https:\/\/www.npcglib.org\/~stathis\/blog\/wp-json\/wp\/v2\/media?parent=475"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.npcglib.org\/~stathis\/blog\/wp-json\/wp\/v2\/categories?post=475"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.npcglib.org\/~stathis\/blog\/wp-json\/wp\/v2\/tags?post=475"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}