【问题标题】:Access to the Gmail unique message ID through Java Mail通过 Java Mail 访问 Gmail 唯一邮件 ID
【发布时间】:2014-09-19 18:33:17
【问题描述】:

我正在尝试通过 JavaMail 获取唯一的邮件 ID,以便以后无需特定 IMAP 文件夹的上下文即可识别邮件。目前我写的代码如下:

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()
}

这会导致以下输出(针对一条消息):

<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

【问题讨论】:

  • 包括 msg.dump 的输出...
  • 是否有任何理由认为标准(不是仅限 gmail)messageID 不够用?
  • @djechlin 当然,它让我忘记了。谢谢。
  • @hsan 是的,要严格从 Gmail API 检索邮件,messageID 是不够的(据我所知)。 developers.google.com/gmail/api/v1/reference/users/messages/get
  • 我可以从this 收集到的是,常规的 FetchProfile 无法做到这一点。在链接条目中,Gmail 的自定义属性在常规提取后使用 doCommand 检索。

标签: groovy jakarta-mail imap gmail-api


【解决方案1】:

【讨论】:

    【解决方案2】:

    比尔一针见血,但我只是想分享一下我遇到的小问题。

    我在问题中发布的代码没有太大变化:

    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) 效果很好。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-06-12
      • 2017-09-09
      • 1970-01-01
      • 1970-01-01
      • 2017-09-20
      • 2018-09-09
      • 1970-01-01
      • 2016-09-26
      相关资源
      最近更新 更多