Command-line mailbox downloader for Cisco Unity Connection

Starting in version 8 of Cisco Unity Connection, it is simple to write scripts to manipulate various aspects of Unity Connection, including user attributes (password/PIN, for example), messages, call handlers, and more, thanks to a new REST API. There are interfaces to both administrative and end-user functions. And not only scripts, but custom web portals or other web integrations. No SOAP and AXL required!

See Cisco’s DocWiki for the details: http://docwiki.cisco.com/wiki/Cisco_Unity_Connection_APIs
And read the rest of this entry for a simple PHP script that connects to a user’s mailbox, dumps all the contents to a local folder, writes out a table of contents and gzips the whole thing up.
#!/usr/bin/php <?php if ($argc !== 3) {   fwrite(STDERR, "Usage: n");   fwrite(STDERR, "  php $argv[0] <mailbox> <password>n");   exit(1); } /* Web connection setup */ $baseURL = "https://YOUR-UCONN-SERVER-HERE:8443"; $auth = base64_encode("$argv[1]:$argv[2]"); $opts = array( 'http' => array ('method' => 'GET',                                 'timeout' => 4,                                 'header' => "Authorization: Basic $auth"),                'ssl' =>  array ('allow_self_signed' => TRUE)              ); $context = stream_context_create($opts); /* Get the user's folders list and counts */ $foldersURL = "$baseURL/vmrest/mailbox/folders"; if (!($result = file_get_contents($foldersURL, false, $context))) {   fwrite(STDERR, "Could not connect to Unity Connection for mailbox folders list.n");   exit(1); } $folders = simplexml_load_string($result); /* Now get contents of each mailbox that has messages */ $currtime = datestring(time()); $outputdir = $argv[1] . "_$currtime"; if (!mkdir($outputdir)) {   fwrite(STDERR, "Couldn't create directory $outputdirn");   exit(1); } $INDEX = fopen("$outputdir/index.txt", 'w'); $mainheader = "Mailbox of $argv[1] downloaded at $currtime"; fwrite($INDEX, "$mainheadern" . sprintf("%'=" . strlen($mainheader) . "snn", "")); foreach ($folders as $folder) {   if ($folder->MessageCount > 0) {     $folderheader = "Folder: $folder->DisplayName";     fwrite($INDEX, "$folderheadern" . sprintf("%'-" . strlen($folderheader) . "snn", ""));     $messagedir = $outputdir . "/" . $folder->DisplayName;     mkdir($messagedir);     $result = file_get_contents($baseURL . $folder->URI . "/messages", false, $context);     $xml = simplexml_load_string($result);     $counter = 1;     foreach ($xml->Message as $message) {       fwrite($INDEX, "$counter. Message from ". ($message->CallerId->CallerName == ""?"(no name listed)":$message->CallerId->CallerName));       fwrite($INDEX, " at " . ($message->CallerId->CallerNumber == ""?"(no number listed)":$message->CallerId->CallerNumber));       fwrite($INDEX, "n");       fwrite($INDEX, "Listened: " . $message->Read . "n");       fwrite($INDEX, "Length: " . $message->Duration/1000 . " secondsn");       fwrite($INDEX, "Timestamp:" . datestring($message->ArrivalTime/1000) . "n");       fwrite($INDEX, "Filename: ");       $filename = datestring($message->ArrivalTime/1000) . "_from_" . $message->CallerId->CallerNumber . ".wav";       fwrite($INDEX, "$filenamenn");       $innerResult = file_get_contents($baseURL . $message->URI, false, $context);       $messageContainer = simplexml_load_string($innerResult);       $audio = file_get_contents($baseURL . $messageContainer->Attachments->Attachment->URI, false, $context);       if (!file_put_contents("$messagedir/$filename", $audio, LOCK_EX))         fwrite(STDERR, "Error writing audio to file: $filenamen");       $counter++;     }     fwrite($INDEX, "n");   } } fclose($INDEX); $tarresult = system("tar czf $outputdir.tar.gz $outputdir"); if ($tarresult !== FALSE) {   system("rm -rf $outputdir"); } else {   fwrite(STDERR, "Unable to create tar.gz file, but the folder is still there.n"); } fwrite(STDERR, "Mailbox dump completed successfully.n"); exit(0); function datestring ($unixtime) {   return date('Y-m-d_H-i-s', $unixtime); } ?>

Google killing off Gizmo5

I just received this e-mail stating that Google is killing off the Gizmo5 VoIP service they acquired in 2009:

Gizmo5 is writing to let you know that we will no longer be providing service starting on April 3, 2011. A week from today, March 11, 2011, you will no longer be able to add credit to your account.

