Dear Fax Machines, Go Fax Yourself

I don't think I'm alone in my hatred for faxes, and I am 100% willing to be the face of the anti-faxxing movement.

The facsimile is a relic of a bygone era. It should have died a graceful death, and been given a respectful "thanks for your service, and farewell" a few hours after Tim Berners-Lee revved up the World Wide Web in 1989. By now you've probably already seen the meme:


But alas, here we are in the year 2021, still shoehorning faxes into the digital world.

The reason they're still around, I suppose, is their simplicity. Feed the paper into a hungry machine, out it spits somewhere else, hopefully to its intended recipient.* Unfortunately for U.S.-based Healthcare IT professionals, the Centers for Medicare & Medicaid Services have been permissive of faxing for the transmission of protected health information. I, uh, have a bone to pick with this generally-accepted standard operating procedure, but I don't have the political power to persuade CMS that faxing is bad, actually.
*no guarantees

But I digress. How am I actually dealing with the reality that faxing is going to continue to exist for the foreseeable future? Glad you asked. You'll never believe this, but I used Python to solve a problem. But first, some background.

One of my first big projects I endeavored upon as the head of the IT department at my present place of employment was to replace an old and disgustingly feature-poor analog Nortel telephone system with a modern PBX. I considered three main options when I conducted the search - Mitel, ShoreTel, and Digium Switchvox (now Sangoma). Each had their benefits and drawbacks, and of course I had a soft spot for the one with open source roots. I assembled a focus-group of phone superusers and they sat in on demos for each. The group collectively decided they liked Switchvox the best. Yay, it was the least expensive, and most open-sourcey solution!

The implementation was not without its hiccups and late nights, but all-in-all, when the PBX was in place, Switchvox was and continues to be a great solution. One of the features it boasts is the ability for any extension to receive an inbound fax, but it's an all-or-nothing proposition when you enable fax detection on, say, a T1 line. This meant that analog station port lines on the system (FXS) would, instead of allowing a fax machine connected to the analog port to accept an inbound fax, get ingested by the Switchvox. This is the antithesis of the benefits of faxing, which is simplicity. Nevertheless, users overwhelmingly wanted the feature turned on so they could easily receive faxes to their own extensions, effectively enabling fax-to-email.

After turning on the fax detection, I had to come up with a solution for the 8-10 fax stations in the facility which were not on separate POTS lines. What I ended up doing was forwarding all the faxes to these numbers to a single Exchange mailbox, and running Outlook on a Windows 7 server utilizing inbox rules to download each fax PDF to a folder based on where it needed to be printed, and utilizing a paid 3rd party program called Autoprint to direct each file to a printer.

Convoluted? Yes! Did it work? Also yes! Except for when the machine was updated and/or rebooted and wasn't logged in as the requisite user and/or maybe Outlook wasn't running or Exchange had rebooted. Other than that, a perfect solution 😒! When it came time to sunset the Windows 7 box I insisted upon implementing something better, and more manageable. Sure, there are third-party solutions, and I even entertained a couple of them by fielding their unsolicited phone calls. In the end those seemed cost prohibitive and pointless, and by giving money to any of these cottage-industry fax solution peddlers I felt like I would be aiding and abetting the horror-show that is the FAXING INDUSTRIAL COMPLEX.

Each extension on a Switchvox PBX has an IMAP-enabled inbox for inbound faxes and voicemails, which can be accessed programmatically or through any email client. I decided to harness some of the Python knowledge I had accumulated to write my own app to handle inbound faxes.

I can't easily share the code since it lives in a private GitLab repo, but the program isn't overly complex. As usual, my development consists of standing on the shoulders of giants and piecing bits of code together like a puzzle to make it do what I want. Then I come up with a super-clever name. Fax_Processor's job is to process an email inbox and do a thing. In addition to sending a PDF to a printer via python's wrapper for CUPS, it can upload an inbound fax to our internal NextCloud instance or drop it in a CIFS shared folder. In some cases, it will pre-process the document into a TIFF and remove a cover sheet so it can be ingested into our electronic medical record system. The app utilizes Python's built-in imaplib to process the mailboxes (although I later discovered imbox, which would have made the code a bit cleaner), cups, and pyocclient. I can run this thing unattended via supervisor on Ubuntu Server without any worries about whether or not it is logged in and Outlook is running.

I can't help but wonder when I see someone thoughtlessly plug in a fax number and feed a document through a machine how convoluted the handling of it is on the other side. The solution I came up with and deployed works, and I'm actually sort of proud of it, but the inescapable fact remains: faxing is horrible and it should not continue to exist. Please do your part and sign the petition to abolish the fax.

Comments