IMAP, tracking moved messages using message id - java

We are developing a mail client written in Java. It has same functionalities like Outlook or Thunderbird, etc. It communicates with the mail server directly. Additionally, our business rules demand that we store all messages in our database and messages should be kept synchronised always. I know that is not very suitable for IMAP, but we must keep everything in our database.
Question arises, how to track an IMAP message moved from folder A to folder B? How can we get informed about that? If you remove a message from A, it is deleted from A and it created newly in B, as a result: The UID value of the message is changed. Can we rely on the MessageID found in the headers? I checked some mails servers and see that the message id in the headers remain unchanged. But i have read somewhere, that the messageids can be empty depending on the mail server.
Are the MessageID in headers always set, can be cases or mailservers that they leave it blank?
Are the MessageID value in headers unique in an IMAP folder?
Is it possible that it gets changed when message is moved or folders UIDVALIDITY changed?
What about setting a custom header during fetch? When I add a non-standart header name value pair, will it be kept on the mail server or is it possible that non-standart mail heraders will be deleted by mail server? Is it a bad idea applying a non-standart header value?
IMAPMessage m;
m.setHeader("myHeader", "myValue");
There were some suggestions in stackoverflow, it is said to generate a hash including messageId and other parameters such as sender, subject etc, is it a safe approach? We can get conflicts if there is no unique MessageID is provided or no MessageID is provided.

There are three things you can do.
First, message-id. You can rely on the message-id being present and unique these days if your mode of failure is good enough. In your case, if the message-id is not there and a message is moved, is the failure just that you waste space in the database and/or download the message twice? The wasted space will be small these days.
Second, x-gm-msgid. That's a gmail-specific feature, a 63-bit number that never changes. If two messages have the same x-gm-msgid, they are the same.
Third, the COPYUID response code tells you about moves, but only applies when you do the moving, not when someone else does.
Put together, these should give you a fairly good understanding of how the user's mailboxes change.

Related

JavaMail API - Reading a large outlook mailbox (>3000) for message content

I have a requirement to read a mailbox having more than 3000 mails. I need to read these mails, fetch their mail contents and feed the body into another api. Its easy to do with a few mails (for me it was approx 250), but after that it slowed down significantly. Is the accepted answer in this link
the only choice, or is there any other alternative way.
NOTE: I have purposely not pasted any snippet,as I have used the straight forward approach, and yes I did use FetchProfile too.
JavaMail IMAP performance is usually controlled by the speed of the server, the number of network round trips required, and the ammount of data being read. Using a FetchProfile is essential to reducing the number of round trips. Don't forget to consider the IMAP-specific FetchProfile items.
JavaMail will fetch message contents a buffer at a time. Large messages will obviously require many buffer fetches, and thus many round trips. You can change the size of the buffer (default 16K) by setting the mail.imap.fetchsize property. Or you can disable these partial fetches and require it to fetch the entire contents in one operation by setting the mail.imap.partialfetch property to false. Obviously the latter will require significant memory on the client if large messages are being read.
The JavaMail IMAP provider does not (usually; see below) cache message contents on the client, but it does cache message headers. When processing a very large number of messages it is sometimes helpful to invalidate the cache of headers when done processing a message by calling the IMAPMessage.invalidateHeaders method. When using IMAPFolder.FetchProfileItem.MESSAGE, the message contents are cache, and will also be invalidated by the above call.
Beyond that, you should examine the JavaMail debug output to ensure only the expected IMAP commands are being issued and that you're not doing something in your program that would cause it to issue unnecessary IMAP commands. You can also look at time-stamps for the protocol commands to determine whether the time is being spent on the server or the client.
Only after all of that has failed to yield acceptable performance, and you're sure the performance problems are not on the server (which you can't fix), would you need to look into custom IMAP commands as suggested in the link you referred to.

Can an email contain multiple Message Ids?

I am implementing a mail client in java and I am retrieving the MessageId using the command: String[] msgIds = msg.getHeader("Message-Id");
Since getHeader() returns an Array. I was wondering if there is any scenario where an email might contain multiple Ids.
I tried testing it by sending/replying/forwarding an email back and forth but it only contained one id every time.
The current specification for internet email message format is RFC 5322. That specifies that an email message can have zero or one "message-id" headers, and that one is recommended. (See page 20 in the linked version)
So any email that has more than one "message-id" header is non-conformant.
However, if you are implementing a mail reader or processor, it is advisable to allow for the possibility of a non-conformant email message. At the very least, your processor should cope with such an email so that it doesn't crash or behave in a destructive fashion. (That kind of fragility could allow someone to attack your mail processor, and maybe the system that it runs on.)
An E-Mail might not contain multiple Message-Id headers but other E-Mail header fields might appear multiple times. The getHeader function is returning an array to take these into account.
For example the Recieved header can be set multiple times to provide a full trace of servers that handled the E-Mail.

Java Chat system protocol design, how to determine message type?

I have a chat program implemented in Java. The client can send lots of different types of information to the server (i.e, Joins the server and sends username, password; requests a private chat with another user on the server, disconnects from the server, etc).
I'm looking for the correct way to have the server/client differentiate between 'text' messages that are just meant to be chat text messages sent from one client to the others, and 'command' messages (disconnect, request private chat, request file transfer, etc) that are meant for the server or the client.
I see two options:
Use serialized objects, and determine what they are on the receiving end by doing an 'instanceof'
Send the data as a byte array, reserving the first N bytes of the array to specify the 'type' of the incoming data.
What is the 'correct' way to do this? How to real protocols (oscar, irc) handle this situation?
I've googled around on this topic and only found examples/discussions centering on simple java chat applications. None that go into detail about protocol design (which I ultimately intend to practice).
Thanks to any help...
Second approach is much better, because serialization is a complex mechanism, that can be easily used in a wrong way (for example you may bind yourself to internal content of a concrete serialized class). Plus your protocol will be bound to JVM mechanism.
Using some "protocol header" for message differentiation is a common way in network protocols (FTP, HTTP, etc). It is even better when it is in a text form (people will be able to read it).
You typically have a little message header identifying the type of content in all messages, including standard text/chat messages.
Either of your two suggestions are fine. (In your second approach, you probably want to reserve some bytes for the length of the array as well.)

Is it possible to specify multiple email addresses to receive bounce messages?

We're using JavaMail API to send emails from our application. To handle bounce back messages (Non delivery report),
we're redirecting bounce backs to a different email address using the following code:
properties.put("mail.smtp.from", "bounce#example.net");
In our case, we want bounce backs to be redirected to multiple email addresses. In fact, we even tried few other options like providing a list of addresses separated by commas, etc., but none of them are working.
My question here is, is it possible to redirect bounce backs to multiple email addresses? I'm not able to find the right answer/solution even after googling.
Any alternative/workaround solution are also appreciated.
Since by definition/RFC the SMTP protocol allows only one address in "MAIL FROM:" Stage (which is the bounce address), the only way of having bounces sent to multiple recipients would be a forwarder from a single bounce address to multiple target adresses.
however, all bounces by would come from the null sender, so you wouln't get any notification if that forwarding fails for any reaseon, it would create a "double-bounce", and the messages would be deleted.
Therefore, I recommend storing the bounces in an imap folder and give all required people or applications access to that (eg. polling the bounces instead of forwarding), if that is feasible in your environment.
Apache Commons Email allows bounce off. But unfortunately it takes single String and does not allow Collection of InternetAddress. HtmlEmail email = new HtmlEmail();
email.setBounceAddress("bounceoff-emailad#abc.com");Hope this helps

Changing subtopics in BlazeDS and Flex

I using messaging in Flex-BlazeDS. When the AIR client starts it connects to a destination and a specific subtopic. During runtime, the user can use a combo box to subscribe to different sets of live data coming in, this combo box change event changes the subtopic by:
messagingConsumer.subtopic = subtopicComboBox.selectedLabel;
messagingProducer.subtopic = subtopicComboBox.selectedLabel;
messagingConsumer.subscribe();
A message is then sent to the server with the new subtopic name as well so the server knows to send to a new subtopic.
This whole mechanism seems very glitchy and I'm wondering if anyone else has tried this and succeeded? Most times it works the first time and the after that either the messages dont get sent or I get server errors like:
[BlazeDS]Endpoint with id 'my-streaming-amf' cannot service the streaming request as either the supplied FlexClient id 'B07F3285-A408-816E-4697-F13F9B17E32C is not valid, or the FlexClient with that id is not valid.
Also sometimes when I change subtopics it will cause the FlexSession and FlexClient to be destroyed instead of just the MessageClient. Once that FlexSession gets destroyed it messes up all kinds of things including logging out the user.
Perhaps I'm over complicating things by changing subtopics to listen to different sets of live data, if anyone has any other ideas on how to accomplish dynamic changing of destinations or subtopics please list those as well.
You might want to try and unsubscribe before you change the subtopic and resubscribe.

Categories

Resources