楽天ブログに自動で記事を投稿したい (2)

  技術情報

前回はpop3でYahooメールの受信箱を巡回して特定メールを読みだすプログラムを書きましたが、受信箱の中のメールをすべて走査する仕組みだったため、受信箱にいっぱいメールがあると時間がかかります。

調べてみると、IMAPというプロトコルであればサーバ側でメールの検索が行えるとのこと。処理時間や通信量の削減が期待できそうなので、さっそくテストコードを書いてみました。

IMAPサーバへの接続設定は下表になります。

設定項目入力内容
受信メール(IMAP)サーバー)imap.mail.yahoo.co.jp
受信メール(IMAP)ポート番号993
アカウント名、または、ログイン名Yahoo! JAPAN ID
パスワードYahoo! JAPAN IDのパスワード
IMAPでの設定

IMAPサーバへの接続はPOPサーバへの接続の時とあまり変わりません。メール検索条件であるSearchTermオブジェクトを生成して、メッセージを取得しているところが今回のポイントです。

  • Subjectに “の日記” が含まれていること。
  • 受信日が本日であること。(時分秒の指定は無視されるため、EQ(一致)、 new Date()で機能します)
  • Fromに “no-reply@plaza.rakuten.co.jp” が含まれていること。

今回はこの3つの条件で、記事投稿用メールアドレスについてのメールかどうかを判定しています。

// https://mvnrepository.com/artifact/com.sun.mail/javax.mail
@Grab(group='com.sun.mail', module='javax.mail', version='1.6.2')

import javax.mail.Folder
import javax.mail.Message
import javax.mail.Session
import javax.mail.Store
import javax.mail.URLName
import javax.mail.search.AndTerm
import javax.mail.search.ComparisonTerm
import javax.mail.search.FromStringTerm
import javax.mail.search.ReceivedDateTerm
import javax.mail.search.SearchTerm
import javax.mail.search.SubjectTerm

String host = 'imap.mail.yahoo.co.jp'
String user = '******'
String pass = '******'
String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";

Properties properties = System.properties
properties.setProperty('mail.imap.socketFactory.class', SSL_FACTORY)
properties.setProperty('mail.imap.ssl.trust', '*')
Session session = Session.getDefaultInstance(properties)

URLName urln = new URLName('imap', host, 993, null, user, pass)
Store store = session.getStore(urln)
store.connect()
Folder inbox = store.getFolder("INBOX")
inbox.open(Folder.READ_ONLY)

SearchTerm[] stlst = [
        new SubjectTerm('日の日記'),
        new ReceivedDateTerm(ComparisonTerm.EQ, new Date()),
        new FromStringTerm('no-reply@plaza.rakuten.co.jp')
    ]
SearchTerm st = new AndTerm(stlst)
    
inbox.search(st).each { Message msg->
    println("Subject : ${msg.getSubject()}")
    println(" From    : ${msg.getFrom()}")
    println(" ReplyTo : ${msg.getReplyTo()}")
}

inbox.close()
store.close()

検索条件は抽象クラスSearchTermを継承した条件クラスのオブジェクトを生成し、単体あるいは組み合わせて指定します。私自身、すこし手こずったので全体像をメモしておきます。
ちなみに日本語で検索するのは思ったように動きませんでした。コツがあるのかもしれません。

抽象クラスメモ
javax.mail.search.SearchTerm
 AddressTerm
  FromTermfromに指定Addressが存在するか。ざっくり絞り込むならFromStringTerm の方が向いていそう。
  RecipientTermrecipientに指定Addressが存在するか。ざっくり絞り込むならRecipientStringTermの方が向いていそう。
 ComparisonTerm比較条件の抽象クラス
  DateTerm日付比較
   ReceivedDateTerm受信日で絞り込む。条件は ComparisonTerm で定義されているものを指定。日付はDate型で指定するが時分秒は無視される。
   SentDateTerm
  IntegerComparisonTerm数値比較
   MessageNumberTerm
   SizeTerm
  FlagTermメッセージのフラグ状態で抽出する。フラグの種類はjavax.mail.Flagsで定義されている。
  ModifiedSinceTerm
  OlderTerm
  YoungerTerm
  StringTerm指定の文字列が含まれているか。
   AddressStringTerm
    FromStringTerm
    RecipientStringTerm
   BodyTerm
   HeaderTerm
   MessageIDTerm
   SubjectTerm
 AndTerm2つ以上の条件オブジェクトをAND結合する。
 OrTerm2つ以上の条件オブジェクトをOR結合する。
 NotTerm指定した条件オブジェクトの論理を反転する。
型階層イメージ

関連記事

LEAVE A COMMENT