Extract primary SMTP address from exchange account using Redemption in Outlook - c#

Is there a way to get the primary SMTP address from an exchange account in Outlook ? I am currently using Redemption and following code keeps returning an empty value.
> IRDOExchangeAccount exAcc = (IRDOExchangeAccount)rdoAcc;
> string email = exchangeAccount.CurrentUser.SMTPAddress;
Currently I am using
exchangeAccount.CurrentUser.Address
property to get the Email and seems it gets me the correct Email address. How reliable that property is ? Is there another better way ?

Related

Reliable way of getting sender's email address using Redemption

I have been getting the sender's email address in Outlook using the RDOMail.SenderEmailAddress property, but I have recently realised that under some cases for SMTP or IMAP email accounts, that this property is null occasionally, right after the email arrives the inbox.
There's a rather convoluted way to get the sender's email address using the Outlook Interop Library: https://msdn.microsoft.com/library/office/ff184624.aspx
However, this does not work with the Redemption RDOMail object because the RDOAddressEntry interface lacks the AddressEntryUserType and the GetExchangeUser method.
The documentation of the RDOAddressEntry object says the following about the SMTPAddress property:
String, read-only. Returns the SMTP address of the given user. If the
address type is "SMTP", the returned value is the same as that
returned by the Address property. If the address type is "EX",
Redemption tries to retrieve the PR_SMTP_ADDRESS property, if
unsuccessful, it retrieves the default SMTP address from the
PR_EMS_AB_PROXY_ADDRESSES Extended MAPI property.
Looks like it might be a more reliable way to get the sender's address if I do this in my method:
if (rdoMail.SenderEmailAddress != null) return rdoMail.SenderEmailAddress;
if (rdoMail.Sender != null) return rdoMail.Sender.SMTPAddress;
return null;
Since I don't have a reliable way to test my theory, I'm seeking help here to see if anyone has more experience in dealing with this problem.
Thanks in advance.
I cannot image why SenderEmailAddress would be null, unless you have a partially downloaded item (IMAP4 specific). There is no reason to have AddressEntryUserType or GetExchangeUser method - all you need is the address type - if it is "EX", you have a GAL user, otherwise an SMTP address.
To get the sender SMTP address, check the SenderEmailType property. If it is anything but "EX", just use the SenderEmailAddress property. If it is "EX", read the PidTagSenderSmtpAddress property using RDOMail.Fields["http://schemas.microsoft.com/mapi/proptag/0x5D01001F"]. If you get back null, check if RDOMail.Sender is not null and read the RDOMail.Sender.SMTPAddress property.

User Email Address Operations using Active Directory Graph API

I'm currently using the Microsoft.Azure.ActiveDirectory.GraphClient in a C# Cloud Service application that manages user provisioning and updates to users in Office 365 based on information stored in a database.
The issue I am facing is the setting of a user's mail address. On provisioning of a new user, setting the mail address property of the new user object causes an error to be thrown by the Graph Client. When provisioning a new user, the primary SMTP address is automatically set to the be the UPN for the user. The following code will successfully create a new user and set the primary SMTP address to be the same as the value set for the UserPrincipalName:
IUser newUser = new User();
newUser.DisplayName = "Firstname Surname";
newUser.UserPrincipalName = "someone#somewhere.com";
newUser.AccountEnabled = true;
newUser.MailNickname = "firstnamesurname";
newUser.ImmutableId = "0k3otwAAEkm8vGSKbJqRZg==";
newUser.PasswordProfile = new PasswordProfile
{
Password = "somerandompassword",
ForceChangePasswordNextLogin = true
};
newUser.UsageLocation = "GB";
_activeDirectoryClient.Users.AddUserAsync(newUser).Wait();
Fair enough - having UPN and primary email address mis-matches can cause AutoDiscover issues.
The problem I have is that the "mail" property of the user object also throws an error when set when updating a user.
The following code will successfully update a user:
User retrievedUser = new User();
List<IUser> retrievedUsers = null;
retrievedUsers = _activeDirectoryClient.Users
.Where(searchUser => searchUser.ImmutableId.Equals(0k3otwAAEkm8vGSKbJqRZg==))
.ExecuteAsync().Result.CurrentPage.ToList();
if (retrievedUsers != null && retrievedUsers.Count == 1)
{
retrievedUser = (User)retrievedUsers.First();
retrievedUser.UserPrincipalName = "someone1#somewhere.com";
retrievedUser.UpdateAsync().Wait();
}
The above code will change the user's UPN, but not update the primary SMTP address as in the add a new user scenario. This I do not understand, as it can then cause AutoDiscover issues (as the UPN is different to the primary SMTP address) and negate any reason for not being able to set the mail address when creating a new user.
I cannot find any details on how to update a user's email address, or set an additional email address as the primary SMTP address. Scenarios for this requirement are such as when a user gets married and they want to have a new email address as their primary email address.
Does anyone have any info please on how to manage a user's primary SMTP address using Microsoft.Azure.ActiveDirectory.GraphClient? I can find information on setting additional email addresses, but not on how to change the primary SMTP address.
Grateful for any help please!
From testing this myself, an update to the userPrincipalName through the AzureAD Graph API automatically updates the following properties:
mail
userPrincipalName
proxyAddresses
With the proxyAddresses property being updated to include the new userPrincipalName as the new primary SMTP address, and the old primary address is preserved but no longer the primary address. This is also reflected in Exchange Online. The proxyAddress which is prefixed with SMTP: (uppercase) is the PrimarySmtpAddress.
As an edge case, this process does not happen if the previous primary address is not the same as the previous UPN. If the UPN and PrimarySmtpAddress do not match, then when the UPN is updated through the AzureAD Graph API then the new UPN will be added as a non-primary address, and the original primary address will remain the primary address.
As far as I know, this behavior is undocumented. However, something similar is documented here: https://support.microsoft.com/en-us/help/3190357/how-the-proxyaddresses-attribute-is-populated-in-azure-ad. It seems the priority of which property determines the PrimarySmtpAddress goes mail > UPN > mailNickName.
In general, I don't think it's a good idea to directly manipulate proxyAddresses because Exchange/AD already do a lot of this for you.
Following a random thought, I've figured out how to change the primary email address for a user in the above scenario. This is done by setting the primary email address in the proxy address list for the user, denoting the primary address with the prefix of "SMTP:" (note it has to be in CAPS):
retrievedUser.ProxyAddresses = new List<string>
{
"SMTP: someone1#somewhere.com"
};
Hope this helps someone else!

Internal addresses are missing after MSG to EML conversion using Redemption

I am currently evaluating the redemption library for converting MSG files to EML files.
RDOSession session = new RDOSession();
RDOMail msg = session.GetMessageFromMsgFile(msgFile);
msg.SaveAs(emlFile, rdoSaveAsType.olRFC822);
So far Redemption is doing a really good job here in contrast to everything else I've tested against our "wild MSG-files corpus".
Nevertheless there is an issue with internal e-mail addresses. For internal e-mail addresses the resulting EML-file does contain the personal part of the addresses only but not the real e-mail address with the # sign.
I can see that RDOMail's recipient objects contains the real e-mail address in the SMTPAddress property in any case.
But there is a difference for the Address property which contains the "real e-mail address" for external addresses but something like /O=EXAMPLE ORGANIZAION/OU=SOME GROUP/cn=Recipients/cn=FBarney for internal addresses.
The latter ones are exactly the addresses that are missing the real e-mail address in the resulting EML-file.
So I tried to override the Address property like that:
recipient.Address = recipient.SMTPAddress;
But this does not have any effect on the resulting EML-file at the end.
How to convert MSG to EML with redemption without losing the real e-mail addresses for internal addresses?
This is an indication that EX type addresses cannot be converted to SMTP. This usually happens if the current MAPI session does not have access to the Exchange server that hosts these GAL objects. In your particular case, there is no MAPI session at all. You can either set the RDOSession.MAPIOBJECT property to Namespace.MAPIOBJECT from the Outlook Object Model to share the session with Outlook or you can call RDOSession.Logon/LogonExchangeMailbox/etc.
You can also try to specify the olRfc822_Redemption format to force Redemption to use its internal MIME convertor (it jumps through quite a few hoops to get the SMTP addresses from the message itself rather than GAL). By default olRfc822 uses the built-in Outlook convertor (IConvertorSession) if Outlook is installed.

