Rubyでメールの送受信をする

みなさんはメールの送受信ってどうやってますか?

普通MacだったらMailなり、ThunderbirdなりのGUIアプリケーションを使用するかと思います。
しかし、インフラをやっているエンジニアだと、telnetなどでメールサーバーにつないで、接続確認を取ることがままあります。
しかし、メールサーバーへ接続するのにtelnetでつなぐと、認証情報をbase64エンコードしたりする場面が出てきます。
これが結構面倒だし、それに加えて手動だとコマンドミスなのかサーバー側の問題かを切り分けしやすいようスクリプト化したいなぁと思ってました。

シェルスクリプトで愚直にexpectも考えましたが、もう少しスマートでメンテナンスしやすいようにできないか調べてたところRubyのmailというgemが簡単そうということを知り、メールの送受信ができるようなスクリプトを作ってみました。

参考にしたサイト

参考にしたはのはこちらのサイトです。
メソッドの使い方などがどのサイトよりも丁寧に書かれていたので、このサイトに書いてあることを参考に下記スクリプトを書きました。

mailscript.rbファイル
require 'yaml'
require 'mail'
require 'date'
require 'socket'
require 'thor'

class EmailScript < Thor

  desc 'smtp','[Usage] ruby emailscript.rb smtp SMTPPORT MAILADDRESS ENVIRONMENT'
  def smtp(port, mailaddress, mailenv)
    pwinfo = YAML.load_file("mailenv.yaml")

    Mail.defaults do
      delivery_method :smtp, :address    => pwinfo["#{mailenv}"]['hostaddress'],
                             :domain     => pwinfo["#{mailenv}"]['hostaddress'],
                             :port       => "#{port}",
                             :authentication => :login,
                             :user_name  => pwinfo["#{mailenv}"]['user_name'],
                             :password   => pwinfo["#{mailenv}"]['password']
    end

    todaydate = Time.now
    svrhostaddress = pwinfo["#{mailenv}"]['hostaddress']

    begin
      Mail.deliver do
        from pwinfo["#{mailenv}"]['from_name']
        to "#{mailaddress}"
        header["X-Mailer"] = "Ruby-EmailScript"
        subject "TEST Mail from #{svrhostaddress} Port #{port} at #{todaydate}"
        body File.read("body.txt")
      end
      puts "Success send mail to #{port} port from #{mailenv}"
    rescue => e
      puts e
      puts "Failed send mail..."
    end
  end

  desc 'popimap', '[Usage] ruby emailscript.rb POPPORTorIMAPPORT ENVIRONMENT'
  def popimap(port, mailenv)
    pwinfo = YAML.load_file("mailenv.yaml")

    case "#{port}"
    when "110", "995"
      Mail.defaults do
        retriever_method :pop3, :address    => pwinfo["#{mailenv}"]['hostaddress'],
                                :port       => "#{port}",
                                :user_name  => pwinfo["#{mailenv}"]['user_name'],
                                :password   => pwinfo["#{mailenv}"]['password'],
                                :enable_ssl => pwinfo["#{mailenv}"]['enable_ssl']
      end
    when "143", "993"
    Mail.defaults do
        retriever_method :imap, :address    => pwinfo["#{mailenv}"]['hostaddress'],
                                :port       => "#{port}",
                                :user_name  => pwinfo["#{mailenv}"]['user_name'],
                                :password   => pwinfo["#{mailenv}"]['password'],
                                :enable_ssl => pwinfo["#{mailenv}"]['enable_ssl']
      end
    end

    begin
        puts <<-EOS
### HEADER \n#{Mail.last.header}
### subject \n#{Mail.last.subject}\n
### body \n#{Mail.last.body}
EOS
      puts "---\nSuccess pop/imap mail #{port} port from #{mailenv}"
    rescue => e
      puts e
      puts "Failed pop/imap mail..."
    end
  end

end

EmailScript.start(ARGV)

mailenv.yamlファイル
docker:
  hostaddress: 接続先サーバーアドレス
  user_name: 認証用のユーザー名
  password: パスワード
  enable_ssl: false
使い方

送信

$ ruby mailscript.rb smtp 25 info@hogepiyo.com docker

受信

$ ruby mailscript.rb popimap 110 docker

※dockerでテストしながら作っていたので、dockerという環境名を例にしています。

ポイントは、認証情報をyamlで管理してることと、thorでオプション追加することでクライアントツールっぽさを出したところです。
mail gemが標準でSSLにも対応しているのと、送信と受信それぞれにとても使いやすいメソッドが用意されていたのでそれを活用してます。
mailenv.yamlに同じように環境を追加していけば、送信と受信をこれ一つで試すことが可能です。

改善余地は多々あると思いますが、ちょっと前から考えていたスクリプトがとりあえず出来たので満足です。
これでメールサーバーへの接続方法が短縮できて、生産性向上です。