Docker で imapsync を使って Google Workspace から個人の Gmail に過去のメールを転送する

Web

概要

  • メールサーバーがわりに Google Workspace を個人利用していたが、メール機能以外を活用できていないので解約し、さくらのネームサーバーに移行することにした
  • これにあたり、Google Workspace で利用しているユーザーアカウントの Gmail に保管されているメールを、個人の Google アカウントの Gmail に合流させておく

関連エントリー

前提

使用するツール

動作環境

手順

Googleアカウント側の準備

  1. 2段階認証の有効化
  2. アプリパスワード発行
    • https://myaccount.google.com/apppasswords
      • IMAP 接続するために必要。2段階認証が無効の状態だと利用できない。
      • 名前はなんでもよいので imapsync用 など用途がわかるようにしておく
      • abcd efgh ijkl mnop のような16桁のコードが発行されるので控える
      • すべての作業が終わったら必ず削除すること

Docker側の準備

以下2つのファイルを1つのディレクトリの中にまとめて配置する。

docker-compose.yml
services:
  imapsync:
    image: gilleslamiral/imapsync
    env_file: ./.env
    command: >
      imapsync
      --host1 ${HOST1} --user1 ${USER1} --password1 ${PASSWORD1} --ssl1 --port1 993
      --host2 ${HOST2} --user2 ${USER2} --password2 ${PASSWORD2} --ssl2 --port2 993
      --dry
.env
HOST1=imap.gmail.com
USER1={アカウント名}@{Google Workspaceに設定しているドメイン}
PASSWORD1=XXXXXXXXXXXXXXXX

HOST2=imap.gmail.com
USER2={アカウント名}@gmail.com
PASSWORD2=XXXXXXXXXXXXXXXX
項目 内容
HOST1 Gmail のホスト名(共通)
USER1 Google Workspace のユーザーアカウントのメールアドレス
PASSWORD1 Google Workspace のユーザーアカウントで発行したアプリパスワード
HOST2 Gmail のホスト名(共通)
USER2 個人の Google アカウントのメールアドレス
PASSWORD2 個人の Google アカウントで発行したアプリパスワード

コンテナ立ち上げ&コマンド実行

自分は Docker を Windows 環境で利用しているため、 PowerShell で以下を実行する。

docker-compose up 2>&1 | Tee-Object -FilePath "log_$(Get-Date -Format 'yyyyMMdd-HHmmss').txt" -Encoding UTF8
上記コマンドで行われる処理
  • Docker コンテナ起動
  • コンテナ内での imapsync コマンドの実行
  • ログの標準出力と保存

なお、コマンド末尾の -Encoding UTF8 は日本語の文字化け対策。PowerShell 7 以上が必要。
PowerShell 5系の場合は、 chcp 65001 であらかじめコンソールの文字コードを UTF-8 に設定しておく。

ログの確認
  • エラーが出た場合は .env の各値などを再確認して修正。
  • 無事最後まで通ったら、ログの内容を詳しくチェックする。

    • 例:フォルダとメッセージの数

      Host1 Nb folders:                     1 folders
      Host2 Nb folders:                     1 folders
      
      Host1 Nb messages:                    4 messages
      Host2 Nb messages:                    0 messages
    • 例:host1(host2)にあるが、host2(host1)には無いメールの数
      Messages found in host1 not in host2    : 0 messages
      Messages found in host2 not in host1    : 0 messages
    • 例:転送(スキップ)した合計容量
      Total bytes transferred                 : 0 (0.000 KiB)
      Total bytes skipped                     : 0 (0.000 KiB)
本番実行と後始末
  • 問題なければ docker-compose.yml に記載のコマンドから --dryをコメントアウトして本番実行する。
  • 完了後、準備フェーズで発行した各 Google アカウントのアプリパスワードを削除する。

おまけ

さくらのメールサーバーに接続する場合

Google Workspace → さくらのメールサーバーへに移行を試みた際の副産物。
誰かの参考になるかもしれないので、設定内容だけは一応書き残しておく。

HOST2=www◯◯◯.sakura.ne.jp
USER2={アカウント名}@{ユーザー名}.sakura.ne.jp
PASSWORD2=XXXXXXXXXXXXXX
項目 内容
HOST2 さくらのレンタルサーバのホスト名(会員メニュー内「契約中のサービス一覧」から確認可能)
USER2 さくらのレンタルサーバで作成したアカウントのメールアドレス
PASSWORD2 さくらのレンタルサーバで作成したアカウントののパスワード

フォルダ単位で実行する場合

  • フォルダ=Gmail のラベル単位で実行したい場合は、コマンドに以下の --folder オプションを追加する
    --folder "hogehoge"
  • 指定するフォルダ名は、 --dry をつけて実行した際のログから確認可能
    • とくに日本語のラベル名は要確認(英数字記号の表記になるため)

フォルダの中身を強制的に置き換えたい場合

imapsync を実行した際、両方のメールアカウントに同一メールが存在すると、重複扱いとなって転送がスキップされるかしこい仕様になっている。

が、ごちゃごちゃとトライ&エラーを繰り返していたせいか、一部のメールが "絶対に Gmail の中にないのに重複扱いになって一生転送されない" という困った状態になってしまった。

最終的には以下の方法でなんとかなったので記録しておく。

対応方法
  1. 各メールボックスの状態を揃える(ラベル名はなんでもいい)

    • Google Workspace側:該当するメールに temp ラベルを設定
    • Gmail側:temp ラベルを新規作成
  2. docker-compose.yml のコマンドに --folder オプションと --delete2 オプションを追加

    --folder "temp"
    --delete2
  3. .env に下記環境を設定して実行

    • host1 = Google Workspace 側
    • host2 = Gmail 側

これにより、host2 の該当フォルダの中身が host1 の内容に揃うので、転送ができた状態になる。

host2 のほうに、host1 に存在しないメールがあった場合は削除されてしまうので注意。host2 側のラベルの中身は空っぽにしておくのが安全。

Comments

  • スパム対策のため、コメント本文にURLが含まれている場合は「承認待ち」となり、すぐに投稿が反映されません。ご了承ください。
  • 公序良俗に反する内容、個人が特定できる情報、スパム投稿と思われるコメント等については、予告なく編集・削除する場合があります。