Hello. I have a new blog.

I've moved this blog to the following URL Kerkness.ca. Thank you for visiting, please update your bookmarks.

Friday, September 5, 2008

GmailReader.php : A PHP IMAP Class for Reading your Gmail Account

One of the requirements I had for a recent project involved keeping track of email communication from multiple Gmail users. My first thought was to simply forward a copy of all incoming and outgoing email to an email account on my server and accessing the email that way. There was one problem with this approach. Gmail only allows you to forward a copy of incoming email somewhere else. Emails composed in Gmail stay in Gmail.

My solution: Use Gmail's IMAP capabilities and monitor the accounts using PHP-IMAP. This turned out to be a fairly easy to implement solution but I thought I would post my GmailReader class to save other people some initial headaches of getting things rolling.

First of all you'll need to enable IMAP for you Gmail Account. Log into Gmail and goto Settings > Forwarding and POP/IMAP

Next you'll need to make sure php is compiled with IMAP enabled. This can be done on ubuntu with the following command and then restart apache for good measure.

sudo apt-get install php5-imap
sudo /etc/init.d/apache2 restart


In my particular scenario I run a script every so often to look for new emails since the last time I checked. So the class file is structured to check for new emails since a specific date string.

Usage Example

include_once( 'GmailReader.php' );
$gmail = new GmailReader( 'username@gmail.com', 'password' );
$email = $gmail->getEmailSince('Fri, 5 Sep 2008 9:00:00');

print_r($email);
The above example will print out an array of all emails ( still in the Inbox ) which arrived no earlier than 9am on the 5th of September.

You can also check your sent mail using the following example.
$gmail = new GmailReader( 'username@gmail.com', 'password' );
$gmail->openSentMail();
$email = $gmail->getEmailSince('Fri, 5 Sep 2008 9:00:00');
Also, if you use Gmail to apply labels to certain email you can monitor just these emails as well.
$gmail = new GmailReader( 'username@gmail.com', 'password' );
$gmail->openMailBox( 'MYLABEL' );
$email = $gmail->getEmailSince('Fri, 5 Sep 2008 9:00:00');
Here is the full GmailReader Class File.
class GmailReader
{
var $mbox;

function GmailReader( $user, $pass )
{
$this->mbox = imap_open("{imap.gmail.com:993/imap/ssl}INBOX",$user,$pass)
or die("can't connect: " . imap_last_error());
}

function openSentMail()
{
imap_reopen($this->mbox, "{imap.gmail.com:993/imap/ssl}[Gmail]/Sent Mail" )
or die("Failed to open Sent Mail: " . imap_last_error());
}

function openMailBox($mailbox)
{
imap_reopen($this->mbox, "{imap.gmail.com:993/imap/ssl}$mailbox" )
or die("Failed to open $mailbox: " . imap_last_error());
}

function getMailboxInfo()
{
$mc = imap_check($this->mbox);
return $mc;
}

/**
* $date should be a string
* Example Formats Include:
* Fri, 5 Sep 2008 9:00:00
* Fri, 5 Sep 2008
* 5 Sep 2008
* I am sure other's work, just test them out.
*/
function getHeadersSince($date)
{
$uids = $this->getMessageIdsSinceDate($date);
$messages = array();
foreach( $uids as $k=>$uid )
{
$messages[] = $this->retrieve_header($uid);
}
return $messages;
}

/**
* $date should be a string
* Example Formats Include:
* Fri, 5 Sep 2008 9:00:00
* Fri, 5 Sep 2008
* 5 Sep 2008
* I am sure other's work, just test them out.
*/
function getEmailSince($date)
{
$uids = $this->getMessageIdsSinceDate($date);
$messages = array();
foreach( $uids as $k=>$uid )
{
$messages[] = $this->retrieve_message($uid);
}
return $messages;
}

function getMessageIdsSinceDate($date)
{
return imap_search( $this->mbox, 'SINCE "'.$date.'"');
}

function retrieve_header($messageid)
{
$message = array();

$header = imap_header($this->mbox, $messageid);
$structure = imap_fetchstructure($this->mbox, $messageid);

$message['subject'] = $header->subject;
$message['fromaddress'] = $header->fromaddress;
$message['toaddress'] = $header->toaddress;
$message['ccaddress'] = $header->ccaddress;
$message['date'] = $header->date;

return $message;
}

function retrieve_message($messageid)
{
$message = array();

$header = imap_header($this->mbox, $messageid);
$structure = imap_fetchstructure($this->mbox, $messageid);

$message['subject'] = $header->subject;
$message['fromaddress'] = $header->fromaddress;
$message['toaddress'] = $header->toaddress;
$message['ccaddress'] = $header->ccaddress;
$message['date'] = $header->date;

if ($this->check_type($structure))
{
$message['body'] = imap_fetchbody($this->mbox,$messageid,"1"); ## GET THE BODY OF MULTI-PART MESSAGE
if(!$message['body']) {$message['body'] = '[NO TEXT ENTERED INTO THE MESSAGE]\n\n';}
}
else
{
$message['body'] = imap_body($this->mbox, $messageid);
if(!$message['body']) {$message['body'] = '[NO TEXT ENTERED INTO THE MESSAGE]\n\n';}
}

return $message;
}

function check_type($structure) ## CHECK THE TYPE
{
if($structure->type == 1)
{
return(true); ## YES THIS IS A MULTI-PART MESSAGE
}
else
{
return(false); ## NO THIS IS NOT A MULTI-PART MESSAGE
}
}


}

No comments:

Post a Comment

Thank you for the comments.