Unified inbox doesn't group conversations with the same sender across mailboxes

I have an issue that I’m unsure about whether it is expected behavior. If it is not a feature yet, I would gladly contribute.

Description

I manage 2 email accounts with mailspring. Sometimes, customers contact me on both emails. I am not sure if it is supposed to do that but mailspring does not present the “conversation” across mailboxes.

To Reproduce…

Steps to reproduce the behavior:

Let’s see we have 3 email accounts: C, X and Z.
X and Z are “my” email accounts, managed in the unified inbox of mailspring. “C” is a customer.

C messages X about an issue on the 20th of January. C also messages Y about an issue later that day.

When I check the unified inbox, I see two entries for C, one for the email sent to X, another one for the email sent to Y.

Expected Behavior

I was hoping the unified inbox is also able to unify conversations (at least that is what I’d need).

What I DO see is all the conversations in the rightmost panel:
email folder panel | messages panel | conversation view panel | contact panel (<- this one)

But having these show up automatically in one thread would make working with that way easier for me.

Setup

  • OS and Version: 10.15.7 (19H2)
  • Mailspring Version: 4.2.12 (4.2.12)

Additional Context

If you can point me to the classes that handle the “conversation matching” that would be very helpful to me. I could implement matching by sender address and if you are interested, make a PR.

Thank you for your time.

Thanks for reporting this. Unfortunately, due to the backlog of issues, there’s a good bit of patience necessary. Mailspring is an open source project that is primarily maintained by one developer — Ben Gotow — in addition to a full time job. This is here, so it’s not likely to get buried.

Right now, threads aren’t really intended to work across mailboxes, nor am I entirely sure most users would expect them to. Ben might have some additional thoughts on future plans, but he’s also got a lot of other things demanding his attention.

Personally, I think the conversation threading will need a significant reworking to address multiple issues reported with it. However, there are quite a few larger fish to fry at the moment.

Be advised, votes on this feature request (yep, I moved it) will make a big difference in terms of if/when it appears on the roadmap.

Hey, I appreciate your response - I do understand your concern about mass-compatibility and if there is no demand for this feature that you don’t necessarily want to add it in.

But as I said before, I would gladly work on this by myself, especially since the project is now more open than it was a month ago. If you can tell me where the matching takes place I could take matters in my own hands - if you want to eventually merge my changes that’s up to you of course.

I’m really not sure where it is. Ben might know, but his limited development time is directed at some long-awaited bug fixes and features.

@Reiszecke You can try to implement this as a plugin, in which case it won’t matter whether we bring it into Mailspring proper or not. However, I know that has much of a “where do I start” as the other situation.

Hey @Phylu, you’ve been neck-deep in Mailspring for a few weeks. Any thoughts here?

If I understand this correctly, the following would be a good test case:

  1. Configure two mail addresses A and B within Mailspring
  2. Send an e-mail from A to B
  3. Answer to the e-mail which creates an e-mail from B to A
  4. Now, there should be only one e-mail thread show that contains 4 messages (A sent, B receives, B sent, A receives)

Is this correct?

If yes, there are two things that should get a thought:

  1. Currently in the mail list there are two different threads displayed. These two needs to be matched so that only one is displayed.
  2. In the thread view all e-mails of both of the originally two threads needs to be displayed.

If I remember correctly, there is a thread id which keeps the same when somebody replies to an e-mail. This is how the matching for a thread is done. If this ID is the same for both accounts, we might change the matching behaviour for the threads so that it is only matching by thread ID and not by account ID.

1 Like

Hey, what you have described in your potential test sounds correct, that’s the behavior the app would show if it was between 2 email addresses, right.

It sounds a bit counter-intuitive with only A and B but for everyone wondering why someone would need this, here is an example modeling a real-world use case for this:

1 Like

I can’t find the edit button (if any). I think I found everything I needed, will keep you posted.

Alright, got a proof of concept in a somewhat working state. These 3 conversations were between 3 inboxes, 2 of which are added to mailspring, one is the “customer”

