php imap mark email as read on office365 mail - php

I had a function to read from gmail then mark it as read and it has been working fine.
We recently switched to office 365 and now we can't mark the mails as read any more. I got no error message. Any help will be appreciated.
Related code:
$authhost = "{outlook.office365.com:993/imap/ssl}INBOX";
$email = "blablabla#companyname.com";//dummy text. I swear i dont have typo here
$emailPassword = "NotGonnaTellYa";//dummy text. No typo here.
$mailbox = imap_open($authhost, $email, $emailPassword);
$mails = imap_search($mailbox, "ALL");
foreach ($mails as $mail) {
$mail_headers = imap_headerinfo($mailbox, $mail);
$structure = imap_fetchstructure($mailbox, $mail);
/*
do something magically to process the emails then save it to local..
*/
imap_delete($mailbox, $mail);
}
imap_expunge($mailbox);
imap_close($mailbox);
I have given the folders Owner permission in office 365 mail but failed to find any settings about allow IMAP to delete mails.
I have tried using CL_EXPUNGE to open the mail box but no luck either.

Related

How to change a pipe-forwarded email's "From" and "To" section in PHP

I am trying to mask emails. Basically give an email to a client like "RandomName#MyDomain.com" and have it forward "MyRealEmail#MyDomain.com".
I am pipe forwarding the emails to a php script on my server, where I want to use the "To" and "From" to find the real recipient of the message and forward the message to them removing any identifiable information from the Sender (From) section.
I can parse almost all the data right now from the header, but my problem is with the body. The html body portion can vary so much from different origins. Outlook have a <html> and <body> section, while Gmail just has <div>s. Regardless, I get these strange "=" signs in my raw email too, in both text and html sections, like <=div>!
I just want to change the "From" and "To" and keep the rest of the email pretty much exactly as it is so it doesn't have anomalies in its text or html section.
How can I do this? Should I just parse the raw email and change the occurrences of the emails? how can I send it then? or should I remake the email using phpmailer or some other class? how can i get the body correct then?
My hosting provider doesn't have MailParse extension installed, since I have seen some solutions on the site using that extension, so I am having to do this using available extensions in PHP 5.5
UPDATE
I managed to figure out the = issue, it was quoted-printable, so now I am calling quoted_printable_decode() to resolve that issue. Still trying to figure the best way to forward the email after altering the header though.
After a lot of failed attempts, finally have a solution I can live with. The host server didn't want to allow MailParse because it was an issue on their shared hosting environment, so I went with Mail_mimeDecode and Mail_MIME PEAR extensions.
// Read the message from STDIN
$fd = fopen("php://stdin", "r");
$input = "";
while (!feof($fd)) {
$input .= fread($fd, 1024);
}
fclose($fd);
$params['include_bodies'] = true;
$params['decode_bodies'] = true;
$params['decode_headers'] = true;
$decoder = new Mail_mimeDecode($input);
$structure = $decoder->decode($params);
// get the header From and To email
$From = ExtractEmailAddress($structure->headers['from'])[0];
$To = ExtractEmailAddress($structure->headers['to'])[0];
$Subject = $structure->headers['subject'];
ExtractEmailAddress uses a solution from "In PHP, how do I extract multiple e-mail addresses from a block of text and put them into an array?"
For the Body I used the following to find the text and html portions:
$HTML = "";
$TEXT = "";
// extract email body details
foreach($structure as $K => $V){
if(is_array($V)){
foreach($V as $KK => $VV){
if(is_object($VV)){
$bodyHTML = false;
$bodyPLAIN = false;
foreach($VV as $KKK => $VVV){
if(!is_array($VVV)){
if($KKK === 'ctype_secondary'){
if($VVV === 'html') { $bodyHTML = true; }
if($VVV === 'plain') { $bodyPLAIN = true; }
}
if($KKK === 'body'){
if($bodyHTML){
$bodyHTML = false;
$HTML .= quoted_printable_decode($VVV);
}
if($bodyPLAIN){
$bodyPLAIN = false;
$TEXT .= quoted_printable_decode($VVV);
}
}
}
}
}
}
}
}
Finally, I had the parts I needed so I used Mail_MIME to get the message out. I do my database lookup logic here and find the real destination and masked From email address using the From and To I extracted from the header.
$mime = new Mail_mime(array('eol' => "\r\n"));
$mime->setTXTBody($TEXT);
$mime->setHTMLBody($HTML);
$mail = &Mail::factory('mail');
$hdrs = array(
'From' => $From,
'Subject' => $Subject
);
$mail->send($To, $mime->headers($hdrs), $mime->get());
I don't know if this will cover all cases of email bodies, but since my system is not using attachments I am ok for now.
Take not of quoted_printable_decode(), that how I fixed the issue with the = in the body.
The only issue is the delay in mail I am having now, but I'll deal with that

