How to send an email directly from code (without server) [closed] - c#

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
The community reviewed whether to reopen this question last year and left it closed:
Original close reason(s) were not resolved
Improve this question
Everytime I google or search here "how to send an email" I get results like: use an smtp client, connect to a smtp server, send the mail over the smtp server.
I am looking for the code (or the idea) how the server it self sends the email to the other server. So the approach from the link above won't work for me.
Any hints what a smtp server library would do?

First you need to find out address of SMTP server for each of the recipients of your email. You do that by querying DNS of recipients domain for MX record(s). In .NET you can do that with, for example, ARSoft.Tools.Net library:
var resolver = new DnsStubResolver();
var records = resolver.Resolve<MxRecord>("gmail.com", RecordType.Mx);
foreach (var record in records.OrderByDescending(c => c.Preference)) {
Console.WriteLine(record.ExchangeDomainName + " : " + record.Preference);
}
Each MX record has preference value, and you should try them in order of preference (highest first, then if it's not available - next one etc).
Now when you have address of target SMTP server - you connect to it (usually on port 25, or if you want to use encrypted connection - on port 465) and perform regular SMTP conversation (smtp is text protocol), for example:
HELO < you start conversation
250 OK < server lets you proceed
MAIL FROM: <someuser#somedomain.com>
250 OK < server is fine with this sender
RCPT TO: <someuser#targetdomain.com>
250 OK < server is fine with recipient
DATA < you are going to send email body
250 OK < server is fine with that - proceed
Here you send your message
250 OK < server accepted message
QUIT
There are libraries which are capable of doing all this (MX discovery, SMTP conversations and more) in .NET, for example MailBee (not free). I used only mentioned library for this, so not aware if there are free libraries.
Now, while it might look easy - in reality it will not go as smooth as I described.
Target SMTP server will perform a series of checks agains your IP address, domain of the sender, and message contents. For example, when you do:
MAIL FROM: <someuser#somedomain.com>
Most decent SMTP servers will perform reverse DNS check to ensure that domain of a sender and IP from which you send your email are related. To pass that check you should of course own target domain (somedomain.com) and put specific DNS record there.
Most SMTP servers will "graylist" you on the first send. That means they will reject your email but encourage you to try later. So you cannot send emails without storing them, because it many cases - several tries are required to sucessfully send your email.
There are many more checks performed by SMTP servers (different kind of signatures for example), so some efforts are required to make this work reliably.
For the above reasons - most people do not implement their own smtp servers but instead relay all of the above work to already existing SMTP server.
To sum up - it's possible to perform direct send to target SMTP server, but doing that naively from your web api is not going to work reliably. You need to setup a service for that purpose, configure it correctly (not trivial) and store messages somewhere (in database), because several retries might be required.

To reliable send an email you need a server. Period. You can use a cloud service like SendGrid if you don't have or want one yourself.
An smtp server is needed because otherwise:
You will need to implement retries yourself of the other server is
down
Most mail servers have spam detection mechanisms in place and won't allow your mail
You will have to resolve the recipient mail servers manually.
Some background reading material about the reasons I listened:
https://superuser.com/questions/1006079/why-do-i-need-an-smtp-server
https://superuser.com/questions/753811/why-mail-clients-do-not-use-directly-the-smtp-server-of-recipient
https://superuser.com/questions/753811/why-mail-clients-do-not-use-directly-the-smtp-server-of-recipient

Related

Send email from C# WPF app without external SMTP

I need to find a way to send e-mails from my WPF application. Of course I tried sending it using for example Gmail SMTP and it works like a charm but for some reason this solution is unacceptable. So is there a way to send email straight from my computer without using any logging credentials or additional/not open source software? I tried something like this:
SmtpClient m = new SmtpClient();
m.Host = "xxx.xxx.xxx.xxx"; // my IP address.
m.Port = 25;
m.Send("Tests#xxx.xxx.xxx.xxx", "tests#gmail.com", "Test", "This is a test email.....");
It doesn't work like that, I've put mu IPV4 addres from ipconfig but the error I got is:
No connection could be made because the target machine actively refused it.
Is this even possible to run this straightforward from my PC like that? I assume its not even my static IP but some kind of dynamically changed IP from my ISP hidden behind NAT. How to configure it in other way?
My app is expected to run for example overnight and then I would like to receive and email after process is finished. Not interested in receiveing any other emails or sending emails to multiple users.
Sending email via SMTP is not complicated is just very legislated.
Each mail provider gmail/office365 has a configuration which you must follow exactly. The configuration is not even to send the email its just to autorize yourself for the smtp account being used.
Doing a quick search online for gmail the conditions are currently::
https://support.google.com/mail/answer/7126229?visit_id=1-636683482170517029-2536242402&hl=es&rd=1
Good luck

Exchange 2013 Transport Agent Sending Separate Email for Internal Vs External Recipients

We are currently going through a proof of concept creating a Transport Agent that is derived from the Microsoft.Exchange.Data.Transport.Routing.RoutingAgent. We use the OnResolvedMessage event to reroute emails to our external Email server (non Exchange server). This all works fine, and we can reroute the emails to the external server. However, it appears that if an email contains both an internal and external recipient the email will be split into two separate emails and result in two emails going to the external email server. While the two emails contain the same content, just different RCPT TO headers, this will cause the external email server to process the same email twice which is less than desirable for our project.
This is my first time creating a transport agent, and I am trying to determine if there is some setting for exchange server that needs to be changed in order to stop emails that meet this criteria from being split into multiple emails?
The main goal of our transport agent will be to allow emails going to internal recipients to be processed by the external email server, as they currently will be placed into the internal user's mailbox unprocessed. It might have to do with our send/receive connectors, any guidance on any gotchas around those would be much appreciated. If a routing agent is not the correct solution for this problem, we are open to other possibilities.
Snippet of our event handler:
private void OnOnResolvedMessage(ResolvedMessageEventSource source, QueuedMessageEventArgs queuedMessageEventArgs)
{
var mailItem = queuedMessageEventArgs.MailItem;
var origSubject = mailItem.Message.Subject;
mailItem.Message.Subject = "RouteAgent: " + origSubject;
foreach (var recipient in mailItem.Recipients)
{
var newRouteDomain = new RoutingDomain("externalSendConnectorAddressSpace.com");
var dest = new RoutingOverride(newRouteDomain, DeliveryQueueDomain.UseOverrideDomain);
source.SetRoutingOverride(recipient, dest);
}
}
By the time OnResolved Message gets called in the Transport Pipeline the recipients will have been resolved and Bifurcation will have happened on the Message the rules for which are mostly explained in https://technet.microsoft.com/en-us/library/bb430743(v=exchg.150).aspx . EdgeTransport.exe.config is the place where the configuration of the Transport pipeline can be done but I don't believe there is any configuration option for what your trying to do.
If you catch the Message in OnSubmission event this will allow you to get the Message before any categorization has occurred. At that point you can more or less do what you want to the Message. However there are other things that occur as part of the Categorization process such as content conversion https://technet.microsoft.com/en-us/library/bb232174(v=exchg.150).aspx .
However, it appears that if an email contains both an internal and external recipient the email will be split into two separate emails and result in two emails going to the external email server. While the two emails contain the same content, just different RCPT TO headers, this will cause the external email server to process the same email twice which is less than desirable for our project.
This shouldn't really be a big deal for the external service as this should be something that would be expected in any process that was processing emails eg its easy for the external service correlate using the Internet MessageId etc. IMO your trying to solve the problem at the wrong end.
Cheers
Glen

Throwing Exception while sending Email to multiple recipients using smtp client

I have an application which uses SmtpClient to send an email. I am trying to send an email to multiple recipients. I have two recipients in my to list e.g "aman#gmail.com,abc#xyz.com". and I am trying to send the email to this list but my application is throwing the exception as below:
Client does not have permission to submit mail to this server. The server response was: 4.7.1 (abc#xyz.com): Relay access denied.
because of this aman#gmail.com is also not able to receive the email.
I need to implement the functionality that even there is an invalid address like abc#xyz.com in the ToList, an email should be sent successfully to aman#gmail.com.
Can anybody please help me in this?
Does this error message come from your own email server, or from that of xyz.com? I'm guessing it's your own server, and that you either need to aunthenticate before sending, or use your own email address for sending (but the latter is kind of a long shot -- "we do not relay" means a server which is neither the sender's or the recipient's refuses to act as a middleman). It is also possible that the mail exchanger for xyz.com is misconfigured (either the MX record in DNS points to the wrong server, or the admin failed to configure it to accept this responsibility - technically basically the same thing) or that your client somehow ends up connecting to the wrong place.
(Not a proper answer but this got too long to fit in a comment.)

SMTP Error Codes and determining if email is still delivered

I am using System.Net.Mail to to send mail. I do not know the type/version of the SMTP relay that it will connect to.
Some errors will result in no email being sent (e.g. no addresses or invalid from address) whilst others errors will still result in an email being sent.
E.g. Send To : bob#somewhere.com CC: fred#somewhere.com and DoesNotExist#somewhere.com may result in an error of
The server response was: 550 #5.1.0 Address rejected DoesNotExist#somewhere.com.
But the email still appears to be delivered to Bob and Fred.
Is there any reference to which error codes will still result in an email being delivered or any programmatic way of determining this?
This is the way that SMTP operates, as described in the RFC.
Failure to deliver to one recipient does not affect delivery to other recipients.
Generically, codes starting with 4 and 5 are failures, codes starting with 2 are success codes - see RFC821 section "4.2.2. NUMERIC ORDER LIST OF REPLY CODES".
"Email being delivered" is hard to define. Email being accepted for delivery by the SMTP server is defined by the SMTP protocol (and the server will signal acceptance to deliver a message) but this server might just relay the message to another server, or operate in a smart host configuration where it just accepts messages and passes them on to the smart host - delivery is another thing and it's usually associated with local delivery (LMTP).
Some mail clients work around this problem of not being able to tell if a message has been delivered by implementing the dreaded read receipts - but this implementation is entirely on the client side and AFAIK it has nothing to to with SMTP.
RFC 821 is the one that describes SMTP and includes information about different types of errors, but not sure if it contains the details you're looking for. And either way, even if you can find out that the mail server accepted the email for some users, that is not the same as saying that it was delivered to them.
As far as I know, there is no way of telling if an email has been delivered except if the recipients mail client will tell you in some way.
Non-delivery reports (NDRs) are system messages that report the delivery status of a message to the sender. The messages are a subclass of a general message information structure that is referred to as delivery status notifications. Delivery status notifications describe three different types of situations:
* Success (2.X.X numeric codes)
* Persistent transient failure (4.X.X numeric codes)
* Permanent failures (5.X.X numeric codes)
To learn more about delivery status notifications, see Request for Comment (RFC) 1891 and RFC 1893.
Qouted from Microsoft Support http://support.microsoft.com/kb/284204

Programatically generated HTML email is classified as junkmail by Outlook [duplicate]

This question already has answers here:
Email messages going to spam folder
(7 answers)
Closed 9 years ago.
I've got a C# application going that needs to send out an html email via smtp. The email gets sent just fine, but the default security setting on outlook (Low) classifies it as junk email.
It's not exactly a showstopper issue, but this is rather annoying, especially since the junk folder turns off html. I don't want to have to make everyone at my company do something special to receive these emails in a readable fashion, does anyone know what I could be doing that makes outlook think this is junk email?
Code that makes the email (basic stuff.) Config is an object that holds strings related to the configuration of this stuff, toList is a list of email addresses, body/subject are filled by other function calls.
Edit: To add, at the moment I'm just sending it out to myself. In the live version, we'll be looking at less than a hundred people being sent to in a worst-case.
Another Edit: It turned out to be happening much much more often for the longer emails I was generating the other day (~200-300 lines at the worst), and not the shorter emails I'm generating now. That's a reasonable enough filter criteria, I suppose.
SmtpClient smtp = new SmtpClient(config.SmtpServer);
NetworkCredential net = new NetworkCredential();
net.UserName = config.SmtpLogin;
net.Password = config.SmtpPass;
smtp.Credentials = net;
MailMessage msg = new MailMessage();
msg.IsBodyHtml = true;
msg.Priority = MailPriority.Normal;
msg.To.Add(String.Join(",", toList.ToArray()));
msg.From = new MailAddress(fromAddr, "Build Server");
msg.Body = "Blah html is here";
msg.Subject = "Build successful: #numberhere and stuff";
try
{
smtp.Send(msg);
}
catch (SmtpException)
{
//stuff
}
I think this is less of a programming issue and more of a configuration issue. The recipients need to add fromAddr to their “Safe Senders List”.
The thing is, if there were a way to configure an e-mail to bypass the junk mail filter then all the spammers will be doing it.
If it's a matter of crafting the perfect non-junk-looking e-mail then it may work sometimes and not others. And all the spammers will be doing it.
You're going to have to tell everyone to allow e-mails from that account. And you probably shouldn't start that e-mail with any unnecessary anatomical or medicinal references.
If your message To contains a large list it may be seen as spam. Try sending a unique email to each person instead of a mass email.
However:
If you're going to loop through your list and send an email for each user, you might want to consider creating a queue that will be processed that allows for failure and retry.
We had a similar issue in our system where after about 20,00 messages sent in quick succession (ie: within a foreach loop) the outgoing mail server rejected any further attempt to relay.
We instead added outgoing messages to a database table, and wrote a service that would process a specified number of emails at a time and then pause for a specified time before going again.
In addition this allowed us to capture failures, and then setup retry rules. After X attempts we mark the message as failed for good and report the issue. We found that this provided a much more reliable system of users getting their messages, plus they were no longer marked as spam.
If you are sending out several mails at a time send them in small batches so you're not flooding the server.
Check the text of the email for words and symbols likely to be considered spam by some filters.
You might also want to look into things such as SPF to reduce the chance that your mails will be marked as spam.
Add following line in your code while creating MailMessage
msg.BodyEncoding = System.Text.Encoding.GetEncoding("utf-8");
Just a thought, try looping through your to list and send a separate email. Also, try experimenting with different wording and html structures.

Categories