FOOD FOR THOUGHT Would like to implement email to fax

billsimon

Well-Known Member
Joined
Jan 2, 2011
Messages
1,540
Reaction score
729
I posted my fetch-n-fax script at https://github.com/billsimon/asterisk-fetch-n-fax

You can use it as-is by putting it in the asterisk user's crontab however often you want to fetch. (Every 5 minutes, for example.) This uses Asterisk's fax module (spandsp), so you would have to modify the sendFax() function or write a new one if you want to use Hylafax instead.

In short, it opens an IMAP (GMail) account and retrieves all unread messages. It takes the destination from the subject line (no error checking) and pulls PDFs out of the body. It converts the PDF(s) to TIFF and faxes them to the destination. Lastly it sends a notice to the sender to say that the fax was processed but there's no status handling here. The fax is left in the IMAP store as a read message so you can go and review later what was sent. If one of the faxes didn't work, just set the message to unread and it will be tried again.

TO DO ... validation of the subject line (destination), clean-up of the TIFFs that are left behind in /tmp, proper status checking and reporting... but here's a starting point for you.
 

billsimon

Well-Known Member
Joined
Jan 2, 2011
Messages
1,540
Reaction score
729
It's Digium's fax module that is no longer available with Asterisk 13+. spandsp continues to be available and supported as it has been for a long time. All you need to do is have spandsp around when building Asterisk and it will happen automatically. You can build the source as your link describes or if you are using Debian/Ubuntu it's available in the standard package repository.

Here is the official word... http://www.digium.com/blog/2015/06/...digium-no-longer-supported-asterisk-13-later/

app_fax shouldn't be around on any modern systems, because the functionality was moved to res_fax.
 
Last edited:

AndyInNYC

Active Member
Joined
May 23, 2013
Messages
772
Reaction score
124
Bill,

Nice solution. My needs are a little more and a little less than what you've done.

I hope to parse the Subject: line to feed parameters to sendfax - I suppose I could use the entire subject line and hope that the sender formats correctly. I don't need to translate the attachments - Sendfax will take a .pdf file send it without intervention (ie it will handle the conversion).

So, I need to study your code and figure out how to 'mangle' it.

<g> Yet another programming language I don't know that I need to modify ...

If I just take the subject line as the Sendfax parameters, that should be easy enough (though not my first choice); I *think* I'll just need to take the .pdf attachments and extract them from the email and give them temp names in a directory and append these filenames to the Sendfax line and then delete the temp names (files) when done.

Sounds like 10 minutes for a pro and 3 days for me - but hey, I have a weekend coming up.

I like how this thread is getting some traction and attention. I think it's a great little 'module' that should make some lives easier for an outdated technology that people still use (my medical doctors won't take an email - it *must* be a fax, for example).


Andrew
 

billsimon

Well-Known Member
Joined
Jan 2, 2011
Messages
1,540
Reaction score
729
I hope to parse the Subject: line to feed parameters to sendfax - I suppose I could use the entire subject line and hope that the sender formats correctly. I don't need to translate the attachments - Sendfax will take a .pdf file send it without intervention (ie it will handle the conversion).

You can use regular expressions to parse out whatever fields you want. But I would say if you are going to parse more than just the phone number, then have the fields in the body of the e-mail instead of the subject. It is easy to take the plaintext body into a variable and then work through it.

I *think* I'll just need to take the .pdf attachments and extract them from the email and give them temp names in a directory and append these filenames to the Sendfax line and then delete the temp names (files) when done.

Use the findDocs() function and php's file_put_contents() to put each pdf to a file on disk. Then give your filenames to the Hylafax script.
 

AndyInNYC

Active Member
Joined
May 23, 2013
Messages
772
Reaction score
124
Wow, i feel stupid. I'm trying to use php for the first time and I can't even get into the batter's box.

I've created a file called EmailToFax.php and chmod'd it to 777.
I'm practicing on an under-utilized Ubuntu 16.04 backup server - even if I kill it, all it does is sync from another server onto it's RAID array. Restoring the OS isn't a big deal.

