Reputation: 4833
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 :)
Upvotes: 17
Views: 14074
Reputation: 1
I contradict SenderName vs CurrentUser, to distinguish between emails in inbox or sent folder.
Upvotes: 0
Reputation: 544
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
Upvotes: 0
Reputation: 241
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!
Upvotes: 24
Reputation: 831
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
}
Upvotes: 2
Reputation: 41
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.
Upvotes: 2
Reputation: 9785
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);
Upvotes: 0
Reputation: 104
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)
Upvotes: 1
Reputation:
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)...
Upvotes: 2
Reputation: 213
Did you try MailItem.Sent property?
Its true for incoming, and false for outgoing.
Upvotes: -5
Reputation: 2716
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.
Upvotes: 0