EWS - Send Email With ConversationId (Not Reply) - c#

I have a conversation going on between the user I'm logged in as on EWS, and some other user. I know the conversation Id. I want to send the other person a message that is a part of the same conversation. I want to make sure that the message has the same conversation Id. But, this is not a reply. I want to send a new email that is a part of the same conversation. How do I do this in c#? The ConversationId property of EmailMessage is read only.
This article is of no help:
https://msdn.microsoft.com/en-us/library/office/dn610351(v=exchg.150).aspx
Alternatively, I can actually get the latest email from the conversation from the server and reply using that with this code:
var latestConversationNode = _ExchangeService.GetConversationItems(conversationId, new PropertySet { ItemSchema.Id, ItemSchema.ConversationId }, null, null, ConversationSortOrder.DateOrderDescending).ConversationNodes.FirstOrDefault();
if (latestConversationNode != null)
{
var latestEmailInConversation = latestConversationNode.Items.FirstOrDefault() as EmailMessage;
if (latestEmailInConversation != null)
{
var replyMessage = latestEmailInConversation.CreateReply(false);
replyMessage.Body = body;
replyMessage.Subject = subject;
foreach (var toRecipient in toRecipients)
{
replyMessage.ToRecipients.Add(toRecipient);
}
replyMessage.SendAndSaveCopy();
return;
}
}
This works sometimes, but for some reason, sometimes the reply doesn't appear as a reply in my inbox. I.e. my mail client doesn't recognize it as being a part of the same conversation.
I guess that what is happening is that the last email received on the server is not actually from the email address that I am sending to, and therefore either Exchange or my mail client don't realise that it's part of the same conversation even though the conversation Id is the same.

What do you want to accomplish with this? And what do you mean with "not a reply". Is it a forward, a new message or something else?
From my understanding, messages must not only have the same conversationId to be in the same conversation, but also have the same conversationTopic and a plausible conversationIndex (which is something like the conversationId concatenated with the timestamps of the mail-reply-history).
If your mails get lost, you could take a look for inconsistencies in these two attributes.
Hope that helps.

Related

Send email with SendGrid API using Office365 email account A which is set to send on behalf of an email account B

I am facing an issue with SendGrid API.
I have added a single user related to an Office365 email account, let's say a#tony.gr. This account has been configured to send on behalf of an other email account, let's say b#tony.gr.
I tried to implement a simple console application in C#, which sends an email message to a recipient from b#tony.gr.
var from = new EmailAddress("b#tony.gr", "B Account");
var subject = "Test";
var to = new EmailAddress("foo#foo.com", "Recipient");
var plainTextContent = "Hello world !!";
var msg = MailHelper.CreateSingleEmail(from, to, subject, plainTextContent, null);
var response = await client.SendEmailAsync(msg);
When I execute the above code even if I do not get any error the mail is not sent.
However, when I set as "from" account the email account a#tony.gr the email is sent. I imagine that I have to include the added single user a#tony.gr in my code, but I don't know how.
Any help would be appreciated.
Thank you in advanced.
When you say you have "added a single user" I assume you mean you have verified that email address as a single sender.
SendGrid has no concept of Office365's configuration and the ability for a#tony.gr to be able to send a message on behalf of b#tony.gr. Your Office365 settings have no effect on how SendGrid works.
If you want to send emails from b#tony.gr then you will need to also verify that email address with SendGrid.

Change sender on reply using EWS Managed API

I'm currently trying to configure Mail2Bug to create Bugs in Azure DevOps when new emails arrive in a shared mailbox. Everything was going well until the part where it needs to reply to the incoming message.
The code which handles this function can be found in EWSIncomingMessage.cs:
public void Reply(string replyHtml, bool replyAll)
{
//_message is of type EmailMessage
var reply = _message.CreateReply(replyAll);
reply.BodyPrefix = new MessageBody(BodyType.HTML, replyHtml);
reply.Send();
}
Instead of replying using the shared mailbox's email, it uses the one from the authenticated user. I'm assuming this has to do with how CreateReply populates the reply MailMessage in combination with EWS.
Are there any ways around this (possibly by creating a new MailMessage and simulate a reply)?
You could refer to the below code:
var message = (EmailMessage) Item.Bind(service, new ItemId(uniqueId), PropertySet.FirstClassProperties);
var reply = message.CreateReply(false);
reply.BodyPrefix = "Response text goes here";
var replyMessage = reply.Save(WellKnownFolderName.Drafts);
replyMessage.Attachments.AddFileAttachment("d:\\inbox\\test.pdf");
replyMessage.Update(ConflictResolutionMode.AlwaysOverwrite);
replyMessage.SendAndSaveCopy();
For more information, please refer to these links:
Replying with attachments to an email message with EWS
How to reply to an email using the EWS Managed API?
Respond to email messages by using EWS in Exchange

