APLawrence.com -  Resources for Unix and Linux Systems, Bloggers and the self-employed

Creating Contact Groups from Mail Groups


2013/06/09

At "Consider using Kerio Connect Contact Groups instead of Mail Groups", I talked about the advantages of Contact Groups for internal lists. If you only had one or two such lists with a small number of contacts in each, you could manually convert them to Contact Groups without much work. But what if you had several dozen to convert? That would be tedious, wouldn't it?

Fortunately, it's not particularly difficult to script this. We first need to understand how Kerio creates Contact Groups, then we need to gather the members of the Mail Groups we want to convert and then (with a little bit more work) we can create new Contact Groups.

(This article is a bit more geekish than usual and the code is longer. It may be of little interest to the average user or administrator.)

Contact Groups Format

Here is an example of what a Contact Group actually looks like on your disk. It's just text; you can examine these things with any text editor.

This one is more complex than we'll actually need because it contains other Contact Groups as well as both individuals and other groups.


Subject: Nested Contact Group
Date: Fri, 7 Jun 2013 08:20:40 -0400
Content-Type: text/x-vcard-dl; charset="utf-8"
Content-Transfer-Encoding: 8bit

BEGIN:VCARD
VERSION:3.0
PRODID:-//kerio.com/Contacts//NONSGML v1.0//EN
X-DL:TRUE
FN:Nested Contact Group
UID:6596500c-5a9d-4788-8aa4-3f7e2ee324c3
BEGIN:X-DL-ITEM
TYPE:REFERENCE
NAME:Robert Lawrence
EMAIL:[email protected]
DATA:fd3ab4b6-4fa0-460a-a14c-2eb13651e369/00000003
END:X-DL-ITEM
BEGIN:X-DL-ITEM
TYPE:REFERENCE
EMAIL:[email protected]
END:X-DL-ITEM
BEGIN:X-DL-ITEM
TYPE:REFERENCE
NAME:AAGroup
EMAIL:[email protected]
DATA:fd3ab4b6-4fa0-460a-a14c-2eb13651e369/00000011
END:X-DL-ITEM
BEGIN:X-DL-ITEM
TYPE:LISTREFERENCE
NAME:Contact Group One
DATA:e14df63c-e49e-45dc-ae98-976e6ff66fca/00000198
END:X-DL-ITEM
END:VCARD

Let's break this down so we understand it. After the stuff that identifies the Contact Group itself, we have the first member:

BEGIN:X-DL-ITEM
TYPE:REFERENCE
NAME:Robert Lawrence
EMAIL:[email protected]
DATA:fd3ab4b6-4fa0-460a-a14c-2eb13651e369/00000003
END:X-DL-ITEM

That all makes sense, but what's that "DATA" line?

That's a reference to another contact. In this case, it happens to be from the GAL (Global Address List) and it is referencing the Public Contacts folder, specifically file 00000003.eml in that folder:

* 00000003.eml in Public Contacts Folder * 

Subject: Robert Lawrence
Date: Tue, 30 Apr 2013 15:15:06 -0400
Content-Type: text/vcard; charset="utf-8"
Content-Transfer-Encoding: 8bit

BEGIN:VCARD
VERSION:3.0
PRODID:-//kerio.com/Contacts//NONSGML v1.0//EN
EMAIL;TYPE=PREF:[email protected]
N:Lawrence;Robert;;;
FN:Robert Lawrence
CATEGORIES:Global Address List
X-SYNCHRONIZED-FROM-GAL:true
UID:a5f72a5b-2264-4ca7-a4f5-8e09294ed86f
X-JABBER:[email protected]
END:VCARD
 

How did I know it would be in the Public Contacts folder? Because inside "status.fld" in that folder is this:

Gfd3ab4b6-4fa0-460a-a14c-2eb13651e369
 

Look familiar? Compare it to

DATA:fd3ab4b6-4fa0-460a-a14c-2eb13651e369/00000003
 

See how the TYPE:REFERENCE works now? The DATA line points it to a folder and a specific contact. It's the same thing for the AAGroup entry - that's 00000011.eml in the Public Contacts.

What about "Contact Group One"? It's a LISTREFERENCE, which means it's pointing at another Contact Group and its DATA tells us it is in the folder with id e14df63c-e49e-45dc-ae98-976e6ff66fca and the file will be 00000198.eml. Where's e14df63c-e49e-45dc-ae98-976e6ff66fca ? That's the same Contacts folder that this Group is stored in; it's status.fld has Ge14df63c-e49e-45dc-ae98-976e6ff66fca in it.

Finally, look at that "nosuchperson" section. There's no DATA line for that, so it didn't come from an existing contact: it was just typed in.

So we see now how we can add items to a Contact Group - we find the members in the Public Contacts if we can and if we can't, we just put them in directly. That part is simple enough.

But what about the first part of the contents?

BEGIN:VCARD
VERSION:3.0
PRODID:-//kerio.com/Contacts//NONSGML v1.0//EN
X-DL:TRUE
FN:Nested Contact Group
UID:6596500c-5a9d-4788-8aa4-3f7e2ee324c3