I have done an apt-get install php and php-imap onto the machine.

I have the first couple lines of my file:

Code:
<?php
$hostname = '{mail.mailserver.com:143}INBOX';
$username = '[email protected]';
$password = 'ReallyStupidPassword';
$inbox = imap_open($hostname,$username,$password);
/* Grab unread emails. Change UNSEEN to ALL if you want to get everything. Be sure to enable the delete and
   purge functions below or else you will send the same faxes over and over. */
$emails = imap_search($inbox,'UNSEEN');

This little snippet of code returns the following errors:


Code:
./EmailToFax.php: line 1: ?php: No such file or directory
./EmailToFax.php: line 2: =: command not found
./EmailToFax.php: line 3: =: command not found
./EmailToFax.php: line 4: =: command not found
./EmailToFax.php: line 5: syntax error near unexpected token `('
./EmailToFax.php: line 5: `$inbox = imap_open($hostname,$username,$password);'

So, basically I can't 'tell' the machine this is php; I can't assign variables and I can't execute a function.

If I run:
Code:
 <?php
echo "Hello World';
exit;
?>

the machine again complains about the <?php line, but it does print 'Hello World' onscreen. So, at least php is running <g>.

Can someone point me in a better direction?

Andrew
 

billsimon

Well-Known Member
Joined
Jan 2, 2011
Messages
1,540
Reaction score
729
Can someone point me in a better direction?

You're missing a very small but important thing.

To run your script, use "php EmailToFax.php"

Or if you want to run the script directly, make the first lines:

#!/usr/bin/php
<?php
...

and then you can ./EmailToFax.php

(Use the command "which php" in your shell first to make sure that /usr/bin/php is right. Use whatever path the which command tells you.)
 

trupsalms

Member
Joined
May 13, 2011
Messages
337
Reaction score
6
I love the idea, of this, i hope to see this coded if possible or documented in a way thats very easy to follow later on down the road
 

billsimon

Well-Known Member
Joined
Jan 2, 2011
Messages
1,540
Reaction score
729
I love the idea, of this, i hope to see this coded if possible or documented in a way thats very easy to follow later on down the road

The version I posted already works "out of the box" if you are using Asterisk's (spandsp) fax module. Just change a few parameters to suit your e-mail account and PBX.

It looks like AndyInNYC is adapting it for Hylafax.

So you will have two options.
 

AndyInNYC

Active Member
Joined
May 23, 2013
Messages
772
Reaction score
124
More like suffering my way through.
I found a php class wrapper for the imap functions which correctly saves my file attachments.

I have a string which contains the body, but I haven't yet figured out how to parse out the text in the way I want. Perhaps someone can point out some php clues for me (I took an analog book out from the library today).

The subject line will have the phone number - easy enough to trap that.
I have a routine to dump the files to a temp directory and grab the filenames in an array - that works, too.

The plan is for the body to have lines starting with: #!# and then the -param and then the variable
so they might look like:

#!#-C CustomCover.html
#!#-f Andrew in NYC
random text
#!#-U 800-555-1212
#!#-x ABC Company
#!#-c Random text making up the comment - may run over several lines
text randomly thrown in

more stuff


so that text is now in the variable $msgtext
What I need to do is find each line that starts with #!# (and ignore the other random text) and build the command line so that I end up with
sendfax -d (subjectline) -C "/var/www/html/avantfax/images/CustomCover.html" -f "Andrew in NYC" -U "800-555-1212" -x "ABC Company" -c "Random text making up the comment - may run over several lines" 1.pdf 2.pdf etc

Some variables (like -n) don't have a text string to follow. I'd like to have the -c (comments take multiple paragraphs - not sure how that would look).

So, how can I parse the line(s) of text in the email body to pull out the variables?


Andrew
 

billsimon

