2

後で特定の IMAP フォルダーのコンテキストなしでメールを識別できるように、JavaMail を介して一意のメッセージ ID を取得しようとしています。これまでに書いたコードは次のとおりです。

def fp = new FetchProfile()

fp.add(FetchProfile.Item.ENVELOPE)
fp.add(FetchProfile.Item.FLAGS)
fp.add(FetchProfile.Item.CONTENT_INFO)
fp.add(javax.mail.UIDFolder.FetchProfileItem.UID)
fp.add("X-mailer")
fp.add("X-GM-MSGID") // Attribute for retrieving the ID in the fetch (?)

uIDFolder.fetch(iMAPmessages, fp);

iMAPmessages.each { msg ->
   println msg.dump()
}

次の出力が得られます (1 つのメッセージに対して)。

<com.sun.mail.imap.IMAPMessage@14c04449 
  bs=com.sun.mail.imap.protocol.BODYSTRUCTURE@5ac31f43
  envelope=com.sun.mail.imap.protocol.ENVELOPE@40399642 
  items=[:] 
  receivedDate=Mon Jul 28 12:18:38 MSK 2014 
  size=3147 
  peek=false 
  uid=991 
  modseq=-1  
  sectionId=null 
  type=null 
  subject=null   
  description=null 
  headersLoaded=false 
  loadedHeaders=[X-GM-MSGID:X-GM-MSGID, X-MAILER:X-mailer] 
  dh=null 
  content=null 
  contentStream=null 
  headers=javax.mail.internet.InternetHeaders@4b7e7ff
  flags=com.sun.mail.imap.protocol.FLAGS@20 
  modified=false 
  saved=true 
  cachedContent=null 
  strict=true 
  msgnum=372 
  expunged=false 
  folder=INBOX 
  session=javax.mail.Session@4f0dc86c>

封筒:

<com.sun.mail.imap.protocol.ENVELOPE@34ea0af2 
  msgno=371 
  date=Sun Jul 27 17:46:08 MSK 2014 
  subject=Re: Require 
  from=[From <from@gmail.com>]
  sender=[sender <sender@gmail.com>] 
  replyTo=[From <from@gmail.com>] 
  to=[receiver <receiver@gmail.com>, =?ISO-8859-1?Q?Johan_W=E4ngl=F6f?= <example@gmail.com>] 
  cc=null 
  bcc=null 
  inReplyTo=<CAHr+Gay-ZX0U-pFuwQUMziyECTOVrLNn-XLtc643DYXwgtdDFQ@mail.gmail.com>
  messageId=<CAHr+GawnCxaT476K8Rm1MeQNPx8HOfL+VqM0ThMydfTNR12rBg@mail.gmail.com>>

取得プロファイルに最後に追加された属性は、一意の ID を取得するための特別な属性です ( https://developers.google.com/gmail/imap_extensions#access_to_the_gmail_unique_message_id_x-gm-msgid )。

私が知る限り、メッセージには一意のメッセージ ID は含まれていません。私は何か完全に間違っていますか?

IMAP セッションのトレース

* 372 FETCH (UID 991 RFC822.SIZE 3147 INTERNALDATE "28-Jul-2014 08:18:38 +0000" FLAGS (\Seen) ENVELOPE ("Mon, 28 Jul 2014 10:18:38 +0200" "Hej du" (("Emil Tholin" NIL "emtholin" "gmail.com")) (("Emil Tholin" NIL "emtholin" "gmail.com")) (("Emil Tholin" NIL "emtholin" "gmail.com")) (("Emil Tholin" NIL "emtholin" "gmail.com")) NIL NIL NIL "<CADsZLRxveuyQX5gXVHvr8ca57yCLopJEc+TpuL2GS-57Kq+yqg@mail.gmail.com>") BODYSTRUCTURE ((("TEXT" "PLAIN" ("CHARSET" "UTF-8") NIL NIL "7BIT" 13 1 NIL NIL NIL)("TEXT" "HTML" ("CHARSET" "UTF-8") NIL NIL "7BIT" 34 1 NIL NIL NIL) "ALTERNATIVE" ("BOUNDARY" "001a11c1250ef810aa04ff3c91b5") NIL NIL)("TEXT" "PLAIN" ("CHARSET" "US-ASCII" "NAME" "rygg.txt") NIL NIL "BASE64" 2138 0 NIL ("ATTACHMENT" ("FILENAME" "rygg.txt")) NIL) "MIXED" ("BOUNDARY" "001a11c1250ef810af04ff3c91b7") NIL NIL) BODY[HEADER.FIELDS (X-mailer X-GM-MSGID)] {4}
)
A4 OK Success
A5 CLOSE
A5 OK Returned to authenticated state. (Success)
DEBUG IMAPS: added an Authenticated connection -- size: 1
specificFolderHeaders() - Closing the mail connection
A6 LOGOUT
* BYE LOGOUT Requested
A6 OK 73 good day (Success)
DEBUG IMAPS: IMAPStore connection dead
DEBUG IMAPS: IMAPStore cleanup, force false
DEBUG IMAPS: IMAPStore cleanup done
4

2 に答える 2

1

JavaMailの最新リリースでGmail 固有の APIを使用します。

于 2014-07-28T21:56:17.890 に答える
1

ビルは頭に釘を打ちましたが、私が直面した小さな問題を共有したいと思いました.

質問に投稿したコードはあまり変わりませんでした:

def messages = []

def fp = new FetchProfile()
fp.add(FetchProfile.Item.ENVELOPE)
fp.add(FetchProfile.Item.FLAGS)
fp.add(javax.mail.UIDFolder.FetchProfileItem.UID)
fp.add("X-mailer")

//Google specific attributes
fp.add(GmailFolder.FetchProfileItem.MSGID)
fp.add(GmailFolder.FetchProfileItem.THRID)

uIDFolder.fetch(iMAPmessages, fp);

iMAPmessages.each { msg ->
  GmailMessage gmsg = (GmailMessage) msg
  println Long.toHexString(gmsg.getMsgId().toLong()) //Eureka!
}

正しく理解するのに時間がかかった部分は、認証トークンを使用して適切に gimap に接続することでした。

def connect(mailAccount) {

  if (mailAccount.provider == "Gmail") {
    Properties props = new Properties();
    props.put("mail.store.protocol", "gimaps");
    props.put("mail.gimaps.sasl.enable", "true"); // Note the "gimaps"
    props.put("mail.gimaps.sasl.mechanisms", "XOAUTH2");
    props.put(OAuth2SaslClientFactory.OAUTH_TOKEN_PROP, mailAccount.token);
    Session session = Session.getDefaultInstance(props, null);

    final String emptyPassword = ""; // Since we authorize with token
    GmailStore store = (GmailStore) session.getStore("gimaps");
    store.connect(
        "imap.gmail.com",
        993,
        mailAccount.emailAddress,
        emptyPassword);
    return store;
  }
  else {
    OAuth2Authenticator.initialize();
    def store = OAuth2Authenticator.connectToImap(
        "imap.gmail.com",
        993,
        mailAccount.emailAddress,
        mailAccount.token,
        false); // Debug flag

    return store;
  }
}

Gmail アドレスときちんとした OAuth2Authenticator ( https://code.google.com/p/google-mail-oauth2-tools/source/browse/trunk/java/com/google/code/samples/ oauth2/OAuth2Authenticator.java?r=3 ) 他のプロバイダーの場合、うまく機能しました。

于 2014-07-31T17:09:10.613 に答える