SendGrid - It's like it does not send email to the customer - .net-core

It's like I have contact Sendrid to hear about how I may not send email.
That's because I need a username and password to be able to do that.
Sendgrid say on Twitter (PM)
For sending mail through SMTP, you will want to set your host to http://smtp.sendgrid.net . You can then use port 587, 2525 or 25 for TLS connections, and can use either your SendGrid username/password for authentication, or an API key generated on your account.
Code:
var resultMail = await _viewRenderService.RenderToStringAsync("~/Views/Templates/NewPassword.cshtml", viewModel);
var api = Environment.GetEnvironmentVariable("azure_xxxxxxx#azure.com");
var client = new SendGridClient(api);
var from = new EmailAddress("hello#hello.com", "J. Petersen");
var to = new EmailAddress("test#test.com", "Test");
var plainTextContent = Regex.Replace(resultMail, "<[^>]*>", "");
var msg = MailHelper.CreateSingleEmail(from, to, title, plainTextContent: plainTextContent,
htmlContent: null);
var resulta = client.SendEmailAsync(msg);
I have looked at Documentation on Sendgrid, and I do not think I'll find that you need to use username and password and port.
It is built in .net core 2.0 - Problems are how can I add my username and password and port to this?

Your using the API not SMTP, Here is the standard smtp
var mailMessage = new MailMessage
{
From = new MailAddress("support#bla.net"),
Subject = "Hello World",
Body = "Test email from Send Grid SMTP Settings"
};
mailMessage.To.Add("someone#somehwere.net");
var smtpClient = new SmtpClient
{
Credentials = new NetworkCredential("Your-Username#azure.com", "Your-Password"),
Host = "smtp.sendgrid.net",
Port = 587
};
smtpClient.Send(mailMessage);

Related

How to send email using service account details only in ASP.NET Core console application?

I have gmail API service account details = client id and service account. How can I just send an email from one id to other without OAuth?
I want to authorize this email sending process with the service account credentials only.
Is there a nuget package that can help fulfill this requirement?
How can I just send an email from one id to other without OAuth?
I assume what you mean is how to send an email with out poping up the Oauth2 consent screen.
Using a service account will allow you to do that, once you have configured the permissions properly in your google workspace account. You grant the service account to preform actions on behalf of one of your domain users. This way the service account can send emails as that user without the user having to consent to that access because you have pre authorized it via google workspace.
The following code will show you how to authorize your application to use a service account.
class Program
{
public static string Base64Encode(string plainText)
{
var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText);
return System.Convert.ToBase64String(plainTextBytes);
}
public static void SendMail()
{
try
{
string ApplicationName = "Gmail API .NET Quickstart";
const string serviceAccount = "xxxx#xxxx-api.iam.gserviceaccount.com";
var certificate = new X509Certificate2(#"c:\XXXX.p12", "notasecret", X509KeyStorageFlags.Exportable);
var gsuiteUser = "YourDomain#YourDomain.com";
var serviceAccountCredentialInitializer = new ServiceAccountCredential.Initializer(serviceAccount)
{
User = gsuiteUser,
Scopes = new[] { GmailService.Scope.GmailSend, GmailService.Scope.GmailLabels }
}.FromCertificate(certificate);
var credential = new ServiceAccountCredential(serviceAccountCredentialInitializer);
if (!credential.RequestAccessTokenAsync(CancellationToken.None).Result)
throw new InvalidOperationException("Access token failed.");
var service = new GmailService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = ApplicationName,
});
var mailMessage = new MailMessage();
mailMessage.From = new MailAddress("se#Yourdomain.com");
mailMessage.To.Add("ddddd#hotmail.com");
mailMessage.ReplyToList.Add("se#Yourdomain.com");
mailMessage.Subject = "test";
mailMessage.Body = "<h1>sdf</h1>";
mailMessage.IsBodyHtml = true;
//foreach (System.Net.Mail.Attachment attachment in email.Attachments)
//{
// mailMessage.Attachments.Add(attachment);
//}
var mimeMessage = MimeKit.MimeMessage.CreateFromMailMessage(mailMessage);
var gmailMessage = new Message
{
Raw = Base64Encode(mimeMessage.ToString())
};
Message message1 = new Message();
UsersResource.MessagesResource.SendRequest sendRequest = service.Users.Messages.Send(gmailMessage, "me");
var s = sendRequest.Execute();
Console.WriteLine("Message delivered!");
}
catch (Exception ep)
{
Console.WriteLine(ep.ToString());
}
}
The trick is to remember to set up the domain wide delegation properly and to decide which user the service account is going to be impersonating and to remember to add that email
without google workspace
If you do not have a google workspace account then you can not use service accounts. You may want to consider going though the smtp server instead.

