Docker で imapsync を使って Google Workspace から個人の Gmail に過去のメールを転送する
概要
- メールサーバーがわりに Google Workspace を個人利用していたが、メール機能以外を活用できていないので解約し、さくらのネームサーバーに移行することにした
- これにあたり、Google Workspace で利用しているユーザーアカウントの Gmail に保管されているメールを、個人の Google アカウントの Gmail に合流させておく
関連エントリー
前提
使用するツール
- Docker
- Imapsync
- 公式サイト: https://imapsync.lamiral.info/
- Github: https://github.com/imapsync/imapsync
- Dockerイメージ: https://hub.docker.com/r/gilleslamiral/imapsync/
動作環境
- Windows 11
- PowerShell 7
手順
Googleアカウント側の準備
- 2段階認証の有効化
- アプリパスワード発行
- https://myaccount.google.com/apppasswords
- IMAP 接続するために必要。2段階認証が無効の状態だと利用できない。
- 名前はなんでもよいので
imapsync用
など用途がわかるようにしておく abcd efgh ijkl mnop
のような16桁のコードが発行されるので控える- すべての作業が終わったら必ず削除すること
- https://myaccount.google.com/apppasswords
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 の中にないのに重複扱いになって一生転送されない" という困った状態になってしまった。
最終的には以下の方法でなんとかなったので記録しておく。
対応方法
-
各メールボックスの状態を揃える(ラベル名はなんでもいい)
- Google Workspace側:該当するメールに
temp
ラベルを設定 - Gmail側:
temp
ラベルを新規作成
- Google Workspace側:該当するメールに
-
docker-compose.yml のコマンドに
--folder
オプションと--delete2
オプションを追加--folder "temp" --delete2
-
.env に下記環境を設定して実行
- host1 = Google Workspace 側
- host2 = Gmail 側
これにより、host2 の該当フォルダの中身が host1 の内容に揃うので、転送ができた状態になる。
host2 のほうに、host1 に存在しないメールがあった場合は削除されてしまうので注意。host2 側のラベルの中身は空っぽにしておくのが安全。