Forward RDOMail from original mail address by using Outlook Redemption

I'm currently developing an application that handles mail for mailboxes automatically. We use the tool Outlook Redemption and connect with one service account to multiple Exchange mailboxes.
Case
The problem we face is forwarding mail from the original mailbox. Say service account 'A' is handling shared mailbox 'B' and is forwarding mail. I'd like the sender to be the mail address of 'B', but when I receive the mail the mail address of 'A' shows up as sender.
Source code
// Initialize the session with the service account.
_session = new RDOSession();
_session.LogonExchangeMailbox(configurationSettings.MailAddress, configurationSettings.Url);
// Connect to the target mailbox and retrieve mail message.
RDOStore store = _session.Stores.GetSharedMailbox(targetMailBox);
RDOMail originalMailItem = store.GetMessageFromID(entryId);
// Creates a forwarded version of the mail.
RDOMail forwardMailItem = originalMailItem.Forward();
// Set sender to target mailbox owner.
if (store is RDOExchangeMailboxStore)
{
forwardMailItem.Sender = ((RDOExchangeMailboxStore)store).Owner;
forwardMailItem.SenderEmailAddress = targetMailBox;
}
// Set recipient and send.
forwardMailItem.Recipients.Clear();
forwardMailItem.Recipients.Add(forwardMailAddress);
forwardMailItem.Send();
Questions
Anyone got a clue on a solution?
If this won't work, is it possible to get the mail address of 'B' in the 'On behalf of' rule?
Thanks in advance!!
The problem is that the message being forwarded is created in the primary store in the profile, not the delegate mailbox.
Besides setting the Sender property, have you tried to also set the SentOnBehalfOf property?

How to get universal outlook mailitem ConversationID for one email chain replied from different users

I am developing an OUTLOOK 2010 addin in C#. This addin will create activities based on conversation.
For example, one user create new email, others reply,forward or CC, treat this email chain as one converstaion thread. Thoes emails have the same mailItem.ConversationID.
Based on this conversationID, my program generated an activty, and link conversationid to the activity which can be seen in each email in this email chain.
It all works fine on my machine (I reply,forward,cc in the same email chain, it get the same conversationID). However when other user reply email trigger my program generate activities, it generated different ConverstationID (the same email chain).
My question is:
1.ConversationID works only in local? Like for the same email Chain in different user's machine, the conversationID is different?
2.Is there universal mailitem conversationID for one email chain as long as user is using the same version of OUTLOOK?
var mailItem = this.OutlookItem as OutlookNS.MailItem;
if (mailItem.ConversationID != null )
{
OutlookHelper.Conversation_Index = mailItem.ConversationIndex;
OutlookHelper.Conversation_Topic = mailItem.ConversationTopic;
OutlookHelper.Current_ConversationID = mailItem.ConversationID;
CreateActivity(mailItem.ConversationTopic,mailItem.ConversationID);
}
I already tried EntryID, this attribute is keep changing.
I figured it out myself.
All the email in the same email chain has the same first 44 character of ConversationIndex. Everytime when a new replyer reply this email, the ConversationIndex will append a new ramdon generated 44 characters string. It is a universal identity applied for user using differet machine. But when the subject of this email is changed, a brand new 44 charaters ConversationIndex will be generated. ConversationID only works in local to track emails in the same email chain

Categories

Resources