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 3 months 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 3 months ago
Thanks. Can we have a valid ssl certificate? Can you provide a solution without an extension? Thanks so much
georgefountain 3 months 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 3 months ago
Can you explain what is the python part for? I don't understand it. Thanks
georgefountain 3 months 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 3 months ago
okay, thanks for your feedback, georgefountain.
Codeword 3 months ago
You are welcome. Hoping that you can find the solution : ) Thanks
georgefountain 3 months ago
P.S: Codeword, have you tested your solution? Does doing just that remove the security warnings?
georgefountain 3 months ago
yes, I have tested this code and it removes the security warnings. I hope it works for you too. Thank you.
Codeword 3 months 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 3 months ago
Do you have an ssl cerificate for you domain?
Codeword 3 months ago
Yes i do.
georgefountain 3 months ago
Okay, Have you tried the above solution?
Codeword 3 months 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 3 months ago
"Low security application". Same problem with outlook
georgefountain 3 months 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 3 months ago
Provide a full solution to the problem to get a 100% extra bonus tip
georgefountain 3 months 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 3 months ago
Thanks. Can you modify your code with what the article suggests? Thanks
georgefountain 3 months ago
I don't see anything on the article about using a security certificate. I don't understand why you sent the article..
georgefountain 3 months 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 3 months 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 3 months ago
In other words, what is it that removed the warning in outlook?
georgefountain 3 months ago
Here it is https://pastebin.com/kNbVCTAk I hope it works for you.
Codeword 3 months ago
Thanks thst works better! So about my question, what made the difference? Thanks
georgefountain 3 months 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 3 months ago
Is everything working like you wanted ? Thanks
Codeword 3 months ago
Thank you Georgefountain.
Codeword 3 months ago
View Timeline