Sending Email Using SendGrid - c#

I'm trying to send email from sendgrid as follows-
public static async Task<int> SendEmail(string fromEmail, string toEmail, string emailMessage, string subject)
{
try
{
// Create the email object first, then add the properties.
var myMessage = new SendGridMessage();
// Add the message properties.
myMessage.AddTo(toEmail);
myMessage.From = new MailAddress(fromEmail);
myMessage.Subject = subject;
myMessage.Html = emailMessage;
var username = ConfigurationManager.AppSettings["NetworkUserId"];
var pswd = ConfigurationManager.AppSettings["NetworkUserPwd"];
var domain = ConfigurationManager.AppSettings["HostName"];
// Create credentials, specifying your user name and password.
var credentials = new NetworkCredential(username, pswd, domain);
// Create an Web transport for sending email.
var transportWeb = new Web(credentials);
if (transportWeb != null)
await transportWeb.DeliverAsync(myMessage);
else
{
await Task.FromResult(0);
}
}
catch (System.Exception ex)
{
//throw ex;
}
return 1;
}
Here I'm using async and await, I got mail successfully but I'm expecting return value as 1. I think my debugger hitch into await.

You do not need to await the result of 0, your code should be:
public static async Task<int> SendEmail(string fromEmail, string toEmail, string emailMessage, string subject) {
try {
// Same as your example
if (transportWeb != null)
await transportWeb.DeliverAsync("");
else {
return 0;
}
}
catch (System.Exception ex) {
//throw ex;
}
return 1;
}

Related

How to send existing email from shared mailbox to other email address using graph API c#

How to send existing email from inbox to other email address using graph API c#
I have tried sending the existing email but Im not able to send it.
It is throwing error -Code: generalException Message: Unexpected exception returned from the service.
Below is the code snippet:
internal static async Task<System.Collections.Generic.IEnumerable<Message>> Sendemail(List<MM_Mailbox_Forward> toAddress, string smptpadd)
{
string from ="xyz#gmail.com"``your text``
var Toptenmessages1 = graphClient.Users["xyz#gmail.com"].MailFolders["Inbox"].Messages.Request().Top(1);
var task = System.Threading.Tasks.Task.Run(async () => await Toptenmessages1.GetAsync());
var authResult2 = task.Result;
foreach (var message in authResult2)
{
try
{
var messages = new Message
{
Subject = message.Subject,
Body = message.Body,
ToRecipients = new List<Recipient>()
{
new Recipient
{
EmailAddress = new EmailAddress
{
Address = "abc#gmail.com"
}
}
},
};
await graphClient
.Users[from]
.SendMail(messages, true)
.Request()
.PostAsync();
}
}
catch (Exception ex)
{
Console.WriteLine("error:" + ex);
}
Make sure you are not using a shared email box, you can't (by default) send email with a shared email box.

How can I properly send email (with error) from catch ()?

I consume an API and now I want to handle possible errors in catch section. What I want to do now is to send email to given user when error is catched. My Email method works fine and sends mails properly. CallAPI method also works fine but when I add Email method to catch section then CallAPI method get highlighted with info that 'not all code paths return a value'. I can't return anything in catch except for sending an email. So how should I properly send email from catch?
CallAPI
private static async Task<T> CallAPI<T>(string endpoint, string accessToken)
{
try
{
var request = new HttpRequestMessage(HttpMethod.Get,
new Uri(ApiUri, endpoint));
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
var _httpClient = new HttpClient();
var response = await _httpClient.SendAsync(request);
response.EnsureSuccessStatusCode();
var responseStream = await response.Content.ReadAsStreamAsync();
var responseObject = await JsonSerializer.DeserializeAsync<T>(responseStream);
return responseObject;
}
catch (Exception e)
{
await Email(e);
}
}
Email
private static async Task Email(Exception e)
{
try
{
MailMessage message = new MailMessage();
SmtpClient smtp = new SmtpClient();
message.From = new MailAddress("mail#mail.com");
message.To.Add(new MailAddress("mail#mail.com"));
message.Subject = "Test test";
message.IsBodyHtml = true;
message.Body = e.ToString();
smtp.Port = 25;
smtp.Host = "mail.yyy.com";
await smtp.SendMailAsync(message);
}
catch (Exception ex) {
Console.WriteLine(ex.Message);
}
}
Returning default(T) might work for reference types but I don't suggest it for value types.
Say, if T is an int, default(T) results in 0, which might actually be an acceptable response.
There should be a more explicit way for the caller to distinguish if the call went in error or not.
With a custom object, such as ResponseBase<T>, you can easily detect that by a simple response.IsSuccess call.
public class ResponseBase<T> {
public bool IsSuccess { get; set; } = true;
public T Output { get; set; }
}
private static async Task<ResponseBase<T>> CallAPI<T>(string endpoint, string accessToken) {
var result = new ResponseBase<T>(); // Added this
try {
var request = new HttpRequestMessage(HttpMethod.Get,
new Uri(ApiUri, endpoint));
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
var _httpClient = new HttpClient();
var response = await _httpClient.SendAsync(request);
response.EnsureSuccessStatusCode();
var responseStream = await response.Content.ReadAsStreamAsync();
var responseObject = await JsonSerializer.DeserializeAsync<T>(responseStream);
result.Output = responseObject; // Added this
}
catch (Exception e) {
await Email(e);
result.IsSuccess = false; // Added this
}
return result; // Added this
}
You didn't set the return result from your catch scope that you might return
generics type from Task<T>
One way you can try to return default(T)
catch (Exception e)
{
await Email(e);
return default(T);
}

Sending email to multiple recipients fails

I am trying to send the same automatic email to multiple email addresses but I can't get it to work.
[HttpGet("largeorderemail")]
public IActionResult LargeOrderEmail()
{
try
{
//var bodyString = $"<h3>{msg}</h3><br/><p> Visit the site <a href='{Startup.appSettings.AllowOrigin}/lidarweb'> LiDAR GIS portal.</a></p>";
var bodyString = $"<h3>email body</h3>" +
<br/>" +
var emailService = new Email { To = "info#tel.net" };
var response = emailService.ExecuteLargeOrder(bodyString);
return Ok();
}
catch (Exception e)
{
Log.Error(e);
return NotFound();
}
}
public async Task<Response> ExecuteLargeOrder(string bodyString)
{
var fromAddr = new EmailAddress(from, "Info");
subject = "large order";
var toAddr = new EmailAddress(to, "User");
plainTextContent = "";
htmlContent = bodyString;
var msg = MailHelper.CreateSingleEmail(fromAddr, toAddr, subject, plainTextContent, htmlContent);
var response = await client.SendEmailAsync(msg);
return response;
}
When I send an email to a single address, it works. Like so: var emailService = new Email { To = "info#tel.net" };
but when I try something like this, it doesn't send the email var emailService = new Email { To = "info#tel.net, info#gmail.com" };
I also tried separating the address like so var emailService = new Email { To = "info#tel.net; info#gmail.com" }; but this also doesn't work.
Any suggestions?
Instead of putting Email addresses, try doing this way. Keep all your Email address in Array and try looping through the Array so that you can achieve your goal.

trying to accept photo as Microsoft chat bot attachment and send it as an email attachment C#

i am trying to accept a photo as an attachment in Microsoft chat-bot waterFall Dialog...then sending it as an attachment or (even in the body) of an email functionality (which i created)..
the email functionality seems to be working....however i am unable to pass the photo attachment in the email
it is like:
cannot convert from microsoft bot schema attachment to string
this is my code : the first method is to ask user to upload photo
private static async Task<DialogTurnResult> UploadAttachmentAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
stepContext.Values["desc"] = (string)stepContext.Result;
if (lang == "en")
{
lang = "en";
return await stepContext.PromptAsync(
attachmentPromptId,
new PromptOptions
{
Prompt = MessageFactory.Text($"Can you upload a ScreenShot of the Error?"),
});
}
else if (lang == "ar")
{
lang = "ar";
return await stepContext.PromptAsync(
attachmentPromptId,
new PromptOptions
{
Prompt = MessageFactory.Text($"هل يمكنك تحميل لقطة شاشة للخطأ؟"),
});
}
else return await stepContext.NextAsync();
}
the second method is the upload code itself:
private async Task<DialogTurnResult> UploadCodeAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
List<Attachment> attachments = (List<Attachment>)stepContext.Result;
string replyText = string.Empty;
foreach (var file in attachments)
{
// Determine where the file is hosted.
var remoteFileUrl = file.ContentUrl;
// Save the attachment to the system temp directory.
var localFileName = Path.Combine(Path.GetTempPath(), file.Name);
// Download the actual attachment
using (var webClient = new WebClient())
{
webClient.DownloadFile(remoteFileUrl, localFileName);
}
replyText += $"Attachment \"{file.Name}\"" +
$" has been received and saved to \"{localFileName}\"\r\n";
}
return await stepContext.NextAsync();
}
and the third is to store the photo as activity result to pass it later
private static async Task<DialogTurnResult> ProcessImageStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
stepContext.Values["picture"] = ((IList<Attachment>)stepContext.Result)?.FirstOrDefault();
await stepContext.PromptAsync(nameof(TextPrompt), new PromptOptions { Prompt = MessageFactory.Text("Attachment Recieved...Thank you!!") }, cancellationToken);
return await stepContext.EndDialogAsync();
}
and finally the step where i am storing the values i got from each stepcontext and should be passed in an email body: (the attachment is supposed to be stoted in ticketProfile.screenShot)
private static async Task<DialogTurnResult> SummaryStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
var ticketProfile = await _ticketDialogAccessor.GetAsync(stepContext.Context, () => new Ticket(), cancellationToken);
ticketProfile.userType = (string)stepContext.Values["userType"];
ticketProfile.staffType = (string)stepContext.Values["staffType"];
ticketProfile.empIdInfo = (string)stepContext.Values["shareId"];
ticketProfile.emailInfo = (string)stepContext.Values["shareEmail"];
ticketProfile.helpType = (string)stepContext.Values["helpType"];
ticketProfile.describeHelp = (string)stepContext.Values["desc"];
ticketProfile.screenShot = (Attachment)stepContext.Values["picture"];
string[] paths = { ".", "adaptiveCard.json" };
var cardJsonObject = JObject.Parse(File.ReadAllText(Path.Combine(paths)));
var userEmailValue = cardJsonObject.SelectToken("body[2].facts[0]");
var userIdValue = cardJsonObject.SelectToken("body[2].facts[1]");
var userTypeValue = cardJsonObject.SelectToken("body[2].facts[2]");
var staffTypeValue = cardJsonObject.SelectToken("body[2].facts[3]");
var helpTypeValue = cardJsonObject.SelectToken("body[2].facts[4]");
var describeValue = cardJsonObject.SelectToken("body[2].facts[5]");
userEmailValue["value"] = ticketProfile.emailInfo;
userIdValue["value"] = ticketProfile.empIdInfo;
userTypeValue["value"] = ticketProfile.userType;
staffTypeValue["value"] = ticketProfile.staffType;
helpTypeValue["value"] = ticketProfile.helpType;
describeValue["value"] = ticketProfile.describeHelp;
var attachment = new Attachment()
{
Content = cardJsonObject,
ContentType = "application/vnd.microsoft.card.adaptive"
};
var reply = stepContext.Context.Activity.CreateReply();
reply.Attachments = new List<Attachment>();
reply.Attachments.Add(attachment);
await stepContext.Context.SendActivityAsync(reply);
Email($"Here you go{Environment.NewLine}{ticketProfile.screenShot}");
return await stepContext.EndDialogAsync(cancellationToken: cancellationToken);
}
the email function:
public static void Email(string htmlString)
{
try
{
MailMessage mail = new MailMessage();
SmtpClient SmtpServer = new SmtpClient();
mail.From = new MailAddress("hassanjarko55#gmail.com");
mail.Subject = "New Ticket";
mail.Body = htmlString;
SmtpServer.Port = 587;
SmtpServer.Host = "smtp.gmail.com";
SmtpServer.EnableSsl = true;
SmtpServer.UseDefaultCredentials = false;
SmtpServer.Credentials = new NetworkCredential("user Name, "password");
SmtpServer.DeliveryMethod = SmtpDeliveryMethod.Network;
mail.To.Add(new MailAddress("hassan.jarko#yahoo.com"));
mail.IsBodyHtml = true;
SmtpServer.Send(mail);
}
catch (Exception e)
{
e.ToString();
}
}
public class Ticket
{
public string userType { get; set; }
public string staffType { get; set; }
public string helpType { get; set; }
public string helpWith { get; set; }
public string describeHelp { get; set; }
public Attachment screenShot { get; set; }
public string emailInfo { get; set; }
public string empIdInfo { get; set; }
}
any help will be much appreciated...thanks in advance
thanks a lot for #Alphonso...appreciate your efforts to hep...
i did the following to send the picture received from my chatbot as attachment as an email:
1-moved my email functionality method inside SummaryStepAsync method.
2-downloaded the image accepted from user using WebClient
string contentURL = ticketProfile.screenShot.ContentUrl;
string name = ticketProfile.screenShot.Name;
using (var client = new WebClient())
{
client.DownloadFile(contentURL, name);
client.DownloadData(contentURL);
client.DownloadString(contentURL);
}
3-passed it to my email functionality
try
{
HttpClient httpClient = new HttpClient();
//Help Desk Email Settings
MailMessage helpDeskMail = new MailMessage();
if (ticketProfile.screenShot != null)
{
System.Net.Mail.Attachment data = new System.Net.Mail.Attachment(ticketProfile.screenShot.Name);
helpDeskMail.Attachments.Add(data);
}
that's it :)
Have you tried attaching the file name instead of attaching a microsoft.bot.schema.attachment type
also have a look # this it might help you
How do I add an attachment to an email using System.Net.Mail?
Also also in you email function you need to add this code in order to have an attachment in your email
mail.Attachments.Add(new Attachment());
Note: I don't have that big knowledge in C# but I like to participate in these type of questions that have no answers to help the future programmers

Cannot send email from server

I am trying to make a .net core application that send me an email from an URL.
It works perfectly in my local machine but when i deploy it to my server IIS throws me the next exception:
Insufficient system storage. The server response was: 4.3.1 Insufficient system resources
I don't have this exception when i test it on my machine and the email send correctly, only in the IIS Server is there any configuration that my server need?
here is my code:
MailController.cs
[EnableCors("MyPolicy")]
[Produces("application/json")]
[Route("api/Mail")]
public class MailController : Controller
{
[HttpPost("Send")]
public string Send([FromBody]Correo mail)
{
try
{
MailMessage data = new MailMessage();
data.Body = mail.Body;
if (mail.BodyEncoding != null)
data.BodyEncoding = mail.BodyEncoding;
data.BodyTransferEncoding = mail.BodyTransferEncoding;
data.DeliveryNotificationOptions = mail.DeliveryNotificationOptions;
if (mail.HeadersEncoding != null)
data.HeadersEncoding = mail.HeadersEncoding;
data.Priority = mail.Priority;
if (mail.SubjectEncoding != null)
data.SubjectEncoding = mail.SubjectEncoding;
if (mail.Headers != null)
foreach (NameValueCollection header in mail.Headers)
{
data.Headers.Add(header);
}
if (mail.Attachments != null)
foreach (String att in mail.Attachments)
{
Attachment attachment = new Attachment(att);
data.Attachments.Add(attachment);
}
if (mail.CC != null)
foreach (String cc in mail.CC)
{
data.CC.Add(cc);
}
data.From = new MailAddress(mail.From);
data.IsBodyHtml = mail.IsBodyHtml;
data.Subject = mail.Subject;
foreach (String to in mail.To)
{
data.To.Add(to);
}
SmtpClient smtp = new SmtpClient("<IP of SMTP server>");
smtp.UseDefaultCredentials = true;
smtp.DeliveryMethod = SmtpDeliveryMethod.Network;
smtp.Send(data);
data.Dispose();
return "Done!";
}
catch (Exception e)
{
return "Mail not send: " + e.Message;
}
}
}
also i send this from an HttpClient from any other code...
AuthOController.cs - Recovery method
[HttpPost("Recovery/{userName}")]
public async Task<IActionResult> Recovery(String userName)
{
try
{
Correo sender = new Correo();
...
...
...
var myContent = JsonConvert.SerializeObject(sender);
var buffer = Encoding.UTF8.GetBytes(myContent);
var byteContent = new ByteArrayContent(buffer);
byteContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
HttpClient httpClient = new HttpClient();
var result = await httpClient.PostAsync("http://MailSender/api/Mail/Send", byteContent);
var contents = await result.Content.ReadAsStringAsync();
}
return Ok("Done!");
}
catch (Exception e)
{
return BadRequest(Errors.AddErrorToModelState("recovery_failure", "There was an error in the service: " + e.Message, ModelState));
}
}
data.From = new MailAddress(mail.From);
this line create new object, Change this
For detail help check here

Categories

Resources