[Windows][Ruby]MicrosoftOutlookのメールをRuby(win32ole)で操作する! その2
前回までのあらすじ
http://d.hatena.ne.jp/kk_Ataka/20110517/1305560776:title
あれから色々変えたので追記。前回のTODOは…
- フォルダ名先頭にYYYYMMDD
- フォルダ名に使用できない文字を全角に置換
- フォルダ存在時の対処
- デスクトップに保存したい
全部消化。とりあえずOutlook開いて添付ファイル付きのメールファイルをデスクトップに保存するだけの簡単なお仕事はできるようになりました!やった!
GitHub
[https://github.com/gosyujin/outlook_for_ruby:title]
なにやってるかの流れ
- まず初期化。
# 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へ保存|
- ぶっこぬきのくだりは次回…。
今ソース貼ってたら命名とか特にひどい><
リファクタリングしよー。
[1] デフォルトだと個人用フォルダ、保存フォルダみたいな名前かな。ostファイル単位?