MicrosoftOutlookのメールをRubyで操作する!

[Ruby][Windows]MicrosoftOutlookのメールをRubyで操作する!

あらすじ

  1. 職場のメールはMicrosoftOutlook…添付ファイルとかメール本文を手動で保存するだけの簡単なお仕事がめんどいのでマクロを作った
  2. ある日、なんか共通マクロを適用してくださいねとか通達がきたので適用した(今まで使っていた自分のマクロは退避した)
  3. 新マクロにはご丁寧にパスワードがかけられていた…編集不可/(^o^)\
  4. Outlookからマクロを実行するのは諦めて外部からメールを操作しよう…[1]
  5. Rubyでできないかな? …win32oleというものがあるらしい!←今ここ

参考サイト

ドンピシャでした。

やりたい事

  • メール本文を保存したい(ファイル名は件名.txt)
  • 添付ファイルを保存したい(ファイル名は添付ファイル名のまま)
  • 上記のファイルをYYYYMMDD_添付ファイル名(拡張子なし)フォルダの中へ格納
  • 保存場所はマイドキュメントかデスクトップ

こんな感じ

[メール]
件名:subsubject
添付ファイル:tmptmpfile.zip

↓ダウンロード

[マイドキュメント]
└[YYYYMMDD_tmptmpfile]
 ├tmptmpfile.zip
 └subsubject.txt

手順

