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

Building contact lists from IMAP searches


I wanted to create a contact list (email addresses) of people found through a search of my Sent Mail. Specifically, I wanted to find people where I had sent an invoice relating to specific Kerio products during the previous month.

Building such a list could be useful or important for many good business reasons. You might want to follow up sales inquiries, do compliance checking on employee activity or maintain a database for some other need.

I used the Perl Mail::IMAPClient module for this. My mail server is Kerio Connect and, for my use here, I wanted to search the "Sent Items" folder.

Gmail note: I would have liked to test this against Gmail also, but that requires IO::Socket::SSL, which I could not get to install. I'll look into that later.

The meat of this is the imap search:

my @my_messages = $imap->search("UNDELETED NOT SUBJECT $notthese
SUBJECT $header_subject2 SUBJECT $header_subject SENTSINCE $sentsince
SENTBEFORE $sentbefore") or die "No emails found\n";

See "Search" at RFC 3501 for all the possibilities. Basically, these conditions are implied "AND", so in the search above I'm looking for messages sent on or after $sentsince, before $sentbefore, are undeleted, have the words $header_subject and $header_subject2 in their subject but NOT $notthese.

If you didn't care to limit by date, you'd just remove that criteria:

my @my_messages = $imap->search("UNDELETED NOT SUBJECT $notthese
SUBJECT $header_subject2 SUBJECT $header_subject") or die "No
emails found\n";

A search condition that might be particularly useful in compliance checking is the "ANSWERED" condition. For example, you might want to search for messages addressed to "Sales" that have not been answered:

my @my_messages = $imap->search("UNDELETED NOT ANSWERED TO
$sales") or die "No emails found\n";

The opposite search might be useful for checking that you have billed for all answered email questions from a particular customer this month:

my @my_messages = $imap->search("UNDELETED ANSWERED FROM
$customer SENTSINCE $sentsince SENTBEFORE $sentbefore") or die
"No emails found\n";

Remember that order doesn't matter and the relationship is "AND" always.

Simple scripts like this can provide information that is otherwise hidden in a mass of data.

#!/usr/bin/perl -w
# from http://aplawrence.com/Kerio/contacts_from_search.html

use strict;
use Time::Local;
use Mail::IMAPClient;

# This is the stuff you'd modify
my $year=2012;
my $month=4;
my $inbox="Sent Items";
my $host="mail.aplawrence.com";
my $user="Sales-Support";
my $passw="xyzxyzx";
my $header_subject="Kerio";
my $header_subject2="Invoice";
my $notthese="Control";

# I'm looking at one month's worth of email only
#  see the article text for more on that
my $since=timegm(0,0,0,1,$month - 1,$year - 1900);

if ($month > 12) {
   $month=0; $year++;
my $before=timegm(0,0,0,1,$month - 1,$year - 1900);

# this will hold unique email addresses
my %mailers;

my $imap = Mail::IMAPClient->new(
				 Server   => $host,
				 User     => $user,
				 Port     => 143,
				 Password => $passw,
				 Peek     => 1,
				) or die "Cannot connect: $@";

my $sentsince = $imap->Rfc2060_date($since);  
my $sentbefore = $imap->Rfc2060_date($before);  


# see article text for notes on this
my @my_messages = $imap->search("UNDELETED NOT SUBJECT $notthese
SUBJECT $header_subject2 SUBJECT $header_subject SENTSINCE $sentsince
SENTBEFORE $sentbefore") or die "No emails found\n";

foreach my $message (@my_messages)
  my $data = $imap->parse_headers($message,"Subject","To","Date");
  my $address = $data->{To}->[0];
  my @adds=split /,/,$address if $address;
  my $date = $data->{Date}->[0];
  if ((defined $data->{Subject}->[0]) ? $data->{Subject}->[0] : '') {
    # uncomment for debugging
    # print "$date $address $data->{Subject}->[0]\n";      
    foreach(@adds) {
      s/^  *//;
      s/  *$//;
      next if $mailers{$_};
# here's the list
foreach (sort keys %mailers) {
   print "$_\n";

Got something to add? Send me email.

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

Printer Friendly Version

-> -> Compliance checking and contact lists from IMAP searches

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

What worries me about religion is that it teaches people to be satisfied with not understanding. (Richard Dawkins)

While we all ooh and ahh over the reports and graphs, Google is quietly building an incredible pile of extremely valuable information. (Tony Lawrence)

This post tagged: