Sending email to multiple recipients via Google - c#

I am working on an C# project where I am building my own SMTP server. It is basically working but I am now trying to get multiple recipients being sent but I am receiving an error.
I am getting the MX record from the senders domain and I am then using MX Record to try and send an email to multiple recipients. If I do two recipients with the same domain it works fine, if the two recipients have different domains, I then get the following response:
Failed to send email. General Exception: Error in processing. The server response was: 4.3.0 Multiple destination domains per transaction is unsupported. Please
There is nothing after please that's the end of the response.
Below is how I am getting the MX Record:
string[] mxRecords = mxLookup.getMXRecords(Classes.CommonTasks.getDomainFromEmail(domain));
public string[] getMXRecords(string domain)
{
DnsLite dl = new DnsLite(library);
ArrayList dnsServers = getDnsServers();
dl.setDnsServers(dnsServers);
ArrayList results = null;
string[] retVal = null;
results = dl.getMXRecords(domain);
if (results != null)
{
retVal = new string[results.Count];
int counter = 0;
foreach (MXRecord mx in results)
{
retVal[counter] = mx.exchange.ToString();
counter++;
}
}
return retVal;
}
Below is how I am sending the email.
if (mxRecords != null)
{
MailMessage composedMail = new MailMessage();
composedMail.From = new MailAddress(message.EmailFromAddress);
//MailAddressCollection test = new MailAddressCollection();
//composedMail.To = test;
composedMail = addRecipientsToEmail(composedMail, message.emailRecipients);
composedMail.Subject = message.subject;
composedMail.Body = message.EmailBody;
if (message.contentType.ToString().Contains("text/html"))
{
composedMail.IsBodyHtml = true;
}
SmtpClient smtp = new SmtpClient(mxRecords[0]);
smtp.DeliveryMethod = SmtpDeliveryMethod.Network;
smtp.Port = 25;
if (Configuration.emailConfig.useSmtpMaxIdleTime)
{
smtp.ServicePoint.MaxIdleTime = 1;
}
library.logging(methodInfo, string.Format("Sending email via MX Record: {0}", mxRecords[0]));
smtp.Send(composedMail);
updateEmailStatus(message.emailID, EmailStatus.Sent);
library.logging(methodInfo, string.Format("Successfully sent email ID: {0}", message.emailID));
}
else
{
string error = string.Format("No MX Record found for domain: {0}", domain);
library.logging(methodInfo, error);
library.setAlarm(error, CommonTasks.AlarmStatus.Warning, methodInfo);
}
This looks as if it is something that Google is restricting from being done but I can't find a way to work around out, other than to send the emails separately for each recipient.
If it's of any use, the two domains are google app domains.
Thanks for any help you can provide.

It seems you are not alone. Check this out.
:
"Based on my investigation and research, I believe what's happening is your system is connecting directly to the delivery server (aspmx.l.google.com). As this is the delivery server, it does not allow:
Delivery to accounts that are not provisioned on Google (i.e., unauthenticated relaying).
Delivery to multiple different domains within the same SMTP session.
The second one is the one that is important to us. As of the beginning of this month(May2012), adjustments were made to our server settings that mean that our delivery server is strictly enforcing the multiple-domain-not-allowed rule. There are two ways to get around this. The first is to send to separate domains on separate smtp sessions, and the second is to use smtp.gmail.com in place of aspmx.l.google.com."
http://productforums.google.com/forum/#!topic/apps/jEUrvTd1S_w

Sine you can send an email with a single recipient through google your issue is not in resolving the mx-record. The Mx record tells an IP-address but doesn't tell about the functionality/behavior of the service behind that ip.
You can resolve the mx-record, so far so good. But you don't need to to resolve the mx on your own as the smtp-client does it on your behalve, just supllying the hostname will do. But note that this was a great excersise to learn more about DNS. No time waste :-)
As far as I recall, sending mail through google in the way you intend you need a google account. Authenticate with the smtp-server with the credentials for that account can open a new perspective

Related

How can I detect if my fetched email is bounced or not

