Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using PHP, How to search through Gmail's archived emails

Tags:

(First time programming in PHP. Had some help. Need a bit more.)

Goal:

Pull the lastContactDate from a given email address from my gmail account. Hoping to answer the question, "When was the last time I contacted [Person]"

What I've done so far:

  • Connected to gmail using imap (inbox only)
  • Grabbed the date and time
  • Printed the person's name and timestamp.

What I can't do:

  • Scour emails for lastContactDate that have been archived (I'm an inbox=0 guy)

Notes:

  • The code is rough, but functional. The php should really be separated onto different pages, but this is first attempt. Thanks in advance for any help!
  • Loving programming, btw. I did a little @edw519 dance more than once the last two days.

Research:

  • I think that messing with the params for imap_open and imap_search is probably my best bet, but not sure.
  • Been using these two pages heavily:
  • http://php.net/manual/en/function.imap-open.php
  • http://php.net/manual/en/function.imap-search.php

Code used thus far:

    /* connect to gmail */ $gmailhostname = '{imap.gmail.com:993/imap/ssl}'; $gmailusername = "[email protected]"; $gmailpassword = "___";      /* try to connect */ $conn = imap_open($gmailhostname,$gmailusername,$gmailpassword) or die('Cannot connect to Gmail: ' . imap_last_error());  $query = mysql_query("SELECT * FROM users");         while($row = mysql_fetch_array($query))     {         $findemail = $row["email"];          /* grab emails */         $emails = imap_search($conn,'FROM "'.$findemail.'"');          /* if emails are returned, cycle through each... */         if ($emails) {              /* begin output var */             $output = '';                          /* put the newest emails on top */             rsort($emails);              /* for 5 emails... */             $emails = array_slice($emails,0,1);              foreach ($emails as $email_number) {                     /* get information specific to this email */                 $overview = imap_fetch_overview($conn,$email_number,0);                 $message = imap_fetchbody($conn,$email_number,2);                  /* output the email header information */                 /*             $output.= '<div class="toggler '.($overview[0]->seen ? 'read' : 'unread').'">';                 $output.= '<span class="subject">'.$overview[0]->subject.'</span> ';                 $output.= '<span class="from">'.$overview[0]->from.'</span>';             */                 $output.= '<span class="from">'.$overview[0]->from.'</span> ';                 $output.= '<span class="date">on '.$overview[0]->date.'</span> <br /><br />';                 mysql_query("UPDATE users SET lastContactDate = '".$overview[0]->date."' WHERE email = '".$findemail."'") or die(mysql_error());                  /* output the email body */                 /* $output.= '<div class="body">'.$message.'</div>'; */             }             echo $output;         }     }  /* close the connection */ imap_close($conn); ?> 
like image 982
andrewfarah Avatar asked Nov 17 '11 22:11

andrewfarah


People also ask

Can you search for archived emails?

To find archived emails, click on the "All Mail" label and scroll through the messages until you find the one you want. Alternately, you can search for the message using Gmail's search bar. N arrow your search by typing the sender's email address or using the arrow on the right of the search bar to widen your search.

How do I find archived Gmail's?

To see archived emails on your Android device —> open your Gmail app —> click on the hamburger icon on top left, and then click on All Mail label. Here you will see all archived emails as shown in the screenshot below.

Does Gmail search include archived emails?

Finding Archived Emails in Gmail Using the Search Bar Unfortunately, there's no “archive” label you can use to search for when you're using the Gmail search bar at the top of the Gmail website or in the Gmail app. You'll need to know the topic, sender, or subject of your archived email to search for it manually.

How do I get an email from archives?

To retrieve the archived message, open the email and tap on the three dots at the top right of the screen. Tap “Move to inbox”, and your message will be instantly sent back to your inbox and the “Archive” label removed.


2 Answers

Problem solved!

Here's the solution. Using the original code above, we only modified the location in which our program searches. Instead of INBOX, it's:

    /* connect to gmail */ $gmailhostname = '{imap.gmail.com:993/imap/ssl}[Gmail]/All Mail'; 

Specifically

[Gmail]/All Mail 

Found the syntax here: http://php.net/manual/en/function.imap-delete.php

But would not have been possible without Ben's epic solution below.. In large part for this bit:

    //You can find out what folders are available with this command: print_r(imap_list($conn, $gmailhostname, '*')); 

print_r listed all the folders in my account by name. We spotted "All Mail", in my case - 22,000+, found a sample piece of code on php.net with the syntax, plugged it in and viola!

Thanks to mmmshuddup for cleaning my code and especially Ben for the enormous researching effort and leading solutions.

This is fun as hell.

like image 112
andrewfarah Avatar answered Nov 09 '22 07:11

andrewfarah


I have never used imap functions, but looking through the manual, the problem might be that your imap_search function is returning simple message sequence numbers instead of UIDs, which are I am guessing, unique message ids?

Maybe someone can help you better I'm just taking a shot with a few things to try.

Try changing your imap_search function to this:

   $emails = imap_search($conn,'FROM "'.$findemail.'"', SE_UID); 

And your fetch functions to these:

  $overview = imap_fetch_overview($conn,$email_number, FT_UID);   $message = imap_fetchbody($conn,$email_number,2, FT_UID); 

If that doesn't work, another thing you may try is just to set fetch_overview to one of these instead:

$overview = imap_fetch_overview($conn,"1:{$email_number}",0); // Or Maybe: $overview = imap_fetch_overview($conn,"{$email_number}:{$email_number}",0); 

Which tells it to grab messages from 1 to, whatever $email_number is I believe, a sequence of message ids rather that Unique Message Ids. Not sure though.

I don't think rsort() will work using the UID method, so you would have to find a different way to sort them, if you used that method. You would probably have to grab an array of all the matching email's headers, and sort that way.

Sorry I am not more helpful, never used imap before, but good luck!

Edit: The man pages are very strange for this, but it looks like the imap_sort function also has search criteria, so in theory, you could do:

  $emails = imap_sort($conn, SORTARRIVAL, 0, SE_UID, 'FROM "'.$findemail.'"');   // and then grab the first one:   $emails = array_slice($emails,0,1);    //And then further down use these two with the UID param    $overview = imap_fetch_overview($conn,$email_number, FT_UID);    $message = imap_fetchbody($conn,$email_number,2, FT_UID); 

If you are still not getting messages from your archive, you might look at this answer:

PHP imap_search not detecting all messages in gmail inbox

Edit Again

Wow there is really more to this than I thought....This is turning into the longest answer ever...

Depending on what your requirements are, if you only ever need to find messages in the archive folder, I believe you need to reopen the connection and connect to that specific folder before searching, something like:

imap_reopen($conn, "{$gmailhostname}Archive") or die(implode(", ", imap_errors())); //You can find out what folders are available with this command: print_r(imap_list($conn, $gmailhostname, '*')); 

If you need to search all your folders...That is harder from what I have seen: You either need to loop through each email inbox that you want to search, or find a way to use this:

http://code.google.com/apis/gmail/imap/#x-gm-raw

I think you would need a custom imap handler, or ZEND. Custom IMAP command in php

That is officially all the info I could find.

like image 35
Ben Avatar answered Nov 09 '22 08:11

Ben