none
Change the body of a sent email RRS feed

  • Question

  • Hi all,

    I want to track when an email has been sent succesfully, I also want to access this mailItem when it did.

    Now i tried a few options:

    - Option 1
    I tried to listen to the Outbox folder with the BeforeItemMoved listener on the folder. This works when I manually delete or move a file. But after it gets moved by Outlook automatically when it is sent this is not fired.

    Folder outbox = Application.GetNamespace("MAPI").GetDefaultFolder(OlDefaultFolders.olFolderOutbox) as Folder;           

    outbox.BeforeItemMove += outbox_BeforeItemMove;

    - Option 2

    I triend listening to the ItemAdd event on the Sent Folder. But in a lot of cases the mailItems aren't saved to this default folder and i cant seem to find out how to get this specific folder.

    Is there any way i can overide the process where the mailItem gets moved from the Outbox so i can fire the event? Any other suggestions are welcome too.



    Wednesday, May 28, 2014 11:49 AM

Answers

  • Hello Bert,

    IPM.Note corresponds to the MailItem class.

    I'd recommend to declare Outlook objects separately and keep them alive. For example:

    mailItem.SaveSentMessageFolder.Items.ItemAdd


    You need to keep the Items object declared at the global scope for handling the ItemAdd event. I think you need to declare a separate function with a parameter declared as object:

    Private Sub myOlItems_ItemAdd(ByVal Item As Object) 

    Also I have noticed that you don't release underlying COM objects instantly. Use System.Runtime.InteropServices.Marshal.ReleaseComObject to release an Outlook object when you have finished using it. Then set a variable to Nothing in Visual Basic (null in C#) to release the reference to the object. You can read more about this in the Systematically Releasing Objects article in MSDN.


    • Marked as answer by Bert Sinnema Wednesday, June 11, 2014 5:28 PM
    Monday, June 2, 2014 12:33 PM

All replies

  • Hello Bert,

    The MailItem class provide the SaveSentMessageFolder property which allows to specify a Folder object that represents the folder in which a copy of the e-mail message will be saved after being sent. In the ItemSend event of the Application class you can check out the folder where the item should be placed after sending and handle the ItemAdd event of that folder. Be aware, the ItemAdd event is not fired when multiple items are added simultaneously (it was more than 16 earlier, didn't check it in recent Outlook versions).


    Wednesday, May 28, 2014 1:33 PM
  • The limit on ItemAdd() remains the same.

    It's also possible that the sent item isn't being saved at all. That can be checked in the ItemSend() event, but at that time it's usually too late to change the value in SaveSentMessageFolder(). For that you'd want to handle the Send() event on the MailItem object.


    Ken Slovak MVP - Outlook

    Wednesday, May 28, 2014 1:38 PM
  • Thank you both for the comment. This made me think of a different way to handle the events.

    I'm thinking if i would attach an ItemAdd listener to the SaveSentMessageFolder in the ItemSend() event it should fire when the MailItem is moved to the SaveSentMessageFolder. I don't think the multiple items limitation is going to be an issue cause i don't really need the event fired when a user would drag multiple MailItems to that folder.

    I'll let you know what the outcome of this approach is.

    Thursday, May 29, 2014 2:53 PM
  • That should work, except in the case where SaveSentMessageFolder is null. In that event handler I think it would be too late to add a save folder at that time, but that can be checked. If it is too late your best option would be to handle the Send() event on the item, which occurs before the Application level event fires.

    Ken Slovak MVP - Outlook

    Thursday, May 29, 2014 3:11 PM
  • So i tried to capture the MailItem as i described before. Instead of getting the actual Mailitem i get a very limited object which is an IPM.Note object.

                mailItem.SaveSentMessageFolder.Items.ItemAdd += (AddedItem) =>
                {
                    Outlk.MailItem addedItem = AddedItem as Outlk.MailItem;
                    addedItem.BodyFormat = Outlk.OlBodyFormat.olFormatHTML;
                    addedItem.HTMLBody = "Altered!";
                    addedItem.Body = "Altered";
                    addedItem.Save();
                };


    The code breaks with a COMException(The message you specified cannot be found.) when i try to set the BodyFormat or set a different body content. In the dynamic view of the debugger all the fields have the following value: 

    System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Runtime.InteropServices.COMException: The message you specified cannot be found.

    I'm starting to think I'm not allowed to alter messages after they have been sent. Or is this the wrong approach?

    Cheers.

    Monday, June 2, 2014 11:55 AM
  • Hello Bert,

    IPM.Note corresponds to the MailItem class.

    I'd recommend to declare Outlook objects separately and keep them alive. For example:

    mailItem.SaveSentMessageFolder.Items.ItemAdd


    You need to keep the Items object declared at the global scope for handling the ItemAdd event. I think you need to declare a separate function with a parameter declared as object:

    Private Sub myOlItems_ItemAdd(ByVal Item As Object) 

    Also I have noticed that you don't release underlying COM objects instantly. Use System.Runtime.InteropServices.Marshal.ReleaseComObject to release an Outlook object when you have finished using it. Then set a variable to Nothing in Visual Basic (null in C#) to release the reference to the object. You can read more about this in the Systematically Releasing Objects article in MSDN.


    • Marked as answer by Bert Sinnema Wednesday, June 11, 2014 5:28 PM
    Monday, June 2, 2014 12:33 PM
  • You are allowed to change the Body (for example) in a sent item. If you change it after changing HTMLBody of course you'd overwrite HTMLBody with whatever you write to Body.

    You definitely need to set up event handler procedures to handle the events, and you also need to do what Eugene mentioned about separating variables and declaring them explicitly. Otherwise your event handler will be garbage collected and stop firing.


    Ken Slovak MVP - Outlook

    Monday, June 2, 2014 1:38 PM
  • Thanks guys. I will give it another go!
    Thursday, June 5, 2014 1:32 PM