Notifying service techs with Kerio Connect


I recently helped a Kerio Connect customer add a new feature to their existing emergency customer service notification system. Their current system is telephone based: when a customer calls, it hunts the list of on-call techs until someone answers. The customer wished to add a web-based request system to augment that.

He contracted with a web firm to design a good looking form and I asked them to email the form data to a new email address we created. That email address is an alias that delivers to a public folder rather than being delivered to a user (that's an option you can choose when creating an alias with Kerio Connect).

I then created a script that watches the public folder for new mail and forks off another script that will send an SMS message to an on-call technician, wait for a reply and try the next on-call tech if it doesn't receive any reply within twenty minutes.

Watching the public folder

There are a number of ways of monitoring file or directory changes, but I opted for the brute force approach here to keep the code less operating system dependent. This happens to be a Linux system, so I created a crontab job to run every ten minutes. The script itself does ten loops, one minute apart, so we are actually checking every minute.

This dual approach (crontab and a loop in the script) has two advantages: one, it lets me easily adjust the resolution of the checks to a smaller or larger time easily and it also helps guard against the script accidentally getting killed - crontab will restart it within ten minutes.

The script does depend upon a file that records the latest file modification time seen, but basically it just loops through the .eml files:

# your public folders can be here or within your domain folder, 
# depending on how you configured the domain.

for ($x=0;$x<10;$x++) {
  open(LAST, "/root/data/lastseen");
  $last = <LAST>;
  foreach (<*>) { 
    system("/root/bin/ $_ &") if ($s[9] > $last);
    # $s[9] is mtime
  open(LAST, ">/root/data/lastseen");
  print LAST $last;
  close LAST;
  sleep 60;

Notifying a tech

The first problem is knowing who to notify. You could do this with a web form that creates a file for us to get the on-call list from, but here we opted to allow the manager to email this list to another alias that goes to another public folder.

To simplify things, the code below assumes that the manager will send the list in plain text. As it might well be HTML, the actual processing for that would be more complicated.

The list send needs to include the technician's SMS email address and (this is important) the address they will reply from. That's how our script will know that it has had a reply (which indicates that the tech received the SMS and will handle the call).

This is not perfect. If the tech neglects to respond or does not respond from a known email address, our script will go on to wake up someone else. We thought about making it more complicated (including information in the SMS that would have to be seen in the reply), but decided that any such additions can still fail, so we decided to go with simple.

So, the email the manager sends might look something like this:

Tom Smith 
Tobias Simpson 
George F. Sampson = 

Note the wrapped line that ends with an "=" sign - we need to handle those, too.

foreach (@lines) {
 $subject=$_ if /^Subject/;
 last if $subject;
exit 0 if $subject !~ /has a problem/;
# the Subject line always takes the form of "Customername has a problem"
# This is where the on-call messages go
# find the latest on-call list
foreach( <*.eml>) {
   open(I, $_);
   while (<I>) {
       if (/Subject: On Call SMS/) {
         if ($s[9] > $latest) {
# Extract the list, joining together any continued lines
open(I,"<:crlf","$oncall") or die "$! $oncall";
while (<I>) {
  $intext=1 if /^\s*$/;
  next if not $intext;
  next if /^$/;
  $oncall[$count].= $_;
  $oncall[$count]=~ s/\=$//;
  if (not /.*\=$/) {
  last if $count > 2;

# Now start notifying techs
foreach (@oncall){
 @mess=split /\s+/;
 foreach(@mess) {
   $sms=$_ if /[0-9]+\@/;
 # As we don't know how many fields there will be, we examine each 
 open(MAIL,"|/usr/sbin/sendmail -f servicerequests\ $sms");
 print MAIL <<EOF;
Subject: $subject
Reply-To: servicerequests\

close MAIL;
sleep 60 * 20; # 20 minutes
# check for reply
foreach(<*.eml>) {
   next if $s[9] < $timesent;
   open(CHECK, $file);
   foreach (@lines) {
    if (/^From:/) {
      @from=split /\s+/;
      foreach (@from) {
        $handled=1 if ($technician =~ /$_/);
   last if $handled;

last if $handled;

That's it. It's imperfect, but simple. It has some vulnerability to abuse by insiders; there are things we could do to make that more difficult if necessary but it probably will not be.

Got something to add? Send me email.

(OLDER) <- More Stuff -> (NEWER)    (NEWEST)   

Printer Friendly Version

-> -> Notifying service techs with Kerio Connect

1 comment

Increase ad revenue 50-250% with Ezoic

More Articles by

Find me on Google+

© Anthony Lawrence

Wed Sep 5 15:45:28 2012: 11270   NickBarron


Like it. Simple but very effective.

Good to see more and more posts coming through to here again :)

Kerio Connect Mailserver

Kerio Samepage

Kerio Control Firewall

Have you tried Searching this site?

Unix/Linux/Mac OS X support by phone, email or on-site: Support Rates

This is a Unix/Linux resource website. It contains technical articles about Unix, Linux and general computing related subjects, opinion, news, help files, how-to's, tutorials and more.

Contact us

privacy policy