AWS SES verifyemailidentity

I wrote the following .net code to add run time email address in AWS-SES "Email Address Identities list" and sending email to user for verification, but its not working, though the response saying "WaitingforActivation". But neither email address is added in SES "Email Address Identities" nor email went to the respective email address for verification. Any help on the same is appreciated.
public void SESVerifyEmailIdentity()
{
var sesClient = new AmazonSimpleEmailServiceClient("XXXXXXXXXXXXX", "XXXXXXXXXXX", "USEast1");
var request = new VerifyEmailIdentityRequest
{
EmailAddress = "Joe#example.com"
};
var response = sesClient.VerifyEmailIdentityAsync(request);
}
I resolved my issue, I was not using the right credentials for AWS. When I used my AWS credentials, its working for me.
public void SESVerifyEmailIdentity()
{
#region SESVerifyEmailIdentity
var awsCredentials = new
Amazon.Runtime.BasicAWSCredentials("YOUR-ACCESS-KEY-HERE", "YOUR-SECRET-KEY-HERE);
var sesClient = new AmazonSimpleEmailServiceClient(awsCredentials, RegionEndpoint.USEast1);
var request = new VerifyEmailIdentityRequest
{
EmailAddress = "Joe#Example.com"
};
var response = sesClient.VerifyEmailIdentityAsync(request);
#endregion
}

Best practice on multiple IdentityServer4 services

I have two identityservers and one Web API.
What Im trying to do is having the API authenticate with one or both of the IdentityServers and being able to switch if one goes down. If possbile I would also like to be able to add a new IdentityServer at runtime.
Is there any best practice here?
As of now it looks like this.
app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
{
Authority = $"http://localhost:5000",
ScopeName = "my.scope",
RequireHttpsMetadata = false,
ScopeSecret = "secret",
});
If I shut down the IdentityServer at port 5000 I can't use the API anymore. Which is to be expected.
Im not sure if this is a good way to solve it. But it's one way.
I ask my routing service for the "first identityservice" to set the Authroity in options.
And then I add a custom IntrospectionBackChannelHandler
app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
{
Authority = $"http://{v.Address}:{v.Port}",
IntrospectionBackChannelHandler = new CustomIntrospectionBackChannelHandler(consulService)
Since all my identity servers look the same but are on different addresses I dont really have to bother to do the Authority thing again.
Inside the custom Introspect.... I check each introspect and send it to the "correct" identityserver. If its not working I try another identityserver.
var qs = await request.Content.ReadAsStringAsync();
var queryDic = QueryHelpers.ParseQuery(await request.Content.ReadAsStringAsync());
var token = queryDic["token"];
var client_id = queryDic["client_id"];
var client_secret = queryDic["client_secret"];
var iRequest = new IntrospectionRequest
{
ClientId = client_id,
ClientSecret = client_secret,
TokenTypeHint = "access_token",
Token = token
};
IntrospectionResponse result = null;
var svc = await _Consul.GetService(OrbitServices.IdentityServer);
result = await TrySendAsync(iRequest, svc);
if (!result.IsActive && result.IsError)
{
svc = await _Consul.GetService(OrbitServices.IdentityServer, true);
result = await TrySendAsync(iRequest, svc);
}
var message = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StringContent(result.Raw, Encoding.UTF8, "application/json")
};
return message;

Sending email using SendGrid take long time