Although the standalone Gizmo5 client will no longer be available, we have since launched the ability to call phones from within Gmail at even more affordable rates.

Thank you,

The Gizmo5 Team

Before Google’s purchase of Gizmo5, the SIP provider had a unique relationship with GrandCentral and then Google Voice that allowed a SIP connection (incoming only) to a Google Voice number. Until FreeSWITCH and Asterisk provided updated Google Talk modules last fall, Gizmo5 was the only way to have a purely VoIP connection to Google Voice.

Some recent projects for fun and work

I’ve had fun with a few personal and work-related VoIP projects lately. I’ll summarize them here, and if there’s any interest I’ll expand one or more of them into full how-to articles. 

speak2tweet
You may have heard about the Google/Twitter project called speak2tweet that was created over a weekend during the Egyptian protests, with the goal of allowing protesters whose Internet connectivity was cut to get their voices on to the web. Some folks on the PBX-in-a-Flash forum were talking about it and we realized it would not be hard to build, especially with the Tropo transcription service available to us.
Check out the first page of that thread for the dial-in numbers, and then try it out yourself. The code is posted on the forum for the first hack at it, which only does transcription. The current version includes links to the recordings, too, just like the original speak2tweet. I need to clean it up and post it. See and hear your spoken tweets at twitter.com/piafspeaktweet.
Fax
I have largely ignored fax over VoIP for a long time, because it’s not something I do. At PSU, we attach fax machines to analog lines; done. But recently, I was asked to assist with a quick-turnaround fax project: send a fax to 4,059 analog lines on campus, calls spaced one minute apart, and record the results, so that we can see how many fax machines are hooked up out there. Interesting. I tried Digium’s Free Fax for Asterisk module, but couldn’t get it to communicate. Next I built the soft-switch.org spandsp module, and told Asterisk to use it, and it worked right away. A Perl script using the excellent Asterisk::AMI module (referenced previously on this blog) drove the dialer, and standard Asterisk CDR with a few extra fields recorded the fax results. By the way, the faxes were sent in audio mode (not T.38) using SIP and G.711u over the Internet, and only 3 out of 4,059 calls failed.
FreeSWITCH revisited
Back when I wrote about using FreeSWITCH alongside Asterisk as a gateway to Google Voice, I determined that at some point I’d come back and dig into FreeSWITCH a little more just to understand it. I updated that article with a slightly better config, including lines that turn on comfort noise, which helps the FreeSWITCH-Asterisk bridge maintain synchronization on RTP. (See the FreeSWITCH wiki for more information on that.)

ssmtp to handle your PBX’s e-mail

Here’s a simple how-to for processing the mail your Asterisk server generates, without running a full mail-transfer agent (MTA) like sendmail or postfix.

First, two assertions:

  • You need to deal with mail, even if you aren’t using Asterisk’s voicemail-attached-to-e-mail feature, because your system daemons like cron are generating mail that you may want to read.
  • Running a mail daemon of any kind is a waste of resources when all you really want to do is get the mail off your Asterisk server to some other server for processing.

In the past, a Linux admin would enable sendmail, set the domain name and basically be done. Mail would work on port 25, everyone would accept everyone else’s mail, and life was good. Then spammers ruined our lives and we have to use strange ports, domain validation and a bunch of other things to make ourselves an official mail server. That’s too much work, especially for a box that’s supposed to be a PBX, not a mail system. And if you’re on a residential Internet connection, forget it–you’re probably in every blacklist.

Enter ssmtp, the simple SMTP sender. We’ll use it to send both Internet e-mail, such as might be produced by Asterisk’s voicemail system, and local root-type mail (e.g. cron alerts) through a legitimate SMTP server. It does not run as a system daemon, only on-demand when something on the server generates e-mail. And it’s simple to set up.

Setup

  • Get the source: http://packages.debian.org/source/sid/ssmtp . The file you want is the orig.tar.bz2 file.
  • tar jxvf ssmtp_(version).orig.tar.bz2 to expand it.
  • ./configure --enable-ssl (if the build fails later, yum install openssl-devel [CentOS/RedHat] to get the necessary SSL libraries)
  • make then make install, as root. On a fresh install, sample configurations are installed in /usr/local/etc/ssmtp/. The program is in /usr/local/sbin/.
  • Edit /usr/local/etc/ssmtp/ssmtp.conf. For a basic configuration that will send all locally-addressed mail to a single address, and Internet-addressed mail to the appropriate address, this is all you need:
    # The person who gets all mail for userids < 1000 root=mailbox@example.com # The place where the mail goes. The actual machine name is required # no MX records are consulted. Commonly mailhosts are named mail.domain.com mailhub=smtp.gmail.com:587 # The full hostname hostname=asteriskbox.example.com fromlineoverride=yes authuser=USERNAME authpass=PASSWORD useTLS=yes useSTARTTLS=yes authmethod=LOGIN 

    This example configuration, as you can guess, is for a Gmail account, and will also work with a Google Apps account. Since so many folks use Gmail, you could just cut and paste this, replacing the hostname and credentials with your own. If you are using a different SMTP server, adjust as necessary. With Gmail, the fromlineoverride won’t work–Gmail uses your Gmail address as the From. But it may work on other servers, especially if you are running your own mail server on a different box and send your mail to that.

  • Finally, get rid of sendmail and link to ssmtp in its place. yum erase sendmail will get rid of it from CentOS. Then ln -s /usr/local/sbin/ssmtp /usr/sbin/sendmail to trick your programs into believing sendmail is there, while ssmtp runs instead.

