Advertisement
  1. Code
  2. Email

Membangun Fitur Email Tingkat Lanjut dengan IMAP dan PHP

Scroll to top
Read Time: 15 min

Indonesian (Bahasa Indonesia) translation by ⚡ Rova Rindrata (you can also view the original English article)

What You'll Be Creating

Dalam tutorial ini, saya akan memandu Anda melalui beberapa contoh nyata tentang bagaimana Anda dapat menggunakan PHP dan IMAP untuk membangun fitur baru untuk mengelola email—fitur yang belum dibangun penyedia email besar bagi kita.

Ketertarikan saya pada ini dimulai pada tahun 2010 ketika saya menulis Dua Belas Gagasan Gmail untuk Merevolusi Email (Lagi), namun sebagian besar gagasan yang saya harapkan tetap berada di luar jangkauan. Sama pentingnya dengan email, inovasi email sebagai aplikasi cukup lambat.

Kita tenggelam dalam email, dan mengelola inbox kita tetap menjadi beban yang berat. Layanan mail dan klien telah melakukan sangat sedikit untuk membantu kita dengan ini. Sebagian besar email yang kita terima dikirim oleh mesin, bukan orang-orang, dan kita adalah orang-orang yang harus memproses semuanya secara individual.

Analisis dari email saya sendiri menunjukkan bahwa saya menerima email dari lebih dari 230 pengirim otomatis, jauh lebih sedikit dari orang yang sebenarnya. Saya sudah bosan membangun filter di Gmail dan mengisi segudang form berhenti berlangganan. Saya ingin memiliki lebih banyak kontrol atas pengelolaan email saya dan menyederhanakan hidup saya.

Akhirnya, tahun yang lalu ini, saya memutuskan untuk membangun fitur yang saya butuhkan. Hasilnya adalah Simplify Email (SE), aplikasi web kecil yang bisa Anda host sendiri yang menawarkan berbagai fitur email keren baru yang semuanya bisa Anda kunjungi di situs web proyek.

Hal yang paling keren tentang SE adalah bahwa ini adalah platform untuk membaca, menganalisis, merutekan dan mengelola email Anda—kemungkinannya berlimpah. Simplify Email pada dasarnya adalah taman bermain yang dapat diprogram untuk "hacking" email Anda sendiri.

Saya akan memandu Anda melalui kode tiga contoh dari SE yang menggunakan PHP, IMAP, dan MySQL untuk bekerja dengan email:

  1. Memeriksa inbox dan penyaringan pesan Anda
  2. Menerapkan tantangan Whitelist kepada pengirim yang tidak dikenal
  3. Melaporkan email yang tidak terjawab

Tutorial ini pasti akan memberi Anda keuntungan saat menulis kode IMAP di PHP. Tapi Anda juga bisa bekerja secara langsung dengan basis kode Simplify Email. Anda dapat membeli kode tersebut sekecil $10, dan ada versi open source yang lebih lama (yang tidak memiliki beberapa fitur yang kami gambarkan di bawah ini). Panduan instalasi disediakan untuk konfigurasi Linux yang khusus. Saya juga menawarkan image pra-instal di Digital Ocean seharga $25 dan juga pemasangan valet alat genggam. SE ditulis dalam PHP, di Kerangka Yii.

Perhatikan bahwa Anda tidak akan dapat mengakses sebagian besar server email melalui mesin pengembangan lokal Anda kecuali Anda mengkompilasi pustaka IMAP yang aman untuk PHP. Inilah salah satu alasan mengapa saya mendorong orang untuk menjalankan Simplify Email dalam droplet di Digital Ocean. Ada juga beberapa trik untuk mendapatkan izin keamanan akun Google agar Anda bisa masuk melalui IMAP.

Bekerja dengan IMAP

Cara Simplify Email Bekerja

Dengan SE, Anda dapat terus menggunakan klien email pilihan Anda di Web dan perangkat seluler Anda. Anda tidak perlu mengubah aplikasi atau kebiasaan pribadi apa pun. SE mengakses akun email Anda di balik layar melalui IMAP; bertindak sebagai asisten pribadi yang cerdas, SE melakukan pra-proses email Anda sebelumnya, memindahkan pesan ke tempat yang sesuai berdasarkan semua hal yang Anda katakan kepadanya.

Saat pesan tiba dari pengirim yang sudah dikenal, SE memindahkannya ke folder yang Anda tentukan. Ketika datang dari pengirim yang tidak dikenal untuk pertama kalinya, ia memindahkannya ke folder tinjauan.

