summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTyler Bischel <tyler.bischel@sendgrid.com>2012-01-10 10:27:42 -0800
committerTyler Bischel <tyler.bischel@sendgrid.com>2012-01-10 10:27:42 -0800
commite40ecaea2026a525650c02f6b84526c68762fbcb (patch)
tree053dea513490029b90dc7f028b5ff6365abd066d
parentb26c82607d13f1ae532f138b94d7eb681c25d658 (diff)
parent116a26d7d8a5fe569ab0a77e72af30af85ccce39 (diff)
downloadsendgrid-csharp-e40ecaea2026a525650c02f6b84526c68762fbcb.zip
sendgrid-csharp-e40ecaea2026a525650c02f6b84526c68762fbcb.tar.gz
sendgrid-csharp-e40ecaea2026a525650c02f6b84526c68762fbcb.tar.bz2
Merge branch 'us1882' of github.com:sendgrid/sendgrid-csharp into us1882
Conflicts: SendGrid/SendGrid.suo SendGrid/SendGrid/ISendGrid.cs
-rw-r--r--.gitignore8
-rwxr-xr-xSendGrid/SendGrid.suobin40448 -> 0 bytes
-rwxr-xr-xSendGrid/SendGrid/Header.cs56
-rwxr-xr-xSendGrid/SendGrid/ISendGrid.cs46
-rwxr-xr-xSendGrid/SendGrid/Mail.csproj2
-rwxr-xr-xSendGrid/SendGrid/SendGrid.cs460
-rwxr-xr-xSendGrid/SendGrid/Transport/ITransport.cs7
-rwxr-xr-xSendGrid/Tests/TestHeader.cs25
-rwxr-xr-xSendGrid/Tests/Tests.csproj11
9 files changed, 582 insertions, 33 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..0a733fc
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,8 @@
+SendGrid/Example/bin/
+SendGrid/Example/obj/
+SendGrid/SendGrid.sln.DotSettings.user
+SendGrid/SendGrid/bin/
+SendGrid/SendGrid/obj/
+SendGrid/Tests/bin/
+SendGrid/Tests/obj/
+SendGrid/_ReSharper.SendGrid/
diff --git a/SendGrid/SendGrid.suo b/SendGrid/SendGrid.suo
deleted file mode 100755
index 0b80204..0000000
--- a/SendGrid/SendGrid.suo
+++ /dev/null
Binary files differ
diff --git a/SendGrid/SendGrid/Header.cs b/SendGrid/SendGrid/Header.cs
new file mode 100755
index 0000000..13f4e90
--- /dev/null
+++ b/SendGrid/SendGrid/Header.cs
@@ -0,0 +1,56 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net.Mail;
+using System.Text;
+
+namespace SendGrid
+{
+ public class Header : IHeader
+ {
+ public void AddTo(IEnumerable<string> recipients)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void AddSubVal(string tag, IEnumerable<string> substitutions)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void AddUniqueIdentifier(IDictionary<string, string> identifiers)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void SetCategory(string category)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Enable(string filter)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Disable(string filter)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void AddFilterSetting(string filter, IEnumerable<string> settings, string value)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void AddHeader(MailMessage mime)
+ {
+ throw new NotImplementedException();
+ }
+
+ public String AsJson()
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/SendGrid/SendGrid/ISendGrid.cs b/SendGrid/SendGrid/ISendGrid.cs
index 2e06efe..9a9d2c2 100755
--- a/SendGrid/SendGrid/ISendGrid.cs
+++ b/SendGrid/SendGrid/ISendGrid.cs
@@ -1,24 +1,31 @@
using System;
using System.Collections.Generic;
+using System.IO;
using System.Linq;
using System.Net.Mail;
+using System.Net.Mime;
using System.Text;
namespace SendGrid
{
+ public enum TransportType
+ {
+ SMTP,
+ REST
+ };
+
public interface ISendGrid
{
#region Properties
- String From { get; set; }
- String To { get; set; }
- String Cc { get; set; }
- String Bcc { get; set; }
+ MailAddress From { get; set; }
+ MailAddress[] To { get; set; }
+ MailAddress[] Cc { get; }
+ MailAddress[] Bcc { get; }
String Subject { get; set; }
- String Headers { get; set; }
+ IHeader Header { get; set; }
String Html { get; set; }
String Text { get; set; }
- String Transport { get; set; }
- String Date { get; set; }
+ TransportType Transport { get; set; }
#endregion
#region Interface for ITransport
@@ -28,39 +35,26 @@ namespace SendGrid
#region Methods for setting data
void AddTo(String address);
void AddTo(IEnumerable<String> addresses);
- void AddTo(IDictionary<String, String> addresssInfo);
- void AddTo(IEnumerable<IDictionary<String, String>> addressesInfo);
+ void AddTo(IDictionary<String, IDictionary<String, String>> addresssInfo);
void AddCc(String address);
void AddCc(IEnumerable<String> addresses);
- void AddCc(IDictionary<String, String> addresssInfo);
- void AddCc(IEnumerable<IDictionary<String, String>> addressesInfo);
+ void AddCc(IDictionary<String, IDictionary<String, String>> addresssInfo);
void AddBcc(String address);
void AddBcc(IEnumerable<String> addresses);
- void AddBcc(IDictionary<String, String> addresssInfo);
- void AddBcc(IEnumerable<IDictionary<String, String>> addressesInfo);
-
- void AddRcpts(String address);
- void AddRcpts(IEnumerable<String> addresses);
- void AddRcpts(IDictionary<String, String> addresssInfo);
- void AddRcpts(IEnumerable<IDictionary<String, String>> addressesInfo);
+ void AddBcc(IDictionary<String, IDictionary<String, String>> addresssInfo);
void AddSubVal(String tag, String value);
void AddAttachment(String filePath);
void AddAttachment(Attachment attachment);
+ void AddAttachment(Stream attachment, ContentType type);
- String GetMailFrom();
IEnumerable<String> GetRecipients();
-
- String Get(String field);
- void Set(String field, String value);
#endregion
#region SMTP API Functions
- IHeader Header { get; set; }
-
void DisableGravatar();
void DisableOpenTracking();
void DisableClickTracking();
@@ -70,7 +64,7 @@ namespace SendGrid
void DisableGoogleAnalytics();
void DisableTemplate();
void DisableBcc();
- void DisableBipassListManaement();
+ void DisableBypassListManagement();
void EnableGravatar();
void EnableOpenTracking();
@@ -81,7 +75,7 @@ namespace SendGrid
void EnableGoogleAnalytics(String source, String medium, String term, String content = null, String campaign = null);
void EnableTemplate(String html = null);
void EnableBcc(String email = null);
- void EnableBipassListManaement();
+ void EnableBypassListManagement();
#endregion
void Mail();
diff --git a/SendGrid/SendGrid/Mail.csproj b/SendGrid/SendGrid/Mail.csproj
index c54c475..2c2a642 100755
--- a/SendGrid/SendGrid/Mail.csproj
+++ b/SendGrid/SendGrid/Mail.csproj
@@ -42,9 +42,11 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
+ <Compile Include="Header.cs" />
<Compile Include="IHeader.cs" />
<Compile Include="ISendGrid.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="SendGrid.cs" />
<Compile Include="Transport\ITransport.cs" />
<Compile Include="Transport\REST.cs" />
<Compile Include="Transport\SMTP.cs" />
diff --git a/SendGrid/SendGrid/SendGrid.cs b/SendGrid/SendGrid/SendGrid.cs
new file mode 100755
index 0000000..c49019f
--- /dev/null
+++ b/SendGrid/SendGrid/SendGrid.cs
@@ -0,0 +1,460 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Net.Mail;
+using System.Net.Mime;
+using System.Runtime.InteropServices.ComTypes;
+using System.Text;
+
+namespace SendGrid
+{
+ public class SendGrid : ISendGrid
+ {
+ private IHeader header;
+
+ private Dictionary<String, String> _filters;
+
+ //apps list and settings
+ private const String ReText = @"<\%\s*\%>";
+ private const String ReHtml = @"<\%\s*[^\s]+\s*\%>";
+
+ public SendGrid(IHeader header)
+ {
+ this.header = header;
+
+ //initialize the filters, for use within the library
+ this.InitializeFilters();
+ }
+
+ public void InitializeFilters()
+ {
+ this._filters =
+ new Dictionary<string, string>
+ {
+ {"Gravatar", "gravatar"},
+ {"OpenTracking", "opentrack"},
+ {"ClickTracking", "clicktrack"},
+ {"SpamCheck", "spamcheck"},
+ {"Unsubscribe", "subscriptiontrack"},
+ {"Footer", "footer"},
+ {"GoogleAnalytics", "ganalytics"},
+ {"Template", "template"},
+ {"Bcc", "bcc"},
+ {"BypassListManagement", "bypass_list_management"}
+ };
+ }
+
+ private MailMessage message;
+
+ // TODO find appropriate types for these
+ const string encoding = "quoted-printable";
+ const string charset = "utf-8";
+
+ /*
+ if (Html != null )
+ {
+ AlternateView htmlView = AlternateView.CreateAlternateViewFromString(html, null, "text/html");
+ message.AlternateViews.Add(htmlView);
+ }
+
+ if (Text != null )
+ {
+ AlternateView plainView = AlternateView.CreateAlternateViewFromString(Text, null, "text/plain");
+ message.AlternateViews.Add(plainView);
+ }
+
+ message.BodyEncoding = Encoding.GetEncoding(charset);
+ */
+
+ public SendGrid(MailAddress from, MailAddress[] to, MailAddress[] cc, MailAddress[] bcc,
+ String subject, String html, String text, TransportType transport, IHeader header = null )
+ {
+ message = new MailMessage();
+ Header = header;
+
+ From = from;
+ To = to;
+
+ _subs = new Dictionary<string, string>();
+
+ message.Subject = subject;
+ message.SubjectEncoding = Encoding.GetEncoding(charset);
+
+ Text = text;
+ Html = html;
+ }
+
+ public MailAddress From
+ {
+ get
+ {
+ return message.From;
+ }
+ set
+ {
+ if (value != null) message.From = value;
+ }
+ }
+
+ public MailAddress[] To
+ {
+ get
+ {
+ return message.To.ToArray();
+ }
+ set
+ {
+ message.To.Clear();
+ foreach (var mailAddress in value)
+ {
+ message.To.Add(mailAddress);
+ }
+ }
+ }
+
+ public MailAddress[] Cc
+ {
+ get
+ {
+ return message.CC.ToArray();
+ }
+ set
+ {
+ message.CC.Clear();
+ foreach (var mailAddress in value)
+ {
+ message.CC.Add(mailAddress);
+ }
+ }
+ }
+
+ public MailAddress[] Bcc
+ {
+ get
+ {
+ return message.Bcc.ToArray();
+ }
+ set
+ {
+ message.Bcc.Clear();
+ foreach (var mailAddress in value)
+ {
+ message.Bcc.Add(mailAddress);
+ }
+ }
+ }
+
+ public String Subject
+ {
+ get
+ {
+ return message.Subject;
+ }
+ set
+ {
+ if (value != null) message.Subject = value;
+ }
+ }
+
+ public IHeader Header
+ {
+ get { throw new NotImplementedException(); }
+ set { throw new NotImplementedException(); }
+ }
+
+ public String Html { get; set; }
+ public String Text { get; set; }
+
+ public TransportType Transport { get; set; }
+
+ public void AddTo(String address)
+ {
+ var mailAddress = new MailAddress(address);
+ message.To.Add(mailAddress);
+ }
+
+ public void AddTo(IEnumerable<String> addresses)
+ {
+ if (addresses != null)
+ {
+ foreach (var address in addresses)
+ {
+ if (address != null) AddTo(address);
+ }
+ }
+ }
+
+ public void AddTo(IDictionary<String, IDictionary<String, String>> addresssInfo)
+ {
+ foreach (var address in addresssInfo.Keys)
+ {
+ var table = addresssInfo[address];
+ //DisplayName is the only option that this implementation of MailAddress implements.
+ var mailAddress = new MailAddress(address, table.ContainsKey("DisplayName") ? table["DisplayName"] : null);
+ message.To.Add(mailAddress);
+ }
+ }
+
+ public void AddCc(String address)
+ {
+ var mailAddress = new MailAddress(address);
+ message.CC.Add(mailAddress);
+ }
+
+ public void AddCc(IEnumerable<String> addresses)
+ {
+ if (addresses != null)
+ {
+ foreach (var address in addresses)
+ {
+ if (address != null) AddCc(address);
+ }
+ }
+ }
+
+ public void AddCc(IDictionary<String, IDictionary<String, String>> addresssInfo)
+ {
+ foreach (var address in addresssInfo.Keys)
+ {
+ var table = addresssInfo[address];
+ //DisplayName is the only option that this implementation of MailAddress implements.
+ var mailAddress = new MailAddress(address, table.ContainsKey("DisplayName") ? table["DisplayName"] : null);
+ message.CC.Add(mailAddress);
+ }
+ }
+
+ public void AddBcc(String address)
+ {
+ var mailAddress = new MailAddress(address);
+ message.Bcc.Add(mailAddress);
+ }
+
+ public void AddBcc(IEnumerable<String> addresses)
+ {
+ if (addresses != null)
+ {
+ foreach (var address in addresses)
+ {
+ if (address != null) AddBcc(address);
+ }
+ }
+ }
+
+ public void AddBcc(IDictionary<String, IDictionary<String, String>> addresssInfo)
+ {
+ foreach (var address in addresssInfo.Keys)
+ {
+ var table = addresssInfo[address];
+ //DisplayName is the only option that this implementation of MailAddress implements.
+ var mailAddress = new MailAddress(address, table.ContainsKey("DisplayName") ? table["DisplayName"] : null);
+ message.Bcc.Add(mailAddress);
+ }
+ }
+
+ private Dictionary<string, string> _subs;
+
+ public void AddSubVal(string tag, string value)
+ {
+ //let the system complain if they do something bad, since the function returns null
+ _subs[tag] = value;
+ }
+
+ public void AddAttachment(string filePath)
+ {
+ var data = new Attachment(filePath, MediaTypeNames.Application.Octet);
+ message.Attachments.Add(data);
+ }
+
+ public void AddAttachment(Attachment attachment)
+ {
+ message.Attachments.Add(attachment);
+ }
+
+ public void AddAttachment(Stream attachment, ContentType type)
+ {
+ var data = new Attachment(attachment, type);
+ }
+
+ public IEnumerable<string> GetRecipients()
+ {
+ List<MailAddress> tos = message.To.ToList();
+ List<MailAddress> ccs = message.CC.ToList();
+ List<MailAddress> bccs = message.Bcc.ToList();
+
+ var rcpts = tos.Union(ccs.Union(bccs)).Select(address => address.Address);
+ return rcpts;
+ }
+
+ private string Get(string field)
+ {
+ throw new NotImplementedException();
+ }
+
+ private void Set(string field, string value)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void DisableGravatar()
+ {
+ this.header.Disable(this._filters["Gravatar"]);
+ }
+
+ public void DisableOpenTracking()
+ {
+ this.header.Disable(this._filters["OpenTracking"]);
+ }
+
+ public void DisableClickTracking()
+ {
+ this.header.Disable(this._filters["ClickTracking"]);
+ }
+
+ public void DisableSpamCheck()
+ {
+ this.header.Disable(this._filters["SpamCheck"]);
+ }
+
+ public void DisableUnsubscribe()
+ {
+ this.header.Disable(this._filters["Unsubscribe"]);
+ }
+
+ public void DisableFooter()
+ {
+ this.header.Disable(this._filters["Footer"]);
+ }
+
+ public void DisableGoogleAnalytics()
+ {
+ this.header.Disable(this._filters["GoogleAnalytics"]);
+ }
+
+ public void DisableTemplate()
+ {
+ this.header.Disable(this._filters["Template"]);
+ }
+
+ public void DisableBcc()
+ {
+ this.header.Disable(this._filters["Bcc"]);
+ }
+
+ public void DisableBypassListManagement()
+ {
+ this.header.Disable(this._filters["BypassListManagement"]);
+ }
+
+ public void EnableGravatar()
+ {
+ this.header.Enable(this._filters["Gravatar"]);
+ }
+
+ public void EnableOpenTracking()
+ {
+ this.header.Enable(this._filters["OpenTracking"]);
+ }
+
+ public void EnableClickTracking(string text = null)
+ {
+ var filter = this._filters["ClickTracking"];
+
+ this.header.Enable(filter);
+ this.header.AddFilterSetting(filter, new List<string>(){ "text" }, text);
+ }
+
+ public void EnableSpamCheck(int score = 5, string url = null)
+ {
+ var filter = this._filters["SpamCheck"];
+
+ this.header.Enable(filter);
+ this.header.AddFilterSetting(filter, new List<string>(){ "score" }, score.ToString(CultureInfo.InvariantCulture));
+ this.header.AddFilterSetting(filter, new List<string>(){ "url" }, url);
+ }
+
+ public void EnableUnsubscribe(string text, string html, string replace, string url, string landing)
+ {
+ var filter = this._filters["Unsubscribe"];
+
+ if(!System.Text.RegularExpressions.Regex.IsMatch(text, SendGrid.ReText))
+ {
+ throw new Exception("Missing substitution tag in text");
+ }
+
+ if(!System.Text.RegularExpressions.Regex.IsMatch(html, SendGrid.ReHtml))
+ {
+ throw new Exception("Missing substitution tag in html");
+ }
+
+ this.header.Enable(filter);
+ this.header.AddFilterSetting(filter, new List<string>(){ "text" }, text);
+ this.header.AddFilterSetting(filter, new List<string>(){ "html" }, html);
+ this.header.AddFilterSetting(filter, new List<string>(){ "replace"}, replace);
+ this.header.AddFilterSetting(filter, new List<string>(){ "landing" }, landing);
+ }
+
+ public void EnableFooter(string text = null, string html = null)
+ {
+ var filter = this._filters["Footer"];
+
+ this.header.Enable(filter);
+ this.header.AddFilterSetting(filter, new List<string>(){ "text" }, text);
+ this.header.AddFilterSetting(filter, new List<string>(){ "html" }, html);
+ }
+
+ public void EnableGoogleAnalytics(string source, string medium, string term, string content = null, string campaign = null)
+ {
+ var filter = this._filters["GoogleAnalytics"];
+
+ this.header.Enable(filter);
+ this.header.AddFilterSetting(filter, new List<string>(){ "source " }, source);
+ this.header.AddFilterSetting(filter, new List<string>(){ "medium" }, medium);
+ this.header.AddFilterSetting(filter, new List<string>(){ "term" }, term);
+ this.header.AddFilterSetting(filter, new List<string>(){ "content" }, content);
+ this.header.AddFilterSetting(filter, new List<string>(){ "compaign" }, campaign);
+ }
+
+ public void EnableTemplate(string html)
+ {
+ var filter = this._filters["Template"];
+
+ if (!System.Text.RegularExpressions.Regex.IsMatch(html, SendGrid.ReHtml))
+ {
+ throw new Exception("Missing substitution tag in html");
+ }
+
+ this.header.Enable(filter);
+ this.header.AddFilterSetting(filter, new List<string>(){ "html" }, html);
+ }
+
+ public void EnableBcc(string email)
+ {
+ var filter = this._filters["Bcc"];
+
+ this.header.Enable(filter);
+ this.header.AddFilterSetting(filter, new List<string>(){ "email" }, email);
+ }
+
+ public void EnableBypassListManagement()
+ {
+ this.header.Enable(this._filters["BypassListManagement"]);
+ }
+
+ public MailMessage CreateMimeMessage()
+ {
+ String smtpapi = Header.AsJson();
+
+ if (!String.IsNullOrEmpty(smtpapi))
+ this.message.Headers.Add("X-SmtpApi", "{" + smtpapi + "}");
+
+ return this.message;
+ }
+
+ public void Mail()
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/SendGrid/SendGrid/Transport/ITransport.cs b/SendGrid/SendGrid/Transport/ITransport.cs
index 43c7202..3f29f14 100755
--- a/SendGrid/SendGrid/Transport/ITransport.cs
+++ b/SendGrid/SendGrid/Transport/ITransport.cs
@@ -1,9 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace SendGrid.Transport
+namespace SendGrid.Transport
{
/// <summary>
///
diff --git a/SendGrid/Tests/TestHeader.cs b/SendGrid/Tests/TestHeader.cs
new file mode 100755
index 0000000..323e394
--- /dev/null
+++ b/SendGrid/Tests/TestHeader.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Moq;
+using NUnit.Framework;
+using SendGrid;
+
+namespace Tests
+{
+ [TestFixture]
+ public class TestHeader
+ {
+ [Test]
+ public void TestAddTo()
+ {
+ var foo = new Mock<IHeader>();
+ foo.Setup(m => m.Enable("foo"));
+
+ var bar = new SendGrid.SendGrid(foo.Object);
+ Assert.AreEqual(1, 2, "I suck");
+
+ }
+ }
+}
diff --git a/SendGrid/Tests/Tests.csproj b/SendGrid/Tests/Tests.csproj
index 2e52e14..08adf52 100755
--- a/SendGrid/Tests/Tests.csproj
+++ b/SendGrid/Tests/Tests.csproj
@@ -52,12 +52,21 @@
<Reference Include="System.Xml" />
</ItemGroup>
<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" />
+ <None Include="packages.config">
+ <SubType>Designer</SubType>
+ </None>
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\SendGrid\Mail.csproj">
+ <Project>{3C687BEF-FF50-44AD-8315-2D4237281AF8}</Project>
+ <Name>Mail</Name>
+ </ProjectReference>
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />