PHP IMAP - Fetch email
New here? Learn about Bountify and follow @bountify to get notified of new bounties! x

I have a PHP application which fetches email using IMAP.

Gmail considers my application of "low-security" and I have to click on "enable low-security applications" to have my application access gmail IMAP, and my app most of the times gets blocked for "suspicious" activity and I need to manually enable it in every email inbox I crawl.

My code currently looks something like this (I simplified it):
https://pastebin.com/hsPLASAk

The main problem seems to be here:

$this->server = '{'. $imap. ':' .$port.'/ssl}';
$this->connection = imap_open($this->server, $emailAddress, $password);

Is there a way to make this connection "more secure" to comply with Gmail standards regarding the IMAP connection so I don't get any "suspicious activity" warnings? Thanks!

Please provide a tested and working solution. Thanks

awarded to Codeword
Tags
PHP

Crowdsource coding tasks.

3 Solutions


Gmail requires OAuth2.0 authentication for gmail if you want to use it in PHP. You should use a PHP extension to get that, it will be easier. Here is an extension that seems to do the work :
https://www.example-code.com/phpext/imap_gmail_oauth2.asp

Thanks, do you have a solution that does not use a php extension? Extensions have security issues and get outdated.
georgefountain 1 month ago
Just seen the last comment on Codeword solution, if there is an issue with the SSL certificate, you can try to disable the check when connecting using the "/novalidate-cert". This may reduce the "suspicious activity warning : $this->server = '{'. $imap. ':' .$port.'/ssl/novalidate-cert}';
kerncy 1 month ago
Thanks. Can we have a valid ssl certificate? Can you provide a solution without an extension? Thanks so much
georgefountain 1 month ago

You need to use OAuth authentication, otherwise GMail will not consider your application secure.

Here's a quick tutorial on how to implement it as quickly as possible:
http://kwynn.com/t/7/03/php_imap_oauth2.html

At the bottom the tutorial mentions why you had to enable low-security applications to make it work.

Good luck! :)

.Your "solution" has Python instead of php and is a badly written article. As bountify states please post a complete working solution so that it can be accepted. Thanks
georgefountain 1 month ago
Can you explain what is the python part for? I don't understand it. Thanks
georgefountain 1 month ago
Winning solution

Hello, the solution to your problem is simple.

Step 1. Go to https://security.google.com/settings/security/apppasswords
Select the following two fields from their drop-down lists 'Select app = mail' and 'Select device =Other'.

Step 2. Click "GENERATE" button and save the app password shown to you.

After this, you need two file index.php  Imap.php

Note : You can use your own code but make sure to use you App password as your password when passing parameters to imap_open() function. Or you can also use the file below

Thank you.

index.php contents

<?php

// include Imap class
include('Imap.php');

// create Imap_parser Object
$parse = new Imap_parser();

$email ='someone@outlook.com';
$password='password';
$em=end(explode('@', $email));
$hostname='';
switch ($em) {
case 'gmail.com':
$hostname='{imap.gmail.com:993/imap/ssl}INBOX';
$password= 'App password you got in step 2';
break;

case 'outlook.com':
    $hostname='{imap-mail.outlook.com:993/ssl}INBOX';
    break;

}

// data '{imap.gmail.com:993/imap/ssl/novalidate-cert}INBOX' or notls
$data = array(
// email account
'email' => array(
'hostname' => $hostname,
'username' => $email,
'password' => $password

),
// inbox pagination
'pagination' => array(
'sort' => 'DESC', // or ASC
'limit' => 5,
'offset' => 0
)
);

// get inbox. Array
$result = $parse->inbox($data);
echo '';
print_r($result);
echo '';
?>

imap.php contents


<?php

