Here is the first ever complete python script I wrote. This was done recently because I wanted a way to receive faxes via FreeSWITCH that I could manipulate and use for multiple fax lines and customers with a minimal amount of overhead. The script receives the fax using spandsp/mod_fax and then converts the fax image into a PDF file, and emails it to me.
This script is meant to be called from the FreeSWITCH dialplan XML, and requires that you have a recent build of FreeSWITCH, a working mod_fax installation, a working mod_python installation, and a functional ghostscript installation with the “ps2pdf” command.
I’ve tested this script to work on various builds of the May 2009 FreeSWITCH SVN trunk codebase, under FreeBSD 7.x, using a virtual server from the amazing VoIP provider Link2VoIP.com. It works great for receiving faxes in email and has no limitation of how many faxes it can receive at once (fax lines don’t ring busy unless FreeSWITCH runs out of CPU/capacity to keep handling them). On my Link2VoIP virtual server I was able to simultaneously send and receive 50 faxes to and from myself concurrently without anything crashing.
Instructions:
Once you have a working FreeSWITCH, with all of the above requirements met, create an extension similar to the following, which calls the script when the extension is called:
<extension name="test_rxfax_python"/>
<condition field="destination_number" expression="^\*90012$">
<action application="set" data="recipient=YOU@YOURDOMAINHERE.com"/>
<action application="python" data="process-rxfax"/>
<action application="hangup"/>
</condition>
</extension>
Set the recipient variable in dialplan to the email address you want the fax to get sent to. The SMTP server specified in the script must be able to relay mail to this email address.
Thanks to the amazing developers of FreeSWITCH and spandsp.
Comments/improvements are appreciated!
Get the script here.
Tags: application, email, fax, freeswitch, link2voip, pdf, programming, python, script, voip, xml
Pfft,
is based on antiquated biological theories. Rethink your philosophy here, or let the world pass you by. Next thing you know you’ll be saying things like, “<condition field=”destination_number”
Seriously.
That said, I have added you to my blog roll.
I was using this script with mod_python for a about 2 week. Worked well and the everything ceased to function.
could be due to an automated svn up. but now we have no fax. ended up trying to rebuilding again off 1.0.4pre9, yet no go. seems like rxfax is either not receiving the data, cause no tiff file gets saved or handed on.
mod_fax is set as a loadable module. had to add:
def fsapi(session, stream, env, args):
print “fsapi\n”
def runtime(args):
print args + “\n”
to the end of this script to stop mod_python errors. argh… this was the best solution IMHO….
I suspect that it does have something to do with keeping your FreeSWITCH at the current SVN level. They are still changing the ways things work in major ways. I keep my FreeSWITCH at 1.0.3 right now after having too many bad things happen while running SVN. Quite often out of the blue the latest SVN would move around things / break things that I had working so it was not at all suitable for production. Running 1.0.3 keeps things more stable although I don’t get as good of performance as one gets using the SVN versions.
All that being said, I don’t know how soon I will have time to update the script to support the latest SVN but that is definitely going to have to happen soon. I’ll post an update on here when I get around to it.
Great news. So does this script work with a stock FS 1.0.3 ?
Thanks.
It has been working for several months (since I first posted it) on FS 1.0.3. I also originally wrote it while using SVN around revision ~11,000 or so. Mind you, it’s worth mentioning that I am using FS with mod_python compiled against Python 2.4 because Python 2.5 on my system was being used by Apache which required a non-threaded python, while Freeswitch required a threaded python. Not sure if that would have anything to do with it not working for you or not.
Spot on. Did as you advised and we now have a working fax. Awesome thanks for releasing the code.
Nice script. However, the fax headers get lost somewhere during the conversion. Any pointers for how to solve this?
Anything that’s happening during the fax conversation is handled by the mod_fax application, and not my script. I’m not sure which fax headers you mean… the header at the top of the page should be preserved, it is with my FS server (currently still running 1.0.3).
Thanks for the kind words. FreeSWITCH is great software, the team behind it deserves a lot of the credit.
Ah. I got it fixed now actually.
I added: tiff2psoptions = ‘-a -h 11,81 -w 8,28 -1 -O ‘
Seems like it goes a bit outside of our (at least european) standard of A4 paper.
Ahhh, interesting. When I wrote the script I was only considering US Letter paper for faxes. This might be handy for any others who are implementing this outside of North America. Thanks for sharing the fix!
Interesting.
Can this script, using single POTS line, have multiple users each capable of receiving their own fax messages ?
We’re trying to get rid off our POTS lines now that mobiles tarrifs are actually cheaper but we couldn’t get rid of our fax machines. [sighs]
Hi
Thats a nice script .
It seems to be working pretty good for me.
Can anybody just tell me , how shall i use the same for a jpeg file or any other file format.
It seems to fail for anything other than .tiff .
One more quest . Why are we changing the TIFF2PS and then PS2PDF & why not TIFF2PDF directly .
Nik: Using a fax modem with FreeSWITCH and a POTS line is not something I have tried, but I think that’s something you can do with OpenZAP? I’m not really familiar with that side of things as I have mostly got experience using IP-only VoIP installations with FreeSWITCH (having previously discovered Asterisk when I was working for a call center).
But I would recommend using FreeSWITCH in conjunction with an online virtual server provider combined with a VoIP account from a provider who can route faxes through their network as a money-saving (and busy-signal preventing) way to receive lots of faxes. Sending faxes out over VoIP protocols is not as reliable unless you support T.38 end-to-end in the transmission which is still uncommon in traditional fax machines.
I use a Virtual Server and VoIP service from my provider, Link2VoIP (note: referral link) because their virtual servers are located in the same datacenter as their inbound PSTN connections so it’s quite reliable for inbound faxing. (I am just a happy customer, they aren’t paying me to astroturf). They have unlimited channel DIDs so I can receive hundreds of concurrent faxes on the same fax number with FreeSWITCH at quite a low cost. It’s pretty amazing
This article by the developer of SpanDSP (which is used by FreeSWITCH and in my script) discusses some of the issues with outbound faxing (and faxing in general) and VoIP. It’s very interesting and I suggest you check it out!
Shourjya: Thanks for the comment! I could not get TIFF2PDF to run properly on my FreeBSD installation, unfortunately, so I worked around the problem. I suppose that the script could definitely be modified. I was re-reading the code again tonight and there are numerous other optimizations that could be made now that I have done a bit more Python programming. I hope to sit down and hack away at it some more soon. Glad to hear this is helping you and others out! It was written because I myself needed the functionality too.. it was absurd to me that FreeSWITCH included mod_fax but didn’t automatically PDF and email the faxes.
Just want to know whether I will be able to receive the multiple pages coming through single fax call.
One more thing…if multiple pages are coming, how to send all the pages through email.
Sharad: Yes, multiple-page faxes are supported by spandsp.
Hi steffler,
Thanks for your answer and am looking forward for any optimization you would be doing to your code.
Il let you know if i have anything to add in the script too .
Let us know when you add the new script .
Hi steffler,
I am using the following dialplan in default.xml
When caller sends 2-3 pages, Freeswitch sends the email to the defined email id but only first page is displayed. & the tmp folder also saves only 1 tiff file.
Plz let me know where I am mistaking.
Regards
Just want to know whether the script `process-fax.py’ receives the fax call or just to email the received tiff.
I think this script is only for emailing the tiff file after converting into PDF.
Plz clarify the same.
Ghan Nidhi
Hi Steffer
Thanks for your script.
I made it working with a fax call which is carrying single page but when I a fax call which is carrying multiple pages, script shows only single tiff file in the defined folder.
Plz let me know where I am wrong or something else is required to configure to receive the multiple pages.
Regards
Ghan Nidhi
The single TIFF file should contain multiple pages. The script uses FreeSWITCH’s mod_fax to receive the fax so it is handled outside of my code.
Sharad: The single .tiff file should contain multiple pages.
sorry…I realized it little later.
Its working fantastically.
Just another question….
Now I am adding some stuff to your script to prepare a database so that I can have a web based applcation where I can view all my faxes.
For this I want to find out how many no. of pages are there in that tiff file. is there any way to get that inside or outside your scripts.
Sharad
Sharad: You should be able to use the tiffinfo program to show that information. http://www.remotesensing.org/libtiff/man/tiffinfo.1.html
I don’t know exactly what the command would be to get it to show you the number of pages in a TIFF file but you could experiment and see what it outputs when you run it with a single page vs a multiple page tiff file.
Ghan: Thanks for the kind words. It should automatically receive multiple pages (as a single .TIFF file). The script’s function is to call the FreeSWITCH mod_fax / spandsp program to receive the fax, then convert the fax to PDF and email it.
Thanks for all your kind support…
Regards
Sharad