Skip to content

Instantly share code, notes, and snippets.

@kellyredding
Created May 16, 2012 17:54
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kellyredding/2712611 to your computer and use it in GitHub Desktop.
Save kellyredding/2712611 to your computer and use it in GitHub Desktop.
Pull Gmail labels via IMAP using Gmail IMAP extensions
require 'net/imap'
# Net::IMAP raises a parse error exception when fetching attributes it doesn't
# recognize. Here I patch an instance of Net::IMAP's `msg_att` method to
# recognize the Gmail IMAP extended attributes
# Refer to:
# * https://developers.google.com/google-apps/gmail/imap_extensions#access_to_gmail_labels_x-gm-labels
# * http://blog.wojt.eu/post/13496746332/retrieving-gmail-thread-ids-with-ruby
GMAIL_USER = 'you@gmail.com'
GMAIL_PW = 'secret'
# you must enable IMAP on your Gmail account for this to work
gmail_imap = Net::IMAP.new('imap.gmail.com', 993, true)
# patch only this instance of Net::IMAP
class << gmail_imap.instance_variable_get("@parser")
# copied from the stdlib net/smtp.rb
def msg_att
match(T_LPAR)
attr = {}
while true
token = lookahead
case token.symbol
when T_RPAR
shift_token
break
when T_SPACE
shift_token
token = lookahead
end
case token.value
when /\A(?:ENVELOPE)\z/ni
name, val = envelope_data
when /\A(?:FLAGS)\z/ni
name, val = flags_data
when /\A(?:INTERNALDATE)\z/ni
name, val = internaldate_data
when /\A(?:RFC822(?:\.HEADER|\.TEXT)?)\z/ni
name, val = rfc822_text
when /\A(?:RFC822\.SIZE)\z/ni
name, val = rfc822_size
when /\A(?:BODY(?:STRUCTURE)?)\z/ni
name, val = body_data
when /\A(?:UID)\z/ni
name, val = uid_data
# adding in Gmail extended attributes
when /\A(?:X-GM-LABELS)\z/ni
name, val = flags_data
when /\A(?:X-GM-MSGID)\z/ni
name, vale = uid_data
when /\A(?:X-GM-THRID)\z/ni
name, val = uid_data
else
parse_error("unknown attribute `%s'", token.value)
end
attr[name] = val
end
return attr
end
end
puts "logging in to Gmail..."
gmail_imap.login(GMAIL_USER, GMAIL_PW)
gmail_imap.select("INBOX")
puts "downloading all msgs in INBOX..."
gmail_msgs = gmail_imap.uid_search(['ALL']).collect do |uid|
# pull some attributes, including 'X-GM-LABELS'
gmail_imap.uid_fetch(uid, ['RFC822', 'FLAGS', 'INTERNALDATE', 'X-GM-LABELS']).first
end
puts "\nGmail Labels:"
puts '-------------'
gmail_msgs.each do |msg|
puts msg.attr['X-GM-LABELS'].inspect
end
puts "\ndone."
@heedspin
Copy link

Line 54 should be "val =" instead of "vale =".

Thanks for the monkey patch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment