Can ConversationID change for existing item in conversation? - vba

We are writing Outlook VSTO add-in and save info about mail items in database. Some features are relying on conversations in Outlook, so we save ConversationID in the database to detect that all messages are from the same thread.
Recently I found that at some point conversationID is changed for the entire conversation! So I have first message with ID
5E2C809C8D7E4BEBA402613311DD8C7B
And then suddenly it becomes
347B0DEB35C68E1EE882EFABE4BCC373
for the next messages. And when I select previous messages they also have this 347 id.
It seems that it broke when I answered an e-mail with changed subject (and it gets out of thread) or after I answered from Win10 mail client. But I can't reproduce this anymore.
Does anyone know in which cases this can happen?

Conversation index can change if the "Thread-Index" MIME header is missing from a message in the conversation. But it will not change for the existing older messages in a conversation. For that to happen, each and every one of them would need to be updated, and if that happened, you should see the updated last modified date.

Related

Send and Save specific emails. Not a sentitem event listener

Edit: I am just going to use an eventlistener. I would delete the post but maybe somebody will find a non eventlistener way to save a sent mailitem before it is received in the sent item inbox.
Issue: Outlook won't receive VBA sent emails until macro completes. If I use wait, sleep, while loops or anything else, the email will not be received. I can't use a Sent Items event listener because I only want specific emails saved to the folder, not all. I individually know how to save from sent items, I know how to send messages. The issue is the delay between sending the email with VBA and it appearing in my Sent Items box. If I saveas before waiting, the email that is saved is the previous email, but if you try to wait, the sent items folder never updates. Any ideas or simple solutions. I might just be dumb.
I have read every forum but haven't found a solution, I had it running at another company but no longer remember how. I use a macro to send very specific emails and do lots of other tasks. I would then like to grab the email I just sent and save it to a folder using vba. The issue is receiving the email in my "Sent Items" folder is delayed. If I try to capture it or wait to receive it, my code never finishes. All solutions I see in the forums are a Sent Item listener / Inbox event listeners, but I don't need that, I know which emails to trigger it on.
One way or another, you'd need to wait for some event to fire, be that Items.ItemAdd on the Sent Items folder, or SyncObject.SyncEnd on the SyncObject - message submission is asynchronous, so no amount of sleep or while loops would help you. You cannot just stop your VBA script and resume it when the message is actually sent since your code is running on the main Outlook thread - if your script pauses, so does Outlook.
You can try using the NameSpace.SendAndReceive method which initiates immediate delivery of all undelivered messages submitted in the current session, and immediate receipt of mail for all accounts in the current profile. Note, calling the SendAndReceive method is asynchronous. SendAndReceive provides the programmatic equivalent to the Send/Receive All command that is available when you click Tools and then Send/Receive.
If you don't need to synchronize all objects, you can use the SyncObjects collection object to select specific objects. For more information, see NameSpace.SyncObjects.
In your VBA code you may also consider using the DoEvents function which yields execution so that the operating system can process other events. DoEvents passes control to the operating system. Control is returned after the operating system has finished processing the events in its queue and all keys in the SendKeys queue have been sent (if any).
DoEvents is most useful for simple things like allowing a user to cancel a process after it has started, for example a search for a file.
Solution, not the solution or used in the past but I settled.
Basically just the event listener solution that everyone in all the forums suggest. I created a separate folder in my Sent Items and use myNameSpace.GetDefaultFolder to set that folder for the VBA sent items.. I send the emails only to that folder and I added the listener to only that folder. This allows me to separate the Sent items and this specific VBA sent emails and then to save them automatically. I am still looking for a way to save the sent Mail Item before the Sent Item Inbox shows it, but I have given up at this point. Thanks for everyone's help. If I find the better answer, I will try to post it along with the code.

How to prevent NServiceBus from not sending messages on errors