Retrieve mail via PHP / IMAP - Header is changed after fetching the mail

i have a big Problem. I'll fetch all mails of a mailbox with php_imap, connecting to pop3 service of an microsoft exchange server.
The Adress of the Mailbox: sample#sample.com
This Mailbox has many aliases: e.G. sample_test#sample.com, sample_test2#sample.com
My problem: When someone writes a mail to sample_test#sample.com the mail is deliverd to the mailbox. So far thats no Problem. When viewing the Header-Source in Microsoft Outlook it displays
To: Sample "sample_test#sample.com"
Still, no problem!
But ...
after receiving this via my php-script and writing the imap_header and imap_body to the file e.G. mail1.eml viewing the source gives me
To: Sample "sample#sample.com"
Here i wish to get
To: Sample "sample_test#sample.com"
My Code:
Heres the Snippet for Understanding how i save this to eml file ...
$mailbox = '{'.$imapHost.':'.$imapPort.'}INBOX';
$imapStream = imap_open($mailbox, $imapUser, $imapPassword, 0, 1, array('DISABLE_AUTHENTICATOR' => 'GSSAPI'));
$hdr = imap_check($imapStream);
$overview = imap_fetch_overview($imapStream, "1:$mailCount");
$size = count($overview);
for($i=$count-1;$i>=0;$i--) {
-->$headers = imap_fetchheader($imapStream, $i, FT_PREFETCHTEXT);
-->$body = imap_body($imapStream, $i);
-->file_put_contents($fullPath . '/' . $saveemlfile, $headers . "\n" . $body);
}
imap_close($imapStream);
Thanks for your Help!

bcc multiple addresses with swiftmailer

Im using the below php code to send an email to one address and bcc 2 other addresses. It sends to the recipient fine but I can only get it to send to one of the 2 bcc addresses. (see comments in code for what ive tried)
Oddly enough though, $result comes back as 3 so it seems that its trying to send the second bcc email but it never comes through.
<?php
$tracker='tracking#pnrbuilder.com';
$subject = $_POST['subject'];
$sender = $_POST['sender'];
$toEmail=$_POST['toEmail'];
$passedInEmail=stripslashes($_POST['message']);
$passedInEmail=preg_replace('/ /',' ',$passedInEmail);
require_once('swiftLib/simple_html_dom.php');
require_once('swiftLib/swift_required.php');
$transport = Swift_MailTransport::newInstance();
$mailer = Swift_Mailer::newInstance($transport);
// Create the message
$message = Swift_Message::newInstance();
//turn the meesage into an object using simple_html_dom
//so we can iterate through and embed each image
$content = str_get_html($passedInEmail);
// Retrieve all img src tags and replace them with embedded images
foreach($content->find('img') as $e)
{
if($e->src != "")
{
$value = $e->src;
$newValue = $message->embed(Swift_Image::fromPath($value));
$e->src = $newValue;
}
}
$message->setSubject($subject);
$message->setFrom($sender);
$message->setTo($toEmail);
//this is my problem
$message->setBcc(array('tracking#pnrbuilder.com',$sender));
//as it is above only "sender" gets the email
//if I change it like this:
//$message->setBcc($tracker,$sender);
//only "tracker" gets the email
//same if I change it like this:
//$message->setBcc($sender);
//$message->addBcc($tracker);
$message->setReplyTo(array('flights#pnrbuilder.com'));
$message->setBody($content,'text/html');
$result = $mailer->send($message);
if ($result=3) {
echo 'Email Sent!';
}
else {
echo 'Error!';
}
?>
What is the proper way to do this?
You can find the swiftmailer tutorial here
example:
$message->setBcc(array(array('some#address.tld' => 'The Name'),array('another#address.tld' => 'Another Name')));
Try setting the names for the email addresses and see if it makes any difference.
This ended up being an issue on the server side, I contacted my hosting provider (GoDaddy) who were able to make some changes on their end fixing the problem. Thank you to all those who tried to help!

Find E-Mails with an exact e-mail address on an IMAP server using PHP

I want to connect to an IMAP-server and find all E-Mails that were sent to abc#server.tld. I tried:
$mbox = imap_open("{imap.server.tld/norsh}", "imap#server.tld", "5ecure3");
$result = imap_search($mbox, "TO \"abc#server.tld\"", SE_UID);
but this also listed e-Mails that were sent e.g. to 123abc#server.tld. Is it somehow possible to do a search for exact matches?
Short answer: you can't. I didn't find anything in RFC 2060 - Internet Message Access Protocol - Version 4rev1 saying that it can be done.
But, there is a workaround. First fetch all emails that contain abc#server.tld, then iterate through the results and select only the exact matches.
$searchEmail = "abc#server.tld";
$emails = imap_search($mbox, "TO $searchEmail");
$exactMatches = array();
foreach ($emails as $email) {
// get email headers
$info = imap_headerinfo($mbox, $email);
// fetch all emails in the TO: header
$toAddresses = array();
foreach ($info->to as $to) {
$toAddresses[] = $to->mailbox . '#' . $to->host;
}
// is there a match?
if (in_array($searchEmail, $toAddresses)) {
$exactMatches[] = $email;
}
}
Now you have all emails matching abc#server.tld in $exactMatches

how can I display the contents of an email to a website?

I would like to display the body contents of an email. I have tried IMAP in php but something is VERY wrong. The IMAP isn't picking up the body of my message. It is picking up ONLY the signature in the body. So I am looking for alternative methods of reading email body contents to a webpage.
here is the original document of my email:
http://pastebin.com/WQra335P
the disclaimer/copyright blur is being grabbed by IMAP but nothing else in the body is being displayed. anyone have alternative methods of reading email from gmail or any other site that can display the contents to a webpage?
I have given up on making IMAP read it because no one has been able to figure out the problem...I have spent hours so I give up but here is the code...
<?php
/* connect to gmail */
$hostname = '{imap.gmail.com:993/imap/ssl}INBOX';
$username = 'username#gmail.com';
$password = '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);
echo $message;
echo imap_qprint($message);
$message = imap_qprint($message);
echo imap_8bit ($message);
$DateFormatted = str_replace("-0500", "", $overview[0] -> date);
/* output the email header information */
$output .= $overview[0] -> subject ;
$output .= $DateFormatted ;
//$bodyFormatted = preg_replace("/This e-mail(.*)/","",$message);
//$bodyFormatted = preg_replace("/Ce courriel(.*)/","",$bodyFormatted);
/* output the email body */
$output .= $message;
}
echo $output;
}
/* close the connection */
imap_close($inbox);
?>
In Addition to what DmitryK suggested,
Adding the below makes everything work fine without the random "=" signs. The Str_replace is used to remove the "="s generated over the pages.
$message = imap_fetchbody($inbox, $email_number, "1.1");
$message = str_replace("=", "", $message);
I dont know 100% why the "="s are generated randomly but this is most likely due to some encryption issue from the Exchange Server's side as our server is about 10 years old.
You are dealing with the multi-part messages (looking at your pastebin e-mail sample).
As a test try using this line:
$message = imap_fetchbody($inbox, $email_number, "1.1");
Plain text version lives under 1.1
HTML version is 1.2
The signature is in the next part - it is 2. And this is what you retrieve in your code sample.
Do you have access to the raw email content (the stuff with all the headers etc)
If so, try using plancacke email parser
I have used it before with good success.
$emailParser = new PlancakeEmailParser(...raw email content...);
$emailTo = $emailParser->getTo();
$emailSubject = $emailParser->getSubject();
$emailCc = $emailParser->getCc();
$emailDeliveredToHeader = $emailParser->getHeader('Delivered-To');
$emailBody = $emailParser->getPlainBody();
$emailHtml = $emailParser->getHTMLBody();
Gmail has some different IMAP settings, follow the original code more closely:
http://davidwalsh.name/gmail-php-imap

Categories