11.13.03
Vonage voicemail WAV to MP3 conversion
Latest update: Vonage has modified the WAV format that they include in the attachment, breaking the above scripts. See this new post detailing what to do now Ok, so Vonage voicemail can be delivered by email. Except the attachment comes as a WAV file, so it’s HUGE if the voicemail is of any length at all. Can’t be helped that I have to receive these gigantic files, but I’ll be damned if I store them in WAV format, or if I have to download them to my MUA when they’re that big. So, to work around this “feature”, I wrote a perl one-liner which can be called from procmail to replace the WAV attachment with an MP3. To have this work, you’ll need to install lame, MIME::Parser, and of course perl.
# Check if this is a voicemail message from Vonage
:0fw
* ^X-Mailer: CommWorks
* ^From: .*your_phone_number@vm.vonage.com.*
| /usr/bin/perl -MMIME::Parser -e ‘$p = new MIME::Parser; $p->output_to_core(1); $e = $p->parse(\*STDIN); $f = “/tmp/$$”; open(PIPE, “|/usr/bin/lame –preset phone -v -q 0 -V 9 –quiet - $f”); print PIPE $e->parts(0)->bodyhandle->as_string; close PIPE; open(PIPE,”< :bytes”,$f); { local $/; $mp3=<PIPE>; } close PIPE; $fh = $e->parts(0)->bodyhandle->open(”w”); $fh->print($mp3); $fh->close; $e->parts(0)->head->replace(”Content-type”,”audio/mpeg”); $e->parts(0)->head->mime_attr(”content-type.name”=>”voice-mail.mp3″); $e->sync_headers(Length=>”COMPUTE”); $e->print; unlink($f);’
UPDATE: Vonage has fixed voicemail emails so that they now include caller-id information in them. But they did it by inserting a MIME part in the mail. So the script needs to change to the following (also X-Mailer changed, and this also now rewrites the From line with callerID info from the message body):this is a voicemail message from Vonage
:0fw
* ^X-Mailer: UTStarcom
* ^From: .*your_phone_number@vm.vonage.com.*
| /usr/bin/perl -MMIME::Parser -e ‘$p = new MIME::Parser; $p->output_to_core(1); $e = $p->parse(\*STDIN); $f = “/tmp/$$”; open(PIPE, “|/usr/bin/lame –preset phone -v -q 0 -V 9 –quiet - $f”); print PIPE $e->parts(1)->bodyhandle->as_string; close PIPE; open(PIPE,”< :bytes”,$f); { local $/; $mp3=<PIPE>; } close PIPE; $fh = $e->parts(1)->bodyhandle->open(”w”); $fh->print($mp3); $fh->close; $e->parts(1)->head->replace(”Content-type”,”audio/mpeg”); $e->parts(1)->head->mime_attr(”content-type.name”=>”voice-mail.mp3″); $e->parts(0)->bodyhandle->as_string =~ /From: (.*?)\r$/m; $b=$e->head->replace(”From”,”$1 <voicemail \@hughes-family.org>”); $e->sync_headers(Length=>”COMPUTE”); $e->print; unlink($f);’
UPDATE:Wordpress consistently buggers up the formatting of perl documents. The perl script from above, updated, cleaned up is available for download here

