Automatically extracting attachments from Gmail can be important for reasons where you need to process the attached files periodically with a CRON job. Also it can be useful for automatically archiving important attachments. Below is a simple proof-of-concept plain PHP code, devoid of any object-oriented features that extracts attachments from your Gmail account. It uses PHPs imap extension to access the inbox.
Before you proceed make sure that imap is enabled in your Gmail settings page. All attachments downloaded in the following code are saved in the current folder, which you can easily change to point to another directory. Downloadable code is given at the end of the post.
<?php /** * Gmail attachment extractor. * * Downloads attachments from Gmail and saves it to a file. * Uses PHP IMAP extension, so make sure it is enabled in your php.ini, * extension=php_imap.dll * */ set_time_limit(3000); /* connect to gmail with your credentials */ $hostname = '{imap.gmail.com:993/imap/ssl}INBOX'; $username = 'YOUR_GMAIL_USERNAME'; # e.g somebody@gmail.com $password = 'YOUR_GMAIL_PASSWORD'; /* try to connect */ $inbox = imap_open($hostname,$username,$password) or die('Cannot connect to Gmail: ' . imap_last_error()); /* get all new emails. If set to 'ALL' instead * of 'NEW' retrieves all the emails, but can be * resource intensive, so the following variable, * $max_emails, puts the limit on the number of emails downloaded. * */ $emails = imap_search($inbox,'ALL'); /* useful only if the above search is set to 'ALL' */ $max_emails = 16; /* if any emails found, iterate through each email */ if($emails) { $count = 1; /* put the newest emails on top */ rsort($emails); /* for every email... */ foreach($emails as $email_number) { /* get information specific to this email */ $overview = imap_fetch_overview($inbox,$email_number,0); /* get mail message */ $message = imap_fetchbody($inbox,$email_number,2); /* get mail structure */ $structure = imap_fetchstructure($inbox, $email_number); $attachments = array(); /* if any attachments found... */ if(isset($structure->parts) && count($structure->parts)) { for($i = 0; $i < count($structure->parts); $i++) { $attachments[$i] = array( 'is_attachment' => false, 'filename' => '', 'name' => '', 'attachment' => '' ); if($structure->parts[$i]->ifdparameters) { foreach($structure->parts[$i]->dparameters as $object) { if(strtolower($object->attribute) == 'filename') { $attachments[$i]['is_attachment'] = true; $attachments[$i]['filename'] = $object->value; } } } if($structure->parts[$i]->ifparameters) { foreach($structure->parts[$i]->parameters as $object) { if(strtolower($object->attribute) == 'name') { $attachments[$i]['is_attachment'] = true; $attachments[$i]['name'] = $object->value; } } } if($attachments[$i]['is_attachment']) { $attachments[$i]['attachment'] = imap_fetchbody($inbox, $email_number, $i+1); /* 4 = QUOTED-PRINTABLE encoding */ if($structure->parts[$i]->encoding == 3) { $attachments[$i]['attachment'] = base64_decode($attachments[$i]['attachment']); } /* 3 = BASE64 encoding */ elseif($structure->parts[$i]->encoding == 4) { $attachments[$i]['attachment'] = quoted_printable_decode($attachments[$i]['attachment']); } } } } /* iterate through each attachment and save it */ foreach($attachments as $attachment) { if($attachment['is_attachment'] == 1) { $filename = $attachment['name']; if(empty($filename)) $filename = $attachment['filename']; if(empty($filename)) $filename = time() . ".dat"; /* prefix the email number to the filename in case two emails * have the attachment with the same file name. */ $fp = fopen($email_number . "-" . $filename, "w+"); fwrite($fp, $attachment['attachment']); fclose($fp); } } if($count++ >= $max_emails) break; } } /* close the connection */ imap_close($inbox); echo "Done"; ?> |
This site is a digital habitat of Sameer Borate, a freelance web developer working in PHP, MySQL and WordPress. I also provide web scraping services, website design and development and integration of various Open Source API's. Contact me at metapix[at]gmail.com for any new project requirements and price quotes.
20 Responses
1
David
May 29th, 2012 at 8:57 am
worked a treat, many thanks
2
phphunger
July 8th, 2012 at 10:30 pm
it says “Done”..but my doubt is where the attachments are stored after downloading….
sameer
July 8th, 2012 at 10:46 pm
The attachments are stored in the directory where the source file is located. However you can change the path to a different one by adding the path information to the filename. So to download the attachments to the directory “d:\gmail\attachments”, you can change the following line in the code (line no. 129):
$fp = fopen($email_number . “-” . $filename, “w+”);
to the following:
$fp = fopen(“d:/gmail/attachments/” . $email_number . “-” . $filename, “w+”);
4
phphunger
July 12th, 2012 at 5:51 am
hi sameer, i changed it to what ever you said..but still its not working….it says “Done”..i checked my path but no luck…any suggestions…
sameer
July 12th, 2012 at 7:04 am
$emails = imap_search($inbox,’ALL’);
After the above line check if any emails are returned using print_r
print_r($emails);
This should return and array something like the following, no empty array should be returned.
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
6
Candy
August 20th, 2012 at 8:56 pm
oh my god it works perfectly, thank you so much!
7
Ravi
September 9th, 2012 at 10:08 pm
Working Great! Thanks a lot.
8
Brett
September 29th, 2012 at 8:27 pm
I would like to use this script to first save a max of 8 attachments to a directory and then write a new row containing the attachment filenames, email body, subject and from address to a mySQL database. Is this possible???
sameer
September 29th, 2012 at 9:57 pm
Yes, it is possible.
10
Josefina
October 8th, 2012 at 3:06 am
Do you have a spam problem on this blog; I also am a blogger, and I was curious about your situation; we have developed some nice
procedures and we are looking to trade strategies with
other folks, why not shoot me an e-mail if interested.
11
Zuber
November 15th, 2012 at 8:03 am
Such a great site, not english likes…
12
Richard
November 22nd, 2012 at 7:44 pm
Nice script, but i have a question. I need it to do 2 things, 1 – get an email from just 1 address and 2 – download the attachment from the email?
13
Mike
December 4th, 2012 at 3:46 pm
How I order the images from by most recent? Showing the most recent first, and the oldest last?
The rsort() function doesn’t seem to work?
14
Ali
December 18th, 2012 at 12:19 am
Hi Sameer,
Thanks a lot for the tutorial. I am having a connection error. I doubt I am doing something wrong. can you please help?
15
Rajendra
January 11th, 2013 at 3:38 am
Thanks buddy….Its really awesome. After searching for 3 days finally your code worked.
Thanks
16
pajko
February 2nd, 2013 at 7:20 am
Great great tutorial! When I use it in non gmail account eg. my own email hosting, the $emails = imap_search($inbox,’NEW’); with NEW paramater must work? Because it is not working..
17
Tim
February 10th, 2013 at 2:24 pm
Can’t seem to get this to work. I get an error log report with the following:
[10-Feb-2013 14:55:29] PHP Warning: imap_open() [function.imap-open]: Couldn’t open stream {imap.gmail.com:993/imap/ssl}INBOX in /home/******/public_html/mywebsite.com/webcam/getimages.php on line 24
sameer
February 10th, 2013 at 8:31 pm
Make sure SSL is enabled on your PHP installation. The OpenSSL extension should be enabled. The IMAP Client library (with SSL) depends on this.
19
Scott
February 19th, 2013 at 3:17 pm
Hey,
Thanks for the script. Works great! Is there a attachement size limit? I can’t seem to save a 2.4mb image, whereas a 1mb saves fine
Scott
20
nagendra
February 27th, 2013 at 1:47 am
Hi,
Thanks for the code it worked like charm. It seems that is also downloading the inline images of mail content(mail body) if any. What if i don’t need any inline images to download and I only need attachments to download.
Please suggest…
Nagendra