I should probably add a section about the actual .msg file format. For now, use the source (see last section for links)
Msg Details
A quick look at using the library to examine some components of an msg:
``` require 'mapi/msg'
msg = Mapi::Msg.load open(filename)
access to the 3 main data stores, if you want to poke with the msg
internals
msg.recipients
=> [#'>]
msg.attachments
=> [#, #]
msg.properties
=> #
creation_time=# ...>
```
API
You can access the underlying ole object, and see all the gory details of how msgs are serialised. See Ole section for more details.
``` puts msg.ole.root.to_tree
=>
-
|- # | |- # | |- # | |- # | |- # | |- # | |- # | |- # | |- # | |- # | - # |- # ... |- # |- # - #
|- # |- # |- # - # ```
Named properties have recently been implemented, and Msg::Properties now allows associated guids. Keys are represented by Msg::Properties::Key, which contains the relevant code.
You can now write code like: ``` props = msg.properties
props[0x0037] # access subject by mapi code props[0x0037, Msg::Properties::PS_MAPI] # equivalent, with explicit GUID. key = Mapi::Msg::Properties::Key.new 0x0037 # => 0x0037 props[key] # same again
keys support being converted to symbols, and then use a symbolic lookup
key.to_sym # => :subject props[:subject] # as above props.subject # still good ```
Under the hood, there is complete support for named properties: ```
to get the categories as set by outlook
props['Keywords', Msg::Properties::PS_PUBLIC_STRINGS]
=> ["Business", "Competition", "Favorites"]
and as a fallback, the symbolic lookup will automatically use named properties,
which can be seen:
props.resolve :keywords
=> #
which allows this to work:props.keywords # as above ```
With some more work, the property storage model should be able to reach feature completion.
More information
Until more specifics are added here, have a look at some of these files in the source:
- lib/mapi/msg.rb - top level msg structure and information about the msg property store format.
- lib/mapi/property_set.rb - information on the higher level mapi property set wrapper.
- data/mapitags.yaml - the mapi tag <=> symbolic name mapping that is used (built from aggregation of a few header files).
- data/named_map.yaml - same sort of thing but for named properties (parsed from a web page i think).