Hack91.Build an Inbound Fax-to-Email Gateway

Hack 91. Build an Inbound Fax-to-Email Gateway

Once you start faxing with your Linux box, why stop there? This hack shows you how to route faxes automatically into emails and PDF files.

In the previous hack, you built a configuration to direct all incoming faxes from Zaptel channels to a file, which, in turn, you could automatically print. But, if the server were working on behalf of many possible fax recipients, you would have to rely on the incoming fax's cover sheet to know which recipient it's destined for. Worse still, someone would have to go to the printer, pick up the fax, and hand-deliver it to the correct person.

There's a better way, of course: email. It's just as easy to email that TIFF file to somebody's inbox as it is to print it. Here is a dialing plan that will do just that:

 exten => fax,1,SetVar(TIFFILE=/var/spool/faxes/thisfax=${CALLERIDNUM}.tif) exten => fax,2,rxfax(${TIFFILE}) ; email the FAX file to the receptionist and then delete it exten => fax,3,SetVar(EMAIL=receptionist@oreilly.com) exten => fax,3,System('mewencode -e ${TIFFILE} | mail -s FAX ${EMAIL}') exten => fax,4,System('rm ${TIFFILE}') 

This configuration receives the fax, MIME-encodes it using the mewencode command (a standard part of most Linux distributions), and emails it to the email address stored in the ${EMAIL} variable. This is a catchall solution; it sends every fax that's received to the same recipient, who can then forward it (and screen it if necessary) to the appropriate person based on the content of each fax message.

7.5.1. Automatic Fax Routing

To have the Linux server automatically route each fax to the right recipient (instead of having a certain email user doing it), we must have a way of associating each fax with the correct recipient. We'll have to associate a certain line (or a certain DID) with each user so that whenever a fax is received on that line (or DID), we'll know where to route it. Each phone line's number, or each DID number, if we're using a primary rate interface (PRI), will become a single user's fax number.

To associate a DID with a particular user's email address, we can use an LDAP inquiry. An LDAP client library for Linux, openldap, provides applications with the ability to access LDAP servers and perform such inquiries. Your LDAP server might be an Exchange or Lotus Domino server where directory information is stored. The Red Hat distribution includes OpenLDAP binary package and the OpenLDAP developer package.

But you'll need more than just the LDAP client library. You'll also need an actual LDAP client for Asterisk, such as Sven Slezak's LDAPget package. Download it from http://www.mezzo.net/asterisk/ and unzip it into the Asterisk source directory, /usr/src/asterisk.

Next, as root, copy the app_ldap.so file into /usr/src/asterisk/apps. Then, use a text editor to add app_ldap.so to the list of applications that begins with APPS= in /usr/src/asterisk/apps/Makefile. While you have the Makefile open, add the following rule just above the app_voicemail.so line:

 app_ldap.so : app_ldap.o $(CC) $(SOLINK) -o $@ $< -llber -lldap 

Now, LDAPget is ready to be compiled. Save your changes in the text editor and exit back to the shell, where you'll issue these commands to compile the package:

 # cd /usr/src/asterisk # make; make install 

If Asterisk isn't currently running, start it. Then, go to the Asterisk command line and load the LDAPget module (alternatively, you can just restart Asterisk):

 pbx*CLI> load app_ldap.so pbx*CLI> show application LDAPget 

The show application command will confirm that the module is installed and loaded by showing you a brief description of the LDAPget dial-plan command. Now, you can set up the LDAP inquiry your dial plan will use to get email addresses based on the DID provided by ${EXTEN}. To set up this query, open /etc/asterisk/ldap.conf. It might not exist yet, since you've only just compiled the LDAP module. Create an entry like this in ldap.conf:

 [mailfromdid] host = ldap.oreilly.com user = cn=root,ou=People,o=oreilly.com pass = jarsflood base = ou=Addressbook,o=oreilly.com filter = (&(objectClass=person)(|(fax=%s))) attribute = email convert = UTF-8,ISO-8859-1 

This configuration will cause an LDAP inquiry to ldap.oreilly.com, asking for an object of the person class with the attribute fax equal to the value of the %s token (which will be replaced with the DID at runtime). The attribute setting tells the inquiry which attribute from the object to return as a value to the dial plan's variable. This might seem confusing right now, but it should be clearer once you see howthe LDAPget command is used in the dial plan.

In the context where your incoming PSTN calls begin (specified in zapata.conf), you can capture the DID from the ${EXTEN} variable and use it to supply an argument to an LDAP inquiry. If the inquiry is successful, Asterisk's LDAP client will return the email address with which the fax number (i.e., DID) is associated, as in this snippet of extensions.conf:

 [incoming-pstn] exten => s,1,SetVar(DID=${EXTEN}) exten => s,2,Answer exten => s,3,Ringing ; allow 4 seconds for the FAX detection exten => s,4,Wait(4) ; if no FAX, send this call to be handled elsewhere exten => s,3,GoTo(incoming-voice) ; here's the fax handling extension, which sends the call to the ; 'inc-fax' context exten => fax,1,Goto(inc-fax,1,1) [inc-fax] exten => s,1,SetVar(TIFFILE=/var/spool/faxes/${DID}.tif) ; The 'mailfromdid' LDAP inquiry is defined in Asterisk's ldap.conf file. exten => s,2,LDAPGet(EMAIL=mailfromdid/${DID}) ; If the LDAP inquiry succeeds, priority will be 2+1. exten => s,3,rxfax(${TIFFILE}) exten => s,4,GoTo(105) ; If the LDAP lookup fails, priority will be 2+101. exten => s,103,SetVar(EMAIL=receptionist@oreilly.com) exten => s,104,rxfax(${TIFFILE}) ; Now, e-mail the FAX file to whichever e-mail address was decided upon. exten => s,105,System('uuencode ${TIFFILE} uuenc | mail -s FAX ${EMAIL}') exten => s,106,System('rm ${TIFFILE}') [incoming-voice] ; non-fax calls are handled here 

The result of all of this compiling and config tuning is that different email recipients now have assigned fax numbers on the PRI (or assigned POTS lines for their exclusive use as inbound fax lines). When you send a fax to Todd's fax number, Todd receives the email. When you send it to Susie's, Susie receives the email, and so on. Of course, it's up to you to populate your LDAP server with the right information and to make sure the inquiry config in ldap.conf matches your LDAP server's schema.

Don't have an LDAP server? You can use Asterisk's built-in database commands to resolve DIDs to email addresses. Chapter 17 of Switching to VoIP (O'Reilly) contains a command reference that covers these dial-plan commands.

7.5.2. Hacking the Hack

In the previous hack, you used the tiff2ps command to create a printable version of the fax, but with a few extra steps, you can turn a TIFF into a PDF file, too. PDF can be preferable to TIFF when using email, as we are in this project. Consider the following dial-plan changes to the [inc-fax] context:

 exten => s,105,System('tiff2ps -2eaz -w 8.5 -h 11 ${TIFFILE}| ps2pdf \  >${TIFFILE}.ps') exten => s,106,System('uuencode ${TIFFILE}.ps uuenc | mail -s FAX ${EMAIL}') exten => s,107,System('rm -f ${TIFFILE}*') 

Now, instead of just encoding the TIFF file and emailing it, the file is converted to a PostScript file and then to a PDF file, before being uuencoded and emailed to the appropriate recipient.

VoIP Hacks
VoIP Hacks: Tips & Tools for Internet Telephony
ISBN: 0596101333
EAN: 2147483647
Year: 2005
Pages: 156

Similar book on Amazon

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net