In response to my series on Automating Outlook with Ruby, several readers have asked about accessing the Inbox and managing messages.
We start by using the win32ole library to create a new instance (or connect to a currently running instance) of the Outlook application object:
require 'win32ole'
outlook = WIN32OLE.new('Outlook.Application')
Next we'll get the MAPI namespace:
mapi = outlook.GetNameSpace('MAPI')
To get a reference to the Inbox folder, call the MAPI object's GetDefaultFolder method, passing it the integer 6, which represents the Inbox folder:
inbox = mapi.GetDefaultFolder(6)
To get the Personal Folders object, call the MAPI object's Folders.Item method, passing it the name of the folder.
personal_folders = mapi.Folders.Item('Personal Folders')
To reference a subfolder, call the parent folder object's Folders.Item method, passing it the name of the folder.
baseball_folder = personal_folders.Folders.Item('Baseball')
You can get a count of a folder's unread items by calling the UnreadItemCount method:
puts "#{inbox.UnreadItemCount} unread messages"
A folder object's Items method returns a collection of message objects, which you can iterate over:
inbox.Items.each do |message|
# Your code here...
end
You can also pass the Items method a (1-based) index to retrieve a single message:
first_message = inbox.Items(1)
Once your code tries to access methods and properties of a Message object, an Outlook security dialog will prompt the user to allow access to Address Book entries. The user must click a checkbox to allow access and select a time limit between 1 and 10 minutes.
Message objects have dozens of methods/properties, including:
SenderEmailAddress
SenderName
To
Cc
Subject
Body
To see a complete list, you could call the ole_methods method, as explained here. So to view a sorted list of the Message object's methods and properties, we could do this:
methods = []
inbox.Items(1).ole_methods.each do |method|
methods << method.to_s
end
puts methods.uniq.sort
To delete a message, call its Delete method:
message.Delete
To move a message to another folder, call its Move method, passing it the folder object:
baseball_folder = personal_folders.Folders.Item('Baseball')
message.Move(baseball_folder)
So, if we wanted to check our Inbox and move all messages that contain 'Cardinals' in the subject line to our 'Baseball' folder, we could do something like this:
inbox.Items.Count.downto(1) do |i|
message = inbox.Items(i)
if message.Subject =~ /cardinals/i
message.Move(baseball_folder)
end
end
As reader Ana points out, we should use the Count and downto methods to ensure that our inbox.Items index stays in sync, even as we move messages out of the Inbox. Otherwise, we run the risk of a message being skipped when the message above it is moved or deleted.
That concludes our program for today. Feel free to post a comment here or send me email with questions, comments, or suggestions.