I want to send email message with smtp/imap and check for reply after a while.
So I am looking for an open source library which provide an API for sending email and check for replies later.
As far as I understand, Every message already contains unique ID and I see a lot of libraries allowing to download message by ID. but none of the SMTP clients that I saw returning this ID when sending emails.
This kind of API is helpful (S22.Imap):
using (ImapClient Client = new ImapClient("imap.gmail.com", 993,
"username", "password", AuthMethod.Login, true))
{
uids = GetUIdsFromMyDatabase();//how can that be achieved?
IEnumerable<MailMessage> messages = Client.GetMessages(uids);
}
But it leaves 2 questions opened:
1. Where can I get the sent message ID?
2. How can I connect between reply and its parent (sent one)?
SMTP clients can make a Message-ID themselves. They just have to be sure that the left-hand-side is sort of unique.
If the client doesn't make an ID the SMTP server will, but it will not tell the SMTP client what the ID is. One easy and safe way is to feed the message you're about to send (the entire message) through an MD5 or SHA1 hash, base64-encode the result and make an ID of the form <hash#doma.in> where hash is the base64'd hash and doma.in is the From field's domain.
The conventional way to connect replies is to use Message-ID and References. When you send a reply, you set your References to be concatenation of the original message's References and Message-ID fields.
Related
I have a basic SmtpClient and I use it to send e-mails.
using (var client = new SmtpClient())
using (var mail = new MailMessage())
{
mail.From = new MailAddress(fromEmailAddress);
mail.Body = "body text";
mail.To.Add(new MailAddress(myEmailAddress));
client.Send(mail);
}
This code works well if I set the fromEmailAddress to a real e-mail address. If I set it to a fake e-mail address, let's say test#test.com, the code sends the message, but I don't receive the e-mail.
I'm using it on a contact form where there is a field for their e-mail and a field for their message.
Is there a way to send the e-mail regardless of whether the e-mail is valid or not? (In PHP's mail method, it was possible)
Optionally, is it possible to check if the e-mail had been received by me? (to display an error to the user)
You make a mistake in thinking your end matters.
What matters is how stupid or not - and in these days you can count on not - the receiving email server is in regarding to spam.
Your email is simply thrown away for being spam, and it is likely obvious - like the domain you send "from" (fake address) either not existing or having an SPF or other record listing the allowed senders - which you aren't one of.
Simple like that. The internet is a bad place and every sysadmin not a total idiot deploys anti spam mechanisms.
Now, if you put up some form like that or something, it needs to be fixed. Seen that many times. You can not do that - because domains are protected. Which means you can not just pretend you are allowed to send on another domain's behalf. I have seen this type sometimes with contact forms - it's a mistake of programmers not understanding that my domains have SPF records.
C# aside, thats not a good idea if you can avoid it. Setting the 'From' field doesnt actually send from that address - this would mean that anyone could impersonate your bank, for instance.
Most mail providers will regard it quite poorly in terms of spam score - meaning you are likely to have delivery issues if you are sending from a domain that you are not authorised to send from - and that is at least one possible reason why you are experiencing issues with fake addresses.
Here's some more info on why this is bad (see point #4), and some other useful tips - https://www.campaignmonitor.com/blog/email-marketing/2015/09/9-things-that-are-killing-your-email-deliverability/
I am trying to convert our current email agent to send email with TLS. We use C# and I just used the following changes.
SmtpClient sclient = new SmtpClient();
sclient.EnableSsl = true;
and a callback method to validate server certificate.
On Testing the mail was sent/received successully, but both I and the receiving end cannot be 100% sure the the email was received encrypted. (I tried to use Fiddler but its not capturing the email)
Based on this http://luxsci.com/blog/how-you-can-tell-if-an-email-was-sent-using-tls-encryption.html, and the header as below
with ESMTP id s7JKErN9002462
(version=TLSv1/SSLv3 cipher=RC4-MD5 bits=128 verify=NO);
Can we safely assume that the mail communication indeed was encrypted? or Should I make any other code changes so that I can be sure that the email is received or it failed? (I think this cannot be certain as it depends on the smtp host) ?
In the end you can always check the TLS connection using network sniffer software such as WireShark.
Of course if you only leave a connection open to the SSL port of the server, and you receive the server certificate, you can be pretty certain the mail did not appear from the blue sky anyway.
You can safely assume that if you are able to connect and send, that the tunnel you're delivering the mail to is secure.
The SmtpClient code is solid and you can trust it. If it fails to connect securely after you've asked it to, it throws an exception, so you'll know something is not like you were expecting.
Using the SmtpClient and MailMessage classes in .NET to send emails through a local mail server (hMailServer), I currently found no way to get the Message-ID header value of a sent message.
The idea behind
I'm trying to programmatically track messages that are undeliverable, so I have to find a way to identify replies from the destination SMTP server that rejects a certain message.
Now I thought of simply remembering the Message-ID SMTP header value and parse incoming mails for this ID.
I've tried to inspect the Headers collection after sending the message, but I did not find any Message-ID.
My question
Is it possible to get the Message-ID header value that my SMTP server adds during sending of a MailMessage instance?
Update 2012-05-27
As per this example I've successfully tried to manually generate a Message-ID on my own, just before sending.
All my examples work so far, so it seems that this is a solution to my question.
You can add your own message id before send the email. I use the next code:
Guid id = Guid.NewGuid(); //Save the id in your database
mensajeEmail.Headers.Add("Message-Id", String.Format("<{0}#{1}>",id.ToString(),"mail.example.com"));
Note: For download messages I use OpenPop.Net, I check the message.Headers.InReplyTo property, and there is the message id sended.
The standard solution to your problem is VERP. Read Bernstein's original article to find out why Message-Id et al. are not reliable. http://cr.yp.to/proto/verp.txt
I'm Using MailKit library for .Net and SMTP Client.
I tried another solution to get the ID of the message sent with SMTP Client, to trace any replied messages.
Before you send your message add a hidden ID property to the message headers,
Now continue and send your message,
Wait about 10 Seconds, Then you will use the IMAP Client to get your Sent folder and for each message in your folder,
loop over the message headers and check if anyone of them is ==messageIdentity, now you catch your
sent message successfully and get any information about it you wand like ID etc...
It seems that when you use SmtpClient class and MailMessage to send emails, everything works fine. And it does send it. However, some servers, such as your business Exchange Server or Gmail.com or whatever services, sometimes reject these emails (because they could be phishing sites or spam sites?)
I'm using this and a lot of places reject the email I believe:
SmtpClient smtp = new SmtpClient
{
Host = smtpClient,
Timeout = 40000, // 40 seconds
DeliveryMethod = SmtpDeliveryMethod.Network
};
How do you work around this? Do you have to use login credentials to some recognized / white-listed server so that it is authorized and trusted email?
I could use something like GMAIL authentication, but my server should be allowed to send emails, it shouldn't have to rely on gmail.
Long ago there were many servers on the Internet that provided the service delivery of e-mail without asking too many questions about who was using the service.
Then came the SPAMMERS!.
A server that was sending mail freely around the world was no longer a benefactor of the internet, but a problem.
Nowadays it is increasingly difficult to find a server that sends mail on the Internet without asking for credentials.
Your e-mail server (smtp.yourbusiness.com or whatever you want) does not trust you.
When you ask it to send an email for you, it wants to know who you are.
SmtpClient smtp = new SmtpClient
smtp.Host = "smtp.yourbusiness.com";
NetworkCredential credentials = new NetworkCredential("your_user_name_on_smtpserver", "your_password_on_smtpserver");
smtp.Credentials = credentials;
are you setting the sender mail address and can your mail server be resolved by reverse dns lookup? Some spam filters distrust mail servers they can't reverse lookup. If you for instance make your mail server send mails using a bogus or foreign mail domain, spam filters will probably pick this up and filter your mail. If you have set up a SPF record for your domain and your sending mail server isn't in that record, mails from that server will also often be filtered by spam filters. Another reason could be an IP address from a range known to be dynamically assigned by internet providers. Mail servers sending from these address ranges are mostly spam bots and are therefore often also filtered.
To send GMail you need to specify a number of settings - yes you'll need to use authentication (GMail wouldn't open up their relay to everyone, or they'd get used for spamming).
If I recall correctly you need to send on TCP port 587, enable SSL, host to mail.google.com and provide a username and password on your SmtpClient to get Gmail to actually send it - neglecting one of those usually generates an email back from them telling you what you've forgotten.
Edit: Just to clarify on the username and password bit; you'd need to create a new NetworkCredential with the username and password for your GMail account, and set the Credentials property of your SmtpClient to that.
If i interpret your question correctly: the messages are sent our from your server, but they are trapped in the spamfilters at the receiving end?
If this is the problem, it has nothing to to with the way you are sending the messages but much more with the content of your message and the characteristics of your server. So it does not matter what credentials you use or if you send it with SmtpClient or any other class. Moving to Gmail does not help and Gmail has a limit to the number of messages you can send.
Spam filters like spam assassin use rules. Match too many: your message is considered spam.
Have a look here for an example:
http://spamassassin.apache.org/tests_3_3_x.html
So make sure your message does not get too high a score and it will go trough.
I am working in C# Email Sending.
I have no problems sending programmatic emails via SMTP using the normal e-mail address like 'myemail#exchange.com'.
But as per Company Policy, whenever they send e-mails outside the network, they add a postfix on the e-add like "myemail#exchange.com#yodachi".
So when I tried sending using that e-add format I get the error: The specified string is not in the form required for an e-mail address.
Any suggestions would be greatly appreciated.
Note: I am using SmtpDeliveryMethod.Network since we are using SMTP thru company network.
Thanks,
Al
Edit: I've found out that the policy I am talking about is Lotus Domino Roaming. The postfix serves as a request on the Main Server to transfer a outgoing mail.