C# Exchange - Forward message As - c#

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?

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.

DMARC failed for some Emails using SendGrid

I am writing a C# application that can send emails using the SendGridClient for .NET.
Everything is set up so far and kept working for a long time.
But since the last days, some emails are no longer forwarded to their target address. GMX and Outlook work, but Gmail does not work. Those addresses are listed as "Blocked" in the SendGrid Activity List because DMARC failed.
I'm sending the mail as following:
SendGridClient client = new SendGridClient(sendGridID);
EmailAddress from = new EmailAddress("xxx#mydomain.com", "My Sender");
EmailAddress to = new EmailAddress(customerEmail, customerName);
var subject = "Account has been created";
var textContent = "Your account has been successfully created";
var htmlContent = "Some Text";
var msg = MailHelper.CreateSingleEmail(from, to, subject, textContent, htmlContent);
await client.SendEmailAsync(msg);
I have checked DKIM and SPD, both seem to be okay. I do not really understand what the problem is. I read about misalignment of the email domains because I'm sending from mydomain.com but the mail itself comes then from sendgrid.net. Is this the problem? How do I fix this? I cannot send from sendgrid.net as this is not the source domain in my case. As I am not a SendGrid pro.. is there a way in SendGrid to configure this?
Blocks happen when your message was rejected for a reason related to the message, not the recipient address. This can happen when your mail server IP address has been added to a deny list, blocked by an ISP, or if the message content is flagged by a filter on the receiving server.
The “Reason on the Block” will clarify what the exact reason is. Typically, it’s possible to have your IP address removed from a deny list, and some lists automatically do this after a period of time. Message content can be modified to correct a filtered block.
Moreover, you can use Address Whitelisting to whitelist Gmail domain. The address whitelist setting whitelists a specified email address or domain for which mail should never be suppressed. For example, you own the domain example.com, and one or more of your recipients use email#example.com addresses, by placing example.com in the address whitelist setting, all bounces, blocks, and unsubscribes logged for that domain will be ignored and sent as if under normal sending conditions.
Mail settings allow you to tell Twilio SendGrid specific things to do to every email that you send to your recipients over Twilio SendGrid's Web API or SMTP Relay.
C# code:
string data = #"{
'enabled': true,
'list': [
'email1#example.com',
'example.com'
]
}";
var json = JsonConvert.DeserializeObject<Object>(data);
data = json.ToString();
var response = await client.RequestAsync(method: SendGridClient.Method.PATCH, urlPath: "mail_settings/address_whitelist", requestBody: data);
Console.WriteLine(response.StatusCode);
Console.WriteLine(response.Body.ReadAsStringAsync().Result);
Console.WriteLine(response.Headers.ToString());
Console.ReadLine();

EWS - Send Email With ConversationId (Not Reply)

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.

Sending emails as company domain from SendGrid

I own a domain, example.com. I'd like to send out emails from my webapp where it displays it's from info#example.com, or support#example.com.
I've used SendGrid a lot in the past from within my websites, but I've always simply been able to fill out where an email is from by editing the From property of the SendGridMessage class, and it just showed up that way on clients.
Is there an official way/API from sendgrid to utilize a domain that I own? What's to stop me or someone else from typing any domain they want using the sendgrid API?
The process of setting up DNS records for your domain that allow your emails to be authenticated, as well as verifying your ownership of the domains, is known at SendGrid as whitelabeling. After this process, SPF and DKIM records will then be available for receiving servers to check.
SPF and DKIM ensure the originating IP is allowed to send email on behalf of the domain in question, and to essentially verify that the contents of the email have not been tampered with respectively.
The thing that will stop others from sending from your domain is called DMARC. Domains owned by yahoo, aol, and very soon google all implement strict policies; emails claiming to be from these domains but that are not will never be delivered. Many other domains will soon be following this trend and implementing DMARC.
The code sample from https://azure.microsoft.com/en-us/documentation/articles/sendgrid-dotnet-how-to-send-email/ shows how to do this:
// Create the email object first, then add the properties.
var myMessage = new SendGridMessage();
// Add the message properties.
myMessage.From = new MailAddress("john#example.com");
// Add multiple addresses to the To field.
List<String> recipients = new List<String>
{
#"Jeff Smith <jeff#example.com>",
#"Anna Lidman <anna#example.com>",
#"Peter Saddow <peter#example.com>"
};
myMessage.AddTo(recipients);
myMessage.Subject = "Testing the SendGrid Library";
//Add the HTML and Text bodies
myMessage.Html = "<p>Hello World!</p>";
myMessage.Text = "Hello World plain text!";

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