I using SendGrid in asp.net mvc. I use this code to send email :
var myMessage = new SendGridMessage();
myMessage.From = new MailAddress("john#example.com");
myMessage.AddTo("testing#something.com");
myMessage.Subject = "Subject";
myMessage.Text = "testing";
var credentials = new NetworkCredential("*********#azure.com", "");
Web transportWeb = new Web(credentials);
await transportWeb.DeliverAsync(myMessage);
The problem is that the email take around 5 minutes to reach the destination. Is this the normal case ? if it is normal how can I decrease this time ?

How to send mail in ASP.Net from google, yahoo or other mail domains?

I have a "Contact Us" page where in users will give in their email id and a query and on submitting the form, web admin would receive that email.
If I configure their email id to "from" MailAddress and send the mail, it will fail to do so if the ID is from popular mail domains like gmail or hotmail but would work with other unpopular or non existent domains like me#abcxyzmail.om without any credentials provided!
It worked with gmail after I configured SMTP and network credentials properly.
The aim is to let the admin of my website who receives the email be able to hit the reply button in his mail client and see the "to" field populated with the "from" field filled in "contact us" page.
Is there any proper way to do this or a tip or trick to accomplish it.
Heres my code
MailMessage emailMessage = new MailMessage();
MailAddress emailTo = new MailAddress("admin#webdev.co.nz", "Web Dev");
MailAddress emailFrom = new MailAddress(tbEmail.Text);
SmtpClient localhost = new SmtpClient("localhost");
emailMessage.To.Add(emailTo);
emailMessage.From = emailFrom;
emailMessage.Subject = "Enquiry / Feedback";
emailMessage.Body = "Name: " + tbName.Text +
"\nAddress: " + tbEmail.Text +
"\nComments: " + tbComments.Text;//emails body
localhost.Send(emailMessage);
Thanks
Sid
Not sure why you've got problems here -- we've got a few systems that do just this without any issues. But mail is a finnicky and hinky beast; I would bet on a configuration setting on the server messing things up -- how much control do you have there?
In any case, the more proper way to do this is use the EmailMessage.ReplyTo (2.0/3.5) or EmailMessage.ReplyToList (4.0) property to send the messages. This will probably bypass any configuration on the server that is causing this problem.
This is because you are using your localhost to send the email - you need an email server. If you actually have a GMail (or whatever) account - then use their server with the correct credentials.
using Microsoft.VisualBasic;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Net.Mail;
public class YourClass
{
private void SendMailFromGmail(string vFrom, string vTo, string vGmailID, string vGmailPass, string vMailText, string vSMPTDNS, string vSubject)
{
MailMessage MyMailMessage = new MailMessage();
SmtpClient SMTPServer = new SmtpClient(vSMPTDNS);
var _with1 = SMTPServer;
//Start by creating a mail message object
//From requires an instance of the MailAddress type
MyMailMessage.From = new MailAddress(vFrom);
//To is a collection of MailAddress types
MyMailMessage.To.Add(vTo);
MyMailMessage.Subject = vSubject;
MyMailMessage.Body = vMailText;
//Create the SMTPClient object and specify the SMTP GMail server
_with1.Port = 587;
_with1.Credentials = new System.Net.NetworkCredential(vGmailID, vGmailPass);
_with1.EnableSsl = true;
try {
_with1.Send(MyMailMessage);
string lNewVariable5 = "Email Sent";
//MessageBox.Show(lNewVariable5)
} catch (SmtpException ex) {
throw ex;
}
}
public void Main()
{
string vFrom = "from_address_here#gmail.com";
string vTo = "to_address_here#domain_name_here";
string vGmailID = "account uid";
string vGmailPass = " account pwd";
string vMailText = "This is the test text for Gmail email";
string vSMPTDNS = "smtp.gmail.com";
string vSubject = "GMail Test";
SendMailFromGmail(vFrom, vTo, vGmailID, vGmailPass, vMailText, vSMPTDNS, vSubject);
}
}
Add a reply to header
mail.Headers.Add( "Reply-To", "users.email.#hisprovider.com" );
This will make the email client to populate this address instead of from address. Is this what you are looking for. The above code is untested.

Resources