class Imap_parser {

function inbox($data)
{

    $result = array();

    $imap = imap_open($data['email']['hostname'], $data['email']['username'], $data['email']['password']) or die ('Cannot connect to yourdomain.com: ' . imap_last_error());

    if ($imap) {

        $result['status'] = 'success';
        $result['email']  = $data['email']['username'];

        $read = imap_search($imap, 'ALL');

        if($data['pagination']['sort'] == 'DESC'){
            rsort($read);
        }

        $num = count($read);

        $result['count'] = $num;

        $stop = $data['pagination']['limit'] + $data['pagination']['offset'];

        if($stop > $num){
            $stop = $num;
        }

        for ($i = $data['pagination']['offset']; $i < $stop; $i++) {

            $overview   = imap_fetch_overview($imap, $read[$i], 0);
            $message    = imap_body($imap, $read[$i], 0);
            $header     = imap_headerinfo($imap, $read[$i], 0);
            $mail       = $header->from[0]->mailbox . '@' . $header->from[0]->host;
            $image = '';

            $message = preg_replace('/--(.*)/i', '', $message);
            $message = preg_replace('/X\-(.*)/i', '', $message);
            $message = preg_replace('/Content\-ID\:/i', '', $message);

            $msg = '';            

            if (preg_match('/Content-Type/', $message)) {
                $message = strip_tags($message);
                $content = explode('Content-Type: ', $message);
                foreach ($content as $c) {
                    if (preg_match('/base64/', $c)) {
                        $b64 = explode('base64', $c);
                        if (preg_match('/==/', $b64[1])) {
                            $str = explode('==', $b64[1]);
                            $dec = $str[0];
                        } else {
                            $dec = $b64[1];
                        }
                        if (preg_match('/image\/(.*)\;/', $c, $mime)) {
                            $image = 'data:image/' . $mime[1] . ';base64,' . trim($dec);
                        }
                    } else {
                        if (!empty($c)) {
                            $msg = $c;
                        }
                    }
                }
            } else {
                $msg = $message;
            }

            $msg = preg_replace('/text\/(.*)UTF\-8/', '', $msg);
            $msg = preg_replace('/text\/(.*)\;/', '', $msg);
            $msg = preg_replace('/charset\=(.*)\"/', '', $msg);
            $msg = preg_replace('/Content\-Transfer\-Encoding\:(.*)/i', '', $msg);

            $result['inbox'][] = array(
                'id' => $read[$i],
                'subject' => strip_tags($overview[0]->subject),
                'from' => $overview[0]->from,
                'email' => $mail,
                'date' => $overview[0]->date,
                'message' => trim($msg),
                'image' => $image
            );

            $result['pagination'] = array(
                'sort' => $data['pagination']['sort'],
                'limit' => $data['pagination']['limit'],
                'offset' => array(
                    'back' => ($data['pagination']['offset'] == 0 ? null : $data['pagination']['offset'] - $data['pagination']['limit']),
                    'next' => ($data['pagination']['offset'] < $num ? $data['pagination']['offset'] + $data['pagination']['limit'] : null)
                )
            );

        }

        imap_close($imap);

    } else {
        $result['status'] = 'error';
    }

    return $result;

}

}

?>

Thanks but the problem is not the password. The problem seems to be the ssl with no certificate which makes the connection insecure. This doesn't solve the problem
georgefountain 1 month ago
okay, thanks for your feedback, georgefountain.
Codeword 1 month ago
You are welcome. Hoping that you can find the solution : ) Thanks
georgefountain 1 month ago
P.S: Codeword, have you tested your solution? Does doing just that remove the security warnings?
georgefountain 1 month ago
yes, I have tested this code and it removes the security warnings. I hope it works for you too. Thank you.
Codeword 1 month ago
Codeword, please can you check how to add a valid security certificate to the connection to make it more secure? If so, I would like to award the bounty to you. Thanks
georgefountain 26 days ago
Do you have an ssl cerificate for you domain?
Codeword 26 days ago
Yes i do.
georgefountain 26 days ago
Okay, Have you tried the above solution?
Codeword 26 days ago
Your solution only applies for Gmail. All other email providers tell me that my connection is insecure. How can we can the connection secure?
georgefountain 26 days ago
"Low security application". Same problem with outlook
georgefountain 26 days ago
I provided the solution specifically for gmail, because it was explicity mentioned "to comply with Gmail standards" in the bounty description. Thank you.
Codeword 26 days ago
Provide a full solution to the problem to get a 100% extra bonus tip
georgefountain 26 days ago
Hey, george, I have found this solution online, you may want to try this. Let me know how it goes. Thank you. https://www.toptal.com/php/building-an-imap-email-client-with-php. Note : I don't have an SSL certified domain, so cannot test solution.
Codeword 26 days ago
Thanks. Can you modify your code with what the article suggests? Thanks
georgefountain 26 days ago
I don't see anything on the article about using a security certificate. I don't understand why you sent the article..
georgefountain 26 days ago
george, Good news, With a little modifications the code seems to work with outlook too. I have tested and it is now working in outlook too.I have updated the code above. Note : requirements of every email provider is a bit different so, I have implemented a switch case here.
Codeword 25 days ago
Thats fantastic news! The code is a bit hard to read. Could you please paste into paste bin? The trick was adding the imap. Host to remove the warning? What made the difference? Thanks so much for the hard work!
georgefountain 25 days ago
In other words, what is it that removed the warning in outlook?
georgefountain 25 days ago
Here it is https://pastebin.com/kNbVCTAk I hope it works for you.
Codeword 25 days ago
Thanks thst works better! So about my question, what made the difference? Thanks
georgefountain 25 days ago
Well I am very much clear about the gmail but, I am not very much sure about outlook, I looked at the imap settings in my outlook account and tried those settings and it worked. Thank you.
Codeword 25 days ago
Is everything working like you wanted ? Thanks
Codeword 25 days ago
Thank you Georgefountain.
Codeword 24 days ago
View Timeline