Tuesday, January 1, 2008

Fixing vonage voicemail to work with the iPhone

We have vonage. We're pretty happy with it. One thing that's particularly nice is that they will e-mail you voicemails as attachments (I wish they would not then also store them in a voicemail box that has to be hosed out periodically, but that's another issue). The one downside is that these voicemails are attached as µLAW WAV files, which aren't compatible with the iPhone.

Not to worry: if you run your own mail server, a little bit of perl can re-encode them as MP3s, which the iPhone is perfectly happy playing. So now vonage voicemail comes in as e-mails on the iPhone, with MP3 attachments that can be listened to. Huzzah!

To use this, set up an alias in sendmail to pipe the e-mail through this perl file, adding the destination e-mail addresses as arguments. For example:

vm-fixit: "| vonagevm.pl user@example.com other@example.com"

Then, set the vonage e-mail address in the voicemail set-up to vm-fixit @ your domain. With the example above, it will change the audio to an MP3 and mail it to user@example.com and other@example.com.



#! /usr/bin/perl

use Email::MIME;
use Email::MIME::Modifier;
use File::Temp qw/ tempfile tempdir tmpnam /;

my $in_msg;

{ local $/=undef;
$in_msg = <STDIN>;
}

my $message = Email::MIME->new($in_msg);

$message->walk_parts(sub {
my $part = shift;
return if ($part->content_type !~ m[audio/wav]);

($fhw, $filenamewav) = tempfile( SUFFIX => ".wav" );
print $fhw $part->body;
close $fhw;

(undef, $filenamemp3) = tempfile(SUFFIX => ".mp3");

system "/usr/local/bin/sox $filenamewav -t wav -w -s -r 8000 - | /usr/local/bin/lame -m m -b 32 - $filenamemp3";

my $mp3audio;
{ local $/=undef;
open FHM, $filenamemp3;
$mp3audio = <FHM>;
close FHM;
}

unlink($filenamewav);
unlink($filenamemp3);

$part->body_set($mp3audio);
$part->content_type_set("audio/mpeg");
$part->name_set("voicemail.mp3");
$part->filename_set("voicemail.mp3");

});

open SENDIT, "|/usr/sbin/sendmail " . join(" ", @ARGV);
print SENDIT $message->header_obj->as_string;
print SENDIT $message->crlf;
print SENDIT $message->body_raw;
close SENDIT;

7 comments:

Brandon said...

Neat tip, I'll have to look into this.

On a separate note I noticed that your machine name was vm-fixit, implying that you're using a virtual machine for this? Personally I'm interested in eliminating machines in my house and replacing them with small virtual machines. Have you done this? If so, would you possibly write a posting about your setup and how it's worked for you?

Thanks!

Nick said...

sorry, in this case "vm" means "voicemail." :)

I'm actually using a FreeBSD machine as a mail server, though I don't see why this wouldn't work reasonably well with any other *nix that has Perl, sox, lame and sendmaill installed.

Anonymous said...

Hey Nick,

I just finished creating a Vonage app for the iPhone - take a look at screenshots at http://www.vonagent.com (has directions to add source as well). Let me know your thoughts

Anonymous said...

I noticed that my vonage emails arrive with a content type of audio/x-wav instead of audio/wav. Changing the appropriate test on line 17 was all that was needed to make it work for me. Just thought I'd mention it if others were having trouble.

Anonymous said...

Interesting you say that the file are not compatible with the iPhone. They play just fine here on my iPhone (with the latest updates).

Anonymous said...

Oh dangit - now I just realized that you posted this one year ago :(

Nick said...

That, and even if the wav files now work, the mp3s are much smaller, which is helpful if (like my wife) you have a 1st gen iPhone.