Google Takeoutのアーカイブを開き、ImportExportTools NGを使ってmboxファイルをThunderbirdに取り込み(Apple Mailの場合もあります)、そのフォルダを新しいIMAPアカウントにドラッグしたとします。メールクライアント上では、メールは年ごとにきれいに並んでいました。ところが移行先のアカウントを開くと、全部が今日の日付になっています。この記事では、Takeoutのmboxを取り込んだときに何が起きているのか、なぜ表示される日付がコピーした日になるのか、数分で確認する方法、そしてサーバー側での修正方法を説明します。
まず知っておいてほしいことがあります。メール自体は無事です。元の日付は、今もメッセージの中に残っています。ただ、移行先のアカウントがその日付を表示に使っていないだけです。
Takeout mboxを取り込んだときのよくあるケース
15年使った個人のGmailアカウントを閉じることにしました。takeout.google.comでエクスポートを依頼し、Googleからの通知を待ち(大きなメールボックスだと2日かかります)、4つのzipアーカイブをダウンロードしました。中にはラベルごとに.mboxファイルが入っています。これをThunderbirdに取り込むと、ローカルフォルダにメールが並び、日付順の並べ替えも完璧です。一番下が2009年、一番上が昨日。
ここで、誰でもやることをやります。フォルダを選択して、移行先のIMAPアカウント(Microsoft 365、ホスティング事業者のメール、Google Workspaceなど)にドラッグするのです。転送には一晩かかりました。月曜の朝、ウェブメールを開きます。
問題は何か。18,400通のメールが、週末のわずか数時間の範囲の日付になっているのです。2014年の契約書が先週のメルマガの隣に並び、時系列でメールを探すことは誰にもできなくなります。
これは古いメールが全部同じ日付になっている場合とよく似ていますが、大きな違いがひとつあります。今回は移行ツールが原因ではありません。ドラッグ&ドロップだけで起きるのです。
1通のメールに3つの日付がある
仕組みを理解するには、まず「メールの日付」をひとつだけだと考えるのをやめる必要があります。mboxファイルから取り込まれたメッセージには、少なくとも3つの日付があり、それぞれ役割が違います。
Dateヘッダー:送信者が書いた日付
RFC 2822(後継はRFC 5322)で定義されているDate:ヘッダーです。送信者のメールクライアントが送信時に書き込むもので、たとえばDate: Tue, 14 Mar 2017 09:12:45 +0100のような形をしています。メッセージの一部として一緒に運ばれ、Takeoutもそのまま保存します。このヘッダーが無傷で残っているからこそ、修正が可能になります。
mboxのFrom行:見せかけの日付
mboxファイルでは、各メッセージの前にFrom で始まる行があります(後ろは空白で、コロンはありません)。これはヘッダーではありません。ファイル形式が使う区切りであって、メッセージの一部ではないのです。まともなツールなら、メールの日付をこの行から判断することはありません。
INTERNALDATE:サーバーに置かれた日付
3つ目は一番目立たない日付で、RFC 3501で定義されたINTERNALDATEです。IMAPサーバーがメッセージの横に(中ではなく)保存する属性で、メッセージがメールボックスに置かれた日時を表します。Outlook、ウェブメール、スマートフォンは、受信日時の表示と並べ替えにこの値を使います。仕組みの詳細はINTERNALDATEとIMAPで日付がおかしくなる理由で解説しています。
ここでひとつ補足です。Received:ヘッダーがよく犯人扱いされますが、今回は違います。エクスポートしたGmailのメールのReceived行には、2017年当時の本当の配送経路が、古くて正しい日付のまま記録されています。つまりこのケースでは、間違った日付はメッセージの中ではなく、サーバーがコピーに付けたメタデータの側にあるのです。
なぜ移行先にはコピーした日の日付が表示されるのか
クライアントがIMAPサーバーにメッセージを置くとき、APPENDコマンドを使います。このコマンドには、メッセージに付ける日付を任意で指定できます。クライアントが指定すれば、サーバーはそれをINTERNALDATEとして保持します。指定がなければ、サーバーはRFC 3501の規定どおり、その時点の日時を使います。つまり、表示される日付は、ツールがメールをどう書き込んだかで決まるのです。元の日付を渡さないツールでは、コピーした日の日付になります。
その結果、フォルダをドラッグしている間、各メッセージは自分が置かれた瞬間の日付を持つことになります。3,000通のフォルダを40分かけてコピーすれば、全部が40分の枠に収まります。
では、Thunderbirdのローカルフォルダはなぜ完璧に見えたのでしょうか。ローカルフォルダにはサーバーがないので、ThunderbirdはサーバーのInternal dateではなくDateヘッダーで並べ替えているからです。Apple Mailで取り込んだメールボックスも似た動きをします。メッセージがMacの中にある間は何も問題がありません。真実が見えるのは、Outlookなど別のソフトがIMAPのメールボックスを読み込んだときです。
ただ、すべてのクライアントが毎回間違うと言い切るのは、正確ではありません。日付を渡すバージョンもあれば渡さないバージョンもあり、アップデートのたびに挙動も変わってきました。そのため、同じ手順を踏んだ同僚2人が違う結果になることもあり、原因の切り分けは見た目以上に厄介です。
ドラッグ&ドロップは移行ではありません。コピーです。そしてコピーには、作られた日の日付が付きます。
5分でこのケースかどうかを確かめる
対策を探す前に、本当にこのケースなのか、別の問題ではないのかを確認しましょう。次の4つで足ります。
- 2か所を比べる。Thunderbirdのローカルフォルダ(またはApple Mailに取り込んだメールボックス)では正しい日付なのに、IMAPアカウントでは同じメッセージが最近の日付になっています。
- 日付の範囲を見る。IMAPアカウントのフォルダ内で、受信日時がフォルダを移動した時間帯の前後、数時間から数分の範囲に収まっています。
- メッセージのソースを開く。Thunderbirdでは「表示」から「メッセージのソース」、Outlookではメッセージのプロパティにインターネットヘッダーが表示されます。画面上は最近の日付なのに、
Date:の行は古い日付になっているはずです。 - 順番を確かめる。メッセージが時系列ではなく、クライアントがコピーした順に並んでいます。
実際のメッセージで比べると、こうなります。
Date: Tue, 14 Mar 2017 09:12:45 +0100 (メッセージ内、無傷)
IMAPアカウントの表示日付:コピーした日 (サーバー側のメタデータ)
この2行が食い違っていれば、まさにこのケースです。なお、表示日付が間違っていてDate:も間違っている場合は、もっと珍しい別の問題で、この記事の範囲外です。
(ちなみに、生のメールヘッダーを読んだことがない人は、コーヒーを用意してください。ビーチで読む本とは、ちょっと違います。)
送信日で並べ替えても応急処置にすぎない
まず思いつくのは、並べ替えを送信日に切り替えることでしょう。Outlookならそこそこ機能しますが、フォルダごと、端末ごとに設定し直す必要があります。しかも検索、通知、古さに基づく振り分けルール、モバイルの表示は、引き続き受信日時を使います。スマートフォンで「去年の9月のメール」を探しても、筋の通った結果は出てきません。
もうひとつ、つい試したくなるのがコピーのやり直しです。すでに使っているアカウントでは、既存のメッセージの隣に重複が増えるだけで、日付は同じ間違いか、また別の間違いになります。100フォルダほど繰り返した頃には、きれいなメールボックスはひとつも残っていません。
サーバー側での修正
朗報は、元の日付がまだ残っていることです。修正とは、メールの中身には一切手を加えずに、移行先のアカウントにその日付を表示させることです。
それを行うのがRedateです。Redateはメールボックスに接続します(Google Workspaceはドメイン全体の委任、Microsoft 365、Outlook.comとHotmailは各ユーザーのMicrosoftアカウント、またはメールアドレスとパスワードによる直接のIMAP接続)。どのツールが問題を起こしたかを知る必要はありません。表示されている日付が元の日付と合っていないメールを見つけ出します。原因がTakeoutのmboxからのドラッグ&ドロップでも、それ以外でも同じです。メールボックスのスキャンは無料で、修正を決める前に被害の大きさを確認できます。
修正そのものには、独自の修正エンジンを使います。多段階の解析パイプラインが各メッセージのヘッダーの連なりを調べ、それぞれのメールに元の日付を戻します。修正したメールは1通ずつ検証され、RFC準拠のチェックとメッセージ構造の保持も確認されます。元のメールは削除されません。ご自身で削除するまで、メールボックス内の見えるフォルダに残ります。
自力で対処するのが危険な理由
問題を理解することと、15,000通を1通も失わずに修正することは、まったく別の話です。
テスト用の10通で動いたスクリプトは、30,000通の本番メールボックスでは通用しません。少し変えただけで署名が無効になるS/MIME署名付きメール、PGPで暗号化されたメッセージ、入れ子のmultipart/alternative構造、整合性の取れないMIME境界、想定外のContent-Transfer-Encoding、RFC 2047でエンコードされた非ASCIIヘッダー、40MBの添付ファイル。さらにAPIのクォータがあり、午前3時にバッチの最中に出る429 Too Many Requestsエラーがあり、11,874通目でネットワークのタイムアウトが処理を止めます。
その先はどうでしょう。各メッセージが無事だと、どうやって確かめるのでしょうか。ロールバックの仕組みがなければ、ミスひとつでメッセージの重複、添付ファイルの消失、スレッドの分断、ラベルの消失が起こります。Redateは各メールを自動で検証し、元のメールを手元に残します。まさに、そんな賭けをしなくて済むようにするためです。
最後にひとつだけアドバイスを。メールボックスの検証が終わるまでは、元のTakeoutアーカイブを取っておいてください。移行先のアカウントが正しく見えても、mboxファイルは基準となるコピーです。
お使いのクライアント別の関連ガイド
コピーに使ったクライアントに応じて、次のガイドが個別のケースを詳しく説明しています。ThunderbirdでのIMAPコピーによる日付の修正と、Apple Mailでの同じケースです。
Takeoutのメールをすでに IMAPアカウントにコピーしてしまい、日付が間違っていますか? Redateの無料スキャンを実行して対象のメール数を確認し、そのうえで1回払いで修正できます。メールボックスのサイズ制限はありません。