Geek stuff, Linux, resources, Tutorials

Web Fax for Asterisk

Over the past few weeks, I have been working with the popular telephony software asterisk and all the stack that stands on top of it. I have (in coordination with a friend) setup asterisk, FreePBX, a2billing, fax for asterisk and vicidial on several production servers. Combined, these provide a complete telephony solution for a wide range of commercial organizations. As a side note, I might be writing tutorials about some of these things in the future.

One of most problematic of these technologies was getting fax to work with asterisk. We tried many variations and finally found out that Digium’s Fax for Asterisk, or Free Fax for Asterisk (FFA) is currently the most stable and easy to set up. However, it does not provide an easy way to let your end users send faxes if they don’t have SIP enabled fax machines. What’s more, there is no software available that would allow you to do that! So, in one of our projects, we had to come up with a custom interface and we decided to open it up so that many others who need it can benefit from our efforts and hopefully build on it.

We call this PHP-based script Web Fax for Asterisk and are releasing it under GPLv3. For those of you who just want to get the code, you can get it from sourceforge.net. You can also get it from the SF SVN repo if you want to contribute. (In that case, gimme a shout and I’ll allow you to commit.)

For those of you who want to learn how it’s made, please read on.

First you need to install asterisk and get FFA to work. Search for any asterisk installation tutorial (you’ll need to go with 1.6 if you want the more stable T.38 support) and then follow this guide to setup FFA. You should also setup FreePBX and get the Fax Configuration module from Schmoozecom. That would help you configure FFA so that your clients can receive faxes in their mailboxes. After that, you can begin with our Web Fax script to enable sending.

Web Fax for Asterisk

The rest of this post will first describe the code that has gone into Web Fax 0.1. At the end, we will cover the installation instructions to get your started. Let’s begin with the HTML form that the users see. It’s a fairly simple form which has some error checking. Web Fax currently supports DOC and PDF formats so you should include some instructions about this in your form. I’ll post the skeleton code here. The Web Fax archive contains a much better interface. So, the form:

<form action="sendfax.php" method="post" enctype="multipart/form-data" name="form1" id="form1">
  <table>
    <tr>
      <td width="188" class="formLabel">FAX Header</td>
      <td width="232">
     <input name="faxHeader" type="text" id="faxHeader" value="CSRDU" /></td>
    </tr>
    <tr>
      <td class="formLabel">Local Station Identifier</td>
      <td>
        <input name="localID" type="text" id="localID" value="3239366136" /></td>
    </tr>
    <tr>
      <td class="formLabel">Notification Email Address </td>
      <td>
        <input name="email" type="text" id="email" value="recluze@gmail.com" /></td>
    </tr>
    <tr>
      <td class="formLabel">FAX Destination</td>
      <td>
        <input name="dest" type="text" id="dest" value="14809073626" /></td>
    </tr>
    <tr>
      <td class="formLabel">Attach file</td>
      <td>
      <input type="file" name="faxFile" id="faxFile" /></td>
    </tr>
    <tr>
     <td>&nbsp;</td>
      <td><input type="submit" name="sendFax" id="sendFax" value="Send FAX" /></td>
      <td>&nbsp;</td>
    </tr>
  </table>
</form>

The sendfax.php script does all the heavy lifting of communicating the information provided by the user to asterisk. It first uploads the document, converts it to tif format as required by Fax for Asterisk and then makes a call through asterisk. Let’s take a look at the salient parts of this script.

SendFax script

Uploading the document is easy. All we need to do is to check what format the document is in. We currently support .doc and .pdf formats. The strategy for .doc is to first convert it to .pdf. For that, we use the wvPDF command. (wvPDF requires tetex-latex or another package providing latex). We first save the uploaded .doc file with a temporary name in /tmp. Then we convert it.

$input_file_noext = unique_name("/tmp", "");
$input_file = $input_file_noext . ".pdf";
$input_file_tif = $input_file_noext . ".tif";
$input_file_doc = $input_file_noext . ".doc";

// needs the following in /etc/sudoers
// asterisk ALL=(ALL) NOPASSWD: /usr/bin/wvPDF
$wv_command = "sudo /usr/bin/wvPDF $input_file_doc $input_file" ;
$wv_command_output = system($wv_command, $retval);

Notice the commented out lines. For some reason, latex won’t run from PHP. So, we add the wvPDF to /etc/sudoers file for user asterisk — we’re running apache as the user asterisk.

Now that we have a .pdf file — whether through conversion from .doc or originally from the user — we can convert it to .tif through ghostscript. (Make sure it’s installed.)

$gs_command = "gs -q -dNOPAUSE -dBATCH -dSAFER -sDEVICE=tiffg3 -sOutputFile=${input_file_tif} -f $input_file " ;
$gs_command_output = system($gs_command, $retval);
$doc_convert_output = $gs_command_output;

Finally, we need to create a .call file that will automate asterisk making a call. We set some parameters, create the file and move it to asterisk’s outgoing directory.

$faxHeader = $_POST["faxHeader"];
$localID = $_POST["localID"];
$email = $_POST["email"];
$dest = $_POST["dest"];

$outbound_route = "@outbound-allroutes";
$outboundfax_context = "outboundfax";

$callfile = "Channel: Local/$dest$outbound_routen" .
			"MaxRetries: 1n" .
			"RetryTime: 60n" .
			"WaitTime: 60n"  .
			"Archive: yesn"  .
			"Context: $outboundfax_context n"  .
			"Extension: sn" .
			"Priority: 1n" .
			"Set: FAXFILE=$input_file_tifn" .
			"Set: FAXHEADER=$faxHeadern" .
			"Set: TIMESTAMP=" . date("d/m/y : H:i:s",time()) . "n" .
			"Set: DESTINATION=$destn".
			"Set: LOCALID=$localIDn" .
			"Set: EMAIL=$emailn";

