Getting a Frequent Sender List With Mail.app and rb-appscript

January 10th, 2009  |  Published in ruby

I was in a meeting yesterday morning when the issue of how often an internal mailing list was utilized came up, so this morning’s fiddle-around time was devoted to using rb-appscript with Mail.app. Once I had a simple message count, I got curious about the days of the week the list was most used and the most frequent contributors, so I tossed in a Google chart and top contributor list:

#!/usr/bin/ruby
require 'rubygems'
require 'appscript'
require 'google_chart'
include Appscript

class Array  # http://snippets.dzone.com/posts/show/2161%20%20def%20sum
  def sum 
    inject( nil ) { |sum,x| sum ? sum+x : x }
  end
end

mail = app("Mail")
account = mail.accounts["Jupitermedia"]
pitch_folder = account.mailboxes["pitch"]

messages = pitch_folder.messages.get

messages_count = messages.size

days = Hash.new(0)
senders = Hash.new(0)
dates = Hash.new(0)

count = 0 
messages.each do |m|
  if m.sender.get =~ /@jupitermedia\.com/ && m.subject.get =~ /^social/i
    date = m.date_received.get.strftime("%Y-%m-%d")
    day = m.date_received.get.strftime("%A")
    sender = m.sender.get.gsub(/<.+?>/, "")
    senders[sender] +=1
    days[day] +=1
    dates[date] +=1
    count +=1
  end

end

puts "#{count} total messages sent to the list."
puts "#{dates.values.sum / dates.size} per day average."

dc = GoogleChart::PieChart.new('500x200', "",  false) 
  days.each do |d,c|
    dc.data "#{d} (#{c})", c
  end


puts dc.to_url

senders.sort {|a,b| b[1] <=> a[1]}.each  { |s| puts "#{s[0]}: #{s[1]}"}

The resulting chart:

Message Day of the Week Chart

The IMAP mailbox I was getting the messages from currently has 4,351 messages. My initial whack at it involved using a filter in rb-appscript to get the right messages, since the list’s contributors follow a subject line naming convention:

messages = pitch_folder.messages[its.subject.begins_with("social")].get

That took about 24 seconds to run. When I dropped the filter and added a conditional to the block where I processed the messages, it took about six seconds to run (and it didn’t make my MacBook’s fan spin up, which sometimes means I’m asking a lot of it, or sometimes means TextMate is about to make my life very, very hard).

appscript’s filters are still pretty handy. The reference forms documentation provides a complete list of available filters. I’d like it if there was regexp support, either similar to the way String’s index method works or with a simple “regexp” method.

Leave a Response

This work by Michael Hall is licensed under a Creative Commons Attribution-ShareAlike 3.0 United States license.