Test it out

You can install mailx with yum install mailx, then try both local mail and Internet mail:

mail root
mail youraddress@example.com

With mail, end your message by pressing Control-D.

Or you can use ssmtp directly: ssmtp root or sendmail root

Try sendmail -t and then fill out the header by typing to: address and so on.

Once you see that mail is moving, you’re done. If you encounter a problem, check /var/log/maillog.

More advanced

If you want to control where mail goes for individual local accounts, check out the revaliases file in /usr/local/etc/ssmtp/. Otherwise, all mail destined to local accounts with UID < 1000 will go to the mailbox specified in the root= line in the config.

Note

If you are using authenticated SMTP (as in the example config above), your ssmtp.conf file contains your SMTP password in plain text. If your box is secure and you are the only user of it, this may not matter. If other users are logging in to the box, and you don’t want them to be able to see the config, you can chmod 600 ssmtp.conf to make it readable only by root, then setuid root the ssmtp binary with chmod +s /usr/local/sbin/ssmtp .

References

Debian wiki on sSMTP

Asterisk hack: make your Google Talk client invisible

It’s been a too-busy-to-write week, but I found some time the last few evenings to brush up my C coding (only hacking at this point, really) to make Asterisk 1.8 do something I’ve wanted from the beginning: Google Talk’s invisible mode for the Google Voice integration.

Quick background: Google wrote a variety of XMPP extensions to make Google Talk do voice and a bunch of other non-standard XMPP things. One of those things is what Google calls “shared statuses,” which also includes invisible mode–the ability to be online but set your client as invisible so that others can’t see you, but could chat with you.

You might want to use this feature if, like me, your Google Voice number is attached to your main GMail account. I don’t use the chat features but I appear online to anyone who has me in their contact list, as long as Asterisk is logged in, and that has the potential to draw unwanted instant messages (that will never get answered).

Note: I want to reinforce that this is a hack. The code is clean enough, but this is only useful for Google Talk and is only implemented as a set of Asterisk CLI commands. Furthermore, this functionality would probably never be implemented in Asterisk’s res_jabber because it’s Google-proprietary. On the other hand, if any Asterisk developers want to run with this, go for it! I don’t guarantee that this code will work for you and if your Asterisk process segfaults, stop using it.

Setup

Apply this patch against Asterisk 1.8.2.2’s (or trunk, currently) res/res_jabber.c by downloading the patch to your Asterisk source directory and running patch < res_jabber.patch . You may have to tell it to apply the patch to res/res_jabber.c.

Rebuild (or build) Asterisk. If you are rebuilding, just run make after applying the patch. You should see make build the res_jabber module. Then make install and restart Asterisk.

Usage

At the CLI, you can issue jabber set invisible on asterisk to turn on invisibility for the Jabber connection named “asterisk.” If you don’t know what your Google Talk XMPP connection is called, just issue jabber show connections and find out. You can set your connection visible again with jabber set invisible off asterisk.

Now, here’s another thing that is really hacky: Google Talk only seems to apply the visibility/invisibility change if you are toggling. Here’s what I mean: if you were invisible, and logged out, then logged back in, Google still thinks you are invisible–but you’re not! So in that case, if you jabber set invisible on ..., it doesn’t do anything, until you first set it off and then back on again. I think I know why this is happening and it has to do with res_jabber sending standard <presence> information at login rather than Google’s special shared-status presence scheme. If you want to be sure you are invisible, just start off by setting invisible off and then set it on. For me, that works every time. (I’d be grateful for someone who really knows all about this to fix it up and make it work right, the first time.)

References

I got the idea from this year-old blog posting about enabling Google Talk invisibility in Pidgin, which refers to the official documents published by Google on how it works.

Update on rotary phone refurbishment

In my last post, I suspected problems with the rotary dial on the Automatic Electric Monophone model 40, and a wiring problem on the Northern Electric 302, both of which kept me from being able to successfully pulse-dial through the HandyTone 502 analog adapter.

