Sử dụng PHP Imap để đọc Email

Đăng bởi:

Duy Nguyễn

Đăng ngày:

Feb 27, 2021

Đăng ở:

Kiến Thức Cơ Bản
Trong trường hợp chúng ta cần sử dụng chức năng về email thông qua các Email Provider (Gmail, Yandex, Yahoo, AOL, ...) , thì  PHP IMAP là một giải pháp tốt nhất  nó một extension của PHP để lấy mail từ hệ thống. Trong bài viết này mình sẽ sử dụng thư viện php-imap/php-imap

Cài đặt

  1. Nếu chưa cài đặt thư viện php-imap thì bạn có thể cài đặt bằng câu lệnh sau (dấu * là phiên bản php muốn cài đặt) :
sudo apt-get install php*-imap php*-mbstring php*-mcrypt && sudo apache2ctl graceful

Để chắc chắn thì bạn có thể sử dụng phpinfo() để kiểm tra xem thư viện đã được kích hoạt chưa

  1. Cài đặt php-imap/php-imap package từ github :
composer require php-imap/php-imap

Tính năng hỗ trợ

  • Kết nối với hộp thư bằng POP3 / IMAP / NNTP, sử dụng phần mở rộng PHP IMAP
  • Nhận email có tệp đính kèm và hình ảnh nội tuyến
  • Nhận email được lọc hoặc sắp xếp theo tiêu chí tùy chỉnh
  • Đánh dấu email là đã thấy / chưa nhìn thấy
  • Xóa email
  • Quản lý các thư mục hộp thư

