I am so close to finishing this, but I'm stuck on downloading attachments.
So far I'm grabbing all my necessary email header information with the following code:
(also, I'm doing this via command line: CentOS 6)
<?php
echo "\n";
$hostname = '{imap.gmail.com:993/imap/ssl}INBOX';
$username = 'myemail#mydomain.com';
$password = 'myfunpassword';
/* try to connect */
$inbox = imap_open($hostname,$username,$password) or die('Cannot connect to Gmail: ' . imap_last_error());
/* grab emails */
$emails = imap_search($inbox,'ALL');
/* if emails are returned, cycle through each... */
if($emails) {
/* begin output var */
$output = '';
/* 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);
$message = imap_fetchbody($inbox,$email_number,1);
$output.= $email_number."\n";
$output.= ($overview[0]->seen ? '[read]' : '[unread]')."\n";
$output.= "date:".$overview[0]->date."\n";
$output.= "to:".$overview[0]->to."\n";
$output.= "from:".$overview[0]->from."\n";
$output.= "size:".$overview[0]->size."\n"; //size in bytes
$output.= "msgno:".$overview[0]->msgno."\n";
$output.= "message_id:".$overview[0]->message_id."\n"; //Message-ID
$output.= "uid:".$overview[0]->uid."\n"; //UID the message has in the mailbox
$output.= "from:".$overview[0]->from."\n";
$output.= "subject:".$overview[0]->subject."\n";
/* output the email body */
$output.= "message:".$message;
/* detect attachments here */
$output.="\n\n";
}
echo $output;
} // eof $emails check
imap_close($inbox);
?>
This works great!
So now, I've got this code to tell me if there are attachments in each email:
<?php
// put this code above where it says "detect attachments here"
// attachments detection
$struct = imap_fetchstructure($inbox,$email_number);
$contentParts = count($struct->parts);
if ($contentParts >= 2) {
for ($i=2;$i<=$contentParts;$i++) {
$att[$i-2] = imap_bodystruct($inbox,$email_number,$i);
}
for ($k=0;$k<sizeof($att);$k++) {
if ($att[$k]->parameters[0]->value == "us-ascii" || $att[$k]->parameters[0]->value == "US-ASCII") {
if ($att[$k]->parameters[1]->value != "") {
$selectBoxDisplay[$k] = $att[$k]->parameters[1]->value;
}
} elseif ($att[$k]->parameters[0]->value != "iso-8859-1" && $att[$k]->parameters[0]->value != "ISO-8859-1") {
$selectBoxDisplay[$k] = $att[$k]->parameters[0]->value;
}
}
if (sizeof($selectBoxDisplay) > 0) {
for ($j=0;$j<sizeof($selectBoxDisplay);$j++) {
$output.= "\n--file:". $selectBoxDisplay[$j]."";
}
}
}
// eof attachments detection
?>
And this works too! But now I'm to the point that I need to download the attachments, and most tutorials show me how to do it using from a browser's point of view, rather than the CLI. So I definitely need a little help here.
I'm expecting there's a way to determine where to download files on the server too.
Related
So I get emails using imap from gmail and outlook.
Gmail encodes like this =?UTF-8?B?UmU6IM69zq3OvyDOtc68zrHOuc67IG5ldyBlbWFpbA==?=
and outlook encodes like this =?iso-8859-7?B?UmU6IOXr6+ft6er8IHN1YmplY3Q=?=
Unfortunately I did not find yet any solution that will help me make this into readable text. Instead I am messing with:
mb_convert_encoding($body, "UTF-8", "UTF-8");
and
mb_convert_encoding($body, "UTF-8", "iso-8859-7");
but I am struggling to find a solution to solve this matter.
This is how I open the IMAP of my account (which has a lot of gmail and outlook messages)
$hostname = '{imappro.zoho.com:993/imap/ssl}INBOX';
$username = 'email#email.com';
$password = 'password';
/* try to connect */
$inbox = imap_open($hostname,$username ,$password) or die('Cannot connect to Zoho: ' . imap_last_error());
/* grab emails */
$emails = imap_search($inbox,'UNSEEN');
Any help?
Unfortunately I did not find yet any solution that will help me make
this into readable text.
Solution
Your strings are base64 encoded.
=?UTF-8?B?UmU6IM69zq3OvyDOtc68zrHOuc67IG5ldyBlbWFpbA==?=
echo base64_decode('UmU6IM69zq3OvyDOtc68zrHOuc67IG5ldyBlbWFpbA==');
prints "Re: νέο εμαιλ new email"
=?iso-8859-7?B?UmU6IOXr6+ft6er8IHN1YmplY3Q=?=
echo base64_decode('UmU6IOXr6+ft6er8IHN1YmplY3Q=');
prints out "Re: subject"
The answer is to use base64_decode in conjunction with your current solutions.
The way to identify base64 encoded text is that it's depicted as letters a-z, A-Z, numbers 0-9 along with two other characters (usually + and /) and it's usually right padded with =.
EDIT:
Sorry, I was already forgetting that the question was to convert from iso-8859-7 to UTF-8 and have it visible.
<?php
$str = base64_decode('UmU6IPP03evt+SDs3u317OE=');
$str = mb_convert_encoding($str,'UTF-8','iso-8859-7');
echo $str;
?>
The result is "Re: στέλνω μήνυμα"
look here
/* connect to gmail */
$hostname = '{imap.gmail.com:993/imap/ssl}INBOX';
$username = 'davidwalshblog#gmail.com';
$password = 'davidwalsh';
/* try to connect */
$inbox = imap_open($hostname,$username,$password) or die('Cannot connect to Gmail: ' . imap_last_error());
/* grab emails */
$emails = imap_search($inbox,'ALL');
/* if emails are returned, cycle through each... */
if($emails) {
/* begin output var */
$output = '';
/* 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);
$message = imap_fetchbody($inbox,$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="date">on '.$overview[0]->date.'</span>';
$output.= '</div>';
/* output the email body */
$output.= '<div class="body">'.$message.'</div>';
}
echo $output;
}
/* close the connection */
imap_close($inbox);
for reading and decoding look here
<?php
$hostname = '{********:993/imap/ssl}INBOX';
$username = '*********';
$password = '******';
$inbox = imap_open($hostname,$username,$password) or die('Cannot connect to server: ' . imap_last_error());
$emails = imap_search($inbox,'ALL');
if($emails) {
$output = '';
rsort($emails);
foreach($emails as $email_number) {
$overview = imap_fetch_overview($inbox,$email_number,0);
$structure = imap_fetchstructure($inbox, $email_number);
if(isset($structure->parts) && is_array($structure->parts) && isset($structure->parts[1])) {
$part = $structure->parts[1];
$message = imap_fetchbody($inbox,$email_number,2);
if($part->encoding == 3) {
$message = imap_base64($message);
} else if($part->encoding == 1) {
$message = imap_8bit($message);
} else {
$message = imap_qprint($message);
}
}
$output.= '<div class="toggle'.($overview[0]->seen ? 'read' : 'unread').'">';
$output.= '<span class="from">From: '.utf8_decode(imap_utf8($overview[0]->from)).'</span>';
$output.= '<span class="date">on '.utf8_decode(imap_utf8($overview[0]->date)).'</span>';
$output.= '<br /><span class="subject">Subject('.$part->encoding.'): '.utf8_decode(imap_utf8($overview[0]->subject)).'</span> ';
$output.= '</div>';
$output.= '<div class="body">'.$message.'</div><hr />';
}
echo $output;
}
imap_close($inbox);
?>
Look here for great tutorial on email structure, and function to extract it.
If you want to decode header elements, there is a PHP function for that: imap_mime_header_decode().
Also, you will need some MIME parser class to decode multipart messages.
To get the headers, you would pass your stream ($inbox) to imap_headers(). There are lots of values you can get in the response, full list: imap_headerinfo
For the actual messages, plain text can be read using imap_body(), passing the stream and the number of the message you want (in $emails after your search). Getting an html/multipart email is a bit trickier. First you need imap_fetchstructure(), which identifies the parts of the message, then imap_fetchbody() to get the piece you are interested in.
Once you have a result from imap_fetchbody(), if you still need to adjust the encoding, it could be done at this point.
I had a task to receive letters from a certain mailbox, parse them and index certain content.
I wanted to have some microservice that would provide me with the data.
Downloading the required content
Convert the received data into a readable format
process the content
So I decided to use ready-made tools.
script for getting emails - imap2maildir
Unix client for processing messages mu
dos2unix converter
Next, I wrote a small bash script that I placed in cron
#!/bin/bash
python /var/mail_dump/imap2maildir/imap2maildir -c /var/mail_dump/imap2maildir/deploy.conf
mu index --maildir=/var/mail_dump/dumps/new
#clean old data
rm -rf /var/mail_dump/extract/*
#search match messages
mu find jivo --fields="l" --nocolor | xargs $1 cp -t /var/mail_dump/extract
#converting
dos2unix -f /var/mail_dump/extract/*
#reassembly of messages in html
cd /var/mail_dump/extract/
for i in /var/mail_dump/extract/*
do
mu extract --parts=0 --overwrite "$i"
rm "$i"
done
Complete !
I got a service that constantly receives emails and prepares them for processing.
php work with the prepared data without thinking about the implementation of low-level logic.
I have completed PHP IMAP code. All the mail result is coming fine. But in the mail if contain any danish character then it show wrong. The code I have done for finding message body is below,
$emails = imap_search($inbox,'ALL');
if($emails) {
rsort($emails);
$total_mail=imap_num_msg($inbox);
echo 'Number of email:'.$total_mail;
/* for every email… */
foreach($emails as $email_number) {
$overview = imap_fetch_overview($inbox,$email_number,0);
$structure = imap_fetchstructure($inbox, $email_number);
if(isset($structure->parts) && is_array($structure->parts) && isset($structure->parts[1])) {
$part = $structure->parts[1];
$message = imap_fetchbody($inbox,$email_number,2);
if($part->encoding == 3) {
$message = imap_base64($message);
} else if($part->encoding == 1) {
$message = imap_8bit($message);
} else {
$message = imap_qprint($message);
}
}
As a example the message in the mail is, Låt deras önskningar gå i uppfyllelse i år med perfekta klappar från Apple., and it is showing in he above code output as L�t deras �nskningar g� i uppfyllelse i �r med perfekta klappar fr�n Apple..
I don't know the problem. I have follow all the rules. The charset is also UTF-8 like, charset="UTF-8". But sill have the same problem.
Please help me to solve this. Advance thanks for help.
I am using IMAP Protocol to fetch my Inbox emails to a small PHP app i am writing.
I am getting this Error message:
Fatal error: Allowed memory size of 33554432 bytes exhausted (tried to
allocate 13055589 bytes) in /home/admin/public_html/boltmail/inbox.php
on line 56
But if i look at this error it does not make a lot of sense.....It says the allowed memory size is 33Mb and it only needed 13Mb to allocate the data.....
PHP Code:
<?php
/* connect to gmail */
$hostname = '{imap.gmail.com:993/imap/ssl}INBOX';
$username = 'tomasz#*****.com';
$password = '*****';
/* try to connect */
$inbox = imap_open($hostname,$username,$password) or die('Cannot connect to Gmail: ' . imap_last_error());
/* grab emails */
$emails = imap_search($inbox,'ALL');
/* if emails are returned, cycle through each... */
if($emails) {
/* begin output var */
$output = '';
/* 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);
$message = imap_fetchbody($inbox,$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="date">on '.$overview[0]->date.'</span>';
$output.= '</div>';
/* output the email body */
$output.= '<div class="body">'.$message.'</div>';
}
echo $output;
}
/* close the connection */
imap_close($inbox);
?>
Besides I am using this tutorial to import my gmail emails: Tutorial Link
The error message may be confusing, but it does make sense: php tried to allocate 13 mb, on top of the 32 mb allowed. So you basically would need at least 45 mb. So first of all, increase the memory limit, that should this problem.
I am building a chat/SMS based system I have it sending out the messages but what I need to do is live update the textarea with data from incoming emails without the user reloading (ajax?) I need to pass a number from the main page to fetch.php which gets the emails and creates an array out of emails which have not been read and come from the right sender what I need to do yet is send the number from the main page to the fetch page and return a array of new messages to the main textarea but all the tutorials I have found on ajax seem to require a database and I have no idea how to go about running and returning data on a delay help would be appreciated.
Here is the content of fetch.php:
<?php
error_reporting(E_ALL);
ini_set('display_errors', TRUE);
ini_set('display_startup_errors', TRUE);
/* connect to gmail */
$hostname = '{imap.gmail.com:993/imap/ssl}INBOX';
$username = 'user#gmail.com';
$password = 'passwd';
/* try to connect */
$inbox = imap_open($hostname,$username,$password) or die('Cannot connect to Gmail: ' . imap_last_error());
/* grab emails */
$emails = imap_search($inbox,'ALL');
/* if emails are returned, cycle through each... */
if($emails) {
$messages[] = '';
/* begin output var */
$output = '';
/* 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);
$message = imap_fetchbody($inbox,$email_number,1);
//print_r($overview);
$Is_sms = strpos($overview[0]->from, "txt.voice.google.com");
if($Is_sms === false) continue;
if($overview[0]->seen != 0) continue;
$pnl = strpos($overview[0]->from, ".");
$pnumber = substr($overview[0]->from, $pnl +2, 10);
if($pnumber != "3303331866") continue;
$messages[] = $message;
//$status = imap_setflag_full($mbox, $mail, "\\Seen \\Flagged", ST_UID);
/* 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="date">on '.$overview[0]->date.'</span>';
$output.= '<span class="pnumber">'.$pnumber.'</span>';
$output.= '</div>';*/
/* output the email body */
//$output.= '<div class="body">'.$message.'</div>';
}
//echo $output;
print_r($messages);
}
/* close the connection */
imap_close($inbox);
The main page is just a to number textbox, a content textarea, a message textbox, and a send button.
The database is required to store the messages for you to fetch later when the AJAX request from a browser needs it. This is because your PHP script does not retain its variables between two subsequent runs and therefor you will need to store the messages somewhere. So it will basically go like this:
Get new message
Place it in some kind of ordered queue where you will be able to fetch everything later than what the client already has.
Send it off to client.
The queue could be numbered with numbers counting upward from the first post, thus allowing clients to specify what the last received message they got was and request everything newer.
BTW, if i did not make it sufficiently clear above, what you said about AJAX requiring a database is somewhat misunderstood. AJAX can function properly without, its just your case that needs some storage and databases are a good way to do it.
Hope that helps :)
can you please tell , how to download attachments from gmail account using php ?
thanks
you could use a php pop or imap client and fetch the mail and extract the attachments from that
As stated by other answerers, an IMAP solution is recommended, and can be found at http://davidwalsh.name/gmail-php-imap. Make sure to check your firewall, and enable the OpenSSL and IMAP in your PHP installation.
http://www.electrictoolbox.com/extract-attachments-email-php-imap/ has excellent code references regarding how to analyze each email's structure using imap_fetchstructure. In the structure of each message lie the attachments. The user contributed notes at http://www.php.net/manual/en/function.imap-fetchstructure.php are particularly helpful (as is the documentation).
Basically, you have to
loop through the structure parts
determine which of them are attachments
decode as appropriate.
Different email clients will have slightly different structures, but it's not too hard with a little effort. The data can then be handled however you choose.
IMAP Solution
/* connect to gmail */
$hostname = '{imap.gmail.com:993/imap/ssl}INBOX';
$username = 'davidwalshblog#gmail.com';
$password = 'davidwalsh';
/* try to connect */
$inbox = imap_open($hostname,$username,$password) or die('Cannot connect to Gmail: ' . imap_last_error());
/* grab emails */
$emails = imap_search($inbox,'ALL');
/* if emails are returned, cycle through each... */
if($emails) {
/* begin output var */
$output = '';
/* 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);
$message = imap_fetchbody($inbox,$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="date">on '.$overview[0]->date.'</span>';
$output.= '</div>';
/* output the email body */
$output.= '<div class="body">'.$message.'</div>';
}
echo $output;
}
/* close the connection */
imap_close($inbox);
You must add to it attachment control and you can read this because from it is this source code http://davidwalsh.name/gmail-php-imap