After a quick wiring check on the 302 and a lot of tweaking and oiling of both dials, I have to throw in the towel on getting these two to pulse-dial. Both need to have their centrifugal governors (the part that regulates the dial’s return speed) adjusted: the 302 pulses too slowly and with some irregularity, and the Monophone 40 pulses too quickly. I have read that telephone technicians of the past had to practice dial repair for a week under supervision before becoming competent at it. That is to say, the final touches are definitely beyond my skill level, and with a voice-driven workaround available, I’ve decided to call these phones “complete”–for now. I’m a tinkerer and may get adventurous some day and rip the phones apart once again.

A brief review of the Grandstream HT-502 ATA

The used HT-502 2-FXS analog telephony adapter I bought from eBay arrived earlier this week, and I hoped that by this time I could write about two functional rotary dial phones happily dialing out through this device.

No such luck, but the HT-502 is not to blame. The Northern Electric 302 seems to be mis-wired, because the ATA isn’t detecting the pulse dialing at all. I’ll have to open it up and dig in this weekend. The Automatic Electric Monophone 40, on the other hand, is wired correctly but needs some adjustment: the upper digits (7 through 0) sometimes miss a click, resulting in mis-dialing.

Image from Grandstream.comThat said, I’m already prepared to give the Grandstream HT-502 ATA very positive reviews. In fact, I might like it even better than my trusty Cisco-Linksys-Sipura SPA3102.

You can read about the device on Grandstream’s web site. Here are the unmentioned features that I really like:

  • It accepts rotary/pulse dialing, without any special configuration or modification. This was the reason I bought it, and indeed, it works. The HT-503 (1 FXS and 1 FXO port) can accept pulse dialing on its FXS port, also.
  • On an active call, it accepts rotary-dialed input and converts to SIP DTMF codes. Thus you can navigate a menu tree with your rotary phone, as long as you don’t need “*” or “#”.
  • You can configure the device with a touch-tone phone (real touch-tone; “*” required), web browser, or telnet. You can also provision the device using TFTP like the “big guys” do.
  • It has an excellent debugger. In the Advanced menu, enter the IP address of your syslog server (prerequisite: set up a syslog server), and set the verbosity to DEBUG. The floodgates will open and you will be able to see every action the device performs or receives, including dialed digits from the analog ports. This is how I was able to see where my rotary dial was sticking.
  • The device can pull its own firmware upgrades over the Internet. Nice if used carefully.
  • It’s super easy to configure. I followed documentation to factory-reset the device, hooked up a laptop to the LAN port, and reconfigured it for my own network in about 5-10 minutes. 
  • Lastly–and this is a rather obscure bonus–it uses the same power supply specifications as the Cisco-Linksys SPA devices. This hardly matters except that I have one of these–a wireless bridge for Cisco SPA devices with pass-through power. I’m planning to make the HT-502 WiFi.

The HandyTone 502 has made a good first impression and I’m looking forward to getting my rotary phones fully working on it.

A new old phone and rotary dialing, revisited

During the holidays I received and lightly restored another beautiful telephone from the 1940s, this Automatic Electric Monophone model 40:

ae40.jpgAutomatic Electric was an independent supplier of telephone equipment throughout the 20th century, eventually being purchased by GTE, and in direct competition with the Bell empire (or Western Electric, Bell’s equipment division) throughout its existence. The community-written Wikipedia article tells more of the story.

Some details about this Monophone:

  • Manufactured from 1939 to the mid-fifties, but I can’t find a stamp on the inside or outside to date it.
  • The coiled handset cable would typically indicate a later model, but the nicked-up brass screws inside the handset where the cable is connected suggest that the coiled cable was an upgrade or repair at some point in this phone’s lifetime. So it may be an old phone body with a newer cable, or it may be a later model, all-original.
  • The dial plate seems to be uncommon. Browsing many pictures of AE model 40s on the web, I haven’t seen any others with white-numbered, black dial plates. Also, it has no alphabet markings, only digits.
  • It’s all Bakelite, and heavy. The Northern Electric 302, with a thermoplastic shell, is almost a full pound lighter. External data: someone weighed their own collection of phones.

The Northern Electric 302 and the Automatic Electric Monophone 40 ready to duel:
ne320-ae40.jpgThe AE40 works fine and will be a new addition to the analog remix, but I decided to do one more search for VoIP analog telephony adapters (ATAs) that will accept rotary/pulse dialing. Recently, a commenter suggested UTStarcom adapters, but others report of an ATA that is still in service and accepts rotary dialing: the Grandstream HT-502/503. I have a 502 coming from an eBay auction and will report back on how it works out.