I want a very reliable way of retrieving data from email headers. Should I use an email parser like eg https://github.com/plancake/official-library-php-email-parser or are php imap functions sufficient to get that data? What is best practice? Is there any experience? I can imagine that there is a lot of differences in formatting email headers composed by many email clients. That is why I want a reliable solution.
I used built-in IMAP functions for a project which requires processing the emails by their dates and didn't need anything else actually. You can try and see if they are useful for you with the code below;
<?php
/* connect to gmail */
$hostname = '{imap.gmail.com:993/imap/ssl}INBOX';
$username = 'user#gmail.com';
$password = 'pass123';
/* try to connect */
$inbox = imap_open($hostname, $username, $password, OP_READONLY,1) or die('Cannot connect to Gmail: ' . print_r(imap_last_error()));
$emails = imap_search($inbox, 'ALL');
/* if emails are returned, cycle through each... */
if ($emails) {
foreach ($emails as $email_number) {
echo imap_fetchbody($inbox, $email_number, 0);
echo imap_fetchbody($inbox, $email_number, 1);
echo imap_fetchbody($inbox, $email_number, 2);
}
}
imap_close($inbox);
?>
The tricky part is imap_fetchbody($inbox, $email_number, 0). This part will return the headers. Once you get them, you can parse or use it as you wish.
Hope it helps.
Related
I am connecting to my inbox via PHP IMAP plugin. Below are my steps
Connection
//The location of the mailbox.
$hostname = '{outlook.office365.com:993/imap/ssl/novalidate-cert}';
//The username / email address that we want to login to.
$username = 'username';
//The password for this email address.
$password = 'password';
I am further opening the inbox connection and looking at anything that is UNSEEN in the inbox
//Attempt to connect using the imap_open function.
$inbox = imap_open($hostname,$username,$password);
$mailboxes = imap_list($inbox, $hostname, '*');
imap_reopen($inbox, $hostname.'INBOX');
$emails = imap_search($inbox, 'UNSEEN');
Further, I am iterating over all the emails and its working well with headers. The issue I am having is with body.
To get the body of the email I am using
//get message body
$message = quoted_printable_decode(imap_fetchbody($inbox, $email_number, 2.1));
if ($message == '') {
$message = quoted_printable_decode(imap_fetchbody($inbox, $email_number, 1));
}
So running a test on 40 emails, 28 emails fetch the body correct and store into the database.
12 emails fetch a body which looks like
PGh0bWwgeG1sbnM6dj0idXJuOnNjaGVtYXMtbWljcm9zb2Z0LWNvbTp2bWwiIHhtbG5zOm89InVy
bjpzY2hlbWFzLW1pY3Jvc29mdC1jb206b2ZmaWNlOm9mZmljZSIgeG1sbnM6dz0idXJuOnNjaGVt
YXMtbWljcm9zb2Z0LWNvbTpvZmZpY2U6d29yZCIgeG1sbnM6bT0iaHR0cDovL3NjaGVtYXMubWlj
cm9zb2Z0LmNvbS9vZmZpY2UvMjAwNC8xMi9vbW1sIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv
VFIvUkVDLWh0bWw0MCI+DQo8aGVhZD4NCjxtZXRhIGh0dHAtZXF1aXY9IkNvbnRlbnQtVHlwZSIg
Y29udGVudD0idGV4dC9odG1sOyBLWZhbWlseToiQ2FsaWJyaSIsc2Fucy1zZXJp
ZjsNCglmb250LXdlaWdodDpib2xkO30NCmE6bGluaywgc3Bhbi5Nc29IeXBlcmxpbmsNCgl7bXNv
LXN0eWxlLXByaW9
How should I be reading the body? So that I can have my test pass all the emails correctly?
Thank you
Also I found a way to get rid of those characters.
I looked at the encoding and I am parsing based on encoding numbers as follow
$encoding = $structure->encoding;
if($encoding == 3) {
$finalmsg = imap_base64($message);
} else if($encoding == 1) {
$finalmsg = imap_8bit($message);
} else {
$finalmsg = imap_qprint($message);
}
I am still having issues when encoding type = 0. The signature is causing major problem
I access to gmail using php to make action on mail. I put these mails into a folder using gmail directly.
So here is my code to get it :
$hostname = '{imap.gmail.com:993/ssl}test';
$username = 'myaddress#gmail.com';
$password = 'mypassword';
/* 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');
//$emails = imap_search($inbox,'RECENT');
print_r($emails);
/* if emails are returned, cycle through each... */
if($emails) {
/* begin output var */
$output = '';
/* put the newest emails on top */
rsort($emails);
$emailCount = 1;
foreach($emails as $email_number) {
//echo 'email n∞' . $emailCount;
/* get information specific to this email */
$overview = imap_fetch_overview($inbox,$email_number,0);
$message = imap_fetchbody($inbox,$email_number,2);
$structure = imap_fetchstructure($inbox,$email_number);
if (!$overview[0]->seen) {
print_r($overview);
$emailCount++;
}
}
// echo $output;
}
/* close the connection */
imap_close($inbox);
No I'd like to move these mail into an other folder, for exemple test2
here is what I do :
imap_mail_move($inbox, $email_number, 'test2') or die('Error');
but I get an error :
Notice: Unknown: [TRYCREATE] No folder test2 (Failure) [THROTTLED] (errflg=2) in Unknown on line 0
I have tried these different kind of solution :
With a subfolder of test named test3
imap_mail_move($inbox, $email_number, 'test3') or die('Error');
same error.
Also tried :
imap_mail_move($inbox, $email_number, '[Gmail]/test3') or die('Error');
Same error :-(
If anyone has a solution that would be cool !
Thanks,
Alex
So after several tries here is what I have found that works :
imap_mail_move($inbox, $email_number, 'INBOX') or die('Error');
imap_mail_move($inbox, $email_number, 'test2') or die('Error');
But that means to move to the inbox then to the second folder. Problem : the message is still in the inbox after these.
Still looking for an other solution.
I'm integrating PHP webmail read functionality in php. I already tried using IMAP functions. But it could not connect.So I just ask you is there any possibility to get messages from webamil with out using IMAP function.
Below is my IMAP Code. Can you check the code also give me suggestions for why doesn't work. I'm looking forward for your valuable reply.
$emailAddress = 'info#example.com'; // Full email address
$emailPassword = 'xxxxxxxx'; // Email password
$domainURL = 'example.com'; // Your websites domain
$useHTTPS = false;
/* BEGIN MESSAGE COUNT CODE */
$inbox = imap_open('{'.$domainURL.':143/notls}INBOX',$emailAddress,$emailPassword) or die('Cannot connect to domain:' . imap_last_error());
$oResult = imap_search($inbox, 'UNSEEN');
if(empty($oResult))
$nMsgCount = 0;
else
$nMsgCount = count($oResult);
imap_close($inbox);
echo('<p>You have '.$nMsgCount.' unread messages.</p>');
Thanks in advance
So I have the basic problem of a mailing list and I am trying to find all the undeliverable emails and turn them off. I am using php imap function and I have been going through all the fetch and structure functions and although they do give you the information is there anything that concisely will say this is a bad email based on the error code. Currently my best option is using imap_fetchbody with option 2 and doing a find for 550 or 5.4.4 or 5.1.1 etc and then grabbing the email. I wanted to know if there was a function that tells you bad good or at least just has the above codes 550, 5.4.4 etc in a concise array format.
set_time_limit(0);
$hostname = "{localhost:110/pop3/novalidate-cert}INBOX";
$username = 'xxxx';
$password = "xxxx";
$inbox = imap_open($hostname, $username, $password) or die("Cannot connect to pop: " . imap_last_error());
$emails = imap_search($inbox, 'ALL');
if($emails){
$output = '';
rsort($emails);
foreach($emails as $key1 => $email_number){
if($key1 < 10){
$imap_fetchstructure = imap_fetchstructure($inbox, $email_number);
$imap_fetchbody = imap_fetchbody($inbox, $email_number, 1);
$imap_fetch_overview = imap_fetch_overview($inbox, $email_number);
$imap_bodystruct = imap_bodystruct($inbox, $email_number, 1);`
} else{
break;
}
}
}
imap_close($inbox);
Okay, this code 'was' working perfectly and then I started playing around with it in order to let others connect to their e-mails and as you do ran into a few open stream errors along the way due to various typos and such.
Since doing this, all of a sudden I can't connect to my e-mail at all? A short while back I was using the exact same connection code and then browsing my inbox.
I always get the "Warning: imap_open() [function.imap-open]: Couldn't open stream" error.
This is strange as I'm using the exact same code as before, but since bumping into errors I can't connect whatsoever now. It also takes ages to respond.
Here is the code:
$mailbox = imap_open('{mail.artisancodesmith.com:143/notls}INBOX', 'admin#artisancodesmith.com', 'PASSWORD');
if ($mailbox) {
$response = "MAIL MENU:<br>
inbox: View your inbox.<br>
compose: Compose an e-mail.<br>
setup: Set your e-mail account's settings.";
$next = "iorcmail";
}
NOTE: The PHP page is connecting to the e-mail on the same server.
UPDATE:
If I replace "mail.artisancodesmith.com" with "localhost" it works again!
I would preferably like to use my actual IMAP host - I'll see if it works again some time in the future I guess.
Thanks to all who helped. :)
Please use the below code to connect successfully,
$hostname = "{imap.gmail.com:993/imap/ssl/novalidate-cert}";
$mailbox = imap_open($hostname, 'admin#artisancodesmith.com', 'PASSWORD');
if ($mailbox)
{
// do work....
}
I ran into this problem and here is how I solved it;
Login to your gmail account, Under Settings -> Forwarding and POP/IMAP -> Enable Imap.
Go to https://www.google.com/settings/security/lesssecureapps and select "Turn On"
Go to: https://accounts.google.com/b/0/DisplayUnlockCaptcha and enable access.
after this, above code works for me....
I have tried this an works perfectly fine for me
$inbox = imap_open("{imap.gmail.com:993/imap/ssl/novalidate-cert/norsh}Inbox", 'username', 'password')
or die('Cannot connect to Gmail: ' . imap_last_error());
$emails = imap_search($inbox,'All');
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);
$header = imap_header($inbox, $email_number);
echo "<h1>data</h1>";
echo "<pre>";print_r($message);
echo "<h1>Message</h1>";
echo "<pre>";print_r($message);
echo "<h1>header</h1>";
echo "<pre>";print_r($message);
$overview[0]->seen;
$overview[0]->subject;
$overview[0]->from;
$overview[0]->date;
}
}
/* close the connection */
imap_close($inbox);
maybe are you behind a proxy? if so, I guess you need to auth against it...
resource imap_open(
string $mailbox ,
string $username ,
string $password [,
int $options = 0 [,
int $n_retries = 0 [,
array $params = NULL ]]]
)