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]nn';}
}
else
{
$message['body'] = imap_body($this->mbox, $messageid);
if(!$message['body']) {$message['body'] = '[NO TEXT ENTERED INTO THE MESSAGE]nn';}
}
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
}
}
}
if this works with any imap server it would be awesome
Thanks.This work to me well. Great work. thanks again
Thank you for this, it has become very very useful for me!
hi, how can i get the addresses from the address book?? all the email addressses?? is there any way using this function?
thnx
Hi,
When i modify my code like: $email = $gmail->getEmailSince(’4 Oct 2008 23:00:00′);
my script shows all emails on october 4. But it must show after 23:00, must not it?
i think there is a problem in time function.