// create the call file in /tmp
$callfilename = unique_name("/tmp", ".call");
$f = fopen($callfilename, "w");
fwrite($f, $callfile);
fclose($f);

// $asterisk_spool_folder is usually /var/spool/asterisk/outgoing
rename($callfilename, $asterisk_spool_folder .  "/" . substr($callfilename,4));

Notice the channel and context fields in the call file. The channel will depend on your outbound route. I found that outboud-allroutes worked for my settings. You might want to try that if you’re not sure of the route. The last thing we need to do is to create a context for sending fax within asterisk conf files.

Outbout Fax Context

The context should ideally be created in /etc/asterisk/extensions_additional.conf. You should also make sure that this file is ‘included’ in extensions.conf. The content of the context follow:

[outboundfax]
exten => s,1,Set(FAXOPT(filename)=${FAXFILE})
exten => s,n,Set(FAXOPT(ecm)=yes)
exten => s,n,Set(FAXOPT(headerinfo)=${FAXHEADER})
exten => s,n,Set(FAXOPT(localstationid)=${LOCALID})
exten => s,n,Set(FAXOPT(maxrate)=14400)
exten => s,n,Set(FAXOPT(minrate)=2400)
exten => s,n,SendFAX(${FAXFILE},d)
exten => s,n,System(${ASTVARLIBDIR}/bin/faxnotify.php INIT "${EMAIL}" "${DESTINATION}" "${TIMESTAMP}" "NO_STATUS" "NO_PAGES")
exten => h,1,NoOp(FAXOPT(ecm) : ${FAXOPT(ecm)})
exten => h,n,NoOp(FaxStatus : ${FAXSTATUS})
exten => h,n,NoOp(FaxStatusString : ${FAXSTATUSSTRING})
exten => h,n,NoOp(FaxError : ${FAXERROR})
exten => h,n,NoOp(RemoteStationID : ${REMOTESTATIONID})
exten => h,n,NoOp(FaxPages : ${FAXPAGES})
exten => h,n,NoOp(FaxBitRate : ${FAXBITRATE})
exten => h,n,NoOp(FaxResolution : ${FAXRESOLUTION})
exten => h,n,System(${ASTVARLIBDIR}/bin/faxnotify.php NOTIFY "${EMAIL}" "${DESTINATION}" "${TIMESTAMP}" "${FAXSTATUSSTRING}" "${FAXPAGES}")
; end of outboundfax context

The important lines are the ones with ‘SendFax’ and ‘System’ calls. SendFax sends the fax (duh!) and system calls out notification script that sends an email to the user describing the status of the transmission. The notification script is essentially a mailer. You can refer to the Web Fax source for the complete script.

And that is how we implemented the Web Fax for Asterisk script.

Advertisements