Well-Known Member
Joined
Jan 2, 2011
Messages
1,540
Reaction score
729
so that text is now in the variable $msgtext
What I need to do is find each line that starts with #!# (and ignore the other random text) and build the command line so that I end up with
sendfax -d (subjectline) -C "/var/www/html/avantfax/images/CustomCover.html" -f "Andrew in NYC" -U "800-555-1212" -x "ABC Company" -c "Random text making up the comment - may run over several lines" 1.pdf 2.pdf etc

Some variables (like -n) don't have a text string to follow. I'd like to have the -c (comments take multiple paragraphs - not sure how that would look).

So, how can I parse the line(s) of text in the email body to pull out the variables?

You can use preg_match (regular expression match) on that variable to extract what you want. http://php.net/preg_match

Code:
if (preg_match('/^#!#-C (.*)$/m', $msgtext, $matches))
    $coverfile = $matches[1];

if (preg_match('/^#!#-f (.*)$/m', $msgtext, $matches))
    $fromPerson = $matches[1];

and so on. (Didn't test that so use and debug at your own risk.) Quick description: if there's a match of this regex pattern (first argument) in the block of text (second argument), then put the parenthesized part (the text after the space and up to the end of the line) into $matches. The parenthesized part will go into $matches[1], and then you can take that as your $coverfile variable for example.

The /m modifier after the regex indicates you are working with a multiline block of text.
 

trupsalms

Member
Joined
May 13, 2011
Messages
337
Reaction score
6
@billsimon where do you place the two files in regards to ubuntu 14.04 asterisk 13 etc, i have avantfax install not sure the difference in hylafax
 

billsimon

Well-Known Member
Joined
Jan 2, 2011
Messages
1,540
Reaction score
729
@billsimon where do you place the two files in regards to ubuntu 14.04 asterisk 13 etc, i have avantfax install not sure the difference in hylafax

My version is for Asterisk's fax module (spandsp / res_fax) and won't work with the Avantfax or Hylafax solution. But if you were using the Asterisk fax module you could place the files anywhere on your filesystem (maybe under Asterisk home directory and owned by the asterisk user) and then you just run the script regularly with crontab to check the mailbox and send the faxes.
 

AndyInNYC

Active Member
Joined
May 23, 2013
Messages
772
Reaction score
124
OK,
I have the text of the message (body) in $msgtxt.
strlen($msgtxt) returns 484

My email body is:
Code:
#!#-c This is an email which should go to the grand poobah of the Americas.  This is a "Special Fax" and we'll see how the special quotes get through.
#!#-f Andrew In NYC
#!#-r Regarding Nothing in Particular
#!#-S 8005551212
#!#-U 6094441212

The search for -f comes back correctly as does a search for the rest. A search for -c (comments) gets truncated and shows up (via echo) as:
This is an email which should go to the grand poobah of the Ameri=

A check voi strlen of the returned string indicates that that is the length captured - ie it's not just truncated onscreen.

I was using a long string containing double quotes to see if the double quotes would come through. The captured text doesn't even get to the string.

Help?

Andrew
 

AndyInNYC

Active Member
Joined
May 23, 2013
Messages
772
Reaction score
124
So, I've used the imap_qprint function on the $msgtxt and I get back 'usable' text. Yay!
Unfortunately, it comes back with a few stray characters.
For example, the -c example above is returned as:
Code:
This is an email which should go to the grand poobah of the Americas.  This is a "Special Fax" and we'll see how the special quotes get through.

Notice the character after the 'Americas.' In the actual text, this is just two spaces and then the word 'This'.

There are a few other examples of the same character. Any idea what this is?

Additionally, I'm thinking of allowing multiple paragraphs of -c and stringing them together so that a multi-paragraph set of comments can be created. I'll stick with 1 (first) for now and add that later if I get everything else working.

I have a feeling that you've now spent more time assisting me than if you'd simply done this yourself <g>. Teach a man to fish, I guess <g>.

Thanks for the help on the accented character appearance above.

Andrew
 

billsimon

Well-Known Member
Joined
Jan 2, 2011
Messages
1,540
Reaction score
729
It's a character conversion error because you are double spacing after the period. The  is a mistranslation of the hard space character. (Double space ends up being one hard/non-breaking space and one regular space.)

Simply stop double spacing after periods and your problem will go away!

Or just use str_replace to change it into a space...
PHP:
$decodedAndCleanedUpText = str_replace('Â', ' ', quoted_printable_decode($msgtext));
 

AndyInNYC

Active Member
Joined
May 23, 2013
Messages
772
Reaction score
124
OK, I'm getting there.

1. I can't figure out how to get the 'hard space' accented character into my nano text to str_replace it. I have tried the Alt -0XXX code, but that doesn't seem to work - what's the trick here?

2. I have built an 'exec'-able line, but I have a questions about double quotes. The comments section is likely - as are other variables (file names, regarding, etc.) to have double quotes or other special characters. Will I need to to use the addslashes() command to 'fix' these, and if so, will they then be interpreted correctly once sendfax hands them off? My sendfax line presently looks like this:

sendfax -d 6095551212 -c "This is an email which should go to the grand poobah of the Americas. This is a "Special Fax" and we'll see how the special quotes get through." -f "Andrew the Sender" -r "Regarding Nothing in Particular" -S "8005551212" -U "6098001212" "/var/FaxMail/imap-dump/A.pdf" "/var/FaxMail/imap-dump/File2.pdf" "/var/FaxMail/imap-dump/A Letter.pdf"

This is 'right' visually, except for the "Special Fax". In theory, the first double quote ends the "-c" variable and foobars the rest of the line. What's the right way to fix this so the command can be executed?

Next steps.

1. Save the files using a random name and send using this name - some email system seemingly can send an email with attachments with duplicate names and my routine doesn't check for dupes.
2. Figure out where on my pbx to store these files/directories. On my test machine, I need to be sudo to actually save the files. I may not have this problem on the PBX by default.
3. Figure out if I can search/search again for the "-c" fields to allow multiple paragraphs of comments - some faxes may be more about the comments than sending an attachment.
4. Rework the code to do as much in a single loop as possible. I'm presently search for parameters and building the array and *then* relooping through the completed array to see which variables are 'used' and building the command line. In theory I don't even need to build the array - just build the command line string on the fly and ignore the interim results. I'll probably keep the completed array (contains the variable [-d], whether it takes an argument, whether it is used and whether it needs to be contained in strings.
5. Delete temp pdf files after sending the fax.
6. Perhaps some form of notification if the email is malformed and sendfax can't/won't send it. Not sure how to go about this. I'll get the stuff that was done right working first.

So, any thoughts on #2 (way above)

Clearly I was way too optimistic about this taking me 3 days ...


Andrew
 

dicko

Still learning but earning
Joined
Oct 30, 2015
Messages
1,633
Reaction score
842
I would suggest that PHP libraries might be a little over the top for mime extraction, basic linux utilities like mu (extract) or the better ripmime will do it just fine in jut a few line of bash, extract the included files but give you also a txt or html body that works (don't use the html version), don't overuse sendfax, it likes 'cheap and cheerful' arguments, body, included files and subject work just fine . echo the body text through a pipe and you are good to go
 
Last edited:

AndyInNYC

Active Member
Joined
May 23, 2013
Messages
772
Reaction score
124
Dicko, thanks. Unfortunately, I need more than 'cheap and cheerful'. The idea is to be able to fax from outside my pbx.
But for (famous last words) taking the double quotes into account, I think I have a viable solution. Maybe not.

Is there a rule for how command line utilities treat, or should treat, quoted text?

Andrew
 

Members online

No members online now.

Forum statistics

Threads
25,812
Messages
167,764
Members
19,241
Latest member
bellabos
Get 3CX - Absolutely Free!

Link up your team and customers Phone System Live Chat Video Conferencing

Hosted or Self-managed. Up to 10 users free forever. No credit card. Try risk free.

3CX
A 3CX Account with that email already exists. You will be redirected to the Customer Portal to sign in or reset your password if you've forgotten it.
Top