Outlook MailItem: How to distinguish whether mail is incoming or outgoing?
Asked Answered
S

10

17

I am writing VSTO Outlook addin in C#, and I need to distinguish, whether given MailItem is incoming or outgoing (or neither, when it is for example a draft).

Is there some foolproof way to do this? Best solution I have now would be getting a list of recipients, cc's, and bcc's, loading email adresses from active accounts, and checking if those two lists intersect, but this seems quite fragile to me, and I hope that there is a better solution.

Use case: I'd like to get a relevant date for an email, which could be either ReceivedTime, or SentOn, but to know which one I should use, I beed to know whether a mail was sent or received.

Thank you for ideas :)

Stupefy answered 17/8, 2009 at 0:12 Comment(2)
Do you have to check all of the recipients, cc's, etc or can you just look at the sender? If the account owner didn't send it, then it's incoming.Bandeau
Hasn't every received mail also been sent?Giselegisella
S
24

Came to this page because I was having same issue in VBA. Checking the parent folders is cumbersome, as a message can be held either several folders deep (and therefore you have to iterate up several folders) or the user may have changed the folder. An extreme example: the deleted items folder contains both incoming and outgoing mail items.

I have chosen a similar solution to another person (Adi Kini) above where I check the ReceivedByName (I think he chose ReceivedEntryID). The ReceivedByName property is always Null ("") for a sent message, wherever it currently lays. This method can find a sent item that has been dragged to the inbox!. It seems a fairly reliable method of checking.

It seems odd that such an apparently straightforward thing as checking whether mail is incoming or outgoing can trip us up!

Swane answered 19/7, 2011 at 15:39 Comment(1)
Note that neither ReceivedByName nor ReceivedEntryID will have a value if the mail item was received by a public folder that has an address assigned.Wriggle
C
2

I came here with the same problem. Since I will explicitly suggest that user moves the mail to some folder in my usecase, checking Parent would not help...

Regarding MailItem.Sent: are you sure that MailItem.Sent works this way? I just wrote a simple code to run through both my Inbox and SentItems and for almost all of them Sent is true. I assume this is really just an indication whether the mail has been sent (= is not draft)...

Christiachristian answered 3/3, 2010 at 10:57 Comment(0)
F
2

I resolved this problem by adding a new UserProperty after e-mail was sent. So when I need to check if e-mail was sent I check this property. This works even if e-mail was moved out of Sent folder. Of course, this works only for newly created e-mails, but you may add this property to all e-mails in Sent folder during first start. The only bug is that UserProperties are printed by default, but this can be overridden.

Fetus answered 27/1, 2011 at 14:55 Comment(1)
This is a pretty heavyweight solution, but probably only one here that could work. However, the add-in would have to run all the time - otherwise we'd get an unmarked received e-mails - and on first start. we wouldn't be able to mark sent e-mails that have been moved to other folder. Maybe it would be possible to scan through all mail and see if recipient is one of user's e-mail addresses, but this could take hours on a large exchange/IMAP account...Certiorari
L
2

This is how I check mail type and it works even if mail is moved to any folder. This solution uses PROPERTY ACCESSOR which is available in outlook 2007. Below is the code

string PR_MAIL_HEADER_TAG = "http://schemas.microsoft.com/mapi/proptag/0x007D001E";

Outlook.PropertyAccessor oPropAccessor = mItemProp.PropertyAccessor;

string strHeader = (string)oPropAccessor.GetProperty(PR_MAIL_HEADER_TAG);

if (strHeader == "")
{
    // MAIL IS OF TYPE SENTBOX
}
else
{
   // MAIL IS OF TYPE INBOX
}
Landry answered 22/4, 2011 at 17:58 Comment(1)
works with exchange mail accounts but not with imap/smtp - tested with ol 2016Nicolle
C
1

MailItem.sent is true for incoming too.

How about checking MailItem.ReceivedByEntryID. But i am sure this will fail (ReceivedByEntryID will be null for mails in inbox) if you say import from outlook express or maybe some other email program

Iterating thru mail accounts/senderemail may help as you said, but its not fool proof (like if you rename the email address)

Cestoid answered 6/5, 2010 at 6:25 Comment(1)
Thanks! This might work for most users, as I don't think many enterprise users would have their e-mails imported from Outlook Expres (and even if they did, most of the useful operations would still only involve recent mails which would be received by Outlook).Certiorari
B
0