I'm new to NServiceBus, so maybe I'm asking something pretty silly here, but is there a way to make NServiceBus not stop sending any messages that are sent in response to a message whose handler fails?
Let me explain with a simple example.
Suppose I have an OrderPaidEvent that has a handler that does the following:
Look for the customer
Start a DB transaction
Update the customer to a good customer
Send an CustomerUpgradedToGoodCustomerEvent message
Commit the DB transaction
Fairly straightforward, all is well in the world. Now a few months later someone else figures that an email would be nice when an order is paid and thus adds another handler to the OrderPaidEvent to send an email.
Unfortunately, now whenever the mailserver has an issue, this second handler will fail with an error which will however prevent the original CustomerUpgradedToGoodCustomerEvent message from being sent (step 4). But because the DB transaction was already committed (step 5) the customer has already been upgraded to a good customer in the database.
This means that even if the OrderPaidEvent handler is retried the customer no longer changes and thus the CustomerUpgradedToGoodCustomerEvent message is never sent. Worse yet, this is all because of a change to the code that has nothing to do with the original message handler and will thus be difficult to detect.
This seems like a massive flaw and since I'm new to this I'm certain there's something I'm doing wrong, but I can't seem to figure out what it is.
Any help from you fine people would be great.
Thanks in advance.
How about breaking down your procedural code into separate handlers?
Thereafter each logical operation will either be done or will not be done based on successful completion of each granular task.
If you add a Saga to the mix then you can make business decisions based on the completed steps in your Saga.
Also maybe read more about transactions and NServiceBus here
First of all I would send out the CustomerUpgradedToGoodCustomerEvent after the commit. At that point you are sure that the event actually took place.
And in response to your question: You could handle the email in some 'SendEmail' command that is raised after the db commit and before the event is published. If that command fails it will not hurt the handling of the OrderPaid event. When mail is up again, the command can be retried and handled normally.

VBA - Outlook message ID - using to identify preeviously processed messages

If processing emails in an outlook mailbox, is it possible to use some kind of ID to record the last message processed avoiding the need to iterate through all messages every time?
I'm trying to write a quick 'attachment stripper' to free up mailbox space and don't want to have to iterate through every message in a mail folder each time the code is ran. At a pinch I could use the mail folder name and the message date, but what happens if a folder is renamed, or messages moved? (Besides, I REALLY hate dates!!! formats to start with, and I have recently experienced randomly changing environment settings in my work environment - a citrix remote desktop - so now have a near phobia of the damn things!)
I was hoping there was some kind of message ID I could use but can see neither the MAPI ID nor the Outlook Mail ID being suitable here (though I could well be wrong). Is there a means of doing this?
If you need to avoid reprocessing previously processed emails, you have no recourse but to either record the email's unique identifiers externally for later checking, or flagging emails with a specific value (such as adding a Category, setting a flag, adding a custom field, setting an internal field, etc.) to avoid processing them later.

Using Dday.ical How can I send multiple events with the same start time and duration

When I setup the event using DDay.ical I can successfully send the events to a user's outlook. The problem arises when multiple events are setup at the same time. When this happens all emails are updates to the original task, not new tasks.
I tried adding a name to the event using the .Name property, which results in the event email being an unsupported calendar invite.
Ended up figuring this out through some good old trial and error.
In the end I was not properly setting the UID property to be a completely unique identifier for each event. Changing this to be unique 100% of the time fixed the issue and allowed me to be able to create as many events as I want, any time I want, and have them all appear as separate events instead of updates.

Re-getting POP3 messages

I am using Peter Huber's POP3 client to connect to gmail and download messages.
The inboxes being accessed are transactional inboxes used only for code-access. That is, a message comes in with a order file attached, code will process it and then delete the message. One stipulation of the code though was a DEBUG flag, which if set would prevent the code from deleting the message so that you can run the program again later without the debug flag and reprocess the message. So, in my code I have
If Not Arguments.Debug Then pop.DeleteEmail(eid)
This works fine. Problem is, even when not deleting the message, running the program a second time will not re-retrieve the message, even though if I login to gmail and look at the inbox, it is still there. The only way I can get the program to see the message again is to forward the message back to the same inbox. But in Peter's code I do not see anywhere where he is keeping track of seen messages between sessions.
Is this something that is done on gmail's end? Refusing to deliver a message to the same client a second time? If so, is there any way I can change my gmail account so that it will always show all messages in the inbox to a client when retrieving the list of messages, even ones already "seen"? I don't see anything in the gmail settings screen.
UPDATE: I tried adding a method to send a RSET command to the server, as per this comment on the codeproject page. I then call my new Reset() method after retrieving my messages but before disconnecting, ... but I still have the same problem.
Okay... found a "sort of" answer after reading through pages of the comments on the codeproject project.
According to this comment, the RSET command does not actually do anything when you are dealing with gmail's servers.
The "answer" is to prepend your username with the string "recent:", so instead of logging in with [myaccount#gmail.com] you log in with [recent:myaccount#gmail.com]. Rather hackish, ... but it works.