options.subscribe = true options.keepalive = 10 options.expunge = true options.info = false options.certificates = false -- Global variables accounts = {} accounts_fetched = 0 fetch_accounts_every = 3600 filter_every = 30 MONTHS={Jan=1,Feb=2,Mar=3,Apr=4,May=5,Jun=6,Jul=7,Aug=8,Sep=9,Oct=10,Nov=11,Dec=12} DATE_FORMAT = "(%d+)-(%a+)-(%d+) (%d+):(%d+):(%d+)" -- Split string function split(str, delim) local result,pat,lastPos = {},"(.-)" .. delim .. "()",1 for part, pos in string.gmatch(str, pat) do table.insert(result, part); lastPos = pos end table.insert(result, string.sub(str, lastPos)) return result end -- Table size function size(tbl) tbl_length = 0 for k, v in ipairs(tbl) do tbl_length = tbl_length + 1 end return tbl_length end -- Move to Gmail Trash with logging function move_to_trash(imap, messages) for _, msg in ipairs(messages) do mbox, uid = table.unpack(msg) print('IMAPFilter ' .. mbox[uid]:fetch_field('From') .. ' ' .. mbox[uid]:fetch_field('To') .. ' ' .. mbox[uid]:fetch_field('Subject') .. ' ' .. mbox[uid]:fetch_date()) end messages:move_messages(imap['[Gmail]/Trash']) end -- IMAP Date string to seconds before now function seconds_old(date_string) local day, mon, year, hour, min, sec = date_string:match(DATE_FORMAT) local time_stamp = os.time({day=day,month=MONTHS[mon],year=year,hour=hour,min=min,sec=sec}) return os.difftime(os.time(), time_stamp) end function fetch_accounts() mysql_command = 'mysql -BNe "select SERVERNAME, smtp_port, mailusername, mailpassword from mailserver where protocol like \'imap%\'"' status, output = pipe_from(mysql_command) accounts = {} for _, account in ipairs(split(output, "\n")) do local _, _, server, port, username, password = string.find(account, '([^%s]+)[%s]+([^%s]+)[%s]+([^%s]+)[%s]+([^%s]+)') if server and port and username and password then local imap = IMAP { server = server, port = tonumber(port), username = username, password = password, ssl = 'tls1.2' } -- Get a list of the available mailboxes and folders local mailboxes, folders = imap:list_all() table.insert(accounts, imap) end end end -- Filters function filter(imap) imap.INBOX:check_status() results = imap.INBOX:select_all() -- * for AND, + for OR, - for NOT, () to group -- Google Calendar Invites calendar_notifications = ( results:contain_from("calendar-notification@google.com") + results:contain_field("Sender", "calendar-notification@google.com") ) if size(calendar_notifications) > 0 then print('IMAPFilter Deleting Google Calendar Invites') move_to_trash(imap, calendar_notifications) end -- Too Old too_old = ( results:is_older(5) ) if size(too_old) > 0 then print('IMAPFilter Deleting Too Old') move_to_trash(imap, too_old) end -- Mailer Daemon mailer_daemon = ( results:contain_from("mailer-daemon@.*") + results:contain_field("Sender", "mailer-daemon@.*") ) if size(mailer_daemon) > 0 then print('IMAPFilter Deleting Mailer Daemon Emails') move_to_trash(imap, mailer_daemon) end -- JIRA Trouble Parsing seen_msgs = ( results:is_seen() ) jira_unable_to_parse = Set {} if size(seen_msgs) > 0 then for _, msg in ipairs(seen_msgs) do mbox, uid = table.unpack(msg) if seconds_old(mbox[uid]:fetch_date()) > 900 then table.insert(jira_unable_to_parse, msg) end end end if size(jira_unable_to_parse) > 0 then print('IMAPFilter Deleting Mail JIRA Cannot Parse') move_to_trash(imap, jira_unable_to_parse) end -- done end function main() print("IMAPFilter Running at " .. os.date("%Y-%m-%d %H:%M:%S")) -- Fetch accounts once per hour from MySQL if os.time() - accounts_fetched > fetch_accounts_every then fetch_accounts() end -- Loop through all accounts and run filtering on them for _, imap in ipairs(accounts) do filter(imap) end -- print('---------') end -- Two methods for running in loop -- Only uncomment one at a time -- become_daemon forks into background and calls a function every x seconds -- become_daemon(filter_every, main) -- While true loop runs in forground -- while true do -- main() -- Lua has no built in sleep function -- os.execute('sleep ' .. filter_every) -- end -- Run once and exit main()