This is not a test or mockup, this is from live gmail accounts. However, not in a shareable state yet, I cheated my way around making things asynchronous. It’s also not sorted yet, which may have to do with the last message breaking something (red error text bad). Would love to investigate but it’s 3am. Good night.

1 Like

Good morning. The error is caused by messages that don’t have a body. Some of them have a snippet which I can force into the body, some of them have nothing so I put a placeholder there. No more error messages. No idea why it doesn’t break in vanilla Mailspring and my fix is getting quite ugly but half of the docs are dead links >.>

I have, just now, also got the sorting working. I took for granted that _sortItemsForDisplay already takes care of the date but it’s only to e.g. put drafts in the correct place, has nothing to do with date.

Performance: This is not optimized AT ALL. Each query result for a thread triggers a new reread and resort and render, this would have to be debounced somewhere. However, thankfully today’s computers are quite fast:

I tested on a database with 70k messages, 25k threads and 19k contacts and selected a contact that I have 64 messages back and forth with in 10 threads. It takes about 1 second to load all these. I expected the load time to be much worse on scale due to the nested and partly redundant requests.

I haven’t checked whether replying works the way it should, will do some more work on this today.

Unfortunately, I won’t be able to offer you a clean PR, I consider my solution to be WAY to hacky for this. This was the first time I have ever done anything in react but if someone needs the code to get the ball rolling in order to make a PR I’m more than happy to share of course

1 Like

If you want, just share the branch where you are working on this. I will take a look and can try to give some comments or see if I can take this over.

2 Likes

Hey mate, definitely not my proudest public commit · Reiszecke/Mailspring-1@7c0e332 · GitHub

It’s ugly, I have warned you. Idk how to get the inbox’s email addresses so I abused the Calendar for that.

I iterate through the involved email addresses and the one that doesn’t match is the stranger’s email. I then search for threads with that email just like the sidebar-related-threads.tsx fetchThreads() function does it.

Then I fetch all the messages of the found threads. The messages then get reflected in the store’s _items object.

I’ve made everything sync because I haven’t thought of .sort()ing the messages earlier which is why the function is now so fragmented.

I haven’t found any usability issues with this so far in my production environment so for me it’s good as-is.

Just for the record, less shallow issues with this are:

  • callbacks are hacked to work in sync, not async (the latter of which would be preferred)

  • if there are “group chats”-like threads, it’s probably only gonna show one stranger’s messages

  • I overwrote the _fetchFromCache method - there should be a user preference the class should check on in order to determine whether or not to employ that “unifying” behavior.

I didn’t bother too much with this because I have yet to receive confirmation whether or not this will make it to the master. I think the demand is there, but that’s just my opinion. Also, again, I’m not too fond of that react stuff so virtually anyone wanting to finish this would probably do be a better job at this than I could.

1 Like

I will try to check it your code next week. I definitely like the functionality that it provides.

Hey @Reiszecke

Thanks for the code! I have added some comments here and hope that they are helpful: definitely not my proudest public commit · Reiszecke/Mailspring-1@7c0e332 · GitHub

Unfortunately, when running your code locally, I had the following problem:

  • I have the mail addresses A and B configured in Mailspring
  • I send a mail via mailspring from A to C
  • I answered from C to A
  • I answered from C to B

Now, I would expect the e-mails to be grouped in the same conversation. Unfortunately, they are still shown separately, but all E-Mails that are related to A are grouped in one thread and all E-Mails related to B are grouped in one thread. This does not take the thread ID or the mail subjet or something like this into account.

I think the main issue here is that the matching is solely done based on the mail address. I personally don’t see threading that only relies on the mail address in mailspring as this would break most normal threads. Unfortunately, looking at the thread model, I don’t see an easy way for the matching.

One idea may be to ensure that the threadId is kept the same for answers even if the recipient address is a different one. I think this would be needed to be handled by the mailsync engine (GitHub - Foundry376/Mailspring-Sync), but I did not find the code in question there.

If you want to provide an alternative threading model which is based on the sender address, then – as @CodeMouse92 said – a plugin may be the best possibility here.

Cheers,
Phylu