まずソースはこんな感じ。GitHubは [https://github.com/gosyujin/outlook_for_ruby:title]

# -*- encoding: UTF-8 -*-
require "win32ole"

# 保存ディレクトリ基準。一応マイドキュメントへ
SaveRootPath = "#{ENV["USERPROFILE"]}\\My Documents"

class Outlook
    def initialize
        # Outlookに接続
        ol = WIN32OLE::connect("Outlook.Application")
        # NameSpace取得(getNameSpaceの引数は"MAPI"のみ)
        @nameSpace = ol.getNameSpace("MAPI")
    end

    # EntryIDを元にメールを取得  
    def mail(entryId)
        item = @nameSpace.GetItemFromID(entryId)
        return item
    end
    
    # メールの一覧を取得
    def mails
        # GetDefaultFolder(6)は受信トレイ
        folder = @nameSpace.GetDefaultFolder(6)
        folder.Items.each do |mail|
            GC.start
            yield mail
        end
    end 
end

outlook = Outlook.new
# メールのタイトル、送信日時、EntryID一欄を表示
outlook.mails do |mail|
    #puts "To     :#{mail.To}"
    puts "#{mail.SentOn} | #{mail.Subject.unpack("a50")}"
    puts "#{mail.EntryID}"
end

# 入力待ち。保存したいメールのEntryIdを貼りつけ
mail = outlook.mail(STDIN.gets.chomp)
#puts mail.Attachments.ole_methods
#puts mail.Attachments.Item(1).ole_methods

# 添付ファイルのファイル名を取得
file = mail.Attachments.Item(1).FileName
# RootPath下に添付ファイル名のディレクトリ作成
SaveDir = "#{SaveRootPath}\\#{file.split(".")[0]}"
Dir.mkdir(SaveDir)

# 添付ファイル保存
mail.Attachments.Item(1).SaveAsFile("#{SaveDir}\\#{file}")

# ディレクトリ下にタイトル.txtファイルを作成し送信者、タイトル、本文を書きこむ
File.open("#{SaveDir}\\#{mail.Subject}.txt", "w") do |file|
    file.write "SENDER      : #{mail.SenderName}(#{mail.SenderEmailAddress})\n"
    file.write "TO          : #{mail.To}\n"
    file.write "CC          : #{mail.CC}\n"
    file.write "ReceivedTime: #{mail.SentOn}\n"
    file.write "SUBJECT     : #{mail.Subject}\n"
    file.write "BODY: \n#{mail.Body}\n"
end

基本的に参考サイトの「Ruby から Outlook を操作する」の章の通りに進めば、まず受信トレイの一覧を取ってこれるまではいけます。詰まったのは添付ファイルの扱い…Attachmentsオブジェクトの扱い方でした。

  • まず、自作のOutlook#mailを呼び出し特定のメールを取得します。(EntryIDを元に)
    # EntryIDを元にメールを取得  
    def mail(entryId)
        item = @nameSpace.GetItemFromID(entryId)
        return item
    end
  • このメールオブジェクトにAttachmentsが。そしてAttachments.Item(number)に添付ファイルが格納されているようです。Itemのnumberは1から始まっている? 0だとエラーが出たような…。
  • Item(number)#FileNameで添付ファイル名が、Item(number)#SaveAsFile(path)で添付ファイルの保存ができました。この辺り。
file = mail.Attachments.Item(1).FileName
# RootPath下に添付ファイル名のディレクトリ作成
SaveDir = "#{SaveRootPath}\\#{file.split(".")[0]}"
Dir.mkdir(SaveDir)

# 添付ファイル保存
mail.Attachments.Item(1).SaveAsFile("#{SaveDir}\\#{file}")

まとめ

  • メール本文を保存したい(ファイル名は件名.txt)
    • とりあえずできた
  • 添付ファイルを保存したい(ファイル名は添付ファイル名のまま)
    • とりあえずできた
  • 上記のファイルをYYYYMMDD_添付ファイル名(拡張子なし)フォルダの中へ格納
    • YYYYMMDD付加はまだ、フォルダはできた
  • 保存場所はマイドキュメントかデスクトップ
    • マイドキュメントに保存はできた

TODO

  • フォルダ名先頭にYYYYMMDD
  • フォルダ名に使用できない文字を全角に置換
  • フォルダ存在時の対処
  • デスクトップに保存したい

穴だらけだしまだわからない事も多いけど、とりあえず動く所までは行けた! ので続く。

[1] もしかしたらググッたら打開策があるのかもしれない。

関連記事(この記事の初版より古い記事はリンクがグレーで表示されます)

  1. 2011/09/30 [Java] [Windows] [Ruby] .msgファイルをパースして中から添付ファイルを抜き出す
  2. 2011/09/07 [Ruby] [Redmine] [SQLite3] [Windows] Redmineのプラグイン作成のための備忘録と、時々SQLite3
  3. 2011/08/23 [Ruby] [Windows] MicrosoftOutlookで消せなくなったフォルダをwin32ole経由でRubyから消してみる
  4. 2011/07/09 [Windows] [Ruby] MicrosoftOutlookのメールをRuby(win32ole)で操作する! その2
  5. 2011/05/01 [Ruby] [Redmine] [Windows] Redmineインストール備忘録(Windows)
  6. 2012/10/01 [Ruby] [Bundle] [Windows] bundle execを省略したいのでバッチを作った(Windows版)
  7. 2012/07/17 [Ruby] [Windows] [Redmine] Windows版Redmineをサービスに登録してブート時に起動させる(宿題あり)
  8. 2012/04/20 [Ruby] [Windows] ZenTestで実行したRSpecの結果をGrowlで通知してくれるようにした
  9. 2012/03/27 [Windows] [Jenkins] [Ruby] simplecovとsimplecov-rcovを使ってJenkinsでカバレッジを確認
  10. 2012/03/20 [Windows] [Jenkins] [Ruby] Windows環境用にrcovをビルドしなおす手順
  11. 2012/02/29 [Ruby] [Rails] [Windows] Rails3レシピブックを読みながらRailsを学ぶ モデル、コントローラ、ビュー、Railsの規約など
  12. 2012/02/28 [Ruby] [Windows] [Rails] Rails3レシピブックを読みながらRailsを学ぶ
  13. 2012/02/20 [Ruby] [Windows] Rubyの実行ファイルを作成するExerbとOcraを試してみた
  14. 2011/12/27 [Evernote] [Ruby] [API] EvernoteのAPIをRubyから叩きたい
  15. 2011/12/26 [Ruby] [Haml] [Sinatra] SinatraでHaml入門