Aaron Freimark said,
March 22, 2004 at 3:51 am
This would be great… unfortunately your blog program is munging your code. Can you post a <pre>-formatted version? Thanks.
Dobs said,
July 3, 2004 at 5:43 am
I am having a little trouble getting this sctipt to work correctly
I currently get an email with a blank From address, and an mp3 attachment of 0 bytes and no sound.
I understand what most of the code above is doing, but i must be missing something. Can you please look over this and see what i may be doing wrong.
This is what i have:
#!/usr/bin/perl
#
use MIME::Parser;
use IO::File;
$p = new MIME::Parser;
$p->output_to_core(1);
$e = $p->parse(\*STDIN);
$out = "/tmp/$$";
open(PIPE, "|/usr/bin/lame --preset phone -v -q 0 -V 9 -quiet - $out");
print PIPE $e->parts(1)->bodyhandle->as_string;
close PIPE;
open(PIPE,"< :bytes",$out);
{ local $/; $mp3; }
close PIPE;
$fh = $e->parts(1)->bodyhandle->open(”w”);
$fh->print($mp3);
$fh->close;
$e->parts(1)->head->replace(”Content-type”,”audio/mpeg”);
$e->parts(1)->head->mime_attr(”content-type.name”=>”voice-mail.mp3″);
$e->parts(0)->bodyhandle->as_string =~ /From: (.*?)\r$/m;
$b=$e->head->replace(”From”,”$1 “);
$e->sync_headers(Length=>”COMPUTE”);
$e->print;
unlink($out);
craig said,
July 6, 2004 at 4:41 am
Looks like you have a copy/paste error there on the second open() call. Is that what you actually have in your code?
Dobs said,
July 7, 2004 at 4:02 pm
I found the error. Thank you.
It was not a copy paste error, but i think an error with your blog.
it did not show the
open(PIPE,\”< :bytes",$f); { local $/; $mp3=; } close PIPE;
correctly. it was missing $mp3 =PIPE because it was surrounded by LT and GT signs.
After doing some research on perl and some of the methods you were using, i changed some things. i have it here if you are interested :
use MIME::Parser;
use IO::File;
$p = new MIME::Parser;
$p->output_to_core(1);
$e = $p->parse(\*STDIN);
$f = "/tmp/$$";
open(PIPE, "|/usr/bin/lame --preset phone -v -q 0 -V 9 -quiet - $f");
print PIPE $e->parts(1)->bodyhandle->as_string;
close PIPE;
if( open(PIPE,"< :bytes",$f) ) {
if( $fh = $e->parts(1)->bodyhandle->open(”w”) ) {
my $buffer;
while( read(PIPE, $buffer, 10240) > 0 ) ### read chunks of 10KB at a time
{
$fh->print($buffer);
}
$fh->close;
} else {
warn “Error opening MIME part for writing: $!”;
}
close PIPE;
} else {
warn “Error opening mp3 file $f: $!”;
}
$e->parts(1)->head->replace(”Content-type”,”audio/mpeg”);
$e->parts(1)->head->mime_attr(”content-type.name”=>”voice-mail.mp3″);
$e->parts(0)->bodyhandle->as_string =~ m/\((\d+)\)/m;
#$b=$e->head->replace(”From”,”$1 “);
$e->sync_headers(Length=>”COMPUTE”);
$e->print;
unlink($f);
Again thanks for the initial script. Great job.
tobiasly said,
March 13, 2005 at 8:20 am
All of these posts have wrong formatting! Wordpress doesn’t seem to be very Perl-friendly. :)
I have posted a correct, working version of this script here: http://www.tobiasly.com/index.php?itemid=291
Thanks for the script to work with!
Craig said,
March 14, 2005 at 12:04 pm
Sorry about the format munging — Wordpress keeps changing the way it does that, I keep going in and fixing the DB to format things properly, and then they break again with the next point release. Very annoying. I’ll just stick a link to the source code file.
tobiasly said,
March 19, 2005 at 12:33 pm
Thanks for the update! The IPC::Open2 use is a good idea, I was wanting to clean up the tempfile use but since I’m the only one who uses my box I wasn’t too worried about it at the moment. I’ll update my post to reflect it!
tobiasly said,
March 22, 2005 at 12:29 pm
A couple more things:
* You may want to store your source code as .pl.txt instead of just .pl, so people don’t accidentally launch the Perl script when trying to view it!
* I’m pretty sure you want to remove the last two lines of your current script (the unlink and rmdir); I’m assuming these are left-over from the tmpfile version.
* Every program I use to open the converted MP3s thinks the duration is half as long as it actually is. I’m guessing this is a LAME issue, but I can’t see what parms might fix it. Does anyone have ideas?