I fetched emails from servers by using IMAP or POP3 and entered the fetched emails to database but I noticed there are a lot of bounced emails entered to the system so I searched a lot on google to check fetched email and if it's bounced email I'll not enter it to the system and I found library BounceDetectResult to detect if email is bounced or not but this library working only with message type MimeMessage so It's useful when I use IMAP but it's not work with message type OpenPop.Mime.Message so I can't use It when I use POP3
var result= BounceDetectorMail.Detect(message);//message type MimeMessage
if (result.IsBounce)
{
em.DelivaryFailure = true;
}
so my problem I didn't find way to detect if my retrieved message is bounced or not when I use pop3 in retrieving
It looks like the MailBounceDetector library that you mentioned uses my MimeKit library to detect if a message is a bounced message or not.
The good news is that you can use that library because I also have a library that does POP3 called MailKit, so you can use that instead of OpenPOP.NET.
For any who may need, from Bounce inspector software library, supports both POP3 and IMAP:
// POP3 server information.
const string serverName = "myserver";
const string user = "name#domain.com";
const string password = "mytestpassword";
const int port = 995;
const SecurityMode securityMode = SecurityMode.Implicit;
// Create a new instance of the Pop3Client class.
Pop3Client client = new Pop3Client();
Console.WriteLine("Connecting Pop3 server: {0}:{1}...", serverName, port);
// Connect to the server.
client.Connect(serverName, port, securityMode);
// Login to the server.
Console.WriteLine("Logging in as {0}...", user);
client.Authenticate(user, password);
// Initialize BounceInspector.
BounceInspector inspector = new BounceInspector();
inspector.AllowInboxDelete = false; // true if you want BounceInspector automatically delete all hard bounces.
// Register processed event handler.
inspector.Processed += inspector_Processed;
// Download messages from Pop3 Inbox to 'c:\test' and process them.
BounceResultCollection result = inspector.ProcessMessages(client, "c:\\test");
// Display processed emails.
foreach (BounceResult r in result)
{
// If this message was identified as a bounced email message.
if (r.Identified)
{
// Print out the result
Console.Write("FileName: {0}\nSubject: {1}\nAddress: {2}\nBounce Category: {3}\nBounce Type: {4}\nDeleted: {5}\nDSN Action: {6}\nDSN Diagnostic Code: {7}\n\n",
System.IO.Path.GetFileName(r.FilePath),
r.MailMessage.Subject,
r.Addresses[0],
r.BounceCategory.Name,
r.BounceType.Name,
r.FileDeleted,
r.Dsn.Action,
r.Dsn.DiagnosticCode);
}
}
Console.WriteLine("{0} bounced message found", result.BounceCount);
// Disconnect.
Console.WriteLine("Disconnecting...");
client.Disconnect();

Exchange - routing agent that changes the email massage's recepient from a distribution group type to single email adresses from its members