What is that "UID:6596500c-5a9d-4788-8aa4-3f7e2ee324c3"?

That's a UUID. On Linux, you can generate one with

# uuid
b3d7bd76-d031-11e2-a82d-effcd23bafde

On Mac OS X, use

$ uuidgen
0DF91624-4C8C-477E-B0BA-5694769EBBF1

It's uuidgen on Windows also. You'll need a UUID for every Contact Group you create manually. There are also library routines for creating uuid's, but I'll use the command line versions here.

I took part of the code from my "Exposing hidden data to users" script. The script is fairly long and a bit clumsy, but I hope the logic is easy to follow.

Changes you'll need to make are marked in red.

Note that this particular script is unusually intrusive and could break things. PLEASE UNDERSTAND IT BEFORE YOU RUN IT. If possible, you should run this on copied data first to be sure it is doing what you want. Obviously you'd need to change some paths to do that.

#!/usr/bin/perl
$domainpath="/opt/kerio/mailserver/store/mail";
$domain="aplawrence.com";
open(I,"/opt/kerio/mailserver/users.cfg");
@stuff=<I>;
# These are the groups we want to change into Contact Groups
@groups=("Planning","Sales");
# Get Public Contacts uuid
 chdir("$domainpath/$domain/#public/Contacts");
 open(U,,"<:crlf","status.fld");
 @U=<U>;
 # uuid is second line and begins with "G"
 $cuid=$U[1];
 $cuid=~s/^.//;
 chomp $cuid;
 chdir("#msgs");
 $first_file_num=100;
 # Set $first_file_num above last currently in Public Contacts
 # Danger here:  NO ADDING OF PUBLIC CONTACTS WHILE RUNNING THIS!
 # If you can't guarantee that, SHUT THE SERVER DOWN!
 $newcontact=sprintf("%0.8x",$first_file_num);
#  Get group members
 foreach (@groups) {
   $group=$_;
   $uuid=`uuid`;
   chomp $uuid;
   while (-e "$newcontact.eml") {
     $newcontact=sprintf("%0.8x",$first_file_num);
     $first_file_num++;
   }
print "Writing $newcontact.eml for $group\n";
open(O,">:crlf","$newcontact.eml");
print O <<EOF;
Subject: $group Contact Group D-List
Date: Fri, 7 Jun 2013 08:20:40 -0400
Content-Type: text/x-vcard-dl; charset="utf-8"
Content-Transfer-Encoding: 8bit

BEGIN:VCARD
VERSION:3.0
PRODID:-//kerio.com/Contacts//NONSGML v1.0//EN
X-DL:TRUE
FN: $group Contact Group D-List
UID:$uuid
EOF
   
   $group=$_;
   foreach (@stuff) {
     chomp;
     $start=1 if /<list name="User">/; 
     $start=0 if /<.list>/;
      next if not $start;
      $user=$_ if /<variable name="Name">/;
      $user=~ s/<variable name="Name">//;
      $user=~ s/<.*//;
      $user=~ s/\s+//g;
      if (/<variable name="Groups">$group/) {
         # now find it in GAL Contacts
         chdir("$domainpath/$domain/#public/Contacts/#msgs");
         $found=0;
         foreach(<*.eml>){
           $emlfile=$_;
            $emlfile=~s/.eml//;
            chomp $emlfile;
            open(I, "<:crlf","$_");
            @cfile=<I>;
            close I;
            $fname="";
            foreach (@cfile) {
              $fname=$_ if /^FN:/;
              $found=1 if /^EMAIL.*$user\@$domain/;
             }
         last if $found;
         }
       $fname=~s/^FN://;
       chomp $fname;
print O <<EOF;
BEGIN:X-DL-ITEM
TYPE:REFERENCE
NAME:$fname
EMAIL:$user\@$domain
DATA:$cuid/$emlfile
END:X-DL-ITEM
EOF
      } 
   }
 print O "END:VCARD\n";
 close O;
 }
 chdir("$domainpath/$domain/#public/Contacts");
 rename("index.fld", "index.bad");
 # A server restart will fix things up quickly, but otherwise it may take some time
 

The hard part here is convincing Connect to reindex the Public Contacts. We rename "index.fld" in the script, but it can be a while before anything gets to there to fix it. You can hasten it with a server restart if you are impatient or use this.

Reindex Public folders

After you are satisified that everything is as it should be, you can delete the Mail Groups and start using these.



Got something to add? Send me email.





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

Printer Friendly Version

-> -> Creating Contact Groups from Mail Groups




Increase ad revenue 50-250% with Ezoic


More Articles by

Find me on Google+

© Anthony Lawrence



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





I just had to take the hypertext idea and connect it to the TCP and DNS ideas and — ta-da!— the World Wide Web. ((Tim Berners-Lee)

Lawyer — One who protects us against robbers by taking away the temptation. (H.L. Mencken)












This post tagged: