Automatic one-click prescription faxing from within OpenEMR

This might be better placed in a “How I do it…” wiki but my hope would be that one of the developer’s might take an interest in it and incorporate it in a more seamless fashion into the basic program. I have no particular need to do so, however, as it works quite well for me already.

Goals: Easy one-button faxing of prescriptions for little or no cost using mostly existing equipment. No need to prescribe Schedule II controlled medications. Additional goals include the auto-filling of default drug quantities, instructions, refills and permission (or lack thereof) to substitute generics (in an over-writable fashion) as well as a “label in Spanish” option (which could be changed to any other language but is handy where I practice). In short, this should work well on an iPad, with most of the work being done simply by clicking on buttons and checkboxes and relatively little need to enter text, which I find to be error-prone inconvenient and time-consuming.

Basic Scheme: Outgoing prescriptions are saved as *.tex files in a newly-created specified folder (interface/faxrx/rx). The folder is watched by the inotifywait program and when a new such file is created or moved to the folder the text contained within it is used to automatically create a pdf file, which is then faxed to the patient’s default pharmacy. The pdf file is then deleted (to save space) and the text file used to create it is saved in the new sites/default/documents/prescriptions folder, where it is stored and can subsequently be reviewed and/or used to manually reprint a pdf file if needed.

Basics: I am running Ubuntu 20.04.2 Server set up as documented next. For anybody who cares, my basic packages installed at setup include mariadb-server libdbd-mariadb-perl libdate-calc-perl libtiff-tools libwww-mechanize-perl libxml-parser-perl php7.4 php7.4-cli php7.4-gd php7.4-curl php7.4-soap php7.4-json php7.4-mbstring php7.4-zip php7.4-xml php7.4-mysql apache2-doc curl imagemagick zip apache2 net-tools and samba. Not all of these are relevant to faxrx. Everything is set up through a command line interface. It’s not difficult but you do have to pay attention to what you’re doing. I use an old fax modem (Zoom 2949C V.90 External Serial Dialup Fax Modem Series 0269) hooked to the OpenEMR server (which doesn’t have a serial port) through a USB-Serial dongle. I just saw a similar modem on eBay for around $20. The dongle was less than that. Instructions for setting these up can be found on the internet. Finally, I run an instance of Hylafax on that same server. I’m reasonably certain this could be set up on any Linux server and probably on a Mac server. Somebody else will have to figure out how to do it on a Windows server.

Prerequisites (system modifications):

  • A server running OpenEMR (obviously).

  • In addition, install hylafax, inotify-tools, rubber, texlive-latex-extra and texlive-latex_recommended on server.

      $ sudo apt install hylafax-server hylafax-client 

    Faxrx will require an installed faxmodem. Select “No Configuration” for Postfix mail cofiguration options. Otherwise accept defaults. This approach uses the sendfax program (part of hylafax) to send the faxes. If you can’t send a test fax manually by using sendfax then none of this will work. My advice: get sendfax working before you mess with the rest. I refer you to Google for how to do this.

      $ sudo apt install inotify-tools 

    Set to watch for newly-created formatted text (*.tex) files in specified folder.

      $ sudo apt install rubber 

    Not entirely certain this is necessary however it is referenced in the file so failing to install it would require editing that file. Initially installed to prevent warnings caused by the insertion of graphics into the pdf file. In my case these were mostly due to using a graphic logo on my letterhead, although they might have been caused by the signature graphic as well. Warnings were generated the first time faxing was attempted although it worked well thereafter. With rubber installed it works well all the time.

      $ sudo apt install texlive-base texlive-latex-recommended 

    Installs pdflatex along with required packages (setspace).

  • Download the files attached below. From within the download directory on your system, the following file needs to be copied or moved into the /usr/local/bin directory. On my system it is given to owner www-data (the webwerver user) and group sudo, with permissions set at 775. This is a shell script that will be run automatically at reboot, starting inotify tasking it to monitor the interface/faxrx/ folder for the appearance of new .tex files. After moving the file you should edit it, substituting in your own office name and wrong number instructions as desired and uncommenting the proper line that pertains to your need or lack of need for a dial-out number to be prefixed to the pharmacy fax number. You may wish to remark out the sendfax line and/or the “rm *.pdf” line for testing purposes.

    $ sudo mv /usr/local/bin-> /usr/local/bin/
    $ sudo chown www-data:sudo /usr/local/bin/
    $ sudo chmod 775 /usr/local/bin/
  • Set crontab to run /usr/local/bin/ as web-user (www-data) on reboot.

    $ sudo nano /etc/crontab

    Add the following line to the bottom of the file:

    @reboot	    www-data /usr/local/bin/

    For the record, that’s five spaces after @reboot, not a tab.

    Can check that running after reboot with the following:

    $ ps -ax | grep faxrx

    but it won’t actually work until the interface/faxrx/rx directory is created. NB: Must reboot the server after editing this file for it to take effect!

  • Modify /etc/sudoers file to allow WEBSERVER_USERS group to send faxes without a password. Apparently, you must use the visudo command rather than nano.

    $ sudo visudo

    Ensure that the following lines exist. Ultimately, the files should look like the attached sudoers file.

    	# User alias specification
    	User_Alias WEBSERVER_USERS = www-data
    	# Cmnd alias specification
    	Cmnd_alias FAX_CMDS = /usr/bin/sendfax
    	# User privilege specification
    	root ALL=(ALL:ALL) ALL
    	# Members of the admin group may gain root privileges
    	%admin ALL=(ALL) ALL
    	# Allow members of group sudo to execute any command
    	%sudo ALL=(ALL:ALL) ALL
    	# Allow everybody to print fax without a password

    After you’ve confirmed that everything works the last two lines can be replaced with the following (if you’re paranoid).

    	# Allow WEBSERVER_USER to print fax without a password
    	www-data ALL=(ALL) NOPASSWD: FAX_CMDS
  • Each patient for whom you wish to fax a prescription must have a default preferred pharmacy entered (Dashboard>Demographics>Choices).

  • Furthermore, each likely pharmacy must be entered with a functional fax number including area code (Administration>Practice>Practice Settings>Pharmacies).