Setiap beberapa jam (atau pada frekuensi yang Anda pilih), SE akan mengirimkan ringkasan dari mana pesan Anda dipindahkan dan pesan mana yang sedang diperiksa. Catatan, tautan untuk pengirim pelatihan disertakan untuk folder tinjauan, sehingga cukup mudah untuk melatih SE dari waktu ke waktu.

The Simplify Email Message Digest Shows You What Came In and How It Was FilteredThe Simplify Email Message Digest Shows You What Came In and How It Was FilteredThe Simplify Email Message Digest Shows You What Came In and How It Was Filtered

Setiap saat, Anda dapat menelusuri folder tinjauan—Anda tidak perlu menunggu mencerna tiba. Namun keuntungan dari SE adalah Anda tidak perlu lagi menelusuri folder Anda; Anda bisa membaca ringkasan Anda untuk mendapatkan tampilan email yang telah Anda terima dan mengatur pengirim baru.

1. Memeriksa Kotak Masuk dan Penyaringan Pesan Anda

SE menggunakan beberapa tugas cron untuk beroperasi di latar belakang server Anda. Masing-masing disebut dari DaemonController.php.

Yang pertama, processInbox, yang sering dipanggil dan perlu beroperasi dengan cepat—tugasnya adalah untuk menyaring email dan memindahkannya keluar dari Kotak Masuk secepat mungkin dan masuk ke folder triase, yang disebut folder penyaringan.

Yang kedua, processFiltering, proses yang lebih intensif dan melakukan operasi yang lebih dalam pada email, akhirnya memindahkan pesan ke tujuan akhir mereka.

Metode ProcessInbox

Tugas cron memanggil processInbox secara teratur:

1
public function actionInbox() {
2
    
3
    // moves inbox messages to @filtering

4
    // runs frequently 

5
    $r = new Remote();
6
    $r->processInbox();    
7
    
8
}
The Simplify Email Accounts Configuration PageThe Simplify Email Accounts Configuration PageThe Simplify Email Accounts Configuration Page

Untuk setiap akun, kami mendekripsi kredensial e-mail Anda dan kemudian menggunakan imap_open untuk membuat aliran IMAP ke folder kotak masuk Anda:

1
public function open($account_id, $mailbox='',$options=NULL) {
2
  // opens folder in an IMAP account

3
  $account = Account::model()->findByPk($account_id);
4
  $this->hostname = $account->address;
5
  if (!stristr($this->hostname,'{'))
6
    $this->hostname = '{'.$this->hostname.'}';
7
  $cred = Account::model()->getCredentials($account->cred);
8
  if ($account->provider == Account::PROVIDER_ICLOUD) {
9
    // icloud accepts only name part of mailbox e.g. stevejobs vs. stevejobs@icloud.com

10
    $temp = explode('@',$cred[0]);
11
    $cred[0]=$temp[0];
12
  }
13
  $this->stream = imap_open($this->hostname.$mailbox,$cred[0],$cred[1],$options,1) or die('Cannot connect to mail server - account_id:'.$account_id .' '.print_r(imap_errors()));
14
}

Di dalam processInbox, kami menggunakan fungsi pustaka PHP imap_search dan imap_fetch_overview untuk mengambil berbagai pesan:

1
// lookup folder_id of this account's INBOX

2
$folder_id = Folder::model()->lookup($account_id,$this->path_inbox);
3
$this->open($account_id,$this->path_inbox);
4
$cnt=0;
5
$message_limit= 50; // break after n messages to prevent timeout

6
echo 'Sort since: '.date("j F Y",$tstamp);           
7
// imap_search date format 30 November 2013

8
 $recent_messages = @imap_search($this->stream, 'SINCE "'.date("j F Y",$tstamp).'"',SE_UID); 
9
 if ($recent_messages===false) continue; // to do - continue into next account

10
 $result = imap_fetch_overview($this->stream, implode(',',array_slice($recent_messages,0,$message_limit)),FT_UID);

Kemudian kami memproses sejumlah pesan di kotak masuk:

1
foreach ($result as $item) {         
2
   if (!$this->checkExecutionTime($time_start)) break;
3
   // get msg header and stream uid

4
   $msg = $this->parseHeader($item); 

Berikut adalah versi adaptasi dari kode parsing header IMAP yang tersedia untuk publik yang mengumpulkan informasi tambahan yang dibutuhkan SE untuk berbagai tugas. Pada dasarnya, ia menggunakan imap_rfc822_parse_adrlist untuk menentukan informasi penerima, message-id, subjek dan timestamp (atau informasi pengirim saat memindai folder terkirim):

1
  public function parseHeader($header) {
2
    // parses header object returned from imap_fetch_overview    

3
    if (!isset($header->from)) {
4
      return false;
5
    } else {
6
      $from_arr = imap_rfc822_parse_adrlist($header->from,'gmail.com');
7
      $fi = $from_arr[0];
8
      $msg = array(
9
        "uid" => (isset($header->uid))
10
              ? $header->uid : 0,
11
         "personal" => (isset($fi->personal))
12
            ? @imap_utf8($fi->personal) : "",
13
          "email" => (isset($fi->mailbox) && isset($fi->host))
14
              ? $fi->mailbox . "@" . $fi->host : "",
15
          "mailbox" => (isset($fi->mailbox))
16
            ? $fi->mailbox : "",
17
          "host" => (isset($fi->host))
18
            ? $fi->host : "",
19
          "subject" => (isset($header->subject))
20
              ? @imap_utf8($header->subject) : "",
21
          "message_id" => (isset($header->message_id))
22
                ? $header->message_id : "",
23
          "in_reply_to" => (isset($header->in_reply_to))
24
                    ? $header->in_reply_to : "",
25
          "udate" => (isset($header->udate))
26
              ? $header->udate : 0,
27
          "date_str" => (isset($header->date))
28
              ? $header->date : ""
29
      );    
30
      // handles fetch with uid and rfc header parsing

31
      if ($msg['udate']==0 && isset($header->date)) {
32
          $msg['udate']=strtotime($header->date);
33
      }
34
      $msg['rx_email']='';        
35
      $msg['rx_personal']='';
36
        $msg['rx_mailbox']='';
37
        $msg['rx_host']='';
38
      if (isset($header->to)) {        
39
        $to_arr = imap_rfc822_parse_adrlist($header->to,'gmail.com');
40
        $to_info = $to_arr[0];
41
        if (isset($to_info->mailbox) && isset($to_info->host)) {
42
          $msg['rx_email']=$to_info->mailbox.'@'.$to_info->host;
43
        }
44
        if (isset($to_info->personal))
45
          $msg['rx_personal']=$to_info->personal;
46
        if (isset($to_info->mailbox))
47
          $msg['rx_mailbox']=$to_info->mailbox;
48
        if (isset($to_info->host))
49
          $msg['rx_host']=$to_info->host;
50
      }
51
      return $msg;
52
    }
53
  }

Kami membuat record untuk pengirim dan amplop pesan di dalam database kami:

1
   // skip any system messages

2
   if ($msg['email']==$system_email) continue;
3
    // if udate is too old, skip msg

4
    if (time()-$msg['udate']>$this->scan_seconds) continue; // skip msg

5
    // default action

6
     $action = self::ACTION_MOVE_FILTERED;
7
     $isNew = $s->isNew($account_id,$msg["email"]);
8
    // look up sender, if new, create them

9
    $sender_id = $s->add($user_id,$account_id,$msg["personal"], $msg["mailbox"], $msg["host"],0);                       
10
    $sender = Sender::model()->findByPk($sender_id);
11
     // create a message in db if needed

12
     $message_id = $m->add($user_id,$account_id,0,$sender_id,$msg['message_id'],$msg['subject'],$msg['udate'],$msg['in_reply_to']);        
13
        $message = Message::model()->findByPk($message_id);

Jika pengirimnya baru dikenal (tidak diketahui), kami akan mengirim email tantangan daftar putih (kita akan membicarakan tantangan daftar putih di bagian selanjutnya di bawah ini):

1
if ($isNew) {
2
        $this->challengeSender($user_id,$account_id,$sender,$message);
3
      }

Selanjutnya, kita menentukan apakah pengguna mungkin telah menyeret pesan dari folder lain kembali ke kotak masuk—berniat untuk mengaturnya melalui drag and drop. Jika iya, kami menetapkan pengaturan untuk pengirim ini ke kotak masuk. Dengan kata lain, lain kali, kami ingin mengarahkan pesan dari pengirim ini ke kotak masuk:

1
         if ($message['status'] == Message::STATUS_FILTERED ||
2
   	    $message['status'] == Message::STATUS_REVIEW ||
3
   	    ($message['status'] == Message::STATUS_TRAINED && $message['folder_id'] <> $folder_id) ||
4
   	    ($message['status'] == Message::STATUS_ROUTED && $message['folder_id'] <> $folder_id))
5
   	    {
6
     	  // then it's a training

7
   	    $action = self::ACTION_TRAIN_INBOX;     	    
8
   	  } else if (($message['status'] == Message::STATUS_TRAINED || $message['status'] == Message::STATUS_ROUTED) && $message['folder_id'] == $folder_id) {
9
   	    // if trained already or routed to inbox already, skip it

10
   	    $action = self::ACTION_SKIP;  
11
   	    echo 'Trained previously, skip ';lb();   	  
12
   	    continue;  
13
   	  }

Jika tidak, kami akan mempersiapkan untuk memindahkan pesan ke folder Filtering untuk diproses lebih lanjut. Pertama, kami mungkin mengirimkan notifikasi ke telepon pengguna jika ada kecocokan pengirim atau kata kunci yang cocok untuk pemberitahuan (dan ini bukan pada jam tenang):

1
   if ($action == self::ACTION_MOVE_FILTERED) {
2
     $cnt+=1;         
3
     if ($sender->exclude_quiet_hours == Sender::EQH_YES or !$this->isQuietHours($user_id)) {
4
       // send smartphone notifications based on sender

5
       if ($sender->alert==Sender::ALERT_YES) {
6
         $this->notify($sender,$message,Monitor::NOTIFY_SENDER);
7
       }
8
       // send notifications based on keywords

9
       if (AlertKeyword::model()->scan($msg)) {
10
         $this->notify($sender,$message,Monitor::NOTIFY_KEYWORD);
11
       }               
12
     }               
13
     // move imap msg to +Filtering

14
     echo 'Moving to +Filtering';lb();
15
     //$result = @imap_mail_move($this->stream,$msg['uid'],$this->path_filtering,CP_UID);

16
     $result = $this->messageMoveHandler($msg['uid'],$this->path_filtering,false);             
17
     if ($result) {
18
       echo 'moved<br />';
19
       $m->setStatus($message_id,Message::STATUS_FILTERED);
20
     }
21
   } 

Jika pesan diseret ke kotak masuk, kami akan memperbarui penetapan pengaturan kami:

1
else if ($action == self::ACTION_TRAIN_INBOX) {
2
     // set sender folder_id to inbox

3
     echo 'Train to Inbox';lb();
4
     $m->setStatus($message_id,Message::STATUS_TRAINED);
5
     // only train sender when message is newer than last setting

6
     if ($msg['udate']>=$sender['last_trained']) {
7
       $s->setFolder($sender_id,$folder_id);
8
     } 
9
   }

Metode ProcessFiltering

Metode pemrosesan sekunder disebut processFiltering, juga di DaemonController.php. Aspek yang lebih menyita waktu untuk memindahkan pesan ke folder yang sesuai:

1
public function actionIndex()
2
{
3
  // processes messages in @Filtering to appropriate folders

4
  $r = new Remote();
5
  $r->processFiltering();
6
  // Record timestamp of cronjob for monitoring

7
  $file = file_put_contents('./protected/runtime/cronstamp.txt',time(),FILE_USE_INCLUDE_PATH);	  
8
}

Metode ini membuka akun email Anda untuk mencari pesan-pesan terakhir dan mengumpulkan data tentangnya. Ini juga menggunakan imap_search, imap_fetch_overview dan parseHeader:

1
$tstamp = time()-(7*24*60*60); // 7 days ago

2
$recent_messages = @imap_search($this->stream, 'SINCE "'.date("j F Y",$tstamp).'"',SE_UID);
3
if ($recent_messages===false) continue; // to do - continue into next account

4
$result = imap_fetch_overview($this->stream, implode(',',array_slice($recent_messages,0,$message_limit)),FT_UID);
5
foreach ($result as $item) {         
6
      $cnt+=1;
7
      if (!$this->checkExecutionTime($time_start)) break;
8
      // get msg header and stream uid

9
      $msg = $this->parseHeader($item);            

Loop pengolahan utama untuk setiap pesan dalam folder penyaringan cukup rinci. Pertama, kami melihat alamat penerima, karena SE memungkinkan orang untuk mengatur folder menurut alamat penerima, mis. pesan-pesan ke domain happyvegetarian.com masuk ke folder sayuran:

1
 // Set the default action to move to the review folder

2
 $action = self::ACTION_MOVE_REVIEW;
3
 $destination_folder =0;
4
 // look up & create recipient

5
 $recipient_id = $r->add($user_id,$account_id,$msg['rx_email'],0);
6
 $routeByRx = $this->routeByRecipient($recipient_id);
7
 if ($routeByRx!==false) {
8
  $action = $routeByRx->action;
9
  $destination_folder = $routeByRx->destination_folder;
10
 }            

Kemudian kami mencari pengirim dan membuat record baru di database (jika perlu). Jika ada pengaturan untuk pengirim, kami bisa mengatur folder tujuan:

1
 // look up sender, if new, create them

2
 $sender_id = $s->add($user_id,$account_id,$msg["personal"], $msg["mailbox"], $msg["host"],0);                       
3
 $sender = Sender::model()->findByPk($sender_id);
4
 // if sender destination known, route to folder

5
 if ($destination_folder ==0 && $sender['folder_id'] > 0) {
6
   $action = self::ACTION_ROUTE_FOLDER;  
7
   $destination_folder = $sender['folder_id'];      
8
 }
9
 

Jika pengirim (baru) yang tidak teratur telah memverifikasi dirinya melalui tantangan Daftar Putih (yang akan kami bahas di bagian selanjutnya di bawah), kami akan mengarahkan pesan ini ke kotak masuk:

1
// whitelist verified senders go to inbox

2
 if ($sender->is_verified==1 && $sender['folder_id'] ==0 && UserSetting::model()->useWhitelisting($user_id)) {
3
   // place message in inbox

4
   $action = self::ACTION_ROUTE_FOLDER;  
5
   $destination_folder = Folder::model()->lookup($account_id,$this->path_inbox);             
6
 }

Kemudian, kami membuat entri pesan di database dengan informasi amplop tentang pesan ini:

1
  // create a message in db

2
      $message = Message::model()->findByAttributes(array('message_id'=>$msg['message_id']));
3
  if (!empty($message)) {
4
    // message exists already, 

5
	  $message_id = $message->id;    	  
6
  } else {
7
    $message_id = $m->add($user_id,$account_id,0,$sender_id,$msg['message_id'],$msg['subject'],$msg['udate'],$msg['in_reply_to']);         
8
  }

Jika dari pengirim yang tidak dikenal dan tidak terverifikasi, kami dapat memindahkan pesan ke folder tinjauan. Folder tinjauan berisi semua pesan dari pengirim yang tidak kita kenali.

Jika pesan berasal dari pengirim yang diketahui dan kita memiliki tujuan tertentu, kita dapat memindahkannya selama tidak pada jam tenang (dan do not disturb tidak aktif):

1
  if ($recipient_id!==false) $m->setRecipient($message_id,$recipient_id);
2
  if ($action == self::ACTION_MOVE_REVIEW) {
3
    echo 'Moving to +Filtering/Review';lb();
4
    //$result = @imap_mail_move($this->stream,$msg['uid'],$this->path_review,CP_UID);

5
    $result = $this->messageMoveHandler($msg['uid'],$this->path_review,false);               
6
    if ($result) {
7
      echo 'moved<br />';
8
      $m->setStatus($message_id,Message::STATUS_REVIEW);
9
    }      
10
 } else if ($action == self::ACTION_ROUTE_FOLDER || $action == self::ACTION_ROUTE_FOLDER_BY_RX) {
11
  // lookup folder name by folder_id

12
  $folder = Folder::model()->findByPk($destination_folder);       
13
  // if inbox & quiet hours, don't route right now

14
  if (strtolower($folder['name'])=='inbox' and $sender->exclude_quiet_hours == Sender::EQH_NO and $this->isQuietHours($user_id)) continue;
15
  echo 'Moving to '.$folder['name'];lb();
16
  $mark_read = Folder::model()->isMarkRead($folder['mark_read']) || Sender::model()->isMarkRead($sender['mark_read']);
17
  //$result = @imap_mail_move($this->stream,$msg['uid'],$folder['name'],CP_UID);

18
  $result = $this->messageMoveHandler($msg['uid'],$folder['name'],$mark_read);
19
  if ($result) {
20
    echo 'moved<br />';
21
    $m->setStatus($message_id,Message::STATUS_ROUTED);         
22
    $m->setFolder($message_id,$destination_folder);
23
  }
24
}

Selama jam-jam tenang, pesan terutama disimpan di folder penyaringan.

Setiap beberapa jam, proses yang berbeda akan membangun pencerna pesan menggunakan record tabel pesan untuk menentukan email mana yang baru saja diterima dan disaring dan bagaimana mereka diarahkan.

2. Menerapkan Tantangan Daftar Putih pada Pengirim yang Tidak Dikenal

Tujuan dari tantangan daftar putih adalah menjaga pesan dari pengirim yang tidak dikenal, mis. mungkin bot pemasaran atau spammer, keluar dari kotak masuk Anda. SE menempatkan email dari pengirim yang tidak dikenal di folder tinjauan. Namun, jika Anda mengaktifkan daftar putih, kami mengirimkan email tantangan yang memberi si pengirim kesempatan untuk memverifikasi bahwa mereka adalah manusia. Jika mereka merespons, kami akan memindahkan pesan ke kotak masuk Anda. Jika email ternyata tidak diinginkan, Anda dapat menghapus pesan dari pencerna atau menyeretnya ke folder manapun yang ingin Anda atur.

Pengguna dapat mengaktifkan dan menonaktifkan daftar putih di pengaturan:

Simplify email settings for whitelistingSimplify email settings for whitelistingSimplify email settings for whitelisting

Pengaturan Simplify Email untuk daftar putihUntuk menerapkan daftar putih, kami mengirimkan tantangan email setiap kali surat masuk dari pengirim baru:

1
if ($isNew) {
2
        $this->challengeSender($user_id,$account_id,$sender,$message);
3
      }

ChallengeSender mengirimkan link berkode kepada pengguna agar mereka klik. Kami juga memiliki beberapa perlindungan untuk memastikan kita tidak menjebak diri kita dalam loop email dengan pesan di luar kantor:

1
 public function challengeSender($user_id,$account_id,$sender,$message) {
2
   // whitelist email challenge

3
   $yg = new Yiigun();
4
   $ac = Account::model()->findByPk($account_id);
5
   if (!empty($ac['challenge_name']))
6
     $from = $ac['challenge_name'].' <no-reply@'.$yg->mg_domain.'>';
7
    else
8
      $from = 'Filter <no-reply@'.$yg->mg_domain.'>';      
9
   $cred = Account::model()->getCredentials($ac->cred);
10
   $account_email = $cred[0];
11
   unset($cred); 
12
   // safety: checks no recent email

13
   if ($sender->last_emailed>(time()-(48*60*60))) return false;   
14
   if ($sender->isBot($sender['email'])) {
15
     // to do - can also set this person to bulk by default

16
     return false;
17
   }
18
$link=Yii::app()->getBaseUrl(true)."/sender/verify/s/".$sender->id."/m/".$message->id.'/u/'.$message->udate;
19
    $subject = 'Please verify the message you sent to '.$account_email;
20
    $body="<p>Hi,<br /><br /> I'm trying to reduce unsolicited email. Could you please verify your email address by clicking the link below:<br /><a href=\"".$link.'">'.$link.'</a><br /><br />Verifying your email address will help speed your message into my inbox. Thanks for your assistance!</p>';
21
    $yg->send_html_message($from, $sender['email'], $subject,$body);
22
    // update last_emailed

23
    $sender->touchLastEmailed($sender->id);
24
 }

Kemudian, jika penerima mengklik tautan kode, kami memverifikasinya di database. Sender Controller memproses permintaan ini dan memeriksa validitasnya:

1
  public function actionVerify($s = 0, $m=0,$u=0) {
2
    // verify that secure msg url from digest is valid, log in user, show msg

3
    $sender_id = $s;
4
    $message_id = $m;
5
    $udate = $u;
6
    $msg = Message::model()->findByPk($message_id);
7
    if (!empty($msg) && $msg->sender_id == $sender_id && $msg->udate == $udate) {
8
      $result = 'Thank you for your assistance. I\'ll respond to your email as soon as possible.';
9
      $a = new Advanced();
10
      $a->verifySender($msg->account_id,$sender_id);
11
    } else {
12
      $result = 'Sorry, we could not verify your email address.';
13
    }
14
    	$this->render('verify',array(
15
			'result'=>$result,
16
		));
17
  }

Ini memberitahu loop pengolahan kami untuk memindahkan pesan ini dan yang akan datang dari pengirim ini ke kotak masuk.

3. Melaporkan Email yang Tidak Terjawab

Terkadang ada baiknya melihat ringkasan pesan yang telah Anda kirim namun tidak mendapat jawaban. Untuk mengidentifikasi ini, Simplify Email memonitor pesan yang telah dikirim namun belum mendapat jawaban.

Setiap pesan yang kami terima berisi id unik, yang disebut message_id (bagian dari spesifikasi IMAP). Seringkali terlihat seperti ini:

1
Message-Id: <CALe0OAaF3fb3d=gCq2Fs=Ex61Qp6FdbiA4Mvs6kTQ@mail.gmail.com>

Message-Id: Selanjutnya, saat pesan dikirim untuk membalas pesan lainnya, mereka memiliki field in_reply_to yang terhubung kembali ke message_id yang asli.

Jadi, kita menggunakan query SQL untuk menemukan semua pesan yang diterima yang tidak memiliki pesan balasan yang sesuai yang mereferensikan message_id mereka. Untuk ini, kami menggunakan LEFT OUTER JOIN dimana tidak ada id in_reply_to:

1
public function getUnanswered($account_id,$mode=0, $range_days = 7) {
2
    if ($mode==0)
3
      $subject_compare = 'not';
4
    else
5
      $subject_compare = '';
6
    $query = Yii::app()->db->createCommand("SELECT fi_sent_message.id, fi_sent_message.recipient_id as sender_id,fi_sent_message.subject,fi_sent_message.udate,fi_message.in_reply_to,fi_sent_message.message_id  FROM fi_sent_message LEFT OUTER JOIN fi_message ON fi_message.in_reply_to = fi_sent_message.message_id WHERE fi_sent_message.account_id = ".$account_id." AND fi_message.in_reply_to is null and fi_sent_message.udate > ".(time()-(3600*24*$range_days))." and fi_sent_message.subject ".$subject_compare." like 'Re: %' ORDER BY fi_sent_message.udate  DESC")->queryAll();
7
    return $query;
8
  }

Kami menggunakan mode $subject_compare untuk membedakan antara pesan terkirim yang belum terjawab dan balasan yang dikirim ke rangkaian yang belum terjawab. Inilah laporan pesan yang tidak terjawab di akun Anda:

Unanswered sent emails and unanswered sent replies threadsUnanswered sent emails and unanswered sent replies threadsUnanswered sent emails and unanswered sent replies threads

SE juga menawarkan informasi ini sebagai pencerna opsional, yang disebut pencerna email yang belum terjawab. Anda bisa menerimanya setiap hari, setiap beberapa hari atau setiap minggu.

Kami juga menggunakan tabulasi SQL serupa dengan Google Charts untuk memberikan laporan tentang seberapa sering orang tertentu mengirim email kepada Anda:

Reports of inbound email frequency by senderReports of inbound email frequency by senderReports of inbound email frequency by sender
1
  public function reportInbound($account_id,$range=30,$limit = 100) {
2
    $result= Yii::app()->db->createCommand('SELECT fi_sender.personal, fi_sender.email,count(sender_id) as cnt

3
      FROM fi_message LEFT JOIN fi_sender ON fi_sender.id =fi_message.sender_id WHERE fi_sender.account_id = :account_id AND fi_message.created_at > DATE_SUB( NOW() , INTERVAL :range DAY )  

4
      GROUP BY sender_id ORDER BY cnt desc LIMIT :limit ')->bindValue('range',$range)->bindValue('account_id',$account_id)->bindValue('limit',$limit)->queryAll();
5
    return $result;
6
  }

Saya akan menulis lebih banyak tentang Google Charts untuk Tuts+ segera.

Langkah Selanjutnya

Saya harap Anda telah menemukan Simplify Email yang cukup menarik untuk dicoba di pemrograman PHP IMAP. Ada begitu banyak fitur keren yang bisa Anda bangun tanpa memerlukan penyedia email besar untuk melakukan sesuatu yang baru.

Jika Anda memiliki pertanyaan atau koreksi, silakan kirimkan ke komentar. Jika Anda ingin mengikuti tutorial Tuts+ saya di masa depan dan serial lainnya, ikuti @reifman atau kunjungi halaman penulis saya. Anda juga bisa menghubungi saya di sini.

Link Terkait

Berikut adalah beberapa tautan tambahan yang mungkin berguna bagi Anda:

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.