MicrosoftOutlookのメールをRuby(win32ole)で操作する! その2
前回までのあらすじ
MicrosoftOutlookのメールをRubyで操作する! - kk_Atakaの日記
あれから色々変えたので追記。前回のTODOは…
- フォルダ名先頭にYYYYMMDD
- フォルダ名に使用できない文字を全角に置換
- フォルダ存在時の対処
- デスクトップに保存したい
全部消化。とりあえずOutlook開いて添付ファイル付きのメールファイルをデスクトップに保存するだけの簡単なお仕事はできるようになりました!やった!
なにやってるかの流れ
- まず初期化。
# MicrosoftOutlookに接続後初期化処理を行う。 # MicrosoftOutlookが起動していないと終了する。 def initialize begin ol = WIN32OLE::connect("Outlook.Application") rescue WIN32OLERuntimeError putsError("MicrosoftOutlookが起動していません。") exit else desktopJa = Kconv.tosjis("デスクトップ") # NameSpace取得(getNameSpaceの引数は"MAPI"のみ) @nameSpace = ol.getNameSpace("MAPI") # 保存パス指定 @saveRootPath = "#{ENV["USERPROFILE"]}\\" + desktopJa + "\\" # 保存パスに作成するディレクトリ作成 @saveDir = "" # フォルダ選択番号、ハッシュ @folderNum = -1 @folder = Hash.new # メール選択番号、ハッシュ @mailNum = -1 @mail = Hash.new # 取得件数のデフォルト値 @defaultCount = 20 end end
- 初期化した後、トップレベル*1のメールフォルダ全部を取得してます。
- コマンドから選べるように{num => EntryID}のハッシュを作っておきます。{ "1" => "受信トレイのEntryID" }みたいな。
# ルートからフォルダの一覧を取得する def folders(count=@defaultCount) folders = @nameSpace.Folders @folderNum = 1 folders.each do |f| if count < @folderNum then break end GC.start puts f.Name puts "N | CNT | FolderName" findFolder(f.EntryId) end end
# entoryIdを元にフォルダ名を再帰的に取得する def findFolder(entryId, count=@defaultCount) folder(entryId).Folders.each do |f| if count < @folderNum then break end begin puts "#{@folderNum} | " + "#{f.Items.Count}通 | " + "#{f.Name}" # + " | #{f.Parent.Name}" @folder[@folderNum.to_s] = f.EntryId @folderNum += 1 findFolder(f.EntryId) rescue => ex putsError(ex) end end end
- フォルダ一覧から一つ選んだら、そのフォルダ内のメール一覧を取得します。
- これもコマンドから選べるように{num => EntryID}のハッシュを作っておきます。{ "1" => "とあるメールのEntryID" }みたいな。
# entryIdを元に対象フォルダのメール一覧を取得する def mails(entryId, count=@defaultCount) f = @nameSpace.GetFolderFromID(entryId) if f.Items.Count == 0 then raise "フォルダにメールがありません。" end @mailNum = 1 puts "N | A | SentOn | Name | Subject" f.Items.each do |mail| if count < @mailNum then break end GC.start puts "#{@mailNum} | " + "#{mail.Attachments.Count} | " + "#{mail.SentOn} | " + "#{mail.SenderName.unpack('A10')} | " + "#{mail.Subject.unpack('A35')}" @mail[@mailNum.to_s] = mail.EntryId @mailNum += 1 end end
- なお、メールオブジェクト(MailItem)からは以下のような情報を取得できます。
MailItem#Attachments.Count | 添付ファイルの数 |
---|---|
MailItem#SentOn | 送信時間 |
MailItem#SenderName | 送信者名 |
MailItem#Subject | 件名 |
MailItem#To | 送信先 |
MailItem#CC | CC |
MailItem#Body | 本文 |
- メール一覧から一つ選んだら、デスクトップにディレクトリを作って、その中にメール本文と添付ファイルを保存します。
# @saveRootPath下にディレクトリを作成する def mkdir(mail) # 受信日のYYYYMMDD receivedTime = Date.strptime(mail.SentOn, "%Y/%m/%d").strftime("%Y%m%d") @saveDir = "#{@saveRootPath}" + "#{receivedTime}_#{replace(mail.Subject)}\\" if !File.exist?(@saveDir) then Dir.mkdir(@saveDir) end end
# @saveDir下にSubject.txtファイルを作成しメール内容を書きこむ def saveMail(mail) fullPath = "#{@saveDir}#{self.replace(mail.Subject)}.txt" File.open(fullPath, "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" #puts "■本文保存 :#{fullPath}" puts "■本文保存 :#{self.replace(mail.Subject)}" end end
# @saveDir下に添付ファイルを保存する def saveFile(mail) if mail.Attachments.Count != 0 then mail.Attachments.each do |item| item.SaveAsFile("#{@saveDir}#{self.replace(item.FileName)}") puts "■添付ファイル保存:#{item.FileName}" # ファイルが.msgだった場合添付ファイルをぶっこぬき # フォルダ名も変更 if item.FileName =~ /.*\.msg/ then msg = MsgParse.new msg.inputMsg("#{@saveDir}#{self.replace(item.FileName)}") fileName = msg.saveFile(@saveDir) renameFolder(mail, fileName) end end else puts "添付ファイルはありません。" end end
- Attachmentオブジェクトからは以下のような情報を取得できます。
Attachment#SaveAsFile(PATH) | 添付ファイルをPATHへ保存 |
---|
- ぶっこぬきのくだりは次回…。
今ソース貼ってたら命名とか特にひどい><
リファクタリングしよー。