OpenEMR file/folder modifcations:

  • interface/faxrx/rx directory

      $ sudo mkdir -p /var/www/html/openemr/interface/faxrx/rx
      $ sudo chown <user>:<group> /var/www/html/openemr/interface/faxrx # Where <user> and <group> are like all the other folders in this directory. In 
      	my case that is david:sudo.
      $ sudo chown <webserver_user>:sudo /var/www/html/openemr/interface/faxrx/rx # For Ubuntu, <webserver_user is www-data
      $ sudo chmod 755 /var/www/html/openemr/interface/faxrx/rx
  • sites/default/documents/prescriptions directory

      $ sudo mkdir /var/www/html/openemr/sites/default/documents/prescriptions
      $ sudo chown www-data:www-data /var/www/html/openemr/sites/default/documents/prescriptions
      $ sudo chmod 755 /var/www/html/openemr/sites/default/documents/prescriptions
  • src/Rx/Faxrx directory

      $ sudo mkdir -p /var/www/html/openemr/src/Rx/Faxrx
      $ sudo chown -R <user>:sudo /var/www/html/openemr/src/Rx #where user is as defined above
      $ sudo chmod -R 755 /var/www/html/openemr/src/Rx
  • The following attached and downloaded files can be over-written into the noted folders in your installation. Alternatively, you can edit your own existing files to reflect similar changes. I would recommend completely over-writing on a test system first to see if this could work for you. The files should be attached below.

      C_Prescription.class.php <user>:sudo 644 -> openemr/controllers 
      	(may need to make edits if your system does/doesn't need a dialout 
      	number (i.e., "9", "91") and/or if you don't have the US standard 3-
      	digit area code followed by a 7-digit phone number)
      sig_<login_name>.png <user>:sudo 644 -> sites/default/images 
      	(replace <login_name> with the OpenEMR user's login name, this is just 
      	a sample "John Henry", in the end you'll have to create your own)
      Rx.png <user>:sudo 644 -> openemr/sites/default/images 
      	(if replacing this with your office letterhead you will then have to 
      	edit the reference to it in C_Prescription.class.php as well)
      TransmitData.php <user>:sudo 644 -> openemr/src/Faxrx/Rx 
      	(various utility functions patterned after previous version 
      	src/Rx/Weno/TransmitData.php file - thank you, Sherwin Gaddis)
      edit_faxrx_drug.php <user>:sudo 644 -> openemr/interface/faxrx 
      	(provides administrators with ability to edit drug list, accessed 
      	through Administration>Practice>Faxrx)
      faxrx_drugs.sql <user>:sudo 644 -> openemr/interface/faxrx 
      	(creates faxrx_drugs table and fills it with sample medications)
      standard.json <user>:sudo 644 -> openemr/interface/main/tabs/menu/menus 
      	(adds administrative menu item for editing faxrx drugs) There may or 
      	may not be some references to some of my other customizations in here. 
      	Clicking on them won't hurt but it won't work either.
      completeRx.php <user>:sudo 644 -> openemr/library/ajax/drug_autocomplete 
      	(completes fields with default values after selection of drug)
      search.php <user>:sudo 644 -> openemr/library/ajax/drug_autocomplete 
      	(interfaces with faxrx_drugs table)
      Prescription.class.php <user>:sudo 644 -> openemr/library/classes 
      	(adds "label in spanish" capability to prescriptions, if you'd prefer 
      	another language search all these files for the word "spanish" and 
      	replaced it with your choice)
      general_edit.html <user>:sudo 644 -> openemr/templates/prescription 
      	(allows auto-completion of rx fields, changed format of form to 
      	compress it vertically so it fits on one iPad screen and doesn't have 
      	to be scrolled)
      general_list.html <user>:sudo 644 -> openemr/templates/prescription 
      	(allows visualization of "faxrx" button, pharmacy and general 
      	functionality, slight changes to format so it fits on one iPad screen)
    <user>:sudo 644 -> openemr/library 
      	(creates "enable faxrx" administrative checkbox in
      faxrx_drugs.sql -> openemr/interface/faxrx 
      	**Run from the mysql/mariadb prompt** ("mysql> SOURCE 
      	faxrx_drugs.sql"), this will prepopulate the table with a few hundred 
      	standard medications, may of which have default values entered 
      	already. If you don't like these meds you can truncate the table (run 
      	"TRUNCATE faxrx_drugs" from the database prompt after installing) and 
      	then add in your own as an administrative user from the 
      	Administration>Practice>Faxrx page.
     (this file) -> openemr/Documentation 
      	(Who knows? You may at some point again need these instructions.)

Other requirements:

  • Must add “spanish” boolean to prescriptions table.

      mysql> ALTER TABLE prescriptions ADD COLUMN spanish BOOLEAN DEFAULT 0;
  • Must enable “simplified prescriptions” (at bottom of Administration>Globals>Appearance)

Other changes:

  • Possibly modify access levels for sites/default/documents/prescriptions in /etc/apache2/sites-enabled/default-ssl.conf to mirror those of documents, edi and era then restart apache ($ systemctl restart apache2). Note: I haven’t done this. I’m not sure about the security implications one way or other other.


  • Reboot your server (Why not? It usually works for me!)

Other Issues:

  • I don’t know as much as I should about security, but the functionality doesn’t appear to show up for non-physician and non-administrative users, which is good unless you want your staff to fax in prescriptions on your behalf. Also, as written only the logged on user has their presumably present and appropriately-named signature file (sig_.pdf) applied to the prescription. No such file == no signature on prescription. If you want your staff to be able to send a prescription under the original prescriber’s name and signature this could be effected by hardcoding the original prescriber’s information in controllers/C_Prescription.class.php.


  • I’d suggest setting up a dummy pharmacy with a fax number that you control for testing purposes and then creating a test patient who defaults to this pharmacy. There’s no sense in bothering others unnecessarily.


  • This has worked very well for me. I hope you can get it to work for you. (12.6 KB) C_Prescription.class.php (47.4 KB) sudoers (919 Bytes) general_list.html (16.1 KB) general_edit.html (13.9 KB) (143.4 KB) Prescription.class.php (22.9 KB) search.php (1.1 KB) completeRx.php (884 Bytes) TransmitData.php (3.2 KB) edit_faxrx_drug.php (13.4 KB) standard.json (54.8 KB) sig_.pdf|attachment (10.9 KB) Rx faxrx_drugs.sql (27.3 KB) (2.1 KB)


I’ve been using this (or at least variants of it) for a few years very successfully. Unfortunately, it has now been somewhat deprecated, at least in those jurisdictions (such as California, which does not consider a fax to be an electronic transmission) now requiring the electronic transmission of all prescriptions. Very sad, in my opinion, as several large-chain pharmacies now appear to be illegally blocking the transmission of electronic prescriptions not coming through Surescripts. Anyhow, feel free to use this if it still works for you and/or adapt it for other purposes.


Would be nice to offer this as an optional addon for those free from clutches of eRx oligopoly.

From a broader perspective, the approach should be extended to all scripts. Until electronic exchanges become norm faxes are here to stay.

@Mouse55 is it possible to merge this code into a module?

Hmm. I’ve been absent from the forum for a while. I might look into this at some point but for right now I’ve got too many other things on my plate.