ruby-gmailにて、ある1日のメールを絞り込んで取得するには、
:ONに当該日付を設定する。
:BEFOREや:AFTERに設定してはいけない。
:BEFOREと:AFTERに同一の日付を設定すると、絞り込みが行われなくなる。
厄介な仕様だ(´・д・`)
使い勝手が悪いので、コードを変更。
以下のような処理を挿入。
lib/gmail/mailbox.rb
if opts[:after] === opts[:before] opts[:on] = opts[:before] opts[:after] = nil opts[:before] = nil end
ダメモトで本家にも、つたない英語で’Pull Request’投げてみたら、通った!!
やってみるもんだ。
次回のバージョンからは反映させるだろう。
なお、コードの全貌は以下。
lib/gmail/mailbox.rb
require 'date' require 'time' class Object def to_imap_date Date.parse(to_s).strftime("%d-%B-%Y") end end class Gmail class Mailbox attr_reader :name def initialize(gmail, name) @gmail = gmail @name = name end def inspect "<#Mailbox name=#{@name}>" end def to_s name end # Method: emails # Args: [ :all | :unread | :read ] # Opts: {:since => Date.new} def emails(key_or_opts = :all, opts={}) if key_or_opts.is_a?(Hash) && opts.empty? search = ['ALL'] opts = key_or_opts elsif key_or_opts.is_a?(Symbol) && opts.is_a?(Hash) aliases = { :all => ['ALL'], :unread => ['UNSEEN'], :read => ['SEEN'] } search = aliases[key_or_opts] elsif key_or_opts.is_a?(Array) && opts.empty? search = key_or_opts else raise ArgumentError, "Couldn't make sense of arguments to #emails - should be an optional hash of options preceded by an optional read-status bit; OR simply an array of parameters to pass directly to the IMAP uid_search call." end if !opts.empty? if opts[:after] === opts[:before] opts[:on] = opts[:before] opts[:after] = nil opts[:before] = nil end # Support for several search macros # :before => Date, :on => Date, :since => Date, :from => String, :to => String search.concat ['SINCE', opts[:after].to_imap_date] if opts[:after] search.concat ['BEFORE', opts[:before].to_imap_date] if opts[:before] search.concat ['ON', opts[:on].to_imap_date] if opts[:on] search.concat ['FROM', opts[:from]] if opts[:from] search.concat ['TO', opts[:to]] if opts[:to] search.concat ['SUBJECT', opts[:subject]] if opts[:subject] # Gmail offers us to search the same way we do on the web interface # https://developers.google.com/gmail/imap_extensions # example: gmail.emails(gm: 'has:attachment in:unread "who is john galt"') # search.concat ['X-GM-RAW', opts[:gm]] if opts[:gm] end # puts "Gathering #{(aliases[key] || key).inspect} messages for mailbox '#{name}'..." @gmail.in_mailbox(self) do @gmail.imap.uid_search(search).collect { |uid| messages[uid] ||= Message.new(@gmail, self, uid) } end end # This is a convenience method that really probably shouldn't need to exist, but it does make code more readable # if seriously all you want is the count of messages. def count(*args) emails(*args).length end def messages @messages ||= {} end end end
元記事はこちらです。
「ruby-gmailにて、ある1日のメールを絞り込んで取得する」