I´m using Sendgrid Email Service with the Library for C# and trying to set multiple users in the ReplyTo field.
This is my code that sends the E-Mail
var msg = new SendGridMessage()
{
Subject = SomeSubject,
From = new MailAddress("from#mail.com", "From name"),
To = new MailAddress[] {new MailAddress("destination#mail.com","destinationName")},
Bcc = new MailAddress[]
{
new MailAddress("BccDestination#mail.com", "BccDestinationName"),
},
ReplyTo = new MailAddress[]{
new MailAddress("someone#email.com", "Jhon Doe"),
new MailAddress("jsmith#email.com", "Jhon Smith"),
},
Html = SomeHtml
};
When i check for the Email sended, and i try to answer it, only appears the first Mail Address (someone#email.com) that i added and there is no trace of the second one (jsmith#email.com). What can i do?
Related
I can send a simple email, I can also send emails using a specific template w/ the TemplateId like the example below, but
QUESTION - How do I send this template below and add or include handlebar data (ex. {"name":"Mike", "url":"some_url", "date":"04/18/2022})?
FYI - I can't find any doc that shows any C# examples. I did find this link to create a transactional template but it doesn't send the email. So not sure here if this is what I'm looking for...
var client = new SendGridClient(Options.SendGridKey);
var msg = new SendGridMessage() {
From = new EmailAddress(fromEmailAddress, fromEmailName),
Subject = subject,
PlainTextContent = message,
HtmlContent = message,
TemplateId = "d-30710e173a174ab58cc641nek3c980d4c"
};
var response = await client.SendEmailAsync(msg);
The solution is that you need to remove the PlainTextContent and HtmlContent properties to make use of the template. Also, you need to provide a dynamicTemplateData object that contains your placeholders.
Here are two code examples that send dynamic template emails with and without the helper class (search for dynamic_template_data and dynamicTemplateData). So the full snippet with the mail helper class would be:
var apiKey = Environment.GetEnvironmentVariable("NAME_OF_THE_ENVIRONMENT_VARIABLE_FOR_YOUR_SENDGRID_KEY");
var client = new SendGridClient(apiKey);
var msg = new SendGridMessage();
msg.SetFrom(new EmailAddress("test#example.com", "Example User"));
msg.AddTo(new EmailAddress("test#example.com", "Example User"));
msg.SetTemplateId("d-d42b0eea09964d1ab957c18986c01828");
var dynamicTemplateData = new ExampleTemplateData
{
Subject = "Hi!",
Name = "Example User",
Location = new Location
{
City = "Birmingham",
Country = "United Kingdom"
}
};
msg.SetTemplateData(dynamicTemplateData);
var response = await client.SendEmailAsync(msg);
PS: Here is the general API documentation that explains the available properties.
I am using the updated DocuSign API with my .NET application and for the Authentication, I'm using the Authentication Code Grant workflow using 'signature%20extended' as the Code. I can successfully authenticate and get back an access token for the user I'm authenticating with.
I then get the Account details without any issue
ApiClient apiClient = new ApiClient("https://demo.docusign.net/restapi");
var docuSignUserInfo = apiClient.GetUserInfo(accessToken).Accounts.FirstOrDefault();
I then proceed with creating my Signer and Document Model
Document document = new Document
{ DocumentBase64 = Convert.ToBase64String(ReadContent(docName)),
Name = "Lorem Ipsum", FileExtension = "pdf", DocumentId = "1"
};
Document[] documents = new Document[] { document };
// Create the signer recipient object
Signer signer = new Signer
{ Email = "test#example.com", FirstName = "Jane", LastName="Doe" ClientUserId = "1000",
RecipientId = "1", RoutingOrder = "1"
};
Signer[] signers = new Signer[] { signer };
Recipients recipients = new Recipients { Signers = new List<Signer>(signers) };
EnvelopeDefinition envelopeDefinition = new EnvelopeDefinition
{ EmailSubject = "Please sign the document",
Documents = new List<Document>( documents ),
Recipients = recipients,
Status = "sent"
};
ApiClient apiClient = new ApiClient("https://demo.docusign.net/restapi");
apiClient.Configuration.AddDefaultHeader("Authorization", "Bearer " + accessToken);
EnvelopesApi envelopesApi = new EnvelopesApi(apiClient.Configuration);
//This is the API call that throws the error below
EnvelopeSummary results = envelopesApi.CreateEnvelope(accountId, envelopeDefinition);
Error calling CreateEnvelope: {
"errorCode": "INVALID_USERNAME_FOR_RECIPIENT",
"message": "The user name for the recipient is invalid. Envelope definition is missing a UserName for recipientId: 1"
}
From my understanding, I shouldn't need to specify any Username/Passwords as I'm using the Access Token for Authentication. Also, I don't understand why a recipient would require a UserName?
I think you need to provide the Name property for the Signer model. Please try that.
I agree that the FirstName and LastName sound like they are all that is needed, but those attributes may not be fully implemented yet (or a bug).
Please advise if this solved your problem. Thank you.
Added
The FirstName and LastName attributes are optional. DocuSign internal bug report DEVDOCS-1079 has been filed to have the documentation for those fields improved.
I'm actually using ASP .NET Core 1.1.
project.json:
"dependencies": {
"SendGrid.NetCore": "1.0.0-rtm-00002",
"Sendgrid": "8.0.5"
}
Code used to send email:
public Task SendEmailAsync(string email, string subject, string content)
{
var message = new SendGridMessage();
message.AddTo(email);
message.From = new System.Net.Mail.MailAddress("geeks#test.io", "test");
message.Subject = subject;
message.EnableTemplateEngine("18d89b42-d094-49fb-86c4-5f5821a2eb67");
message.Html = "test";
message.Text = "test";
var credentials = new System.Net.NetworkCredential(
_emailSettings.Username,
_emailSettings.Password
);
var transportWeb = new SendGrid.Web(credentials);
return transportWeb.DeliverAsync(message);
}
I'm unable to send email when I try to use template [message.EnableTemplateEngine("18d89b42-d094-49fb-86c4-5f5821a2eb67")]. However, any email sent without template is working as expected.
I also tried this instead of EnableTemplateEngine in reference to SendGrid SMTP API for Applying Template:
message.Header.AddFilterSetting("templates", new List<string>() { "template_id" }, "18d89b42-d094-49fb-86c4-5f5821a2eb67");
message.Header.AddFilterSetting("templates", new List<string>() { "enable" }, "1");
I receive this error:
JSON in x-smtpapi could not be parsed
Any thoughts?
Finally, I do not use the class "SendGridMessage".
https://github.com/sendgrid/sendgrid-csharp/blob/master/USE_CASES.md
I am trying to send email with SendGrid to multiple recipients in an ASP.Net C# web application
According to the SendGrid documentation I need to add X-SMTPAPI header to my message in JSON formatted string. I do so, for first check I just added a hand-typed string before building my json email list progamatically here is my code:
string header = "{\"to\": [\"emailaddress2\",\"emailaddress3\"], \"sub\": { \"%name%\": [\"Ben\",\"Joe\"]},\"filters\": { \"footer\": { \"settings\": { \"enable\": 1,\"text/plain\": \"Thank you for your business\"}}}}";
string header2 = Regex.Replace(header, "(.{72})", "$1" + Environment.NewLine);
var myMessage3 = new SendGridMessage();
myMessage3.From = new MailAddress("emailaddress1", "FromName");
myMessage3.Headers.Add("X-SMTPAPI", header2);
myMessage3.AddTo("emailaddress4");
myMessage3.Subject = "Test subject";
myMessage3.Html = "Test message";
myMessage3.EnableClickTracking(true);
// Create credentials, specifying your user name and password.
var credentials = new NetworkCredential(ConfigurationManager.AppSettings["xxxxx"], ConfigurationManager.AppSettings["xxxxx"]);
// Create an Web transport for sending email.
var transportWeb = new Web(credentials);
// Send the email, which returns an awaitable task.
transportWeb.DeliverAsync(myMessage3);
But it just seems to ignore my header, and sends the email to the one email "emailaddress4" used in "addto".
According the documentation if the header JSON is parsed wrongly, then SendGrid sends an email about the error to the email address set in "FROM" field, but I get no email about any error.
Anyone got any idea?
For me using the latest 9.x c# library the only way I could solve this was by using the MailHelper static functions like this:
var client = new SendGridClient(HttpClient, new SendGridClientOptions { ApiKey = _sendGridApiKey, HttpErrorAsException = true });
SendGridMessage mailMsg;
var recipients = to.Split(',').Select((email) => new EmailAddress(email)).ToList();
if (recipients.Count() > 1)
{
mailMsg = MailHelper.CreateSingleEmailToMultipleRecipients(
new EmailAddress(from),
recipients,
subject,
"",
body);
}
else
{
mailMsg = MailHelper.CreateSingleEmail(
new EmailAddress(from),
recipients.First(),
subject,
"",
body);
}
if (attachment != null)
{
mailMsg.AddAttachment(attachment.Name,
attachment.ContentStream.ToBase64(),
attachment.ContentType.MediaType);
}
var response = await client.SendEmailAsync(mailMsg).ConfigureAwait(false);
if (response.IsSuccessStatusCode)
{
_log.Trace($"'{subject}' email to '{to}' queued");
return true;
}
else {
throw new HttpRequestException($"'{subject}' email to '{to}' not queued");
}
I'm not sure why you wouldn't recieve any errors at your FROM address, but your JSON contains the following flaws:
, near the end makes the string invalid json
spaces around the first % in %name%, that might make sendgrid think it's an invalid substitution tag
if you use the X-SMTPAPI header to specify multiple recipients, you are not supposed to add a standard SMTP TO using AddTo().
Besides that, you didn't wrap the header at 72 characters (see the example in the documentation).
I figured that however the X-SMTPAPI documentation talks about passing the header as JSON, the API itself expects it as a parameter, containing Ienumerable string. So the working code is:
var myMessage3 = new SendGridMessage();
myMessage3.From = new MailAddress("email4#email.com", "Test Sender");
myMessage3.AddTo("email2#email.com");
myMessage3.Subject = "Új klubkártya regisztrálva";
myMessage3.Html = "Teszt üzenet";
myMessage3.EnableClickTracking(true);
/* SMTP API
* ===================================================*/
// Recipients
var addresses = new[]{
"email2#email.com", "email3#email.com"
};
//string check = string.Join(",", addresses);
myMessage3.Header.SetTo(addresses);
// Create credentials, specifying your user name and password.
var credentials = new NetworkCredential(ConfigurationManager.AppSettings["xxxxxxx"], ConfigurationManager.AppSettings["xxxxxxxxx"]);
// Create an Web transport for sending email.
var transportWeb = new Web(credentials);
// Send the email, which returns an awaitable task.
transportWeb.DeliverAsync(myMessage3);
I am using SendGrid to send emails to a list of users through a console application in asp.net. I am sending a list of user's email addresses in the AddTo section while sending an email. The code looks like this:
SendGridMessage message = new SendGridMessage();
message.AddTo(new List<string>() { "user1#abc.com", "user2#xyz.com", "user3#abc.com", "user4#xyz.com" });
The email is sent as expected, but in the "To" section of the email, I am able to see all the email ids of users to whom this email was sent(image attached below). I want the email ids to be hidden so that no one misuses the other email ids in the list. Is there anyway I can accomplish this using SendGrid?
Use .AddBcc() instead of .AddTo(). BUT if you do this then you'll have to set the To address to something like "no-reply#example.com" which isn't ideal and might increase the chances of the message ending up in the SPAM or Junk folders of your users.
SO instead, write a for loop to send the email per user.
var emailAddresses = new List<string>() { "user1#abc.com", "user2#xyz.com", "user3#abc.com", "user4#xyz.com" };
for (var emailAddress in emailAddresses)
{
var email = new SendGridMessage();
email.AddTo(emailAddress);
// set other values such as the email contact
// send/deliver email
}
Is the content of the email message the same for everyone? I would assume each person would have different "monthly usage" amounts and if so the for loop would be better...
To send to multiple recipients in SendGrid without them seeing each other, you want to use the X-SMTPAPI header, as opposed to the native SMTP To header.
var header = new Header();
var recipients = new List<String> {"a#example.com", "b#exampe.com", "c#example.com"};
header.SetTo(recipients);
var subs = new List<String> {"A","B","C"};
header.AddSubstitution("%name%", subs);
var mail = new MailMessage
{
From = new MailAddress("please-reply#example.com"),
Subject = "Welcome",
Body = "Hi there %name%"
};
// add the custom header that we built above
mail.Headers.Add("X-SMTPAPI", header.JsonString());
The SMTPAPI header will be parsed by SendGrid, and each recipient will get sent a distinct single-To message.
You need to use personalization for that, there are 2 options:
var message = new SendGridMessage();
message.Personalizations = new List<Personalization>();
foreach(var email in emails)
{
var personalization = new Personalization();
personalization.AddTo(new Email(email));
}
Or:
var message = new SendGridMessage();
foreach(var email in emails)
message.AddTo(email, emails.IndexOf(email));
Alternatively you can also use MailHelper with the showAllRecipients flag:
MailHelper.CreateSingleEmailToMultipleRecipients()