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.
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";
?>
Update
Check updated article here.
Download Code file
Downloads : [downloadcounter(Gmail-Imap)] / File size : [downloadsize(Gmail-Imap)]
Downloads : [downloadcounter(Gmail-Imap)] / File size : [downloadsize(Gmail-Imap)]
worked a treat, many thanks 🙂
it says “Done”..but my doubt is where the attachments are stored after downloading….
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+”);
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…
$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
oh my god it works perfectly, thank you so much!
Working Great! Thanks a lot.
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???
Yes, it is possible.
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.
Such a great site, not english likes…
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?
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?
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?
Thanks buddy….Its really awesome. After searching for 3 days finally your code worked.
Thanks
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..
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
Make sure SSL is enabled on your PHP installation. The OpenSSL extension should be enabled. The IMAP Client library (with SSL) depends on this.
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
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
Hi,
Great post, works great.
How do i save attachments embedded into the mail body, like images?
Thanks,
TNR
This code doesn’t work fine in Ubuntu.
Issues:
– Saving the attachment in the directory
– Contents of attachment
Please let me know what to do
Greetings
I am trying to download from other email server not gmail, I did print_r($emails);
It shows 1 2 3 4 5 as you wrote above in one post . I am running the code on ubuntu,
It says done but the attachement is not there in the soucre directory.
Is it exlusively for gmail. I am using it for pop3
mail.somesite.com/pop3/novalidate-cert}INBOX
This doesnt work for pop3 I think?
Any Comments ?
Thanks
Greetings again
I should have done this before the first comment.
Ok I change pop3 to imap in the server string
{mail.someservre.com/imap/novalidate-cert}INBOX
It gives one Notice after Done
DonePHP Notice: Unknown: rsh to IMAP server timed out (errflg=1) in Unknown on line 0
Thanks
Thanks for this snipped of code! That really helped me.
Is it possible you mixed comments when decoding attachments from base64/quoted-printable encoding? It seems to me the comments are in the wrong order to the code itself!
Kind regards
Thanks for the code. It works perfectly. Do have a question though:
/* get mail message */
$message = imap_fetchbody($inbox,$email_number,2);
1. Where do I find what 2 stands for? Can not seen to find what specific parts there are.
2. Why is the above line actually in your code example when you don’t use it any further in your code?
Thank you very much! super useful code
Greetings! Very helpful advice witthin this article! It is the little changes that will make the modt significant changes.
Thanks a lott for sharing!
its not work
Firstly really thankyou for script…………..I am facing some issue when getting the body content with attachment, the content is not coming in proper format some encode is coming along.
Thanks in Advance
Great article. I’m facing some of tthese issues aas well..
i got error like ” Cannot connect to Gmail: Can not authenticate to IMAP server: [ALERT] Please log in via your web browser: http://support.google.com/mail/accou“.
Please kindly Help me……
1. Make sure IMAP is enabled in Gmail settings.
2. Go to https://www.google.com/settings/security page and enable ‘Access for less secure apps’ (please note the security risk with this)