C# Exchange - Forward message As

I'm using C# for an Exchange Online related utility. I authenticate to the server using an admin account, and that account performs some tasks on user's messages in specific folders.
If I want to send a message from a user (as opposed to the admin account in the From field) I can do this:
EmailMessage confirmationMessage = new EmailMessage(service);
confirmationMessage.ToRecipients.Add("recipient#contoso.com");
confirmationMessage.Subject = "Confirmation: " + message.Subject + " Sent";
confirmationMessage.From = "testuser#contoso.com";
confirmationMessage.Send();
And the message is sent with "testuser#contoso.com" in the From field instead of "admin#contoso.com" (the account used to authenticate to Exchange Online). This of course requires 'Send As' permissions, which have been granted.
However, if I want to forward a message out of a user's mailbox instead of sending a new message "admin#contoso.com" ends up in the From field:
foreach (EmailMessage message in itemResults)
{
//forward the message to each of the users assistants
ResponseMessage forward = message.CreateForward();
forward.ToRecipients.Add("recipient#contoso.com");
forward.Send();
}
There doesn't seem to be any way to edit the ResponseMessage From property, and changing the From property of the message before converting it to a ResponseMessage doesn't make a difference. Is there way way to forward a message with a specified address in the From field?

How to mark message as read, properly get from address and delete message

It seems as though I can finally access the service and get all unread mails from the inbox by using the EWS API but it seems as though the message doesn't send
EmailMessage message = new EmailMessage(emailService);
message.Subject = string.Format("Electricity token for: {0}", house.Number);
message.Body = html.HTMLCode;
message.ToRecipients.Add(email.From);
message.SendAndSaveCopy();
"email" refers to the list of unread emails I get back
what must I do to correctly get the senders email address and how do I mark it as read and then delete it?
Based on your other post, it appears that the problem was indeed that you hadn't bound to the original mail.

how to send email in C# even when one of the recipient is invalid?

I am trying to send email to multiple recipients and it works fine when all the recipients have valid email address.
But when one of the recipients have invalid email address, email is not sent even to other recipients whose email address is valid and I am getting an exception:
The server rejected one or more recipient addresses. The server
response was: 550 #5.1.0 Address rejected.
Is there any way I can send the email to other valid recipients even if one of the email address is invalid?
public static void sendMails(string ptxtSubject, string ptxtBody)
{
string txtTo = "valid1#aaa.com,valid2#aaa.com,invalid1#aaa.com";
string txtFrom = "valid#aaa.com";
string txtSubject = ptxtSubject;
string txtBody = ptxtBody;
MailMessage mail = new MailMessage();
mail.To = txtTo;
mail.From = txtFrom;
mail.Subject = txtSubject;
mail.Body = txtBody;
try
{
SmtpMail.SmtpServer ="smtp.aaa.com";
SmtpMail.Send(mail);
}
catch (Exception ex)
{
//log the exception
throw;
}
}
I can send separate mail to each of them but users(recipients) will not know who else is in the email distribution list. My requirement is everyone should be able to know who else is receiving the email.
Outlook sends the email to all the valid users and notifies us back of invalid users. Is there anyway we can do the same using C#?
Unless all the recipients definitely know each other (and they don't mind other people knowing they are receiving email from you), you should be sending separate emails anyway.
This would also take care of your problem, i.e. if one send operation fails, it won't disrupt the others. Note that in your case, it appears that the initial relay is failing because the addresses are from the same host as the SMTP server.
Once an email is routed to multiple hosts, the success/failure is no longer interdependent. For example, a gmail.com server probably doesn't know/care that a yahoo.com server rejected a recipient.
If performance is a concern, you can send the messages asynchronously to get achieve better throughput. Note that you can still handle exceptions when sending asynchronously.
As always, if you are sending any quantity of email, it's probably advisable to use a 3rd party service.
I really don't see any way to accomplish this. Sending an email with SmtpMail.Send() is pretty much an atomic function and you need correct data for it to work without an exception.
The only option I see here is to send separate emails to each recipient.

Categories