Bắt đầu

  1.  Tạo migrations để lưu email được đọc,m ở đây mình tạo 1 bảng có tên 'mails' gồm các trường như sau:
    <?php
    
    use Illuminate\Database\Migrations\Migration;
    use Illuminate\Database\Schema\Blueprint;
    
    class CreateMailsTable extends Migration {
    
    	/**
    	 * Run the migrations.
    	 *
    	 * @return void
    	 */
    	public function up()
    	{
    		Schema::create('mails', function(Blueprint $table)
    		{
    			$table->increments('id');
                $table->bigInteger("mid"); // mail ID
                $table->string('messageId')->unique(); // message id
    			$table->integer('user_server'); // id of curent server
                $table->string('references'); // message id
                $table->string('in_reply_to'); // message id
                $table->dateTime("date");
                $table->string("subject")->nullable();
                $table->string("fromName")->nullable();
                $table->string("fromAddress")->nullable();
                $table->string("to")->nullable();
                $table->string("cc")->nullable();
                $table->string("reply")->nullable();
                $table->text("plain")->nullable();
                $table->text("html")->nullable();
                $table->string('folder')->nullable();
                $table->integer('mess_references')->default(0);
    
    			$table->timestamps();
    		});
    	}
    
    
    	/**
    	 * Reverse the migrations.
    	 *
    	 * @return void
    	 */
    	public function down()
    	{
    		Schema::drop('mails');
    	}
    
    }
    ​
  2. Tạo bảng 'mail_attachments' để lưu các tệp tin từ các mail được đọc
    <?php
    
    use Illuminate\Database\Migrations\Migration;
    use Illuminate\Database\Schema\Blueprint;
    
    class CreateMailAttachmentsTable extends Migration {
    
    	/**
    	 * Run the migrations.
    	 *
    	 * @return void
    	 */
    	public function up()
    	{
    		Schema::create('mail_attachments', function(Blueprint $table)
    		{
    			$table->increments('id');
    			$table->integer("mail_id")->unsigned();
                $table->string("aid")->unique();
                $table->string("name")->nullable();
                $table->string("path")->nullable();
    
    			$table->timestamps();
    		});
    	}
    
    
    	/**
    	 * Reverse the migrations.
    	 *
    	 * @return void
    	 */
    	public function down()
    	{
    		Schema::drop('mail_attachments');
    	}
    
    }
    ​
  3. Tạo command 'mails:GetMail' để kết nối với server mail , đọc mail và lưu vào cơ sở dữ liệu
    <?php
    
    namespace Sudo\MailConfig\Commands;
    
    use Illuminate\Console\Command;
    use Carbon\Carbon;
    use Log;
    use DB;
    use Form;
    use Sudo\MailConfig\Models\Mail;
    use Sudo\MailConfig\Models\MailAttachment;
    use PhpImap;
    
    class GetMail extends Command
    {
        /**
         * The name and signature of the console command.
         *
         * @var string
         */
        protected $signature = 'mails:GetMail';
    
        /**
         * The console command description.
         *
         * @var string
         */
        protected $description = 'Lay mail tu folder inbox';
    
        /**
         * Create a new command instance.
         *
         * @return void
         */
        public function __construct()
        {
            parent::__construct();
        }
    
        /**
         * Execute the console command.
         *
         * @return int
         */
        public function handle()
        {
        	\Log::info('start get inbox');
            $mailbox = new PhpImap\Mailbox('{imap.gmail.com:993/ssl}INBOX', '[email protected]', 'XXXX', public_path()."/uploads/mail-attachments/", 'UTF-8');
            $mailIds = $mailbox->searchMailBox('ALL');
            // }
            if(!$mailIds) {
                $this->info("No mail!");
            } else {
                $list_message = $mailbox->getMailsInfo($mailIds);
                $check_references = Mail::where('user_server', 1)->pluck('messageId', 'id')->toArray();
                foreach ($list_message as  $value) {
                    if(Mail::where("messageId", $value->message_id)->count() == 0) {
                        $getMail = $mailbox->getMail($value->uid);
    
                        $ccs = [];
                        foreach($getMail->cc as $ccMail => $ccName) {
                            $ccs[] = $ccName."(".$ccMail.")";
                        }
                        $replys = [];
                        foreach($getMail->replyTo as $replyMail => $replyName) {
                            $replys[] = $replyName."(".$replyMail.")";
                        }
                        $mess_references = 0;
                        $current_references = explode(' ', $value->references??'');
                        if(count($current_references) > 0 && count($check_references) > 0) {
                            foreach ($check_references as $key => $ref) {
                                if($current_references[0] == $ref) {
                                    $mess_references = $key;
                                }
                            }
                        }
                        $mail = new Mail;
                        $mail->mid = $getMail->id;
                        $mail->messageId = $value->message_id;
                        $mail->user_server = 1;
                        $mail->references = $value->references ?? '';
                        $mail->in_reply_to = $value->in_reply_to ?? '';
                        $mail->date = date('Y-m-d H:i:s', strtotime($value->date));
                        $mail->subject = $getMail->subject ?? '';
                        $mail->fromName = $getMail->fromName ?? '';
                        $mail->fromAddress = $getMail->fromAddress ?? '';
                        $mail->to = $value->to ?? '';
                        $mail->cc = implode(",", $ccs);
                        $mail->reply = implode(",", $replys);
                        $mail->plain = $getMail->textPlain ?? '';
                        $mail->html = json_encode($getMail->textHtml ?? '');
                        $mail->folder = 'inbox';
                        $mail->mess_references = $mess_references ?? 0;
                        $mail->save();
    
                        $check_references[$mail->id] = $value->message_id;
    
                        foreach($getMail->getAttachments() as $getAttachment) {
                            $attachment = new MailAttachment();
                            $attachment->aid = $getAttachment->id;
                            $attachment->name = $getAttachment->name;
                            $attachment->path = $getAttachment->filePath;
                            $attachment->mail_id = $mail->id;
                            $attachment->save();
                        }
    
                        $this->info("New Mail:".$mail->subject);
                    }
                }
            }
            \Log::info('End get inbox');
    
        }
    }
    ​
  4. Kết quả
    DUY NGUYEN@DESKTOP-44OJ9TS MINGW64 /d/laragon/www/sudo-mail
    $ php artisan mails:GetMail
    New Mail:MaiI, messenger and cloud storage for files: welcome to Yandex.Connect!
    New Mail: [Slack] Notifications from the Sudo E-Convnerce workspace
    New Mail: Xác nhận thanh toán​

kết luận

Như vậy với những thao tác đơn giản mình có thể hoàn toàn đọc mail và lưu mail về cơ sở dữ liệu để dễ dàng sử dụng

Nguồn  thư viện: https://github.com/barbushin/php-imap

 

default_image
Tác giả: Duy Nguyễn
ADMIN

Bình luận

Để lại bình luận

Email và số điện thoại sẽ không được công khai. Những trường bắt buộc được đánh dấu *

Repository deleted Your repository has remove
Loading