Created
May 16, 2012 17:54
-
-
Save kellyredding/2712611 to your computer and use it in GitHub Desktop.
Pull Gmail labels via IMAP using Gmail IMAP extensions
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 = '[email protected]' | |
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." |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Line 54 should be "val =" instead of "vale =".
Thanks for the monkey patch.