Becky! (emlファイル) を Gmail へ一括転送するには?

 

Becky! からエクスポートされた emlファイルを、Gmail へ一括転送するための Rubyスクリプトを作成しました。 これにより、Becky! のメールデータを、そっくり Gmail 上に再現できます (転送中にヘッダ情報が追加されるので、完全に同じにはなりません)。

emlファイルであれば、Becky! 以外のメーラからエクスポートしたものでも大丈夫だと思いますが、 確認は行っていません。

スクリプト作成の経緯

わざわざスクリプトを作成するはめになったのは次の経緯からです。

スクリプトの仕様

  • エクスポートファイルは eml とします。 なぜ、UNIX mbox ではなく eml を採用するかと言うと、UNIX mbox の仕様があまりにも怪しげなため、 信頼性に疑問を感じたからです。
  • メール(emlファイル)を転送するために、自分のプロバイダ(ISP)の SMTPサーバを使用します。 理由は、Google の SMTPサーバを使用すると、From: フィールドが自分の Gmailアドレスに書き換わってしまうためです (これでは、本来のメール送信者が誰だったのか分らなくなってしまいます)。
  • スクリプトでは、POP before SMTP 機能を提供しません。 そのため、スクリプトを実行する際には Becky! を起動してダミーの受信を行う必要があります。 大抵の場合は、定期的にメールを受信をするように設定されていると思うので、 その場合は Becky! を起動しておくだけで OK です。
  • Rubyスクリプトは Windows 上で動かすものします。 そのために Windows版 Ruby が必要ですが、安定版(1.8.5) ではなく 開発版(1.9.0) を使用します。 これは、Google の SMTPサーバ(STARTTLS) を使用した実験もできるようにしておくためです。

ソースコード

emlファイルを Gmail へ転送するスクリプトです。 (smtp_to の設定を変更すれば、Yahoo! や livedoor など、好きなところに送信できます。)

変数 smtp_server, smtp_to は、自分の環境に合わせて修正してください。 修正は十分に注意して行ってください。 特に、smtp_to はメールの送信先なので、間違えるとかなり顰蹙を買うことになるでしょう。

eml2gmail.rb
require 'net/smtp'

$stdout.sync = true                 # 標準出力をバッファリングしない

eml_dir     = 'c:/eml2gmail/eml'    # emlファイルのエクスポート先
interval    = 0.5                   # メールの送信間隔
sess_max    = 100                   # 1セッションあたりの最大送信数
count       = 0                     # 送信済みメール数

smtp_server = 'smtp.example.com'    # 自分のISPのSMTPサーバ
smtp_port   = 25                    # SMTPで使用するポート
smtp_from   = ''                    # 送信元、Return-Path:
smtp_to     = 'example@gmail.com'   # 送信先、Delivered-To:

catch(:exit) {
    loop {
        catch(:newsession) {
            Net::SMTP.start(smtp_server, smtp_port) { |smtp|
                Dir.glob("#{eml_dir}/*.eml").each { |fullpath|
                    File.open(fullpath) { |mail|
                        smtp.send_mail mail, smtp_from, smtp_to
                    }
                    File.delete(fullpath)
                    sleep interval
                    print "#"
                    count += 1
                    if count % sess_max == 0
                        puts
                        throw :newsession
                    end
                }
                throw :exit
            }
        }
    }
}
puts "\ndone: #{count}"

emlファイルの転送手順

emlファイルを Gmail へ転送する手順は、次の通りです。

  1. 環境構築
    • Windows版 Ruby をインストールします。 PATH 環境変数に ruby.exe の在処を設定するのを忘れないでください。
    • c:\eml2gmail フォルダを作成して eml2gmail.rb を配置します。
    • c:\eml2gmail フォルダの下に eml フォルダを作成します。
  2. Becky! を起動して、Gmail へ転送するメールを eml形式でエクスポートします。 エクスポート先は c:\eml2gmail\eml フォルダとします (emlファイルは送信完了と同時に削除されます)。 Becky! の起動は、POP before SMTP を兼ねています。
  3. c:\eml2gmail\eml フォルダの中に、emlファイルが作成されていることを確認します。 Becky! でのエクスポートは、操作ミスしやすいので注意してください (フォルダを丸ごとエクスポートしたつもりが、1通だけになってしまう)。
  4. コマンドプロンプトを起動して、eml2gmail.rb を実行します。 以下の例では、4通のメールが送信されています。
    C:\eml2gmail>ruby eml2gmail.rb
    ####
    done: 4
    
  5. エクスポートしたメールが Gmail に届いていることを確認します。

ヒント

  • 本格的に転送を行う前に、最小限の転送で検証してみることをお勧めします( ヘッダーがおかしくなってないか、 文字化けしてないか、 添付ファイルは大丈夫か、 本文に破損がないか、など)。
  • 送信と受信の数が合わない場合は、Gmail がメールをスレッド単位で管理していることを思い出してください。

問題点

  • ほとんどのSMTPサーバは、1メールあたりのサイズを制限しています。 このスクリプトでは、サイズの制限によりSMTPサーバから転送を拒否されても検知できません。
  • Gmail でのメールの表示順は、Gmail 自身が受信した日時でソートされます。 メールヘッダの Date: でソートできると良いのですが、、、

改版履歴

日付 内容
2006-11-19 問題点を追記(Gmail でのメールの表示順について)。
2006-11-17 ソースコードの修正( 標準出力をバッファリングしない、 メールの送信間隔 0 → 0.5、 1セッションあたりの最大送信数を設定可能)。 送信と受信の数が合わない場合について追記。 メールのサイズ制限について追記。
2006-11-16 初版