i'm building a routing agent for exchange 2010 using c# (framework 3.5)
i have a 3rd party app that recieves emails , and authenticate users via their email address.
the problem starts when i sent an email to a distribution group,
the "To" field is set to the D-group email address, and it causes my trouble with the 3rd party app.
how can i convert the TO field of an email massage sent to : xxxGroup#xxx.com
into: user1inGroup#xxx.com;user2inGroup#xxx.com,.....
this is part of my code, i tried deleting the "to" field, but nothing seems to work.
void ownRoutingAgent_OnResolvedMessage(ResolvedMessageEventSource source, QueuedMessageEventArgs messageEventArgs)
{
bool forwardToSeg = false;
if (true) EventViewerLogger.WriteInfo("FromAddress: " + messageEventArgs.MailItem.FromAddress.ToString());
if (true) EventViewerLogger.WriteInfo("SecureSenders: " + m_SecureSenderAddress);
distGroupList = generateDistGroupList();
////////////////////////////////////////////
//Check if recepient is a distrebution group
Random rnd = new Random();
int numOfUser = rnd.Next(0, senderAddresses.Length);
messageEventArgs.MailItem.FromAddress = new RoutingAddress(senderAddresses[numOfUser]);
// run over all recipients list
//foreach (EnvelopeRecipient recp in messageEventArgs.MailItem.Recipients)
//{
foreach (MyClass disGrp in distGroupList)
{
// Checks if Recipients contain an e-mail group.
// if yes, does not route to seg.
if (messageEventArgs.MailItem.Message.To[0].NativeAddress.ToString().ToUpper() == disGrp.emailAdress.ToUpper())
{
messageEventArgs.MailItem.Message.To[0].NativeAddress.Remove(0);
messageEventArgs.MailItem.Message.To.Remove(new EmailRecipient(messageEventArgs.MailItem.Message.To[0].DisplayName.ToString(),messageEventArgs.MailItem.Message.To[0].NativeAddress.ToString()));
foreach (EnvelopeRecipient yywx in messageEventArgs.MailItem.Recipients)
{
//remove group address from mail-recipients
// messageEventArgs.MailItem.Message.To.Add*******
// = messageEventArgs.MailItem.Recipients
//add all group members to the "TO" field
//messageEventArgs.MailItem.Recipients;
}
}
}
use the AddressBook class to do that or expand the recipients of a message in a Transport Agent . if you want to expand a list that would requires an AD call which can be very costly in terms of performance in a Transport Agent.

Read email one at a time using IMap4Client

I'm reading emails using Imap. My code, which is working, is as follows:
Client.ConnectSsl(mailServer, port);
Mailbox mails = Client.SelectMailbox("inbox");
MessageCollection messages = mails.SearchParse("UNSEEN");
return messages;
But I want to get one email at a time instead of getting all the messages as a MessageCollection. I don't want to loop through MessageCollection either. Is there any method which returns only one message?
For example :
Message email = mails.Search("UNSEEN");
Thank you.
You can Find the below solution
Imap4Client imap = new Imap4Client();
imap.ConnectSsl("imap.gmail.com", 993);
imap.Login("abc#gmail.com", "thatsmypassword");
imap.Command("capability");
Mailbox inbox = imap.SelectMailbox("inbox");
int[] ids = inbox.Search("UNSEEN");
if (ids.Length > 0)
{
Message msg_first = inbox.Fetch.MessageObject(ids[0]);
}
Thanks,
Gauttam

netduino check email

I see lot of examples on how to send email with a but I'm looking to run an action checking an email account.
Does anyone know if that can be done (im sure it can) and point me to some examples?
There are a couple of ways you can get a gmail inbox.
OpenPop
If you do want to just use POP, and you do not mind using external libraries, this looks like the best/easiest way to go. OpenPop allows you to access a secure/unsecure email account and lets you choose the port. See this post to get started.
OpenPop is an open source C#.NET code bundle that implements mail
fetching and parsing. As of this writing, it only uses Microsoft .NET
framework libraries to do the required. But for accessing secure pop
servers, openPop can be extended by using some SSL library.
For example, to access Gmail via Pop:
POPClient poppy = new POPClient();
poppy.Connect("pop.gmail.com", 995, true);
poppy.Authenticate(username#gmail.com, "password");
int Count = poppy.GetMessageCount();
if (Count > 0)
{
for (int i = Count; i >= 1; i -= 1)
{
OpenPOP.MIMEParser.Message m = poppy.GetMessage(i, false);
//use the parsed mail in variable 'm'
}
}
TcpClient POP3:
To retrieve emails from any provider via Pop3, you could use a TcpClient. With Gmail, it is only slightly different, because Gmail uses SSL and port 995 for POP. There is an example of that here:
// create an instance of TcpClient
TcpClient tcpclient = new TcpClient();
// HOST NAME POP SERVER and gmail uses port number 995 for POP
tcpclient.Connect("pop.gmail.com", 995);
// This is Secure Stream // opened the connection between client and POP Server
System.Net.Security.SslStream sslstream = new SslStream(tcpclient.GetStream());
// authenticate as client
sslstream.AuthenticateAsClient("pop.gmail.com");
Gmail Atom Feed:
The first way is to use GmailAtomFeed, which is part of the C# .Net Gmail Tools. The website says:
The GmailAtomFeed class provides a simple object layer for
programmatic access to gmails atom feed. In just a couple lines of
code the feed will be retreived from gmail and parsed. After that the
entries can be accessed through an object layer
AtomFeedEntryCollection, plus access to the raw feed and the feeds
XmlDocument is also available.
And this is an example of how you use it:
// Create the object and get the feed
RC.Gmail.GmailAtomFeed gmailFeed = new RC.Gmail.GmailAtomFeed("username", "password");
gmailFeed.GetFeed();
// Access the feeds XmlDocument
XmlDocument myXml = gmailFeed.FeedXml
// Access the raw feed as a string
string feedString = gmailFeed.RawFeed
// Access the feed through the object
string feedTitle = gmailFeed.Title;
string feedTagline = gmailFeed.Message;
DateTime feedModified = gmailFeed.Modified;
//Get the entries
for(int i = 0; i < gmailFeed.FeedEntries.Count; i++) {
entryAuthorName = gmailFeed.FeedEntries[i].FromName;
entryAuthorEmail = gmailFeed.FeedEntries[i].FromEmail;
entryTitle = gmailFeed.FeedEntries[i].Subject;
entrySummary = gmailFeed.FeedEntries[i].Summary;
entryIssuedDate = gmailFeed.FeedEntries[i].Received;
entryId = gmailFeed.FeedEntries[i].Id;
}
IMAP
Another way, if you are not LIMITED to POP, is to use IMAP. With IMAP, you can connect to a SSL server and choose a port along with that:
using (Imap imap = new Imap())
{
imap.ConnectSSL("imap.gmail.com", 993);
imap.Login("angel_y#company.com", "xyx***"); // MailID As Username and Password
imap.SelectInbox();
List<long> uids = imap.SearchFlag(Flag.Unseen);
foreach (long uid in uids)
{
string eml = imap.GetMessageByUID(uid);
IMail message = new MailBuilder()
.CreateFromEml(eml);
Console.WriteLine(message.Subject);
Console.WriteLine(message.TextDataString);
}
imap.Close(true);
}
I found this code online but "POP3_Client" isn't recognized and I don't see any refrences to add it
POP3_Client Mailbox = new POP3_Client(new >>>>IntegratedSocket<<<<<("pop.yourisp.com", 110), "yourusername", "yourpassword");
Mailbox.Connect();
Debug.Print("Message count: " + Mailbox.MessageCount.ToString());
Debug.Print("Box size in bytes: " + Mailbox.BoxSize.ToString());
uint[] Id, Size;
Mailbox.ListMails(out Id, out Size);
for (int Index = 0; Index < Id.Length; ++Index)
{
string[] Headers = Mailbox.FetchHeaders(Id[Index], new string[] { "subject", "from", "date" });
Debug.Print("Mail ID " + Id[Index].ToString() + " is " + Size[Index].ToString() + " bytes");
Debug.Print("Subject: " + Headers[0]);
Debug.Print("From: " + Headers[1]);
Debug.Print("Date: " + Headers[2]);
Debug.Print("======================================================================");
}
Mailbox.Close();

Transfer content of email to C# page

I have created one web-form that contains controls to add name, date of birth, gender info of user with add button, once add button clicked that info goes to database.
But i have my mailbox, for eg. gmail some mails are coming in inbox that contains info same as earlier(Name, Date of birth, gender etc.). So can i have functionality to transfer that inbox data to my database?
Yes - you can.
There are a lot of libraries that you can leverage to make it trivial to check a Gmail account. Here is just one: http://sourceforge.net/projects/hpop/
Here is sample code for fetching all of your e-mails:
public static List<Message> FetchAllMessages(string hostname, int port, bool useSsl, string username, string password)
{
// The client disconnects from the server when being disposed
using (Pop3Client client = new Pop3Client())
{
// Connect to the server
client.Connect(hostname, port, useSsl);
// Authenticate ourselves towards the server
client.Authenticate(username, password);
// Get the number of messages in the inbox
int messageCount = client.GetMessageCount();
// We want to download all messages
List<Message> allMessages = new List<Message>(messageCount);
// Messages are numbered in the interval: [1, messageCount]
// Ergo: message numbers are 1-based.
// Most servers give the latest message the highest number
for (int i = messageCount; i > 0; i--)
{
allMessages.Add(client.GetMessage(i));
}
// Now return the fetched messages
return allMessages;
}
}
You'll still need to go through each one and determine if it's valid for your database and then grab the data and insert it into the database; but it should be pretty straight-forward (and almost identical to what you are already doing)
For GMail you can use the following to get your mail:
List<Message> myMail = FetchAllMessages("pop.gmail.com", 995, true, "MyEmail#gmail.com", "mysupersecretpasswordshhhhh!");

Categories