summaryrefslogtreecommitdiffstats
path: root/SendGrid
diff options
context:
space:
mode:
Diffstat (limited to 'SendGrid')
-rwxr-xr-xSendGrid/SendGrid/Mail.csproj3
-rwxr-xr-xSendGrid/SendGrid/SendGrid.cs1
-rwxr-xr-xSendGrid/SendGrid/Transport/ITransport.cs7
-rwxr-xr-xSendGrid/SendGrid/Transport/REST.cs82
-rwxr-xr-xSendGrid/SendGrid/Transport/SMTP.cs119
-rwxr-xr-xSendGrid/Tests/Tests.csproj3
-rwxr-xr-xSendGrid/Tests/Transport/TestREST.cs18
-rwxr-xr-xSendGrid/Tests/Transport/TestSMTP.cs18
8 files changed, 251 insertions, 0 deletions
diff --git a/SendGrid/SendGrid/Mail.csproj b/SendGrid/SendGrid/Mail.csproj
index d6b0d55..2c2a642 100755
--- a/SendGrid/SendGrid/Mail.csproj
+++ b/SendGrid/SendGrid/Mail.csproj
@@ -34,6 +34,7 @@
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Net" />
+ <Reference Include="System.Web" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
@@ -47,6 +48,8 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SendGrid.cs" />
<Compile Include="Transport\ITransport.cs" />
+ <Compile Include="Transport\REST.cs" />
+ <Compile Include="Transport\SMTP.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
diff --git a/SendGrid/SendGrid/SendGrid.cs b/SendGrid/SendGrid/SendGrid.cs
index 15c549a..c49019f 100755
--- a/SendGrid/SendGrid/SendGrid.cs
+++ b/SendGrid/SendGrid/SendGrid.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Globalization;
using System.IO;
using System.Linq;
using System.Net.Mail;
diff --git a/SendGrid/SendGrid/Transport/ITransport.cs b/SendGrid/SendGrid/Transport/ITransport.cs
index 92557b1..3f29f14 100755
--- a/SendGrid/SendGrid/Transport/ITransport.cs
+++ b/SendGrid/SendGrid/Transport/ITransport.cs
@@ -1,7 +1,14 @@
namespace SendGrid.Transport
{
+ /// <summary>
+ ///
+ /// </summary>
public interface ITransport
{
+ /// <summary>
+ ///
+ /// </summary>
+ /// <param name="message"></param>
void Deliver(ISendGrid message);
}
}
diff --git a/SendGrid/SendGrid/Transport/REST.cs b/SendGrid/SendGrid/Transport/REST.cs
new file mode 100755
index 0000000..8e6baf8
--- /dev/null
+++ b/SendGrid/SendGrid/Transport/REST.cs
@@ -0,0 +1,82 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Text;
+using System.Web;
+using System.Xml;
+
+namespace SendGrid.Transport
+{
+ public class REST : ITransport
+ {
+ // REST delivery settings
+ public const String Endpoint = "https://sendgrid.com/api/mail.send";
+ public const String JsonFormat = "json";
+ public const String XmlFormat = "xml";
+
+ private readonly NameValueCollection _queryParameters;
+ private readonly String _restEndpoint;
+ private readonly String _format;
+
+ public REST(NetworkCredential credentials, String url = Endpoint)
+ {
+ _queryParameters = HttpUtility.ParseQueryString(String.Empty);
+ _queryParameters["api_user"] = credentials.UserName;
+ _queryParameters["api_key"] = credentials.Password;
+
+ _format = XmlFormat;
+ _restEndpoint = url + "." + this._format;
+ }
+
+ public void Deliver(ISendGrid message)
+ {
+ // TODO Fix this to include all recipients
+ _queryParameters["to"] = message.To.First().ToString();
+ _queryParameters["from"] = message.From.ToString();
+ _queryParameters["subject"] = message.Subject;
+ _queryParameters["text"] = message.Text;
+ _queryParameters["html"] = message.Html;
+
+ String smtpapi = message.Header.AsJson();
+
+ if (!String.IsNullOrEmpty(smtpapi))
+ _queryParameters["x-smtpapi"] = smtpapi;
+
+ var restCommand = new Uri(_restEndpoint + "?" + _queryParameters);
+
+ var request = (HttpWebRequest)WebRequest.Create(restCommand.AbsoluteUri);
+ var response = (HttpWebResponse)request.GetResponse();
+
+ // Basically, read the entire message out before we parse the XML.
+ // That way, if we detect an error, we can give the whole response to the client.
+ var r = new StreamReader(response.GetResponseStream());
+ var status = r.ReadToEnd();
+ var bytes = Encoding.ASCII.GetBytes(status);
+ var stream = new MemoryStream(bytes);
+
+ using (var reader = XmlReader.Create(stream))
+ {
+ while (reader.Read())
+ {
+ if (reader.IsStartElement())
+ {
+ switch (reader.Name)
+ {
+ case "result":
+ break;
+ case "message": // success
+ return;
+ case "error": // failure
+ throw new ProtocolViolationException(status);
+ default:
+ throw new ArgumentException("Unknown element: " + reader.Name);
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/SendGrid/SendGrid/Transport/SMTP.cs b/SendGrid/SendGrid/Transport/SMTP.cs
new file mode 100755
index 0000000..0b8b684
--- /dev/null
+++ b/SendGrid/SendGrid/Transport/SMTP.cs
@@ -0,0 +1,119 @@
+using System;
+using System.Net;
+using System.Net.Mail;
+
+namespace SendGrid.Transport
+{
+ /// <summary>
+ /// Transport class for delivering messages via SMTP
+ /// </summary>
+ public class SMTP : ITransport
+ {
+ /// <summary>
+ /// SendGrid's host name
+ /// </summary>
+ public const String SmtpServer = "smtp.sendgrid.net";
+
+ /// <summary>
+ /// Port for Simple Mail Transfer Protocol
+ /// </summary>
+ public const Int32 Port = 25;
+
+ /// <summary>
+ /// Port for Secure SMTP
+ /// </summary>
+ public const Int32 SslPort = 465;
+
+ /// <summary>
+ /// Port for TLS (currently not supported)
+ /// </summary>
+ public const Int32 TlsPort = 571;
+
+ /// <summary>
+ /// Client used to deliver SMTP message
+ /// </summary>
+ private readonly ISmtpClient _client;
+
+ /// <summary>
+ /// Transport created to deliver messages to SendGrid using SMTP
+ /// </summary>
+ /// <param name="client">SMTP client we are wrapping</param>
+ /// <param name="credentials">Sendgrid user credentials</param>
+ /// <param name="host">MTA recieving this message. By default, sent through SendGrid.</param>
+ /// <param name="port">SMTP port 25 is the default. Port 465 can be used for Secure SMTP.</param>
+ private SMTP(ISmtpClient client, NetworkCredential credentials, string host = SmtpServer, int port = Port)
+ {
+ _client = client;
+ switch (port)
+ {
+ case Port:
+ break;
+ case SslPort:
+ _client.EnableSsl = true;
+ break;
+ case TlsPort:
+ throw new NotSupportedException("TLS not supported");
+ }
+ }
+
+ /// <summary>
+ /// Deliver an email using SMTP protocol
+ /// </summary>
+ /// <param name="message"></param>
+ public void Deliver(ISendGrid message)
+ {
+ var mime = message.CreateMimeMessage();
+ _client.Send(mime);
+ }
+
+ /// <summary>
+ /// Transport created to deliver messages to SendGrid using SMTP
+ /// </summary>
+ /// <param name="credentials">Sendgrid user credentials</param>
+ /// <param name="host">MTA recieving this message. By default, sent through SendGrid.</param>
+ /// <param name="port">SMTP port 25 is the default. Port 465 can be used for Secure SMTP.</param>
+ public static SMTP SmtpFactory(NetworkCredential credentials, String host = SmtpServer, Int32 port = Port)
+ {
+ var client = new SmtpWrapper(host, port, credentials, SmtpDeliveryMethod.Network);
+ return new SMTP(client, credentials, host, port);
+ }
+
+ /// <summary>
+ /// Interface to allow testing
+ /// </summary>
+ private interface ISmtpClient
+ {
+ bool EnableSsl { get; set; }
+ void Send(MailMessage mime);
+ }
+
+ /// <summary>
+ /// Implementation of SmtpClient wrapper, separated to allow dependency injection
+ /// </summary>
+ private class SmtpWrapper : ISmtpClient
+ {
+ private readonly SmtpClient _client;
+ public bool EnableSsl
+ {
+ get
+ {
+ return _client.EnableSsl;
+ }
+ set
+ {
+ _client.EnableSsl = value;
+ }
+ }
+
+ public SmtpWrapper(String host, Int32 port, NetworkCredential credentials, SmtpDeliveryMethod deliveryMethod)
+ {
+ _client = new SmtpClient(host, port) { Credentials = credentials, DeliveryMethod = deliveryMethod };
+ }
+
+ public void Send(MailMessage mime)
+ {
+ _client.Send(mime);
+ }
+ }
+ }
+}
diff --git a/SendGrid/Tests/Tests.csproj b/SendGrid/Tests/Tests.csproj
index 778e879..08adf52 100755
--- a/SendGrid/Tests/Tests.csproj
+++ b/SendGrid/Tests/Tests.csproj
@@ -54,6 +54,8 @@
<ItemGroup>
<Compile Include="TestHeader.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="Transport\TestREST.cs" />
+ <Compile Include="Transport\TestSMTP.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config">
@@ -66,6 +68,7 @@
<Name>Mail</Name>
</ProjectReference>
</ItemGroup>
+ <ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
diff --git a/SendGrid/Tests/Transport/TestREST.cs b/SendGrid/Tests/Transport/TestREST.cs
new file mode 100755
index 0000000..747e540
--- /dev/null
+++ b/SendGrid/Tests/Transport/TestREST.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using NUnit.Framework;
+
+namespace Tests.Transport
+{
+ [TestFixture]
+ class TestREST
+ {
+ [Test]
+ public void Deliver()
+ {
+
+ }
+ }
+}
diff --git a/SendGrid/Tests/Transport/TestSMTP.cs b/SendGrid/Tests/Transport/TestSMTP.cs
new file mode 100755
index 0000000..45398ee
--- /dev/null
+++ b/SendGrid/Tests/Transport/TestSMTP.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using NUnit.Framework;
+
+namespace Tests.Transport
+{
+ [TestFixture]
+ public class TestSMTP
+ {
+ [Test]
+ public void Deliver()
+ {
+
+ }
+ }
+}