75 thoughts on “Web Fax for Asterisk”

  1. Hi Nauman,

    I tried to install this package, but when I try to send a fax, I don’t see anything happening on the Asterisk CLI.

    How can I debug?

    Also, is the .call file supposed to be created automatically or is it something we need to create and save somewhere? It’s not included in the package.

    Thanks.

  2. Hello David,

    First, the .call file is created by the sendfax.php script dynamically. You don’t need to create it.

    For debugging, you have the following options.

    Put some echos in the sendfax.php script to see how far it’s proceeding. Most often, it’s the document conversion that fails. Make sure you can execute wvPDF, ghostscipt and latex on the linux CLI and that you have taken care of the /etc/sudoers configuration as described in the post.

    Also, you can tail -f /var/log/asterisk/full to see if the .call file is actually being read by asterisk.

    If it doesn’t work out, post some debug info and I’ll see how I can help.

  3. Hi Nauman,

    Thank you for your prompt response.

    It seems that the problem is somewhere here:
    if ($ext == “pdf”) {
    if(move_uploaded_file($_FILES[‘faxFile’][‘tmp_name’], $input_file)) {
    $input_file_type == “pdf”;

    In my debug, I notice that $input_file_type is empty, so it’s probably related to the result of move_uploaded_file.

    I tried to set the ownership of sendfax.php to apache and/or root, but it doesn’t work.

    [root@sip webfax]# ls -l
    total 40
    -rwxr-xr-x 1 apache root 2548 Oct 18 10:48 faxnotify.php
    -rwxr-xr-x 1 apache root 1845 Oct 16 08:23 faxout.pl
    drwxr-xr-x 2 apache root 4096 Oct 19 07:23 links
    -rwxr-xr-x 1 apache root 2926 Oct 18 10:48 README.txt
    -rwxr-xr-x 1 apache root 4452 Oct 19 07:45 sendfaxform.html
    -rwxr-xr-x 1 root root 8460 Oct 19 10:06 sendfax.php
    -rwxr-xr-x 1 apache root 44 Oct 18 09:31 wvPDF.php

    Do you have any suggestions?

    Thanks.

  4. If you’re running asterisk you’ve probably configured apache to run as ‘asterisk’ user. So you should chown the files in webfax to asterisk:asterisk.

    Secondly, try isolating the file upload to see if that works for you.

  5. I found the bug. I that line you put == instead of =:
    $input_file_type == “pdf”;

    I removed it and I’m moving forward to check the rest.

    Thanks.

  6. Hi Nauman,

    I reached the point where the call file is generated and copied to the /var/spool/asterisk/outgoing folder and I see on Asterisk CLI that it fails to be sent.

    My extensions.conf file contains the new context that I created (outboundfax), but for all the outgoing calls, we have a context called “outgoing”, where the relevant provider is chosen, based on the destination.

    For example, international calls are routed like this:
    exten => _00Z., 1, Dial(SIP/${EXTEN}@Main,50,tTr)
    ;exten => _00Z., n, Dial(SIP/${EXTEN}@Second,50,tTr)
    exten => _00Z., n, Hangup

    How do I change the “Channel” field in the call file to send the calls to that context for outbound delivery?

    Thanks.

  7. OK, Got the channel issue sorted out:
    $callfile = “Channel: Local/$dest@outgoingn” .

    Now, a strange thing happens. When we get a reINVITE with T.38 “codec”, it says that:
    Got T.38 offer in SDP in dialog 74ca1e4e3e86a1b873428773477e201f@10.0.0.3
    Capabilities: us – 0x102 (gsm|g729), peer – audio=0x0 (nothing)/video=0x0 (nothing)/text=0x0 (nothing), combined – 0x0 (nothing)
    Non-codec capabilities (dtmf): us – 0x1 (telephone-event), peer – 0x0 (nothing), combined – 0x0 (nothing)
    Got T.38 Re-invite without audio. Keeping RTP active during T.38 session.

    and then Asterisk sends Trying followed by:
    SIP/2.0 488 Not acceptable here

    Why sin’t T.38 supported. Should it be enable somewhere?

    Thanks.

  8. For the channel, you should change the outbound-route variable but you already figured that out 🙂

    For the T.38, does your ITSP allow T.38 and are you using asterisk 1.6. (I’m assuming you are if you’re using digium’s FFA). You should mail them to check it out.

    Also, you need to set in your extensions.conf

    udptl=yes
    udptl_tcp = yes
    udptl_udp = yes

  9. My colleague opened a ticket on the mailing list.

    Can you elaborate regarding the extensions.conf insertions? where exactly should we add these lines?

    in sip.conf we have t38pt_udptl and canreinvite enabled.

    Thanks.

  10. Hello All,
    I managed to get the initial install done with all but one of the required packages installed.
    I went line by line in the README.txt file and picked up a few more things from the above thread.
    I can’t seem to locate wvPDF. How is that called and where does it come from? From what I have read, it looks like the library gets installed with tetex but my directory does not look like the one above when I do an ls -l…
    -rwxr-xr-x 1 asterisk asterisk 1845 Oct 19 12:19 faxout.pl
    drwxr-xr-x 3 asterisk asterisk 4096 Oct 19 12:19 links
    -rw-r–r– 1 asterisk asterisk 2926 Oct 19 12:19 README.txt
    -rw-r–r– 1 asterisk asterisk 4521 Oct 19 12:19 sendfaxform.html
    -rwxrwxrwx 1 asterisk asterisk 7557 Oct 19 12:19 sendfax.php

    The end result is that after I put in all of the required information in the form I get an immediate “Your fax document could not be converted. Please try again or upload the document in another format. The error details follow.” I have tried a Word 2003 and PDF format.
    Any thoughts on what I might look for?
    Thanks,
    Perry

  11. Perry,

    You should first try seeing if wvPDF command works for you on the CLI. If not, try installing AbiWord. I believe that installs wvPDF. Anyway, you first need to get wvPDF and ghostscript working.

    Once you do that, you should try executing the conversion scripts present in sendfax.php from the CLI. That would let you know if they are working fine with your setup.

    The final thing would be to make sure you’ve setup the /etc/sudoers to allow wvPDF to be called from php.

  12. Hi,

    I played around with this code and changed the faxnotify.php to include the fax that was sent and a nicer and more detailed HTML format. This is the code, if anyone wants to use it:

    #!/usr/bin/php -q
    <?php

    // set some global variables here
    $SUCCESS_STATUS = "FAX_SUCCESS";
    $FROM_EMAIL = "Smartel-PBX@smartel.co.il";
    $FROM_NAME = "Smartel PBX Fax Server";
    $CONTACT_EMAIL = "info@smartel.co.il";

    if ($argc != 7) {
    echo "Usage faxnotify.php messagetype email destination timestamp status_string pages n ";
    echo "message type can be one of INIT or NOTIFY ";
    }
    echo "Starting faxnotify.php n";

    // setting up
    $messtype = $argv[1];
    $email = $argv[2];
    $dest = $argv[3];
    $timestamp = $argv[4];
    $statuscode = $argv[5];
    $numpages = $argv[6];
    $filename = $argv[7];
    $bitrate = $argv[8];
    $status = $argv[9];
    $remoteid = $argv[10];

    $random_hash = md5(date('r', time()));

    $headers = "From: $FROM_NAME rnReply-To: $CONTACT_EMAIL”;
    $headers .= “rnContent-Type: multipart/mixed; boundary=”PHP-mixed-“.$random_hash.”””;
    $attachment = chunk_split(base64_encode(file_get_contents($filename)));

    // end setting up

    if ($messtype == “INIT”) { // SendFAX called successfully in the dialplan…
    $emailSubject = “Your fax to $dest has been initiated”;
    $notice = “Your fax to $dest sent on $timestamp has been initiated. You will get a notification ” .
    “email when the transmission is complete. “;
    $emailBody = “Hi! nn” . $notice . ” nn ” .
    “If you have any queries, please contact us at: $CONTACT_EMAIL”;
    mail($email, $emailSubject, $emailBody, $headers);
    }
    else { // meaning $messtype = “NOTIFY” … sending of fax is complete. Need to check if SUCCEEDED
    $tech_details = “—————————— n”.
    “DESTINATION = $dest n”;
    if($statuscode == $SUCCESS_STATUS) {
    $tech_details .= “REMOTE ID= $remoteid n”;
    }
    $tech_details .= “TIMESTAMP = $timestamp n”.
    “STATUS = $status n”;
    if($statuscode != $SUCCESS_STATUS) {
    $tech_details .= “STATUS CODE= $statuscode n”;
    } else {
    $tech_details .= “SPEED = $bitrate n”.
    “PAGES = $numpages n”;
    }
    $tech_details .= “—————————— n”;

    $html_tech_details = “n” .
    “” .
    “DESTINATION =$dest“;
    if($statuscode == $SUCCESS_STATUS) {
    $html_tech_details .= “REMOTE ID =$remoteid“;
    }
    $html_tech_details .= “TIMESTAMP =$timestamp” .
    “STATUS =$status“;
    if($statuscode != $SUCCESS_STATUS) {
    $html_tech_details .= “STATUS CODE =$statuscode“;
    } else {
    $html_tech_details .= “SPEED =$bitrate“.
    “PAGES =$numpages“;
    }
    $html_tech_details .= “”;

    echo “Sending fax notification email to: $email from $FROM_EMAIL n”;

    if($statuscode == $SUCCESS_STATUS) {
    $emailSubject = “Your fax to $dest was delivered successfully”;
    $notice = “This is an automated message to let you know that your attached fax to ” .
    “$dest sent on $timestamp was delivered successfully.”;
    } else {
    $emailSubject = “Your fax to $dest was not delivered”;
    $notice = “This is an automated message to let you know that your fax to ” .
    “$dest sent on $timestamp could not be delivered. n”;
    }

    $emailBody = “–PHP-mixed-” . $random_hash . “n” .
    “Content-Type: multipart/alternative; boundary=”PHP-alt-” . $random_hash . “”n” .
    “–PHP-alt-” . $random_hash . “n” .
    “Content-Type: text/plain; charset=”iso-8859-1″n” .
    “Content-Transfer-Encoding: 7bitn” .
    “Hi! nn” . $notice . “nn” . $tech_details . ” nn ” .
    “If you have any queries, please contact us at: $CONTACT_EMAILn” .
    “–PHP-alt-” . $random_hash . “n” .
    “Content-Type: text/html; charset=”iso-8859-1″n” .
    “Content-Transfer-Encoding: 7bitn” .
    “Hi! ” . $notice . “” . $html_tech_details . ” ” .
    “If you have any queries, please contact us at: $CONTACT_EMAILn” .
    “–PHP-alt-” . $random_hash . “n” .
    “–PHP-mixed-” . $random_hash . “n” .
    “Content-Type: image/tiff; name=”” . substr($filename, 5) . “”n” .
    “Content-Transfer-Encoding: base64n” .
    “Content-Disposition: attachmentn” .
    $attachment . “n” .
    “–PHP-mixed-” . $random_hash . “–“;

    mail($email, $emailSubject, $emailBody, $headers );
    }
    ?>

    It also requires the following change in extensions.conf:

    exten => h,n,System(/var/lib/asterisk/agi-bin/faxnotify.php NOTIFY “${EMAIL}” “${DESTINATION}” “${STRFTIME(${EPOCH},,%H:%M:%S %d/%m/%Y)}” “${FAXSTATUSSTRING}” “${FAXPAGES}” “${FAXFILE}” “${FAXBITRATE}” “${FAXSTATUS}” “${REMOTESTATIONID}”)

    Enjoy,

    David

    PS. If anyone knows how to set the dialplan to retry n (5 in my case) times to resend a fax if it fails, I’ll be glad to get the necessary code.

  13. Hi David,

    Thanks for posting the code. I will send you an email if you are willing to send me the file. I would commit it to the SVN repo so that others can use it. If you have a SF username, I can also give you commit access.

  14. Hi Nauman,

    I’m not sure what SF means, but you can email me and I’ll send you the page.

    On another issue, I’ve been struggling in the past couple of hours to allow the sendfax.php file to accept also tif files, but SendFAX rejects my files with this error:
    FAX handle 0: failed to queue document ‘filename.tif’

    Int e admin manual of FFA, it says that the file size should be 1680*2285, so I installed ImageMagick to resize and crop the file to this size, but it’s still rejected. Do you have any idea how to generate tif files without converting them from PDF sources?

    BTW, just like the other guys that commented here, I also do not have wvPDF, so I can’t use it for MS-Word docs yet. I couldn’t find it for CentOS 5.5.

    Ciao.

  15. Hi David,

    SF = sourceforge.net 🙂

    I also tried sending my own tif files (created with Adobe Photoshop) and got similar errors. It probably has something to do with the different tif settings. I couldn’t figure out the right combination.

    About wvPDF, I wasn’t able to find it in any repos either but it was present in my vanilla install of CentOS. The recommended way to get wvPDF (and its siblings) is to install AbiWord. Have you tried that?

  16. My colleague found that the file resolution has to be 204×196 instead of 200×200 to be accepted by FFA.

    As for AbiWord, it’s called now antiword, but when we tried to install it on our CentOS 5.5, we get this dependency error:
    Missing Dependency: libc.so.6(GLIBC_2.7)(64bit) is needed

  17. Dear friend,

    to have a doubt about the README.txt of webfax
    4. Moves to $ faxnotify.php ASTERISDIR / bin / faxnotify.php
    mv / var / www / html / webfax / faxnotify.php
    I have to create the BIN folder in / var / lib / asterisk?

    thank you for attention

    1. Francisco,

      That’s agi-bin folder in /var/lib/asterisk and it should already be there. Sorry for the mistake.

  18. I am grateful for your attention.

    is … actually I’m using the asterisk app_fax spandsp and not even with the fax from Digium as you refer.
    I can work with your script without problem with the fax own asterisk-1.6.2.11?

    again I am grateful for your attention.
    verjuice for the way you help.

  19. I don’t think it will work directly with anything other than the Digium FFA. You can try it though and let us know how it goes. 🙂

  20. Hello dear friend.

    all in peace?

    I have a duviva when I use the script to give this error:

    asterisk ALL = (ALL) NOPASSWD: / usr / bin / wvPDF (for whatever is the apache user) $ wv_command = “sudo / usr / bin / $ wvPDF input_file_doc $ input_file” / / echo ”
    executing: ‘. $ wv_command. ”
    N “; $ wv_command_output = system ($ wv_command, $ retval) / / echo $ wv_command_output; if ($ retval! = 0) {echo” There was an error converting your DOC file to PDF. Try uploading the file again or with an older version of PDF ‘, $ error = $ ERROR_CONVERTING_DOCUMENT; $ doc_convert_output = $ wv_command_output / / die ();} else {/ / set the input file type to pdf. Now the it’s converted $ input_file_type = “pdf”;}} else {echo “There was an error uploading the file, please try again”;}} / / END DOC file detected / / If It Was Originally a PDF if ($ ext == “pdf “) {if (move_uploaded_file ($ _FILES [‘faxFile’] [‘tmp_name’], $ input_file)) {$ input_file_type =” pdf “} else {echo” There was an error uploading the file, please try again! ” ;}} / / We Should Have a PDF file now Which We Will convert to tif if ($ error == $ & & $ ERROR_NO_ERROR input_file_type == “pdf”) {/ / convert the attached PDF to. ghostsccript tif using … $ gs_command = “gs-q-dNOPAUSE-dBATCH-dsaf-sDEVICE = tiffg3-sOutputFile input_file_tif = $ {}-f $ input_file”; $ gs_command_output = system ($ gs_command, $ retval) = $ $ doc_convert_output gs_command_output; if ( $ retval! = 0) {echo “There was an error converting your PDF file to TIF. Try uploading the file again or with an older version of PDF ‘, $ error = $ ERROR_CONVERTING_DOCUMENT / / die ();} else {/ / call the script to create faxout.pl call the file and copy the required files to appropriate directories / / ———————————————— ————————————————– —- / / $ = $ script_local_path _REAL_BASE_DIR = realpath (dirname (__FILE__)); faxHeader $ = $ _POST [“faxHeader”]; localID $ = $ _POST [“localID”], $ email = $ _POST [“email “], $ dest = $ _POST [” dest “] / / echo” Sending FAX. Debug information:
    N “/ / echo” – faxHeader: $ faxHeader
    N “/ / echo” – localID: $ localID
    N “/ / echo” – email: $ email
    N “/ / echo” – dest: $ dest
    N “/ / PERL SCRIPT ———————– ——- ——– NOW NOT USING FORM ———————————- / / setting up the options required by faxout.pl / / $ faxout_command script_local_path = $. / faxout.pl “/ / calling faxout.pl now / / exec ($ faxout_command, $ faxout_output, $ retval) / / echo $ retval.”
    N “/ / Should be 0 for correct output by faxout.pl / / echo $ faxout_output / / END faxout.pl call / / ——————- ————————————————– ——————————— / / ————— ——– ——- END PERL SCRIPT FORM NOW NOT USING —————————- ————– / / —————————— CREATING CALL FILE AND SENDING THROUGH ——————————- PHP $ callfile = “Channel: Local / $ $ dest outbound_route n “.” MaxRetries: 1 n “.” RetryTime: 60 n “.” WaitTime: 60 n “.” Archive: yes n “.” Context: $ outboundfax_context n “.” Extension: s n ” . “Priority: 1 n”. “Set: = $ FAXFILE input_file_tif n”. “Set: = $ FAXHEADER faxHeader n”. “Set: = TIMESTAMP.” date (“d / m / y H: i : s “, time ()).” n “.” Set: DESTINATION = $ dest n “.” Set: = $ LOCALID localID n “.” Set: EMAIL = $ email n “/ / echo $ callfile / / create the call file in / tmp $ callfilename Unique_Name = (“/ tmp”. “call”); $ f = fopen ($ callfilename, “w”) fwrite ($ f, $ callfile); fclose ($ f) / / move the file to asterisk outgoing spool directory / / stopping the call to asterisk .. for now TODO: uncomment before deploying .. rename ($ callfilename, $ asterisk_spool_folder. “/.” substr ($ callfilename , 4)); //————————- END CREATE FILE ————– CALL ———————————————}} / / if in error, display That Will Be notification sent.?> END HACK HTML to suppress errors appearing on screen. -> Your fax document Could Not Be converted. Please try again or upload the document “. “In another format. The error details follow.

    “.” Doc_convert_output $ “}>

  21. Thanks for the tip.
    Solved this problem well, thank you again for your eye.

    One more doubt in your REAME.txt you talk about the> chmod + x insert_dialplan.sh
    >. / insert_dialplan.sh, more in the file that you have to dowload does not have the insert_dialplan.sh. sendfaxform.php when I call, he runs it all in stride without any problems, more in the asterisk cli does not show anything and no email arrives informing status. I’m a little request. sorry if I’m being annoying, the more your solution is a good show.

  22. Recluze could you configure it for me in our system? How long will take you and what is your rate?

    Thanks in advance,

  23. I installed this promising application. However when using asterisksvr/sendfaxform.html is not found in the browser. All the files are in the proper locations. Did the chown asterisk:asterisk, what you think could be the reason. I am accesing from internal network.

  24. Excellent!
    As someone else say before, “thanks a lot for this. Works perfectly with my SIP trunk. Had been looking for a simple way to configure sending faxes”

    I’m using it on a Trixbox System, and it works fine.

    For people with problems don’t forget to look at /var/log/http/error.log for tracking issues.

    Thanks again, from Colombia.

    1. Thanks a lot for the appreciation Nelson. It’s always nice to know that I’ve been helpful — in whatever small way possible. 🙂

  25. How do i chmod or chown the .call file in the faxout.pl script, before or after its send to the asterisk outgoing directory???
    Asterisk can’t handle the call file, because its owened by apache.

    1. Hi Paul, You need to run the following commands as root:

      chown asterisk:asterisk

      This is assuming that apache is running as user asterisk (which is usually the case for asterisk deployments)

    1. It’s a complicated question. The way I did it was to have a DID allocated to FAX for a particular a2billing customer and maintain that separately. You can then charge the interested customers on a per-month basis.

  26. HI,

    I invisioned that solution, but anybody that has access to the webpage will be able to send faxes.

    I am thinking to modify to sendfax.html to include customer’s credential and verify with customer information in a2billing database along with the faxe information so I can use a2billing trunk information and charge the customer on just for the call.

    Regards,

    Al

    1. That’s a very good idea. I’m pretty sure you can do that through basic PHP and don’t need to do anything with asterisk. Just protect the page using the customer login info present in the a2billing db.

  27. Hi,
    I am trying to get test.call file working with Google Voice. My SIP dialingout via google voice works like a charm. I also read you can fax using google voice.

    here is my extension.conf

    [outboundfax]
    exten => s,1,Answer
    exten => s,2,Dial(SIP/1000)
    exten => fax,1,Dial(SIP/203,30)
    exten => fax,2,Congestion
    exten => fax,102,Congestion

    exten => s,1,Set(FAXOPT(filename)=${FAXFILE})
    exten => s,n,Set(FAXOPT(ecm)=yes)
    exten => s,n,Set(FAXOPT(headerinfo)=${FAXHEADER})
    exten => s,n,Set(FAXOPT(localstationid)=${LOCALID})
    exten => s,n,Set(FAXOPT(maxrate)=14400)
    exten => s,n,Set(FAXOPT(minrate)=2400)
    exten => s,n,SendFAX(${FAXFILE},d)
    exten => s,n,System(${ASTVARLIBDIR}/bin/faxnotify.php INIT “${EMAIL}” “${DESTINATION}” “${TIMESTAMP}” “NO_STATUS” “NO_PAGES”)
    exten => h,1,NoOp(FAXOPT(ecm) : ${FAXOPT(ecm)})
    exten => h,n,NoOp(FaxStatus : ${FAXSTATUS})
    exten => h,n,NoOp(FaxStatusString : ${FAXSTATUSSTRING})
    exten => h,n,NoOp(FaxError : ${FAXERROR})
    exten => h,n,NoOp(RemoteStationID : ${REMOTESTATIONID})
    exten => h,n,NoOp(FaxPages : ${FAXPAGES})
    exten => h,n,NoOp(FaxBitRate : ${FAXBITRATE})
    exten => h,n,NoOp(FaxResolution : ${FAXRESOLUTION})
    exten => h,n,System(${ASTVARLIBDIR}/bin/faxnotify.php NOTIFY “${EMAIL}” “${DESTINATION}” “${TIMESTAMP}” “${FAXSTATUSSTRING}” “${FAXPAGES}”)
    ; end of outboundfax context

    here is my test.call file that i move to /var/spool/asterisk/outgoing folder.

    Channel: Local/14241231234@outboundfax
    MaxRetries: 1
    RetryTime: 60
    WaitTime: 60
    Archive: yes
    Context: outboundfax
    Extension: s
    Priority: 1
    Set: FAXFILE=test.tif
    Set: FAXHEADER=TEST
    Set: TIMESTAMP=11/11/2011:11:11:59
    Set: DESTINATION=14241231234
    Set: LOCALID=12343434343
    Set: EMAIL=email@email.com

    Is the Context and outboundcontact the same? I am getting google voice is rang the fax. In the first try fax machine tried to pickup the voice call and end up disconnecting. Then on the retry, fax machine picks up the fax i get a success but fax is not printed? In the debug screen i get all including exten => h,n,System line is executed. What am i doing wrong with about test.call and [outboundfax] context? I am trying to get my dial plan and call file working before i ding around the php to work.

    Any help is appreciated.

  28. Hello ,

    I’am trying to use the SendFax application in the free digim fax solution . The probem I have is that a waring appears saying that : WARNING[5378]: res_fax.c:2835 acf_faxopt_write: channel ‘SIP/0412345678-00000000’ set FAXOPT(filename) to ‘/112676251.tif’ is unhandled!
    [Apr 24 18:09:26] WARNING[5378]: res_fax.c:2835 acf_faxopt_write: channel ‘SIP/0412345678-00000000’ set FAXOPT(filename) to ‘112676251.tif’ is unhandled!

    I’ve built the tiff file using ghostscript to convert pdf to tiff with the next command : gs -q -dNOPAUSE -dBATCH -dSAFER -sDEVICE=tiffg3 -r204x196 -sPAPERSIZE=a4 -sOutputFile=${input_file_tif} -f $input_file.

    my .call file is :
    Channel: SIP/0412345678
    MaxRetries: 1
    RetryTime: 60
    WaitTime: 60
    Archive: yes
    Context:
    Extension: s
    Priority: 1
    Set: FAXFILE=/tmp/1033181112.tif
    Set: FAXHEADER=TEST
    Set: TIMESTAMP=20/04/12 : 15:39:35
    Set: DESTINATION=0412345678
    Set: LOCALID=0512345678
    Set: EMAIL=testmail@gmail.com

    StartRetry: 3169 1 (1334929235)
    Status: Completed

    my entension.conf file is :

    [outboundfax]

    exten => s,1,NoOp(send a fax)
    same => n,Wait(3)

    exten => s,n,Set(FAXOPT(filename)=/home/sst/Bureau/112676251.tif)
    exten => s,n,Set(FAXOPT(ecm)=yes)
    exten => s,n,Set(FAXOPT(headerinfo)=${FAXHEADER})
    exten => s,n,Set(FAXOPT(localstationid)=${LOCALID})
    exten => s,n,Set(FAXOPT(maxrate)=14400)
    exten => s,n,Set(FAXOPT(minrate)=2400)
    exten => s,n,SendFAX(${FAXFILE},d)
    exten => s,n,System(${ASTVARLIBDIR}/bin/faxnotify.php INIT “${EMAIL}” “${DESTINATION}” “${TIMESTAMP}” “NO_STATUS” “NO_PAGES”)
    exten => h,1,NoOp(FAXOPT(ecm) : ${FAXOPT(ecm)})
    exten => h,n,NoOp(FaxStatus : ${FAXSTATUS})
    exten => h,n,NoOp(FaxStatusString : ${FAXSTATUSSTRING})
    exten => h,n,NoOp(FaxError : ${FAXERROR})
    exten => h,n,NoOp(RemoteStationID : ${REMOTESTATIONID})
    exten => h,n,NoOp(FaxPages : ${FAXPAGES})
    exten => h,n,NoOp(FaxBitRate : ${FAXBITRATE})
    exten => h,n,NoOp(FaxResolution : ${FAXRESOLUTION})
    same => n,Verbose(5,STATUS : ${FAXSTATUSSTRING} , PAGES : ${FAXPAGES} )
    exten => h,n,System(/var/lib/asterisk/agi-bin/faxnotify.php NOTIFY “${EMAIL}” “${DESTINATION}” “${STRFTIME(${EPOCH},,%H:%M:%S %d/%m/%Y)}” “${FAXSTATUSSTRING}” “${FAXPAGES}” “${FAXFILE}” “${FAXBITRATE}” “${FAXSTATUS}” “${REMOTESTATIONID}”)
    ; end of outboundfax context

    I’am waiting for your answer .
    Thanks in advance.

  29. You are my inhalation, I have few blogs and often run out from post :). “Follow your inclinations with due regard to the policeman round the corner.” by W. Somerset Maugham.

  30. Looks like error witj comments in sendfax.php


    “// –> asterisk ALL=(ALL) NOPASSWD: /usr/bin/wvPDF (for whatever the apache user is)”

    Any tries to change commenintg not helps with problem like above


    Web FAX for Asterisk

    asterisk ALL=(ALL) NOPASSWD: /usr/bin/wvPDF (for whatever the apache user is) $wv_command = “sudo /usr/bin/wvPDF $input_file_doc $input_file” ; // echo ”
    executing : “. $wv_command . ”
    n”;

    sudo works OK

    [root@freepbx asterisk]# usermod -s /bin/bash asterisk
    [root@freepbx asterisk]# su asterisk
    bash-3.2$ sudo /usr/bin/wvPDF
    error: ” unreadable

    Help

  31. Hello all
    Thank you for this application/ It was exactly what i was looking for. But I’ve got some problem with it. I’ve done everything from Readme and got following error from /var/log/apache2/error.log
    [error] [client 192.168.1.8] PHP Notice: Undefined variable: input_file_type in /var/www/webfax/sendfax.php on line 120, referer: http://ats/webfax/sendfaxform
    Because of this script doesn’t appear to work.
    I’m not strong at all in PHP but I do think it’s because of this: PHP Warning: Directive ‘register_globals’ is deprecated in PHP 5.3 and greater in Unknown on line 0.
    I’ve got Ubuntu 12.04 LAMP installed i386 and asterisk 1.8 compilled from source with SpanDSP 0.0.6
    So please could some one help to fix this error.
    Regards

  32. Hello there,

    How to go about if we want to use a mail client to send fax through mail rather than using this custom web-fax form?? How to send fax directly from a mail client via sendmail to the fax or asterisk server?

  33. Dear Sirs,

    I am able to send out the fax call, I confirmed by dial my cell that the dialing out is working. However while trying to send a fax to a fax machine I am getting this error:

    [2013-04-16 17:57:12] NOTICE[25192]: pbx_spool.c:353 attempt_thread: Call failed to go through, reason (3) Remote end Ringing
    [2013-04-16 17:57:12] NOTICE[25192]: pbx_spool.c:356 attempt_thread: Queued call to Local/1XXXXXXXXXX@outbound-allroutes expired without completion after 1 attempt

    I am getting the impression that the app is not detecting the fax machine on the PSTN network.

    Your help would be greatly appreciated. I am using FreePBX 2.10 / Asterisk 1.8.12 / 1 free fax license from Digium

  34. I’ve been exploring for a bit for any high-quality articles or blog posts in this kind of area . Exploring in Yahoo I finally stumbled upon this site. Reading this info So i’m glad to
    convey that I have an incredibly just right uncanny feeling I found out exactly what
    I needed. I most without a doubt will make sure to do not omit this
    website and provides it a glance on a relentless basis.

  35. Hi,

    Thanks for the nice little script.

    One thing though – I think some users will need to update the php script in sendfax.php to replace all <? to <?php for some servers to work. I believe the new servers require that for scripts that have HTML and PHP in the same file. I would suggest changing the original script to include <?php for all the tags.

    Any suggestion for a multi-user script with Inbox and Outbox that uses Fax-For-Asterisk ? I know about AvantFax, but that's for HylaFax, I don't know if it works with FFA. Please suggest if you know of any.

    Cheers !

    Najib

  36. tanks for information Your code is very simple and efficient and I was able to test it asterisk 11.7 and SpanDSP library for FAX.
    are you have any solution for sending fax over web interface?
    Best regards.
    and many tanks to you

  37. Wow, marvelous weblog layout! How lengthy have you
    been running a blog for? you make running a blog look easy.
    The overall look of your web site is excellent, as
    neatly as thhe content material!

  38. Hello ,

    I’am trying to use the SendFax application in the free digim fax solution . The probem I have is that a waring appears saying that : WARNING[5378]: res_fax.c:2835 acf_faxopt_write: channel ‘SIP/0412345678-00000000′ set FAXOPT(filename) to ‘/112676251.tif’ is unhandled!
    [Apr 24 18:09:26] WARNING[5378]: res_fax.c:2835 acf_faxopt_write: channel ‘SIP/0412345678-00000000′ set FAXOPT(filename) to ‘112676251.tif’ is unhandled!

    I’ve built the tiff file using ghostscript to convert pdf to tiff with the next command : gs -q -dNOPAUSE -dBATCH -dSAFER -sDEVICE=tiffg3 -r204x196 -sPAPERSIZE=a4 -sOutputFile=${input_file_tif} -f $input_file.

    my .call file is :
    Channel: SIP/0412345678
    MaxRetries: 1
    RetryTime: 60
    WaitTime: 60
    Archive: yes
    Context:
    Extension: s
    Priority: 1
    Set: FAXFILE=/tmp/1033181112.tif
    Set: FAXHEADER=TEST
    Set: TIMESTAMP=20/04/12 : 15:39:35
    Set: DESTINATION=0412345678
    Set: LOCALID=0512345678
    Set: EMAIL=testmail@gmail.com

    StartRetry: 3169 1 (1334929235)
    Status: Completed

    my entension.conf file is :

    [outboundfax]

    exten => s,1,NoOp(send a fax)
    same => n,Wait(3)

    exten => s,n,Set(FAXOPT(filename)=/home/sst/Bureau/112676251.tif)
    exten => s,n,Set(FAXOPT(ecm)=yes)
    exten => s,n,Set(FAXOPT(headerinfo)=${FAXHEADER})
    exten => s,n,Set(FAXOPT(localstationid)=${LOCALID})
    exten => s,n,Set(FAXOPT(maxrate)=14400)
    exten => s,n,Set(FAXOPT(minrate)=2400)
    exten => s,n,SendFAX(${FAXFILE},d)
    exten => s,n,System(${ASTVARLIBDIR}/bin/faxnotify.php INIT “${EMAIL}” “${DESTINATION}” “${TIMESTAMP}” “NO_STATUS” “NO_PAGES”)
    exten => h,1,NoOp(FAXOPT(ecm) : ${FAXOPT(ecm)})
    exten => h,n,NoOp(FaxStatus : ${FAXSTATUS})
    exten => h,n,NoOp(FaxStatusString : ${FAXSTATUSSTRING})
    exten => h,n,NoOp(FaxError : ${FAXERROR})
    exten => h,n,NoOp(RemoteStationID : ${REMOTESTATIONID})
    exten => h,n,NoOp(FaxPages : ${FAXPAGES})
    exten => h,n,NoOp(FaxBitRate : ${FAXBITRATE})
    exten => h,n,NoOp(FaxResolution : ${FAXRESOLUTION})
    same => n,Verbose(5,STATUS : ${FAXSTATUSSTRING} , PAGES : ${FAXPAGES} )
    exten => h,n,System(/var/lib/asterisk/agi-bin/faxnotify.php NOTIFY “${EMAIL}” “${DESTINATION}” “${STRFTIME(${EPOCH},,%H:%M:%S %d/%m/%Y)}” “${FAXSTATUSSTRING}” “${FAXPAGES}” “${FAXFILE}” “${FAXBITRATE}” “${FAXSTATUS}” “${REMOTESTATIONID}”)
    ; end of outboundfax context

    I’am waiting for your answer .
    Thanks in advance.

  39. A tick sheet count of the charts shows over 40% of
    the constituents are currently in long or short term downtrends that have lasted more
    than a month. This article is intended to provoke thought about investment
    possibilities. It seems likely catalysts for this drop are already in place, but others could prop up along the way.

  40. Good day! This post couldn’t be written any better!
    Reading this post reminds me of my good old room mate! He always kept chatting
    about this. I will forward this page to him. Fairly certain he will have a good read.
    Many thanks for sharing!

  41. I sent you an email already, but not sure if you noticed it and maybe you will notice my message through here. I was wondering if you could help me. I have installed Web Fax, but every time I try to send a fax, I get an error that the document could not be converted. I am running Asterisk on CentOS 6.5. Any help would be greatly appreciated.

  42. certainly like your website however you need to test the spelling
    on several of your posts. Several of them are rife with spelling problems and I in finding it very bothersome to tell the truth then again I will certainly come again again.

  43. Aw, this was an exceptionally nice post. Spending some time and actual effort to make a superb article… but what
    can I say… I procrastinate a whole lot and never seem to get anything
    done.

Comments are closed.