GmailでPOPする時にサーバ側で未読既読管理をされてしまうらしいのでユーザ名にrecentを付ける

GmailをPOPする時にメールのリストを上手く取得できずハマったのでメモメモ。


現象

  • Gmailからメールを取得するテストをしていたら、「一度取得したメールが取得できない」かつ「一度に250件ずつくらいしか取得できない」という状態が起こった

調査

ググったりしてみたところ、いくつか同じような話が出て来た。
どうやらGmail側で一度POPしたものを既読扱いにするため再度取得できないようにしている様子。
PROGRAMMMMMMMING: php => pop + gmailPROGRAMMMMMMMING: php => pop + gmail (続)

gmailの既読フラグについて。

popでbodyをfetchすると、内部的にフラグが立つ。
headerをfetchしただけでは既読にならない。

で、disconnect したタイミングでサーバー側にフラグの設定が反映されるようだ。
いったん既読にマークされてしまうと、api側からメッセージを取得できなくなる。

既読にされるのはまぁ良いとして、250件ずつしかこない状態だとちょっと厳しいので「何か方法はないのかなぁ」と更にググった。
そして見つけたのが以下。

Gmailは通常の状態ではPOP3の受信可否の判断に未読フラグを使っているので、POP3からメールを削除しようがしまいが、一度受信したメールはPOP3から再度受信することはできないようになっているようです。この挙動を変更して一般的なのPOP3と同じようにするためのモードが下記で紹介されている最新モードと呼ばれる機能のようです。
GmailのPOPと通常のPOPの異なるところ


実際のGoogleのドキュメント。

それでもメールをダウンロードできない場合は、次の手順を試してください。

最新モードを使用していない場合は、POP クライアントの設定画面で [メッセージをサーバーに残す] チェックボックスをオフにしていることを確認してください。
POP クライアントで最新モードを有効にしてみてください。それには、POP クライアントの設定で、[ユーザー名] 欄を「username@gmail.com」から「recent:username@gmail.com」に変更し、[メッセージをサーバーに残す] をオンにします。
最新モードでは、他の設定とは無関係に過去 30 日間のメールがダウンロードされます。[メッセージをサーバーに残す] がオフの場合、メールはダウンロード後に [ゴミ箱] に移動されます。

POP クライアントで Gmail アドレスのエントリをいったん削除し、正しい設定で追加し直してみてください。このときに、ダウンロード済みの Gmail メールのローカル コピーが失われる可能性があることに注意してください。
一部のメールがダウンロードされない - Gmail ヘルプ

POP で複数のクライアントから Gmail にアクセスする場合、Gmail の最新モードを使用すると、最初にアクセスしたクライアントだけでなく、各クライアントがすべてのメッセージにアクセスできます。
複数のクライアントまたは携帯端末で POP を使用する - Gmail ヘルプ

ということで、POPするときのアカウントの始めにrecent:を付けて取得することで一気にデータを取ることにしました。