none
Send a second email possible from inside the ItemSend RRS feed

  • Question

  • Hi,

    Is the below possible to do? If so, how?

    I have certain logic in side the ItemSend event to detect if a second email should be sent. I want to send this second email programmatically without requiring any user input AFTER the original email. I understand it might be possible to add regular "email send" code inside the ItemSend event, but I am not sure if the order of the emails be correct then as I want the second email to be sent AFTER the first email. Maybe someone understands how the Outlook event model works in more detail. I find that the documentation does not have much information.

    Many thanks.

    Thursday, December 24, 2015 8:45 AM

Answers

  • Hello,

    You can use a low-level code (Extended MAPI) to send any emails. In that case the ItemSend event will not be fired. For example, you may consider using any third-party wrappers around Extended MAPI such as Redemption and etc.

    Also you can use the Outlook object model for submitting other items, but the ItemSend event will be fired for such items as well. So, you will need to add a user property (or any other marker) to skip any processing in the ItemSend event handler or you will get an endless loop.

    You may consider using a timer which fires events (Tick) on the main thread. So, just start a timer in the ItemSend event when you need to send a copy. In that case you will be sure the copy will be sent after the original.

    Thursday, December 24, 2015 10:20 AM
  • To avoid recursion problems, simply start a timer in the ItemSend event handler. When the timer fires (you will be out of the ItemSend event handler by then), disable the timer (so it won't fire again) and run your code that creates and sends the new message.

    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.5 is now available!

    Thursday, December 24, 2015 8:47 PM
  • Hi Digoshark,

    In addition to ensure the order of sending message, we can check the Sent property of original message in the time ticket event and send the second message after this property is true.

    Regards & Fei


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Friday, December 25, 2015 2:46 AM
    Moderator
  • MailItem.Sent property will be true *only* after the message is actually sent and recreated in the Sent Items folder. The earliest you can catch that is in the Items.ItemAdd event on the Sent Items folder.

    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.5 is now available!

    Friday, December 25, 2015 3:21 AM

All replies

  • Hello,

    You can use a low-level code (Extended MAPI) to send any emails. In that case the ItemSend event will not be fired. For example, you may consider using any third-party wrappers around Extended MAPI such as Redemption and etc.

    Also you can use the Outlook object model for submitting other items, but the ItemSend event will be fired for such items as well. So, you will need to add a user property (or any other marker) to skip any processing in the ItemSend event handler or you will get an endless loop.

    You may consider using a timer which fires events (Tick) on the main thread. So, just start a timer in the ItemSend event when you need to send a copy. In that case you will be sure the copy will be sent after the original.

    Thursday, December 24, 2015 10:20 AM
  • Thank you.
    Thursday, December 24, 2015 11:17 AM
  • To avoid recursion problems, simply start a timer in the ItemSend event handler. When the timer fires (you will be out of the ItemSend event handler by then), disable the timer (so it won't fire again) and run your code that creates and sends the new message.

    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.5 is now available!

    Thursday, December 24, 2015 8:47 PM
  • The ItemSend event will be fired for items submitted programmatically from the timer's Tick event. So, the timer will not help to avoid the recursion. As I've already described above, we need to add any marker (for example, a user property) which can be checked in the ItemSend event handler and skip any further processing if required.  
    Thursday, December 24, 2015 9:10 PM
  • Yea, that is what I most likely will do. Will probably set timer to something really short. Will then just set a string skipProcessingEmailWithThisSubject that will be reset to null after it has skipped the second email.

    I am still a bit curious about sending the email right away inside ItemSend because it might be that the second email will not be sent until ItemSend from the first email returns anyway, but that depends on how the library is written. But might be cleaner to user a timer to avoid undocumented functionality.

    • Edited by Dingoshark Thursday, December 24, 2015 10:01 PM
    Thursday, December 24, 2015 9:57 PM
  • The definition of recursion is entering a function again by a call from the same function. Timer will most definitely help with that problem. As well as with the problem of OOM preventing some of its Object Model calls within certain event handlers. 

    To avoid automatically processing the second message you need to distinguish the messages automatically sent. User property is only necessary if *all* outgoing messages trigger the automatic message logic. If, for example, it is triggered by a certain keyword or a recipient address not present in the automatically generated message, no user property is necessary.


    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.5 is now available!

    Thursday, December 24, 2015 10:39 PM
  • Just make sure (if you are using .Net) to use the Timer from the Forms namespace rather than System - the one from Forms uses the same thread (which is what you want). The interval can be 0 for all practical purposes - it will run immediately after Outlook's message pump becomes idle.

    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.5 is now available!

    Thursday, December 24, 2015 10:42 PM
  • Thanks, that is a great tip!
    Thursday, December 24, 2015 11:14 PM
  • Hi Digoshark,

    In addition to ensure the order of sending message, we can check the Sent property of original message in the time ticket event and send the second message after this property is true.

    Regards & Fei


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Friday, December 25, 2015 2:46 AM
    Moderator
  • MailItem.Sent property will be true *only* after the message is actually sent and recreated in the Sent Items folder. The earliest you can catch that is in the Items.ItemAdd event on the Sent Items folder.

    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.5 is now available!

    Friday, December 25, 2015 3:21 AM
  • I was under the impression that sending a second email from inside a timer (Forms not System timer) that is started from the ItemSend event will guarantee the second message being sent after the first one.

    Hence, I see now reason for listening to Items.ItemAdd on the Sent Items folder nor checking the Sent property on the original email from within the Timer callback where the second email is being sent.

    Or do you think I need to do the below to be 100% sure about the correct order?

    Store a variable to the original email of type MailItem. Start a reoccuring timer of say 50ms from the ItemSend of the original email. Inside the timer callback, I check if the originalMailItem.Sent is true, and if it is I can go and send the second email and stop the timer. If it is not true, I will just return from the function and wait for the timer to trigger again. the solution above could fail in edge cases when sending the first email would take seconds, and the user manages to open a new email and click Send again, so might need to store an array of MailItems such as "mailsThatNeedSecondEmails"... I really do not want to make this too complicated.





    • Edited by Dingoshark Friday, December 25, 2015 9:28 AM
    Friday, December 25, 2015 9:18 AM
  • > To avoid recursion problems, simply start a timer in the ItemSend event handler. When the timer fires (you will be out of the ItemSend event handler by then), disable the timer (so it won't fire again) and run your code that creates and sends the new message.

    I have already described that way above. Using a timer without filtering items in the ItemSend event is not enough for avoiding recursion.

    Friday, December 25, 2015 4:09 PM
  • It is overcomplicated I think. Moreover, the ItemAdd event is not fired when a large number of items are added to the folder at once (more than 16). This is a know issue in OOM.
    Friday, December 25, 2015 4:29 PM
  • What you describe is avoiding an infinite loop. It is not recursion.

    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.5 is now available!

    Friday, December 25, 2015 4:33 PM
  • How do you access originalMailItem? You are not supposed to hold a reference to the item being sent - it will be sent and deleted. A new (sent) item will be created in the Sent Items folder.

    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.5 is now available!

    Friday, December 25, 2015 4:35 PM
  • It is really hard to manually send more than 16 emails at once. The only case when a large number of items will be added to the Sent Items folder is when the user drags a large number of emails to the Sent items folder or when the folder is being synchronized with the remote Exchange server. I doubt those emails need to be processed to begin with.

    Dmitry Streblechenko (MVP)
    http://www.dimastr.com/redemption
    Redemption - what the Outlook
    Object Model should have been
    Version 5.5 is now available!

    Friday, December 25, 2015 4:38 PM
  • In that statement I agree with you, but it didn't change the meaning.

    Using a timer without filtering items in the ItemSend event is not enough for avoiding an infinite loop :)

    Friday, December 25, 2015 5:55 PM
  • I will just use a single-event timer (Forms.Timer) say 50 ms delay that will be started from inside the ItemSend event from the first email. In this timer event callback function, I will send the second email and store the second email's subject as a string in a global variable called ignoreNextSendEventForThisEmailSubject. This variable will be used as its named, and will ensure that there ItemSend will not process the second email. This logic should assure correct ordering and no recursion problems.
    Friday, December 25, 2015 6:03 PM