PHPからIMAP接続で取得したメールを既読にしない方法
お客さんから、「メールが勝手に既読になって困ってるんです」という依頼を受けた際に
若干ハマったのでメモ。
そもそもの「Gmailからimap接続でメールを取得してくる」という部分は以下のサイト様を参考にさせていただきました。mm
(というかほぼそのまま)
https://blog.ver001.com/php-gmail/
https://nob-log.info/2015/03/16/connecting-to-gmail-through-imap-with-php/
結論
接続したメールボックスから、メールを1件1件回り、
imap_fetchbody()で本文を取得してるんですが、ココだった。
https://www.php.net/manual/ja/function.imap-fetchbody.php
imap_fetchbody ( resource $imap_stream , int $msg_number , string $section [, int $options = 0 ] ) : string
options
ビットマスクであり、以下の組合わせとなります。
FT_UID - msg_numberは UID である
FT_PEEK - 既に設定されていない場合、 \Seen フラグを設定しない
FT_INTERNAL - 内部フォーマットで文字列を返す。CRLF に正規化しない。
第4引数にFT_PEEKを指定できる。
これを指定しておくと、明示的に「既読しないぜ」って言えるので、取得したメールが既読にならずに済むってワケでした。
ちなみに、第4引数に複数指定したい場合は以下のような感じ。
imap_fetchbody($imap_stream, $msg_number, $section, FT_UID | FT_PEEK);
備考とごにょごにょ
そもそも、IMAP接続はPOP3とちがって、
「さまざまな端末、場所から同じところに接続しても、既読状況等を同期できる」
という部分が売りでもあるわけなので、
今回みたいな悩みがあるならPOPにしなよって話があるんですが。
(他にもっとやりたいところがあってなるべく早く解決したかったゴニョゴニョ)
あと、同じコードで運用してて今までは既読がつかずに運用できていたのに、
他のコードをいじったり環境をいじいじした時から、
当コードが走ると既読がつくようになってしまった。
きっと
「FT_PEEK - 既に設定されていない場合、 \Seen フラグを設定しない」
「既に設定されていない場合」ってところがミソなんだろうなー。
今まではほかの部分でうまく設定されてしまっていて、特に困っていなかったが、
変更を加えたことによりガバが露呈してしまったと。