Take a look at the MailItem's .Parent property - examine the folder properties to determine if it is the inbox, outbox, drafts, sent items, etc.

Bandeau answered 17/8, 2009 at 0:34 Comment(2)
But what if user (or mail filter rules) already moved mail to some generic folder (for example, folder for project XYZ) with both incoming and outgoing emails? In that case, incoming/outgoing would be a property specific to email, not to folder. Nice idea though, this didn't occur to me :).Certiorari
That's a very good question. I don't have a god answer for that one.Bandeau
H
0

You can check if it's inside the Outlook.OlDefaultFolders.olFolderInbox or olFolderOutbox, then there should be other methods you can use to check if it's inside either of these folders!

Outlook.Application _application = new Outlook.Application();
Outlook.MAPIFolder folder = _application.GetNamespace("MAPI").GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox);
Hyperpituitarism answered 20/7, 2010 at 11:37 Comment(1)
I think that this wouldn't work on sent/received mails that have been moved to another folder (for example with a filter) - would it?Certiorari
R
0

For a simple sended/received control by SMTP address, i suggest an address-check approach. It can be done in this way:

'Get mail address sender
        Dim mailSender As String = GetSenderSMTPAddress(outMailItem)

'Get current user mail address
        Dim mailUser As String = OutlookMail2DocScriba.GetUserSMTPAddress(oNameSpace.CurrentUser.AddressEntry)

        'If sender and current user matches is a sended mail, otherwise received
        If String.Compare(mailSender, mailUser, True) = 0 Then
            Return "Sended"
        Else
            Return "Received"
        End If





    Public Shared Function GetSenderSMTPAddress(ByVal mail As Outlook.MailItem) As String
            'http://msdn.microsoft.com/en-us/library/microsoft.office.interop.outlook.oladdresslisttype.aspx

            If mail Is Nothing Then
                Throw New ArgumentNullException()
            End If
            If mail.SenderEmailType = "EX" Then
                Dim sender As Outlook.AddressEntry = Nothing

                Try
                    sender = mail.Sender
                Catch ex As Exception
                    'Se non è stato in grado di reperire il sender (Outlook 2007), 
                    'ignoro l'eccezione e procedo.
                End Try

                If sender IsNot Nothing Then
                    Return GetUserSMTPAddress(sender)
                Else
                    Return Nothing
                End If
            Else
                Return mail.SenderEmailAddress
            End If
        End Function

        Public Shared Function GetUserSMTPAddress(ByVal sender As Outlook.AddressEntry) As String
            'Now we have an AddressEntry representing the Sender
            'http://msdn.microsoft.com/en-us/library/office/ff868214(v=office.15).aspx
            Const EXCHANGE_USER_ADDRESS_ENTRY As Int32 = 0
            Const EXCHANGE_REMOTE_USER_ADDRESS_ENTRY As Int32 = 5
            Dim PR_SMTP_ADDRESS As String = "http://schemas.microsoft.com/mapi/proptag/0x39FE001E"

            If sender.AddressEntryUserType = EXCHANGE_USER_ADDRESS_ENTRY OrElse _
               sender.AddressEntryUserType = EXCHANGE_REMOTE_USER_ADDRESS_ENTRY Then
                'Use the ExchangeUser object PrimarySMTPAddress
                Dim exchUser As Object = sender.GetExchangeUser()
                If exchUser IsNot Nothing Then
                    Return exchUser.PrimarySmtpAddress
                Else
                    Return Nothing
                End If
            Else
                Return TryCast(sender.PropertyAccessor.GetProperty(PR_SMTP_ADDRESS), String)
            End If
        End Function
Resonator answered 19/11, 2014 at 10:12 Comment(0)
N
0

I contradict SenderName vs CurrentUser, to distinguish between emails in inbox or sent folder.

enter image description here

Nickeliferous answered 29/6, 2021 at 8:46 Comment(1)
That won't work if you have multiple accounts in the profile - I, for example, have at several POP3/SMTP accounts delivering to an Exchange mailbox.Parve
S
-5

Did you try MailItem.Sent property?

Its true for incoming, and false for outgoing.

Secondclass answered 22/2, 2010 at 12:37 Comment(1)
Nope - see David's answer #1286213Certiorari

© 2022 - 2024 — McMap. All rights reserved.