Home > database >  Spring Integration's `ImapIdleAdapter` doesn't mark messages as read
Spring Integration's `ImapIdleAdapter` doesn't mark messages as read

Time:07-26

I have declared a mail listener with Spring Integration like this:

@Bean
public IntegrationFlow mailListener() {
    return IntegrationFlows.from(
            Mail.imapIdleAdapter(getUrl())
                    .searchTermStrategy((s, f) -> new FlagTerm(new Flags(Flags.Flag.SEEN), false))
                    .shouldMarkMessagesAsRead(true)
                    .shouldDeleteMessages(false)
                    .get())
            .<Message>handle((payload, header) -> handle(payload)).get();
}

In my test mail account I have a few 'unread' and a few 'read' messages. Starting the application I see in the logs that the listener fetches all of the 'unread' messages over and over again without ever marking them as 'read'.

Given that I specified shouldMarkMessagesAsRead(true) I would expect the Adapter to mark a message as read after fetching it.

Am I understanding and/or doing something wrong?

CodePudding user response:

In this type of situations we recommend to set:

.javaMailProperties(p -> p.put("mail.debug", "true"))

on that Mail.imapIdleAdapter().

Probably your e-mail server really does not support that \seen flag, so the message is marked as read via some other flag.

So, with that mail debugging option you should see some interesting info in your logs.

The logic in our default DefaultSearchTermStrategy is like this around that Flags.Flag.SEEN :

if (supportedFlags.contains(Flags.Flag.SEEN)) {
                NotTerm notSeen = new NotTerm(new FlagTerm(new Flags(Flags.Flag.SEEN), true));
                if (searchTerm == null) {
                    searchTerm = notSeen;
                }
                else {
                    searchTerm = new AndTerm(searchTerm, notSeen);
                }
            }

See if you really need a custom strategy and why a default one is not enough for you: https://docs.spring.io/spring-integration/docs/current/reference/html/mail.html#search-term

CodePudding user response:

Thanks to Artem Bilan's hint on activating debug output I found out that the mailbox was opened in read-only mode.

And thanks to Gary Russell's answer to another question I tried removing the .get() call on the ImapIdleChannelAdapterSpec:

@Bean
public IntegrationFlow mailListener() {
    return IntegrationFlows.from(
            Mail.imapIdleAdapter(getUrl())
                    .shouldMarkMessagesAsRead(true)
                    .shouldDeleteMessages(false))
            .<Message>handle((payload, header) -> handle(payload)).get();
}

Now the mailbox gets opened in read-write mode and marking the messages with the SEEN flag works fine.

I also don't actually need the custom SearchTermStrategy now as Artem Bilan already suggested.

  • Related