Introduction
This is a small Windows service that processes SMTP traffic from SharePoint, constructs an e-mail, and sends it off to a remote SMTP server that requires authentication.
Background
I've been struggling to get WSS 3.0 to send e-mail to an authenticated SMTP server. I have tried the SMTP server that is part of IIS with little success. So, I came up with this quick solution after finding code to process SMTP commands. I figured this might be a common problem.
Using the code
Just install SMTPRelaySetup.msi on your SharePoint server and edit the config file.
<configuration>
<appsettings>
<add value="192.168.1.1" key="AllowedIPAddress" />
<add value="Sharepoint Mail" key="MailFromName" />
<add value="mail@sharepoint.com" key="MailFromAddress" />
<add value="mail.sharepoint.com" key="RelayServer" />
<add value="mail@sharepoint.com" key="RelayServerUser" />
<add value="p@ssw0rd" key="RelayServerPassword" />
</appsettings>
</configuration>
The solution contains four projects. There's a WSSMailRelay library project containing most of the functionality, with two projects referencing this library. The WSSMailRelayConsole project is a console application used for testing purposes. The WSSMailRelayService project is the actual Windows service. Finally, WSSMailRelaySetup is the setup project that builds the MSI installer.
I hate debugging Windows services, so whenever I am developing one, I always put most of my code into a separate library. I then reference it from a console application and use that to exclusively debug. The same library is also referenced in the Windows service.
Points of interest
I used Ivar Lumi's SMTP server to process SMTP commands. You can check it out here. Anyways, all I did was create handlers for all the various events that his SMTP server generates and start-up the server.
The most interesting part is when it handles the StoreMessage
event. All I did was create a standard MailMessage
from all the data that was passed into the event argument e
.
void smtpServer_StoreMessage(object sender, LumiSoft.Net.SMTP.Server.NewMail_EventArgs e)
{
Console.WriteLine("Mail From: " + e.MailFrom);
foreach (string email in e.MailTo)
{
Console.WriteLine("Mail To: " + email);
}
StreamReader sr = new StreamReader(e.MessageStream);
string rawBody = sr.ReadToEnd();
Console.WriteLine("Message: " + rawBody);
Console.WriteLine("");
MailMessage message = new MailMessage();
message.From = new MailAddress(e.MailFrom);
foreach (string email in e.MailTo)
{
message.To.Add(email);
}
message.Headers.Clear();
foreach (string line in rawBody.Split(
new string[] { "\r\n" }, StringSplitOptions.None))
{
if (line == string.Empty)
break;
if (line.Contains(":"))
{
string[] headerPair = line.Split(':');
switch (headerPair[0].Trim())
{
case "Subject":
message.Subject = headerPair[1];
break;
case "Reply-To":
message.ReplyTo = new MailAddress(headerPair[1]);
break;
case "From":
message.From = new MailAddress(
ConfigurationManager.AppSettings["MailFromAddress"],
ConfigurationManager.AppSettings["MailFromName"]);
break;
case "Content-Type":
if (headerPair[1].Contains("text/html"))
message.IsBodyHtml = true;
else
message.IsBodyHtml = false;
break;
default:
message.Headers.Add(headerPair[0].Trim(), headerPair[1].Trim());
break;
}
}
}
message.Body = rawBody.Split(new string[] { "\r\n\r\n" },
StringSplitOptions.None)[1];
SmtpClient emailClient = new
SmtpClient(ConfigurationManager.AppSettings["RelayServer"]);
System.Net.NetworkCredential SMTPUserInfo = new
System.Net.NetworkCredential(ConfigurationManager.AppSettings["RelayServerUser"],
ConfigurationManager.AppSettings["RelayServerPassword"]);
emailClient.UseDefaultCredentials = false;
emailClient.Credentials = SMTPUserInfo;
emailClient.Send(message);
}
History
- June 11, 2009 - Initial release.