« In the Hopper | Main | Minor Updates »

Call Center Recordings Script

One of the conditions of my transfer from medical records to IT all those years ago was that I would manage the phone system. The company I work for is in a weird place, size-wise, where it is typically too expensive to use hosted services, but also too expensive to have specialist employees who know a lot about a given subject and can run them in house. What ends up happening is we do whatever it is in house, and the duty to learn and maintain the thing falls to me or my boss. The particularly unsavory tasks (like managing the phone system) tend to fall to me.

Recently, I got a call from our call center manager asking if we could record all the customer calls for the call center, and hold them for 90 days. Usually we record all the calls for new call center people for a month to make sure they're doing an ok job. The phone server doesn't have the capacity to hold that much (roughly 6GB per month per user), so I started looking for alternatives.

We use Avaya IP Office and Voicemail Pro, and we kind of lucked out because VM Pro stores everything as Windows directories and WAV files. I did a little experimentation, and it didn't seem to harm anything if I manipulated those files through Windows instead of their interfaces, so I knew I could write something to extract the desired files and store them somewhere with enough room.

Here's my list of requirements for the script:

  • Has to differentiate by user
  • Has to store 90 days of recordings for each user

Nothing too difficult, but I wanted to deliver a little something more. So I quietly added, to myself:

  • Has to use familiar names for call center agents instead of the VM account names
  • Has to further differentiate by date of recording
  • Call center manager has to be able to update the Call Center user list
  • Logging

The first requirement is simple, provided the phone server is set up properly. It uses voice mailboxes to store recordings, so I needed unique locations to store each user's recordings. This may be an odd implementation, but I opted to make a hunt group with CCRec and the number of their desk in the call center for the name. This served 2 purposes. 1 - There are far fewer hunt groups than users, so there is little chance these entries in the system will be confused for actual users. Empty hunt groups with a naming convention like that should be pretty obvious to someone familiar with IP Office. 2 - Hunt group mailboxes can be added as additional mailboxes on IP phone units. User mailboxes are restricted to 1. So if the call center manager wanted to access a particular user's recordings as they are happening, they can be set up as alternate mailboxes on the phone.

I say "as they are happening" because the script will only run once a day, after hours. So there will never be access to the current day's recordings, unless they are associated with the phone. I don't think this is likely to happen, but it gives me options.

Once the hunt groups were set up, I got to work on the script. When writing this stuff, I tend to try to make it work first, then refine it later. So I just stuck all the user names in a big array, with a subarray for each user (that way I could keep the user name and the actual person's name together). The script would loop through the large array, extract the necessary user names, and move the files from the server to the computer, creating folders when necessary.

This is one of the things I enjoy about Powershell. I knew what I wanted to do, and more or less how to do it, but I wasn't sure of the specifics. Powershell gives you a lot of tools to extract properties of a file and do stuff with them. I knew I wanted to split the recordings by day, and have it work if a few days were missed for whatever reason, so I knew I wanted to create the day folders using the last write time for the file. Powershell makes it so easy to extract that, and then repurpose it. And since I was grabbing a datetime object, why not use the actual time part to name the file, that way they sort correctly automatically when viewed in the folder?

Computer sorting is fun. Using month names is out, since they don't fit alphabetic sorting conventions. month/day/year is pretty standard for us Americans, but it kind of falls apart if you need multiple years. All your months will sort together, then day and year. If you think you'll need to track years of data, you need to start with the year, then month and day. Since I was naming folders after the date, too, I couldn't use / as delimiter. That's a no-no for Windows file/folder names, so my dates ended up looking like this: 2014-05-16, which would be May 16th, 2014. Using the time for the recording name presented a similar challenge. I didn't realize it at first, but you run into the same problem as starting with month numbers if you start with the hour. Starting with the hour is fine if you're using a 24 hour format, but if you're using 12, then the sorting gets screwed up if you don't put the AM/PM first. Colons are also a no-no for filenames, so I had to resort to hyphens again. So the times look like this: AM-09-22-49 for a recording that happens at 9:22:49 AM. Using the seconds probably wasn't necessary, but I found it easier to understand the time that way. Here's that time without the seconds: AM-09-22. The AM makes it obvious that it's a time, but I think it would be easy to confuse a lot of these with dates.

I was happy with all that, so I moved on to the next thing.

Now I kind of ignored the 90 day limit when writing this script. My plan is to write a separate script that will check for items older than 90 days and delete them. I saw no reason to add that to this particular script. Plus I have 90 days until I REALLY need to worry about it, right? So as far as the call center manager was concerned, I could call it a day. I really wanted to make this thing shine, though, so I kept going.

I had already added the part about using actual names on the recordings copies. Basically it would use the name associated with the user account in the array to name a folder, then create the date folders inside that. So the only things left on my list were logging and giving the manager a way to edit the user list.

Logging was fairly simple. This is not a very critical app, so outputting a success or failure message to a text file was sufficient. I had a little realization while writing this part. This is going to sound ridiculous considering how much time I've spent in the past year or so teaching myself programming, but I don't think I really understood that you can store the boolean result of a function in a variable. I can't remember if this got changed later, but I know at one point I was performing the copy action and saving the result to a variable, and then testing the variable with an if statement to see if it evaluated to true or false. I feel like this is something that should be trivially obvious to anyone into this stuff, but it never quite connected like it did while writing this script. Once done I ran a few tests and was satisfied with the result. I couldn't figure out a way to make it fail. The script gets the names of the files to copy by pulling a list of files from the actual directory, so creating a mismatch between the actual file name and the expected file name is basically impossible. I'll probably mess around with it a bit more before I'm satisfied.

The trickiest part of the script ended up being the ability to let the manager change the names. I knew expecting the manager to open the script file and manually change the names was out of the question. So I switched the users array from being an array of arrays to being a simple text file that the script uses to populate the agents array. This would prevent the manager from screwing up my script (or at least lowered the potential). Even this seemed like a lot to ask for, since they would have to preserve the exact structure I'm using in the script. The next step?

I ended up writing a quick PHP page that would grab the file, extract its contents and stick it in a form, and let the manager change the names using that form. This had its own problems, but nothing worth going into here. I probably should have used C# for the forms page, but for something quick and dirty like this PHP just seems easier to me. I think it might be due to me learning and exclusively using PHP for a good chunk of time before getting into anything else.

After a good amount of testing, I'm happy with the whole thing. I just finished deploying it on Friday, and it is currently set up to only work with the newest agent still on probation. The manager likes to take his time replying to me, so I'm still waiting on the green light to start it for everyone. Probably good to start on a single person anyway, make sure everything is behaving.

If all goes according to plan, this thing could actually be useful to other people (imagine that!) with similar systems. I think the script is sufficiently modular that it would be easy to redeploy on someone else's system. The biggest hassle would probably be setting up the PHP page if the webserver wasn't already set up with it.

I want to write some documentation, and remove the work-specific paths and what not, then I'll probably add it to GitHUb. I have some other powershell scripts that might be useful, maybe I'll make a little powershell collection.

PrintView Printer Friendly Version

EmailEmail Article to Friend

Reader Comments

There are no comments for this journal entry. To create a new comment, use the form below.

PostPost a New Comment

Enter your information below to add a new comment.

My response is on my own website »
Author Email (optional):
Author URL (optional):
All HTML will be escaped. Hyperlinks will be created for URLs automatically.