Managed EWS - Reply Post with alternative From property - exchange-server

In managed Exchange Web Services there is a class PostItem, which can be instantiate with ExchangeService object.
But after assigning all properties including with InReplyId and From, and calling Save(folderId) method:
PostItem newPost = new PostItem(mService);
newPost.InReplyTo = originalPost.Id.UniqueId;
newPost.From = new EmailAddress( "Max Gontar", "mgontar#server.com" );
newPost.Subject = msg.Subj;
newPost.Body = msg.TextBody;
newPost.Save(mCurrentFolderId);
It still creates a separate Post, not a Reply Post:
Other way I have tried:
PostReply reply = originalPost.CreatePostReply();
reply.Subject = msg.Subj;
reply.Body = msg.TextBody;
reply.Save( currentFolder.Id )
There is no way to set From property, so it should create Post Reply with current credentials Contact email address. But it gives null there!
Can you help me?
Thank you!

Im just learning about this api but this code may work:
newpost.Update(ConflictResolutionMode.AutoResolve)

Related

Can't send custom Slack Message with version 3 of Bot Connector

I have a bot that replies with a message consisting only of attachments. When it works on Slack, it uses Slack attachment formatting quite heavily, thus I have to use ChannelData property.
In version 1 of BotConnector, the code was like this
var reply = message.CreateReplyMessage();
reply.Attachments = new List<Attachment>();
var attachments = new List<object>(); //Slack-formatted attachments
//filling attachments...
reply.ChannelData = new {attachments};
and it worked. Now, in version 3 code has changed to
var reply = activity.CreateReply();
reply.Attachments = new List<Attachment>();
var attachments = new List<object>(); //Slack-formatted attachments
//filling attachments...
reply.ChannelData = new {attachments};
var connector = new ConnectorClient(new Uri(activity.ServiceUrl));
await connector.Conversations.ReplyToActivityAsync(reply);
which, basically, boils down to using different method to create reply, and another one to send the reply back.
Now, the problem is, that I don't get the reply back to Slack. Diagnostics in AppInsight show me that somewhere in Connector something like this happens:
Exception type: System.ArgumentNullException
Failed method: SlackChannel.SlackMapper+d__5.MoveNext
Exception Message: value cannot be null. Parameter name: source
ChannelData: {}
message: Invalid ChannelData
Please note that ChannelData in this diagnostics seems to be empty. So what I gather from all this is that something has changed in the way BotConnector processes ChannelData. How can I find out what exactly am I doing wrong?
Actually the problem is inside the ConnectorClient client, which strips channelData. The reason for that lies in its serialization settings which use ReadOnlyJsonContractResolver, which skips all read-only properties - and of course all the properties in anonymous class are read-only.
Knowing that, the solution is quite simple:
reply.ChannelData = JObject.FromObject(new {attachments});
Note the explicit use of JObject instead of anonymous class.

How do I get the displayname of the logged in user in EWS?

Exchange Autodiscovery will give me the user's Display Name via the UserSettingName.UserDisplayName property.
However, in cases where autodiscovery fails and connection needs to be done manually I can't figure out how to get the DisplayName.
I tried this, but I just get the users' email address:
_service = new ExchangeService();
_service.Credentials = new System.Net.NetworkCredential(exchangeSettings.EmailAddress, exchangeSettings.Password);
_service.Url = new Uri(exchangeSettings.ExternalEwsUrl);
NameResolutionCollection resolvedNames = _service.ResolveName(exchangeSettings.EmailAddress);
exchangeSettings.UserDisplayName = resolvedNames.First().Mailbox.Name;
Thanks
If you are going to use ResolveName and you want the displayName then you should use the overload to specify that the operation should return the AD contact information. Then you can just use the DisplayName property.
NameResolutionCollection ncCol =
service.ResolveName("user#domain.com",ResolveNameSearchLocation.DirectoryOnly,true);
Console.WriteLine(ncCol[0].Contact.DisplayName);

Forward email using EWS managed api keeping the headers

I am looking for a sample code on how to forward an existing email message (one that is already in my inbox) using the managed api.
When forwarded is there some way to keep a message original headers while forwarding it?
for example someone sent an email to me -i would like that ews will forward it to another recipient without changing the headers (original receive time from ,bcc etc...).
Given an EmailMessage object, you can just call the CreateForwareMessage() method:
var forwareMessage = item.CreateForward();
Regarding the other question: Get the MIME content of the mail and attach it to a new message:
item.Load(new PropertySet(BasePropertySet.IdOnly, ItemSchema.MimeContent));
var mail = new EmailMessage(service);
var attachment = mail.Attachments.AddFileAttachment("Original message.eml", item.MimeContent.Content);
attachment.ContentType = string.Format("message/rfc822; charset={0}", item.MimeContent.CharacterSet);
mail.ToRecipients.Add("hkrause#infinitec.de");
mail.Subject = "testmail";
mail.SendAndSaveCopy();
EDIT:
Create forward message and set reply to header:
var fw = item.CreateForward();
var fwMsg = fw.Save(WellKnownFolderName.Drafts);
fwMsg.ReplyTo.Add("personA#company.com");
fwMsg.SendAndSaveCopy();

Exchange Web Services (EWS) API "To" header for alias

I have an inbox set up in exchange, hello#mycompany.com
Additionally, there is an alias for this, news#mycompany.com, so all emails to the news address end up in the hello inbox.
Ideally, I want to be able to tell which alias an email has been sent to, using EWS.
When I send an email to news#mycompany.com, and examine the Internet headers of the message using Microsoft Outlook, the To: header reads To: Hello <news#mycompany.com> which is exactly what I want to see.
However, using EWS, when I look at the ToRecipients property of the message, the reported email address is always that of the primary SMTP address. Also the InternetMessageHeaders property of the Webservices.Data.Item does not contain the To: property. I also can't seem to see the correct address using EWSEditor to examine all the properties of the message.
The answer to this forum post seems to suggest that,
...The Information about the actual email address a message is sent to is stored in the recipients collection which you can't access (outside of exportmessage) in EWS...
How would I go about doing this programatically so I can find the correct To: address?
This works for me:
private static string GetToAddress()
{
ExchangeService exService = new ExchangeService();
exService.Credentials = new NetworkCredential("username", "password", "domain");
exService.Url = new Uri("https://youraddress/EWS/Exchange.asmx");
ExtendedPropertyDefinition PR_TRANSPORT_MESSAGE_HEADERS = new ExtendedPropertyDefinition(0x007D,MapiPropertyType.String);
PropertySet psPropSet = new PropertySet(BasePropertySet.FirstClassProperties)
{PR_TRANSPORT_MESSAGE_HEADERS, ItemSchema.MimeContent};
FindItemsResults<Item> fiResults = exService.FindItems(WellKnownFolderName.Inbox, new ItemView(1));
foreach (Item itItem in fiResults.Items)
{
itItem.Load(psPropSet);
Object valHeaders;
if (itItem.TryGetProperty(PR_TRANSPORT_MESSAGE_HEADERS, out valHeaders))
{
Regex regex = new Regex(#"To:.*<(.+)>");
Match match = regex.Match(valHeaders.ToString());
if (match.Groups.Count == 2)
return match.Groups[1].Value;
}
return ToAddress;
}
return "Cannot find ToAddress";
}
The code is from:
http://social.technet.microsoft.com/Forums/en-au/exchangesvrdevelopment/thread/1e5bbde0-218e-466e-afcc-cb60bc2ba692

Using Redemption to reply to a mail only intermittently sets the body text

I'm using the below method to reply to mails coming in to a business function mailbox.
The body text being added is only intermittently being set. This method is only called when someone has emailed in to unsubscribe from a mailing but the email address of the sender (or in the body) hasn't been found in the database and we want to ask them to send us the mail address they want to unsubscribe.
private void replyToMail(OutlookItem item)
{
RDOSession session = new RDOSession();
session.Logon(null, null, null, true, null, null);
RDOMail thisItem = session.GetMessageFromID(item.EntryID, item.StoreID, null);
RDOMail reply = thisItem.Reply();
RDOAddressEntry optingout = session.AddressBook.GAL.ResolveName("optingout");
//reply.Sender = optingout; this had no effect
reply.SentOnBehalfOf = optingout;
reply.Subject = "Automated Response - Could not complete unsubscribe";
reply.Body = "This is an automated response from the Newsletter unsubscribe system. We couldn't find "+item.Sender+" in our database to unsubscribe you from our mailings.\r\n\r\nPlease reply to this mail and include the email address you want to unsubscribe.\r\n\r\nKind Regards\r\n.";
reply.Send();
session.Logoff();
}
Firstly, if you are already usign OOM, there is no reason to call RDOSession.Logon. You can simply ste the MAPIOBJECT property:
Replace the line session.Logon() with
session.MAPIOBJECT = item.Application.Session.MAPIOBJECT
do not call Logoff.
Secondly, do yo umean the message is received with out a body? Do you see teh empty bofy in the Sent Items folder?
I had to edit thingie.HTMLBody as well as thingie.Body.
I suppose I could have figured out how to tell when to set the value of each one but since I just want to be sure that I have control of the body in this instance I'm simply setting both.

Resources