First we have to allow third parties to access your gmail.
Even I turn on “Less secure app access”, it still doesn’t work.
Workable solution is to turn on 2-step verification for your google account then set an app password, which you can find the config on the section “Signing in to Google”
Secondly, go to https://mail.google.com and click the setting icon then see all settings. press Forwarding and POP/IMAP on the top horizontal menu, click “Enable IMAP”
Gmail is ready for you to access, let’s code it!
composer require php-mail-client/client composer require ssilence/php-imap-client
Before we start, we download the above libraries using composer then we try to connect.
use SSilence\ImapClient\ImapClient as Imap; use SSilence\ImapClient\ImapClientException; try { $imap = new Imap("imap.gmail.com", "yourname@gmail.com", "app-password", Imap::ENCRYPT_SSL); } catch (ImapClientException $error) { throw new InstagramAuthException('Login error. Cannot login to imap server: ' . $error->getMessage()); }
Try to get the count of unread messages in INBOX folder.
$imap->selectFolder("INBOX"); try { $unreadMessages = $imap->countUnreadMessages(); var_dump('countUnreadMessages: ' . $unreadMessages); } catch (ImapClientException $e) { var_dump($e); }
Try to search Criteria: UNSEEN, on today, from a specified email using imap_search and form an array storing the mails and their IDs.
$date = date("j F Y"); var_dump($date); $result = imap_search($imap->getImap(), 'UNSEEN FROM "xxx@mail.xxx.com" ON "'.$date.'"'); $countId = count($result); var_dump('countId: ' . $countId); foreach($result as $key=>$id) { //var_dump($id); $emails[]= ['email'=>$imap->getMessage($id), 'id'=>$id]; } var_dump($emails);
Why do we get the ID? because we can set the email to be read.
$imap->setSeenMessage($id);
Here I have a completed source code to keep checking the email and stop once I receive a special email with a verification code inside the email.
<?php require __DIR__ . '/vendor/autoload.php'; use SSilence\ImapClient\ImapClient as Imap; use SSilence\ImapClient\ImapClientException; const MAIL_MAX_WAIT_TIME = 600; const MAIL_WAIT_STEP_TIME = 10; try { $imap = new Imap("imap.gmail.com", "user@gmail.com", "app-password", Imap::ENCRYPT_SSL); echo keepChecking($imap); } catch (ImapClientException $error) { throw new InstagramAuthException('Login error. Cannot login to imap server: ' . $error->getMessage()); } function keepChecking($imap) { $startTime = time(); while (time() - $startTime < MAIL_MAX_WAIT_TIME) { sleep(mt_rand(60,MAIL_WAIT_STEP_TIME*60)/60); try { $code = getCodeFromEmail($imap); } catch (ImapClientException $e) { break; } if ($code) return $code; sleep(MAIL_WAIT_STEP_TIME); } throw new InstagramAuthException('Login error. Verification email read timeout.'); } function searchEmail($imap) { $date = date("j F Y"); var_dump($date); $result = imap_search($imap->getImap(), 'UNSEEN FROM "from@mail.com" ON "'.$date.'"'); $countId = count($result); var_dump('countId: ' . $countId); foreach($result as $key=>$id) { //var_dump($id); $emails[]= ['email'=>$imap->getMessage($id), 'id'=>$id]; } return array_reverse($emails); //desc } function getCodeFromEmail($imap) { $imap->selectFolder("INBOX"); try { $unreadMessages = $imap->countUnreadMessages(); var_dump('countUnreadMessages: ' . $unreadMessages); $code = false; if ($unreadMessages) { $emails = searchEmail($imap); foreach ($emails as $mailWrap) { $mail = $mailWrap['email']; echo "{$mailWrap['id']} [{$mail->header->date}] ({$mail->header->from}) {$mail->header->subject}\n"; if ($mail->header->from !== 'Demo <from@mail.com>') { continue; } $message = json_encode($mail->message); if (preg_match('/>(\d{6})</', $message, $matches)) { $code = $matches[1]; var_dump($code); $imap->setSeenMessage($mailWrap['id']); return $code; } } } } catch (ImapClientException $e) { var_dump($e); } }