0

In my Outlook Addin, I need to know if the Sender email adddress in the From field is a type of shared mailbox email address before allowing the email to be sent out. Currently, I'm checking that if the sender address doesn't exist in one of the current sessions' accounts' email address, I would assume it as a shared mailbox email address because it is not possible for a person to login to Outlook using a shared mailbox email address.

However, this logic is flawed because non-shared mailbox email address can also be set in the From field (Correct me if I'm wrong).

Here is my code:

    public bool isSharedMailboxAccount(Microsoft.Office.Interop.Outlook.MailItem mail)
    {
        string fromEmail = mail.Sender.PropertyAccessor.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x39FE001E").ToString();
        bool isShared = true;

        foreach (Microsoft.Office.Interop.Outlook.Account acc in mail.Session.Accounts)
        {
            if (acc.SmtpAddress == fromEmail)
            {
                isShared = false;
                break;
            }
        }
        return isShared;
    }

Is there a better way to determine whether the Sender email address in the From field is a shared mailbox email address or not?

John Evans Solachuk
  • 1,953
  • 5
  • 31
  • 67
  • "Shared" in a sense "another Exchange account"? – Dmitry Streblechenko Nov 01 '21 at 00:55
  • @DmitryStreblechenko I'm actually not really sure if it's another account. I was referring to a shared mailbox that was set up according to this https://support.microsoft.com/en-us/office/open-and-use-a-shared-mailbox-in-outlook-d94a8e9e-21f1-4240-808b-de9c9c088afd. The shared mailbox address would be something like `support@contoso.com` and essentially, I want my Outlook AddIn to recognize that this address is a shared mailbox address. – John Evans Solachuk Nov 01 '21 at 04:15
  • You can check autodiscover XML to see if it is listed there for the current user. Otherwise it looks just like a regular mailbox. – Dmitry Streblechenko Nov 01 '21 at 15:13
  • @DmitryStreblechenko Thnx to your suggestion, I found it at `C:\Users\%username%\AppData\Local\Microsoft\Outlook` and it seems Shared mailbox emails are listed under `Autodiscover/Response/Account/AlternativeMailbox` element's `SmtpAddress` or `OwnerSmtpAddress` element. Also, its `Type` element gives the value `Delegate` so I think I can do something like make my plugin check this XML file for list of `AlternativeMailbox` elements that has `Type` value of `Delegate` and compare its `SmtpAddress` value with Sender's email to determine whether Sender's email is a shared email or not. – John Evans Solachuk Nov 03 '21 at 06:26
  • @DmitryStreblechenko Do you foresee any potential issue with this solution? e.g. whether this local XML file will always be accurate, reliable or available for any version of Outlook 2007 and above? – John Evans Solachuk Nov 03 '21 at 06:30
  • @DmitryStreblechenko Also, I noticed your answer at https://stackoverflow.com/a/35753512/3526156 may also be a solution. I was thinking of something like scanning available mailboxes in Outlook at startup or when new account is added and read each of its `PR_MDB_PROVIDER` value. The ones that has `pbExchangeProviderDelegateGuid` as its value shall have its mailboxes' email addresses saved somewhere as a shared email address. Do you think this 2nd method could also be a viable solution? – John Evans Solachuk Nov 03 '21 at 06:38
  • Autodiscover XML is available through the `Namespace.AutoDiscoverXml` property as well as `Account.AutoDiscoverXml`. I am not sure what you are trying to achieve? Figure out if a message is from another Exchange mailbox in the same org? Or that the sender's mailbox is open in the current user's profile in Outlook? – Dmitry Streblechenko Nov 03 '21 at 16:16
  • @DmitryStreblechenko I'm trying to figure out if a Sender (who is a member of a shared mailbox) is sending an email using their shared mailbox's email address so that my plugin can intercept the email before it is sent to Outlook's Outbox in order to do some quick verification and modification on it. My plugin is only interested in intercepting emails from a shared mailbox email address. – John Evans Solachuk Nov 04 '21 at 04:19
  • So, in other words, you are trying to figure out if the sender is different from the current user? – Dmitry Streblechenko Nov 04 '21 at 16:22
  • @DmitryStreblechenko Yes, but I want to specifically target shared mailbox email addresses. Correct me if I'm wrong, I believe if I just check that the sender is different from the current user, it would also include non-shared mailbox email addresses e.g. a group email address or distribution lists, right? Which is not what I would like. – John Evans Solachuk Nov 05 '21 at 00:38
  • OK, so you'd need to compare the sender with the shared mailbox owner / address. – Dmitry Streblechenko Nov 05 '21 at 03:13
  • @DmitryStreblechenko Yes. I will check if Autodiscover XML have this info (shared mailbox owner/address). Else, I'm thinking of scanning available mailboxes' store's `PR_MDB_PROVIDER` property for the `pbExchangeProviderDelegateGuid` value to get this info. – John Evans Solachuk Nov 05 '21 at 04:18
  • @DmitryStreblechenko You are right, there seems to be nodes called `AlternativeMailbox` that lists the shared mailbox address of the account. I have posted my answer. Let me know if there are any potential issues with it if possible. Thanks! – John Evans Solachuk Nov 08 '21 at 07:15

1 Answers1

0

Thanks to @DmitryStreblechenko who gave me the idea to look into AutoDiscoverXml in the comments . Indeed, in AutoDiscoverXml, there are nodes called AlternativeMailbox which seems to indicate the list of shared mailboxes that the account user is a part of. Querying this XML nodes will allow us to extract the email address of the shared mailbox from two child nodes called SmtpAddress and OwnerSmtpAddress.

I'm not sure about the difference between those two but in this case, I'm using SmtpAddress.

public bool isSharedMailboxAccount(Microsoft.Office.Interop.Outlook.MailItem mail)
{
    string fromEmail = mail.Sender.PropertyAccessor.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x39FE001E").ToString();
    bool isShared = false;

    foreach (Microsoft.Office.Interop.Outlook.Account acc in mail.Session.Accounts)
    {
        //using XMLDocument to query AutoDiscoverXML value
        XmlDocument xml = new XmlDocument();
        xml.LoadXml(account.autoDiscoverXml);
        
        XmlNodeList alts = xml.GetElementsByTagName("AlternativeMailbox");
        foreach (XmlNode alt in alts)
        {
            //NOTE: I'm not entirely sure that alt mailboxes that has Type == Delegate will always mean shared mailbox but so far in my tests, it seems to be so.
            if(alt.ChildNodes.OfType<XmlElement>().Where(e => e.LocalName == "Type").First().InnerText.Equals("Delegate"))
            {
                if(alt.ChildNodes.OfType<XmlElement>().Where(e => e.LocalName == "SmtpAddress").First().InnerText.Equals(fromEmail))
                {
                    isShared = true;
                    break;
                }
            }
        }
        
        if(isShared)
        {
            break;
        }
    }
    return isShared;
}
John Evans Solachuk
  • 1,953
  • 5
  • 31
  • 67
  • Thanks for the great solution. Small typo : account.autoDiscoverXml => xml.LoadXml(acc.AutoDiscoverXml); I wish it also works when changing from a mail to an appointment item but it seems that the autodiscover does not return the AlternativeMailbox node :-/ – Salim Jun 25 '22 at 04:18