summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-x.gitignore14
-rwxr-xr-x[-rw-r--r--]README0
-rwxr-xr-xSendGrid/Example/Example.csproj16
-rwxr-xr-xSendGrid/Example/Program.cs65
-rwxr-xr-xSendGrid/Example/RESTAPI.cs95
-rwxr-xr-xSendGrid/Example/SMTPAPI.cs202
-rwxr-xr-xSendGrid/Example/app.config4
-rwxr-xr-xSendGrid/SendGrid.sln2
-rwxr-xr-xSendGrid/SendGrid.suobin39936 -> 0 bytes
-rwxr-xr-xSendGrid/SendGrid/Header.cs56
-rwxr-xr-xSendGrid/SendGrid/IHeader.cs21
-rwxr-xr-xSendGrid/SendGrid/ISendGrid.cs87
-rwxr-xr-xSendGrid/SendGrid/SendGrid.cs301
-rwxr-xr-xSendGrid/SendGrid/Transport/ITransport.cs7
-rwxr-xr-xSendGrid/SendGridMail/Header.cs173
-rwxr-xr-xSendGrid/SendGridMail/IHeader.cs69
-rwxr-xr-xSendGrid/SendGridMail/ISendGrid.cs163
-rwxr-xr-xSendGrid/SendGridMail/Mail.csproj (renamed from SendGrid/SendGrid/Mail.csproj)14
-rwxr-xr-xSendGrid/SendGridMail/Properties/AssemblyInfo.cs (renamed from SendGrid/SendGrid/Properties/AssemblyInfo.cs)13
-rwxr-xr-xSendGrid/SendGridMail/SendGrid.cs540
-rwxr-xr-xSendGrid/SendGridMail/Transport/ITransport.cs14
-rwxr-xr-xSendGrid/SendGridMail/Transport/REST.cs136
-rwxr-xr-xSendGrid/SendGridMail/Transport/SMTP.cs132
-rwxr-xr-xSendGrid/SendGridMail/Utils.cs52
-rwxr-xr-xSendGrid/SendGridMail/Web/IWebApi.cs45
-rwxr-xr-xSendGrid/SendGridMail/WebFileUpload.cs114
-rwxr-xr-xSendGrid/Tests/TestHeader.cs81
-rwxr-xr-xSendGrid/Tests/TestJsonUtils.cs17
-rwxr-xr-xSendGrid/Tests/TestSendgrid.cs289
-rwxr-xr-xSendGrid/Tests/TestSendgridMessageSetup.cs162
-rwxr-xr-xSendGrid/Tests/TestTreeNode.cs100
-rwxr-xr-xSendGrid/Tests/Tests.csproj13
-rwxr-xr-xSendGrid/Tests/Transport/TestREST.cs24
-rwxr-xr-xSendGrid/Tests/Transport/TestSMTP.cs68
-rwxr-xr-xSendGrid/packages/CodeScales.Http.dllbin0 -> 40960 bytes
35 files changed, 2602 insertions, 487 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100755
index 0000000..a492975
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,14 @@
+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/
+*.suo
+SendGrid/Example/bin/
+SendGrid/Example/obj/
+SendGrid/*/bin/
+SendGrid/*/obj/
+
diff --git a/README b/README
index e69de29..e69de29 100644..100755
--- a/README
+++ b/README
diff --git a/SendGrid/Example/Example.csproj b/SendGrid/Example/Example.csproj
index 8ce66d2..cb778d1 100755
--- a/SendGrid/Example/Example.csproj
+++ b/SendGrid/Example/Example.csproj
@@ -11,7 +11,8 @@
<RootNamespace>Example</RootNamespace>
<AssemblyName>Example</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
- <TargetFrameworkProfile>Client</TargetFrameworkProfile>
+ <TargetFrameworkProfile>
+ </TargetFrameworkProfile>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
@@ -46,6 +47,19 @@
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="RESTAPI.cs" />
+ <Compile Include="SMTPAPI.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\SendGridMail\Mail.csproj">
+ <Project>{3C687BEF-FF50-44AD-8315-2D4237281AF8}</Project>
+ <Name>Mail</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="app.config">
+ <SubType>Designer</SubType>
+ </None>
</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/Example/Program.cs b/SendGrid/Example/Program.cs
index abf67f0..87c44a4 100755
--- a/SendGrid/Example/Program.cs
+++ b/SendGrid/Example/Program.cs
@@ -1,16 +1,79 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Net;
using System.Net.Mail;
using System.Text;
+using SendGridMail;
+using SendGridMail.Transport;
namespace Example
{
class Program
{
- static void Main(string[] args)
+ static void Main(String[] args)
{
+ var restInstance = REST.GetInstance(new NetworkCredential("sgrid_username", "sgrid_password"));
+ //create a new message object
+ var message = SendGrid.GenerateInstance();
+
+ message.AddTo("cj.buchmann@sendgrid.com");
+ message.AddTo("tyler.bischel@sendgrid.com");
+ message.AddTo("kyle.partridge@sendgrid.com");
+ message.From = new MailAddress("cj.buchmann@sendgrid.com");
+ message.Html = "<div>hello world</div>";
+ message.Subject = "Hello World SUbject";
+ message.AddAttachment(@"C:\Users\Public\Pictures\Sample Pictures\Koala.jpg");
+ message.AddAttachment(@"C:\Users\Public\Pictures\Sample Pictures\Jellyfish.jpg");
+
+ restInstance.Deliver(message);
+
+ Console.WriteLine("Message Sent");
+ Console.WriteLine("DONE!");
+ Console.ReadLine();
}
+
+ // this code is used for the SMTPAPI examples
+ /*static void Main(string[] args)
+ {
+ var username = "cjbuchmann";
+ var password = "gadget15";
+ var from = "cj.buchmann@sendgrid.com";
+ var to = new List<String>
+ {
+ "cj.buchmann@sendgrid.com"
+ };
+
+ var bcc = new List<string>
+ {
+ "eric@sendgrid.com"
+ };
+
+ var cc = new List<string>
+ {
+ "eric@sendgrid.com"
+ };
+
+ //initialize the SMTPAPI example class
+ var smtpapi = new SMTPAPI(username, password, from, to);
+
+ //send a simple HTML encoded email.
+ //smtpapi.SimpleHTMLEmail();
+
+ //send a simple Plaintext email.
+ //smtpapi.SimplePlaintextEmail();
+
+ //send a gravatar enabled email.
+ //smtpapi.EnableGravatarEmail();
+
+ //send an open tracking enabled email.
+ //smtpapi.EnableOpenTrackingEmail();
+
+ //send an open tracking enabled email.
+ smtpapi.EnableClickTrackingEmail();
+
+ Console.ReadLine();
+ }*/
}
}
diff --git a/SendGrid/Example/RESTAPI.cs b/SendGrid/Example/RESTAPI.cs
new file mode 100755
index 0000000..73dbf04
--- /dev/null
+++ b/SendGrid/Example/RESTAPI.cs
@@ -0,0 +1,95 @@
+using System;
+using System.Linq;
+using System.Collections.Generic;
+using System.Net;
+using System.Net.Mail;
+using SendGridMail;
+using SendGridMail.Transport;
+
+namespace Example
+{
+ class RESTAPI
+ {
+ private String _username;
+ private String _password;
+ private String _from;
+ private IEnumerable<String> _to;
+ private IEnumerable<String> _bcc;
+ private IEnumerable<String> _cc;
+
+ public RESTAPI(String username, String password, String from, IEnumerable<String> recipients, IEnumerable<String> bcc, IEnumerable<String> cc)
+ {
+ _username = username;
+ _password = password;
+ _from = from;
+ _to = recipients;
+ _bcc = bcc;
+ _cc = cc;
+ }
+
+ public void SimpleHTMLEmail()
+ {
+ //create a new message object
+ var message = SendGrid.GenerateInstance();
+
+ //set the message recipients
+
+ if(_to != null)
+ {
+ foreach (String recipient in _to)
+ {
+ message.AddTo(recipient);
+ }
+ }
+
+
+ if(_bcc != null)
+ {
+ foreach (String blindcc in _bcc)
+ {
+ message.AddBcc(blindcc);
+ }
+ }
+
+ if(_cc != null)
+ {
+ foreach (String cc in _cc)
+ {
+ message.AddCc(cc);
+ }
+ }
+
+ var headers = new Dictionary<String, String>
+ {
+ {"key1", "value1"},
+ {"key2", "value2"},
+ {"icanhazcheeze", "kthnxbye"}
+ };
+
+ message.AddHeaders(headers);
+
+ //var replyTo = new List<MailAddress> { new MailAddress("tyler.bischel@sendgrid.com") };
+
+ //message.ReplyTo = replyTo.ToArray();
+
+ //set the sender
+ message.From = new MailAddress(_from);
+
+ //set the message body
+ message.Html = "<html><p>Hello</p><p>World</p></html>";
+
+ //set the message subject
+ message.Subject = "Hello World Simple Test";
+
+ message.AddAttachment(@"D:\att_proj\21.jpg");
+
+ //Utils.PrepareAttachments();
+
+ //create an instance of the SMTP transport mechanism
+ var restInstance = REST.GetInstance(new NetworkCredential(_username, _password));
+
+ //send the mail
+ restInstance.Deliver(message);
+ }
+ }
+}
diff --git a/SendGrid/Example/SMTPAPI.cs b/SendGrid/Example/SMTPAPI.cs
new file mode 100755
index 0000000..b46520b
--- /dev/null
+++ b/SendGrid/Example/SMTPAPI.cs
@@ -0,0 +1,202 @@
+using System;
+using System.Collections.Generic;
+using System.Net;
+using System.Net.Mail;
+using SendGridMail;
+using SendGridMail.Transport;
+
+namespace Example
+{
+ class SMTPAPI
+ {
+ private String _username;
+ private String _password;
+ private String _from;
+ private IEnumerable<string> _to;
+
+ public SMTPAPI(String username, String password, String from, IEnumerable<string> recipients)
+ {
+ _username = username;
+ _password = password;
+ _from = from;
+ _to = recipients;
+ }
+
+ /// <summary>
+ /// Send a simple HTML based email
+ /// </summary>
+ public void SimpleHTMLEmail()
+ {
+ //create a new message object
+ var message = SendGrid.GenerateInstance();
+
+ //set the message recipients
+ foreach(string recipient in _to)
+ {
+ message.AddTo(recipient);
+ }
+
+ //set the sender
+ message.From = new MailAddress(_from);
+
+ //set the message body
+ message.Html = "<html><p>Hello</p><p>World</p></html>";
+
+ //set the message subject
+ message.Subject = "Hello World Simple Test";
+
+ //create an instance of the SMTP transport mechanism
+ var smtpInstance = SMTP.GenerateInstance(new NetworkCredential(_username, _password));
+
+ //send the mail
+ smtpInstance.Deliver(message);
+ }
+
+ /// <summary>
+ /// Send a simple Plain Text email
+ /// </summary>
+ public void SimplePlaintextEmail()
+ {
+ //create a new message object
+ var message = SendGrid.GenerateInstance();
+
+ //set the message recipients
+ foreach(string recipient in _to)
+ {
+ message.AddTo(recipient);
+ }
+
+ //set the sender
+ message.From = new MailAddress(_from);
+
+ //set the message body
+ message.Text = "Hello World Plain Text";
+
+ //set the message subject
+ message.Subject = "Hello World Simple Test";
+
+ //create an instance of the SMTP transport mechanism
+ var smtpInstance = SMTP.GenerateInstance(new NetworkCredential(_username, _password));
+
+ //send the mail
+ smtpInstance.Deliver(message);
+ }
+
+ /// <summary>
+ /// Enable The Gravatar Filter.
+ /// Currently the filter a 1x1 pixel gravatar image.
+ /// Find more info at http://docs.sendgrid.com/documentation/apps/gravatar/
+ /// </summary>
+ public void EnableGravatarEmail()
+ {
+ //create a new message object
+ var message = SendGrid.GenerateInstance();
+
+ //set the message recipients
+ foreach (string recipient in _to)
+ {
+ message.AddTo(recipient);
+ }
+
+ //set the sender
+ message.From = new MailAddress(_from);
+
+ //set the message body
+ message.Html = "<p style='color:red';>Hello World Gravatar Email</p>";
+
+ //set the message subject
+ message.Subject = "Hello World Gravatar Test";
+
+ //create an instance of the SMTP transport mechanism
+ var smtpInstance = SMTP.GenerateInstance(new NetworkCredential(_username, _password));
+
+ //enable gravatar
+ message.EnableGravatar();
+
+ //send the mail
+ smtpInstance.Deliver(message);
+ }
+
+ /// <summary>
+ /// Enable the Open Tracking to track when emails are opened.
+ /// http://docs.sendgrid.com/documentation/apps/open-tracking/
+ /// </summary>
+ public void EnableOpenTrackingEmail()
+ {
+ var header = new Header();
+ //create a new message object
+ var message = SendGrid.GenerateInstance();
+
+ //set the message recipients
+ foreach (string recipient in _to)
+ {
+ message.AddTo(recipient);
+ }
+
+ //set the sender
+ message.From = new MailAddress(_from);
+
+ //set the message body
+ message.Html = "<p style='color:red';>Hello World Plain Text</p>";
+
+ //set the message subject
+ message.Subject = "Hello World Open Tracking Test";
+
+ //create an instance of the SMTP transport mechanism
+ var smtpInstance = SMTP.GenerateInstance(new NetworkCredential(_username, _password));
+
+ //enable gravatar
+ message.EnableOpenTracking();
+
+ Console.WriteLine(header.AsJson());
+
+ //send the mail
+ smtpInstance.Deliver(message);
+
+ Console.WriteLine("done");
+ }
+
+ /// <summary>
+ /// Enable the Open Tracking to track when emails are opened.
+ /// http://docs.sendgrid.com/documentation/apps/open-tracking/
+ /// </summary>
+ public void EnableClickTrackingEmail()
+ {
+ var header = new Header();
+ //create a new message object
+ var message = SendGrid.GenerateInstance();
+
+ //set the message recipients
+ foreach (string recipient in _to)
+ {
+ message.AddTo(recipient);
+ }
+
+ //set the sender
+ message.From = new MailAddress(_from);
+
+ //set the message body
+ var timestamp = DateTime.Now.ToString("HH:mm:ss tt");
+ message.Html = "<p style='color:red';>Hello World Plain Text</p> <a href = 'http://microsoft.com'>Checkout Microsoft!!</a>";
+ message.Html += "<p>Sent At : " + timestamp + "</p>";
+
+ //set the message subject
+ message.Subject = "Hello World Click Tracking Test";
+
+ //create an instance of the SMTP transport mechanism
+ var smtpInstance = SMTP.GenerateInstance(new NetworkCredential(_username, _password));
+
+ //enable clicktracking
+ message.EnableClickTracking("1");
+
+ Console.WriteLine(header.AsJson());
+
+ //send the mail
+ smtpInstance.Deliver(message);
+
+ Console.WriteLine("done");
+ Console.WriteLine("Sent at : "+timestamp);
+ }
+
+ }
+}
diff --git a/SendGrid/Example/app.config b/SendGrid/Example/app.config
new file mode 100755
index 0000000..e212038
--- /dev/null
+++ b/SendGrid/Example/app.config
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<configuration>
+<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup>
+</configuration>
diff --git a/SendGrid/SendGrid.sln b/SendGrid/SendGrid.sln
index 9b0b5b6..cf551e2 100755
--- a/SendGrid/SendGrid.sln
+++ b/SendGrid/SendGrid.sln
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mail", "SendGrid\Mail.csproj", "{3C687BEF-FF50-44AD-8315-2D4237281AF8}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mail", "SendGridMail\Mail.csproj", "{3C687BEF-FF50-44AD-8315-2D4237281AF8}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests", "Tests\Tests.csproj", "{0319E73A-7039-4858-B047-1EDF88BB6BD1}"
EndProject
diff --git a/SendGrid/SendGrid.suo b/SendGrid/SendGrid.suo
deleted file mode 100755
index 1b103bc..0000000
--- a/SendGrid/SendGrid.suo
+++ /dev/null
Binary files differ
diff --git a/SendGrid/SendGrid/Header.cs b/SendGrid/SendGrid/Header.cs
deleted file mode 100755
index 42a538f..0000000
--- a/SendGrid/SendGrid/Header.cs
+++ /dev/null
@@ -1,56 +0,0 @@
-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 void AsJson()
- {
- throw new NotImplementedException();
- }
- }
-}
diff --git a/SendGrid/SendGrid/IHeader.cs b/SendGrid/SendGrid/IHeader.cs
deleted file mode 100755
index 640d985..0000000
--- a/SendGrid/SendGrid/IHeader.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Net.Mail;
-using System.Text;
-
-namespace SendGrid
-{
- public interface IHeader
- {
- void AddTo(IEnumerable<String> recipients);
- void AddSubVal(String tag, IEnumerable<String> substitutions);
- void AddUniqueIdentifier(IDictionary<String, String> identifiers);
- void SetCategory(String category);
- void Enable(String filter);
- void Disable(String filter);
- void AddFilterSetting(String filter, IEnumerable<String> settings, String value);
- void AddHeader(MailMessage mime);
- void AsJson();
- }
-}
diff --git a/SendGrid/SendGrid/ISendGrid.cs b/SendGrid/SendGrid/ISendGrid.cs
deleted file mode 100755
index 20e7114..0000000
--- a/SendGrid/SendGrid/ISendGrid.cs
+++ /dev/null
@@ -1,87 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Net.Mail;
-using System.Text;
-
-namespace SendGrid
-{
- public interface ISendGrid
- {
- #region Properties
- String From { get; set; }
- String To { get; set; }
- String Cc { get; set; }
- String Bcc { get; set; }
- String Subject { get; set; }
- IHeader Header { get; set; }
- String Html { get; set; }
- String Text { get; set; }
- String Transport { get; set; }
- String Date { get; set; }
- #endregion
-
- #region Interface for ITransport
- MailMessage CreateMimeMessage();
- #endregion
-
- #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 AddCc(String address);
- void AddCc(IEnumerable<String> addresses);
- void AddCc(IDictionary<String, String> addresssInfo);
- void AddCc(IEnumerable<IDictionary<String, String>> addressesInfo);
-
- 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 AddSubVal(String tag, String value);
-
- void AddAttachment(String filePath);
- void AddAttachment(Attachment attachment);
-
- String GetMailFrom();
- IEnumerable<String> GetRecipients();
-
- String Get(String field);
- void Set(String field, String value);
- #endregion
-
- #region SMTP API Functions
- void DisableGravatar();
- void DisableOpenTracking();
- void DisableClickTracking();
- void DisableSpamCheck();
- void DisableUnsubscribe();
- void DisableFooter();
- void DisableGoogleAnalytics();
- void DisableTemplate();
- void DisableBcc();
- void DisableBipassListManaement();
-
- void EnableGravatar();
- void EnableOpenTracking();
- void EnableClickTracking(String text = null);
- void EnableSpamCheck(int score = 5, String url = null);
- void EnableUnsubscribe(String text, String html, String replace, String url, String landing);
- void EnableFooter(String text = null, String html = null);
- 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();
- #endregion
-
- void Mail();
- }
-}
diff --git a/SendGrid/SendGrid/SendGrid.cs b/SendGrid/SendGrid/SendGrid.cs
deleted file mode 100755
index 966dc6d..0000000
--- a/SendGrid/SendGrid/SendGrid.cs
+++ /dev/null
@@ -1,301 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Net.Mail;
-using System.Text;
-
-namespace SendGrid
-{
- public class SendGrid : ISendGrid
- {
- public SendGrid(IHeader header)
- {
- throw new NotImplementedException();
- }
-
- public string From
- {
- get { throw new NotImplementedException(); }
- set { throw new NotImplementedException(); }
- }
-
- public string To
- {
- get { throw new NotImplementedException(); }
- set { throw new NotImplementedException(); }
- }
-
- public string Cc
- {
- get { throw new NotImplementedException(); }
- set { throw new NotImplementedException(); }
- }
-
- public string Bcc
- {
- get { throw new NotImplementedException(); }
- set { throw new NotImplementedException(); }
- }
-
- public string Subject
- {
- get { throw new NotImplementedException(); }
- set { throw new NotImplementedException(); }
- }
-
- public IHeader Header
- {
- get { throw new NotImplementedException(); }
- set { throw new NotImplementedException(); }
- }
-
- public string Html
- {
- get { throw new NotImplementedException(); }
- set { throw new NotImplementedException(); }
- }
-
- public string Text
- {
- get { throw new NotImplementedException(); }
- set { throw new NotImplementedException(); }
- }
-
- public string Transport
- {
- get { throw new NotImplementedException(); }
- set { throw new NotImplementedException(); }
- }
-
- public string Date
- {
- get { throw new NotImplementedException(); }
- set { throw new NotImplementedException(); }
- }
-
- public MailMessage CreateMimeMessage()
- {
- throw new NotImplementedException();
- }
-
- public void AddTo(string address)
- {
- throw new NotImplementedException();
- }
-
- public void AddTo(IEnumerable<string> addresses)
- {
- throw new NotImplementedException();
- }
-
- public void AddTo(IDictionary<string, string> addresssInfo)
- {
- throw new NotImplementedException();
- }
-
- public void AddTo(IEnumerable<IDictionary<string, string>> addressesInfo)
- {
- throw new NotImplementedException();
- }
-
- public void AddCc(string address)
- {
- throw new NotImplementedException();
- }
-
- public void AddCc(IEnumerable<string> addresses)
- {
- throw new NotImplementedException();
- }
-
- public void AddCc(IDictionary<string, string> addresssInfo)
- {
- throw new NotImplementedException();
- }
-
- public void AddCc(IEnumerable<IDictionary<string, string>> addressesInfo)
- {
- throw new NotImplementedException();
- }
-
- public void AddBcc(string address)
- {
- throw new NotImplementedException();
- }
-
- public void AddBcc(IEnumerable<string> addresses)
- {
- throw new NotImplementedException();
- }
-
- public void AddBcc(IDictionary<string, string> addresssInfo)
- {
- throw new NotImplementedException();
- }
-
- public void AddBcc(IEnumerable<IDictionary<string, string>> addressesInfo)
- {
- throw new NotImplementedException();
- }
-
- public void AddRcpts(string address)
- {
- throw new NotImplementedException();
- }
-
- public void AddRcpts(IEnumerable<string> addresses)
- {
- throw new NotImplementedException();
- }
-
- public void AddRcpts(IDictionary<string, string> addresssInfo)
- {
- throw new NotImplementedException();
- }
-
- public void AddRcpts(IEnumerable<IDictionary<string, string>> addressesInfo)
- {
- throw new NotImplementedException();
- }
-
- public void AddSubVal(string tag, string value)
- {
- throw new NotImplementedException();
- }
-
- public void AddAttachment(string filePath)
- {
- throw new NotImplementedException();
- }
-
- public void AddAttachment(Attachment attachment)
- {
- throw new NotImplementedException();
- }
-
- public string GetMailFrom()
- {
- throw new NotImplementedException();
- }
-
- public IEnumerable<string> GetRecipients()
- {
- throw new NotImplementedException();
- }
-
- public string Get(string field)
- {
- throw new NotImplementedException();
- }
-
- public void Set(string field, string value)
- {
- throw new NotImplementedException();
- }
-
- public void DisableGravatar()
- {
- throw new NotImplementedException();
- }
-
- public void DisableOpenTracking()
- {
- throw new NotImplementedException();
- }
-
- public void DisableClickTracking()
- {
- throw new NotImplementedException();
- }
-
- public void DisableSpamCheck()
- {
- throw new NotImplementedException();
- }
-
- public void DisableUnsubscribe()
- {
- throw new NotImplementedException();
- }
-
- public void DisableFooter()
- {
- throw new NotImplementedException();
- }
-
- public void DisableGoogleAnalytics()
- {
- throw new NotImplementedException();
- }
-
- public void DisableTemplate()
- {
- throw new NotImplementedException();
- }
-
- public void DisableBcc()
- {
- throw new NotImplementedException();
- }
-
- public void DisableBipassListManaement()
- {
- throw new NotImplementedException();
- }
-
- public void EnableGravatar()
- {
- throw new NotImplementedException();
- }
-
- public void EnableOpenTracking()
- {
- throw new NotImplementedException();
- }
-
- public void EnableClickTracking(string text = null)
- {
- throw new NotImplementedException();
- }
-
- public void EnableSpamCheck(int score = 5, string url = null)
- {
- throw new NotImplementedException();
- }
-
- public void EnableUnsubscribe(string text, string html, string replace, string url, string landing)
- {
- throw new NotImplementedException();
- }
-
- public void EnableFooter(string text = null, string html = null)
- {
- throw new NotImplementedException();
- }
-
- public void EnableGoogleAnalytics(string source, string medium, string term, string content = null, string campaign = null)
- {
- throw new NotImplementedException();
- }
-
- public void EnableTemplate(string html = null)
- {
- throw new NotImplementedException();
- }
-
- public void EnableBcc(string email = null)
- {
- throw new NotImplementedException();
- }
-
- public void EnableBipassListManaement()
- {
- throw new NotImplementedException();
- }
-
- public void Mail()
- {
- throw new NotImplementedException();
- }
- }
-}
diff --git a/SendGrid/SendGrid/Transport/ITransport.cs b/SendGrid/SendGrid/Transport/ITransport.cs
deleted file mode 100755
index 92557b1..0000000
--- a/SendGrid/SendGrid/Transport/ITransport.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace SendGrid.Transport
-{
- public interface ITransport
- {
- void Deliver(ISendGrid message);
- }
-}
diff --git a/SendGrid/SendGridMail/Header.cs b/SendGrid/SendGridMail/Header.cs
new file mode 100755
index 0000000..f1328f5
--- /dev/null
+++ b/SendGrid/SendGridMail/Header.cs
@@ -0,0 +1,173 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net.Mail;
+
+namespace SendGridMail
+{
+ public class Header : IHeader
+ {
+ private const string SendgridHeader = "X-Smtpapi";
+ private readonly HeaderSettingsNode _settings;
+
+ public Header()
+ {
+ _settings = new HeaderSettingsNode();
+ }
+
+ public void AddSubVal(string tag, IEnumerable<string> substitutions)
+ {
+ var keys = new List<String> {"sub", tag};
+ _settings.AddArray(keys, substitutions);
+ }
+
+ public void AddUniqueIdentifier(IDictionary<string, string> identifiers)
+ {
+ foreach (var key in identifiers.Keys)
+ {
+ var keys = new List<String> {"unique_args", key};
+ var value = identifiers[key];
+ _settings.AddSetting(keys, value);
+ }
+ }
+
+ public void SetCategory(string category)
+ {
+ var keys = new List<String> {"category"};
+ _settings.AddSetting(keys, category);
+ }
+
+ public void Enable(string filter)
+ {
+ AddFilterSetting(filter, new List<string>(){ "enable" }, "1");
+ }
+
+ public void Disable(string filter)
+ {
+ AddFilterSetting(filter, new List<string>(){"enable"}, "0");
+ }
+
+ public void AddFilterSetting(string filter, IEnumerable<string> settings, string value)
+ {
+ var keys = new List<string>() {"filters", filter, "settings" }.Concat(settings).ToList();
+ _settings.AddSetting(keys, value);
+ }
+
+ public void AddHeader(MailMessage mime)
+ {
+ mime.Headers.Add(SendgridHeader, AsJson());
+ }
+
+ public String AsJson()
+ {
+ if(_settings.IsEmpty()) return "";
+ return _settings.ToJson();
+ }
+
+ internal class HeaderSettingsNode
+ {
+ private readonly Dictionary<String, HeaderSettingsNode> _branches;
+ private IEnumerable<String> _array;
+ private String _leaf;
+
+ public HeaderSettingsNode()
+ {
+ _branches = new Dictionary<string, HeaderSettingsNode>();
+ }
+
+ public void AddArray(List<String> keys, IEnumerable<String> value)
+ {
+ if (keys.Count == 0)
+ {
+ _array = value;
+ }
+ else
+ {
+ if (_leaf != null || _array != null)
+ throw new ArgumentException("Attempt to overwrite setting");
+
+ var key = keys.First();
+ if (!_branches.ContainsKey(key))
+ _branches[key] = new HeaderSettingsNode();
+
+ var remainingKeys = keys.Skip(1).ToList();
+ _branches[key].AddArray(remainingKeys, value);
+ }
+ }
+
+ public void AddSetting(List<String> keys, String value)
+ {
+ if (keys.Count == 0)
+ {
+ _leaf = value;
+ }
+ else
+ {
+ if(_leaf != null || _array != null)
+ throw new ArgumentException("Attempt to overwrite setting");
+
+ var key = keys.First();
+ if (!_branches.ContainsKey(key))
+ _branches[key] = new HeaderSettingsNode();
+
+ var remainingKeys = keys.Skip(1).ToList();
+ _branches[key].AddSetting(remainingKeys, value);
+ }
+ }
+
+ public String GetSetting(params String[] keys)
+ {
+ return GetSetting(keys.ToList());
+ }
+
+ public String GetSetting(List<String> keys)
+ {
+ if (keys.Count == 0)
+ return _leaf;
+ var key = keys.First();
+ if(!_branches.ContainsKey(key))
+ throw new ArgumentException("Bad key path!");
+ var remainingKeys = keys.Skip(1).ToList();
+ return _branches[key].GetSetting(remainingKeys);
+ }
+
+ public IEnumerable<String> GetArray(params String[] keys)
+ {
+ return GetArray(keys.ToList());
+ }
+
+ public IEnumerable<String> GetArray(List<String> keys)
+ {
+ if (keys.Count == 0)
+ return _array;
+ var key = keys.First();
+ if (!_branches.ContainsKey(key))
+ throw new ArgumentException("Bad key path!");
+ var remainingKeys = keys.Skip(1).ToList();
+ return _branches[key].GetArray(remainingKeys);
+ }
+
+ public String GetLeaf()
+ {
+ return _leaf;
+ }
+
+ public String ToJson()
+ {
+ if (_branches.Count > 0)
+ return "{" + String.Join(",", _branches.Keys.Select(k => Utils.Serialize(k) + " : " + _branches[k].ToJson())) + "}";
+ if (_leaf != null)
+ return Utils.Serialize(_leaf);
+ if (_array != null)
+ return "[" + String.Join(", ", _array.Select(i => Utils.Serialize(i))) + "]";
+ return "{}";
+ }
+
+ public bool IsEmpty()
+ {
+ if (_leaf != null) return false;
+ return _branches == null || _branches.Keys.Count == 0;
+ }
+ }
+ }
+}
diff --git a/SendGrid/SendGridMail/IHeader.cs b/SendGrid/SendGridMail/IHeader.cs
new file mode 100755
index 0000000..f55eadd
--- /dev/null
+++ b/SendGrid/SendGridMail/IHeader.cs
@@ -0,0 +1,69 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net.Mail;
+using System.Text;
+
+namespace SendGridMail
+{
+ /// <summary>
+ /// Represents the additional functionality to add SendGrid specific mail headers
+ /// </summary>
+ public interface IHeader
+ {
+ /// <summary>
+ /// This adds a substitution value to be used during the mail merge. Substitutions
+ /// will happen in order added, so calls to this should match calls to addTo in the mail message.
+ /// </summary>
+ /// <param name="tag">string to be replaced in the message</param>
+ /// <param name="substitutions">substitutions to be made, one per recipient</param>
+ void AddSubVal(String tag, IEnumerable<String> substitutions);
+
+ /// <summary>
+ /// This adds parameters and values that will be bassed back through SendGrid's
+ /// Event API if an event notification is triggered by this email.
+ /// </summary>
+ /// <param name="identifiers">parameter value pairs to be passed back on event notification</param>
+ void AddUniqueIdentifier(IDictionary<String, String> identifiers);
+
+ /// <summary>
+ /// This sets the category for this email. Statistics are stored on a per category
+ /// basis, so this can be useful for tracking on a per group basis.
+ /// </summary>
+ /// <param name="category">categories applied to the message</param>
+ void SetCategory(String category);
+
+ /// <summary>
+ /// Shortcut method for enabling a filter.
+ /// </summary>
+ /// <param name="filter">The name of the filter to enable</param>
+ void Enable(String filter);
+
+ /// <summary>
+ /// Shortcut method for disabling a filter.
+ /// </summary>
+ /// <param name="filter">The name of the filter to disable</param>
+ void Disable(String filter);
+
+ /// <summary>
+ /// Allows you to specify a filter setting. You can find a list of filters and settings here:
+ /// http://docs.sendgrid.com/documentation/api/web-api/filtersettings/
+ /// </summary>
+ /// <param name="filter">The name of the filter to set</param>
+ /// <param name="settings">The multipart name of the parameter being set</param>
+ /// <param name="value">The value that the settings name will be assigning</param>
+ void AddFilterSetting(String filter, IEnumerable<String> settings, String value);
+
+ /// <summary>
+ /// Attaches the SendGrid headers to the MIME.
+ /// </summary>
+ /// <param name="mime">the MIME to which we are attaching</param>
+ void AddHeader(MailMessage mime);
+
+ /// <summary>
+ /// Converts the filter settings into a JSON string.
+ /// </summary>
+ /// <returns>String representation of the SendGrid headers</returns>
+ String AsJson();
+ }
+}
diff --git a/SendGrid/SendGridMail/ISendGrid.cs b/SendGrid/SendGridMail/ISendGrid.cs
new file mode 100755
index 0000000..a292edc
--- /dev/null
+++ b/SendGrid/SendGridMail/ISendGrid.cs
@@ -0,0 +1,163 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Net.Mail;
+using System.Net.Mime;
+using System.Text;
+
+namespace SendGridMail
+{
+ /// <summary>
+ /// Internal object to represent the way in which email may be sent.
+ /// The library supports sending through either SMTP or REST interfaces.
+ /// </summary>
+ public enum TransportType
+ {
+ SMTP,
+ REST
+ };
+
+ /// <summary>
+ /// Represents the basic set of functions that will be called by the user
+ /// includes basic message data manipulation and filter settings
+ /// </summary>
+ public interface ISendGrid
+ {
+ #region Properties
+ MailAddress From { get; set; }
+ MailAddress[] To { get; set; }
+ MailAddress[] Cc { get; }
+ MailAddress[] Bcc { get; }
+ MailAddress[] ReplyTo { get; set; }
+ String[] Attachments { get; set; }
+ String Subject { get; set; }
+ Dictionary<String, String> Headers { get; set; }
+ IHeader Header { get; set; }
+ String Html { get; set; }
+ String Text { get; set; }
+ TransportType Transport { get; set; }
+ #endregion
+
+ #region Interface for ITransport
+ MailMessage CreateMimeMessage();
+ #endregion
+
+ #region Methods for setting data
+ /// <summary>
+ /// Set the To address. In this case the input is a single string eg. 'you@company.com'
+ /// </summary>
+ /// <param name="address"></param>
+ void AddTo(String address);
+ /// <summary>
+ /// Set the To address. In this case the expected input is a list of addresses as strings
+ /// </summary>
+ /// <param name="addresses"></param>
+ void AddTo(IEnumerable<String> addresses);
+ /// <summary>
+ /// Set the To address. In this case the expected input is a list of addresses with paramaters.
+ /// The first parameter is a string for the email address.
+ /// The second paramater is a dictionary containing the key, value pairs for a property's name and its value.
+ /// Currently the only value that you can set with the MailAddress data object is the 'DisplayName' field.
+ /// </summary>
+ /// <param name="addresssInfo"></param>
+ void AddTo(IDictionary<String, IDictionary<String, String>> addresssInfo);
+
+ /// <summary>
+ /// Add the CC address. In this case the expected input is a single email address eg "you@company.com"
+ /// </summary>
+ /// <param name="address"></param>
+ void AddCc(String address);
+ /// <summary>
+ /// Set the CC address. In this case the expected input is a list of addresses as strings
+ /// </summary>
+ /// <param name="addresses"></param>
+ void AddCc(IEnumerable<String> addresses);
+ /// <summary>
+ /// Set the CC address. In this case the expected input is a list of addresses with paramaters.
+ /// The first parameter is a string for the email address.
+ /// The second paramater is a dictionary containing the key, value pairs for a property's name and its value.
+ /// Currently the only value that you can set with the MailAddress data object is the 'DisplayName' field.
+ /// </summary>
+ /// <param name="addresssInfo"></param>
+ void AddCc(IDictionary<String, IDictionary<String, String>> addresssInfo);
+
+ /// <summary>
+ /// Set the Bcc address. Expects a single email as the input eg "you@company.com"
+ /// </summary>
+ /// <param name="address"></param>
+ void AddBcc(String address);
+ /// <summary>
+ /// Set the Bcc address. Expects a list of emails as an array of strings.
+ /// </summary>
+ /// <param name="addresses"></param>
+ void AddBcc(IEnumerable<String> addresses);
+ /// <summary>
+ /// Set the Bcc address. In this case the expected input is a list of addresses with paramaters.
+ /// The first parameter is a string for the email address.
+ /// The second paramater is a dictionary containing the key, value pairs for a property's name and its value.
+ /// Currently the only value that you can set with the MailAddress data object is the 'DisplayName' field.
+ /// </summary>
+ /// <param name="addresssInfo"></param>
+ void AddBcc(IDictionary<String, IDictionary<String, String>> addresssInfo);
+
+ /// <summary>
+ /// Sets a list of substitution values for the email.
+ /// the 'tag' parameter is the value in the email that you'll replace eg. '-name-'
+ /// the 'value' parameter is a list of values that will be substituted in for the tag.
+ /// In our example above the list would be something like ['eric', 'tyler', 'cj'].
+ /// The 'value' parameter expects a 1:1 mapping from email addresses to values.
+ /// If you are left with more email addresses then values to substitute then the substitution tag will be left blank.
+ /// </summary>
+ /// <param name="tag"></param>
+ /// <param name="value"></param>
+ void AddSubVal(String tag, params String[] value);
+
+ /// <summary>
+ /// Add an attachment to the message.
+ /// The 'filePath' paramater expects a fully qualified file path as a string
+ /// </summary>
+ /// <param name="filePath"></param>
+ void AddAttachment(String filePath);
+
+ /// <summary>
+ /// GetRecipients returns a list of all the recepients by retrieving the to, cc, and bcc lists.
+ /// </summary>
+ /// <returns></returns>
+ IEnumerable<String> GetRecipients();
+
+ /// <summary>
+ /// Add custom headers to the message
+ /// </summary>
+ /// <param name="headers">key value pairs</param>
+ void AddHeaders(IDictionary<String, String> headers);
+ #endregion
+
+ #region SMTP API Functions
+ void DisableGravatar();
+ void DisableOpenTracking();
+ void DisableClickTracking();
+ void DisableSpamCheck();
+ void DisableUnsubscribe();
+ void DisableFooter();
+ void DisableGoogleAnalytics();
+ void DisableTemplate();
+ void DisableBcc();
+ void DisableBypassListManagement();
+
+ void EnableGravatar();
+ void EnableOpenTracking();
+ void EnableClickTracking(String text = null);
+ void EnableSpamCheck(int score = 5, String url = null);
+ void EnableUnsubscribe(String text, String html, String replace, String url, String landing);
+ void EnableFooter(String text = null, String html = null);
+ 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 EnableBypassListManagement();
+ #endregion
+
+ void Mail(NetworkCredential credentials);
+ }
+}
diff --git a/SendGrid/SendGrid/Mail.csproj b/SendGrid/SendGridMail/Mail.csproj
index d6b0d55..f333f36 100755
--- a/SendGrid/SendGrid/Mail.csproj
+++ b/SendGrid/SendGridMail/Mail.csproj
@@ -8,8 +8,8 @@
<ProjectGuid>{3C687BEF-FF50-44AD-8315-2D4237281AF8}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
- <RootNamespace>SendGrid</RootNamespace>
- <AssemblyName>SendGrid</AssemblyName>
+ <RootNamespace>SendGridMail</RootNamespace>
+ <AssemblyName>SendGridMail</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
@@ -31,9 +31,15 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
+ <Reference Include="CodeScales.Http">
+ <HintPath>..\packages\CodeScales.Http.dll</HintPath>
+ </Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Net" />
+ <Reference Include="System.Runtime.Serialization" />
+ <Reference Include="System.ServiceModel.Web" />
+ <Reference Include="System.Web" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
@@ -47,6 +53,10 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SendGrid.cs" />
<Compile Include="Transport\ITransport.cs" />
+ <Compile Include="Transport\REST.cs" />
+ <Compile Include="Transport\SMTP.cs" />
+ <Compile Include="Utils.cs" />
+ <Compile Include="WebFileUpload.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/Properties/AssemblyInfo.cs b/SendGrid/SendGridMail/Properties/AssemblyInfo.cs
index 9d0b25e..0108aa9 100755
--- a/SendGrid/SendGrid/Properties/AssemblyInfo.cs
+++ b/SendGrid/SendGridMail/Properties/AssemblyInfo.cs
@@ -5,11 +5,11 @@ using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
-[assembly: AssemblyTitle("SendGrid")]
+[assembly: AssemblyTitle("SendGridMail")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("SendGrid")]
+[assembly: AssemblyProduct("SendGridMail")]
[assembly: AssemblyCopyright("Copyright © 2012")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
@@ -22,6 +22,15 @@ using System.Runtime.InteropServices;
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("193fa200-8430-4206-aacd-2d2bb2dfa6cf")]
+[assembly: InternalsVisibleTo("Tests")]
+[assembly:InternalsVisibleTo("DynamicProxyGenAssembly2," +
+"1310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b" +
+"PublicKey=002400000480000094000000060200000024000052534" +
+"3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d926665" +
+"4753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb" +
+"4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c486" +
+"1eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")]
+
// Version information for an assembly consists of the following four values:
//
// Major Version
diff --git a/SendGrid/SendGridMail/SendGrid.cs b/SendGrid/SendGridMail/SendGrid.cs
new file mode 100755
index 0000000..0a6a466
--- /dev/null
+++ b/SendGrid/SendGridMail/SendGrid.cs
@@ -0,0 +1,540 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Net.Mail;
+using System.Net.Mime;
+using System.Runtime.InteropServices.ComTypes;
+using System.Text;
+using SendGridMail.Transport;
+
+namespace SendGridMail
+{
+ public class SendGrid : ISendGrid
+ {
+ #region constants/vars
+ //private/constant vars:
+ private Dictionary<String, String> _filters;
+ private MailMessage message;
+
+ // TODO find appropriate types for these
+ const string encoding = "quoted-printable";
+ const string charset = "utf-8";
+
+ //apps list and settings
+ private const String ReText = @"<\%\s*\%>";
+ private const String ReHtml = @"<\%\s*[^\s]+\s*\%>";
+ #endregion
+
+ #region Initialization and Constructors
+ /// <summary>
+ /// Creates an instance of SendGrid's custom message object
+ /// </summary>
+ /// <returns></returns>
+ public static SendGrid GenerateInstance()
+ {
+ var header = new Header();
+ return new SendGrid(header);
+ }
+
+ /// <summary>
+ /// Creates an instance of SendGrid's custom message object with mail parameters
+ /// </summary>
+ /// <param name="from">The email address of the sender</param>
+ /// <param name="to">An array of the recipients</param>
+ /// <param name="cc">Supported over SMTP, with future plans for support in the REST transport</param>
+ /// <param name="bcc">Blind recipients</param>
+ /// <param name="subject">The subject of the message</param>
+ /// <param name="html">the html content for the message</param>
+ /// <param name="text">the plain text part of the message</param>
+ /// <param name="transport">Transport class to use for sending the message</param>
+ /// <returns></returns>
+ public static SendGrid GenerateInstance(MailAddress from, MailAddress[] to, MailAddress[] cc, MailAddress[] bcc,
+ String subject, String html, String text, TransportType transport)
+ {
+ var header = new Header();
+ return new SendGrid(from, to, cc, bcc, subject, html, text, transport, header);
+ }
+
+ internal SendGrid(MailAddress from, MailAddress[] to, MailAddress[] cc, MailAddress[] bcc,
+ String subject, String html, String text, TransportType transport, IHeader header = null ) : this(header)
+ {
+ From = from;
+ To = to;
+ Cc = cc;
+ Bcc = bcc;
+
+ message.Subject = subject;
+
+ Text = text;
+ Html = html;
+ }
+
+ internal SendGrid(IHeader header)
+ {
+ message = new MailMessage();
+ Header = header;
+ Headers = new Dictionary<string, string>();
+
+ //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"}
+ };
+ }
+ #endregion
+
+ #region Properties
+ public MailAddress From
+ {
+ get
+ {
+ return message.From;
+ }
+ set
+ {
+ if (value != null) message.From = value;
+ }
+ }
+
+ public MailAddress[] ReplyTo
+ {
+ get
+ {
+ return message.ReplyToList.ToArray();
+ }
+ set
+ {
+ message.ReplyToList.Clear();
+ foreach (var replyTo in value)
+ {
+ message.ReplyToList.Add(replyTo);
+ }
+ }
+ }
+
+ 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 Dictionary<String, String> Headers { get; set; }
+ public IHeader Header { get; set; }
+ public String Html { get; set; }
+ public String Text { get; set; }
+ public TransportType Transport { get; set; }
+ #endregion
+
+ #region Methods for setting data
+ 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 List<String> _attachments = new List<String>();
+ public String[] Attachments
+ {
+ get { return _attachments.ToArray(); }
+ set { _attachments = value.ToList(); }
+ }
+
+ public void AddSubVal(String tag, params String[] value)
+ {
+ //let the system complain if they do something bad, since the function returns null
+ Header.AddSubVal(tag, value);
+ }
+
+ public void AddAttachment(String filePath)
+ {
+ _attachments.Add(filePath);
+ }
+
+ 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;
+ }
+
+ public void AddHeaders(IDictionary<string, string> headers)
+ {
+ headers.Keys.ToList().ForEach(key => Headers[key] = headers[key]);
+ }
+ #endregion
+
+ #region SMTP API Functions
+ public void DisableGravatar()
+ {
+ Header.Disable(this._filters["Gravatar"]);
+ }
+
+ public void DisableOpenTracking()
+ {
+ Header.Disable(this._filters["OpenTracking"]);
+ }
+
+ public void DisableClickTracking()
+ {
+ Header.Disable(this._filters["ClickTracking"]);
+ }
+
+ public void DisableSpamCheck()
+ {
+ Header.Disable(this._filters["SpamCheck"]);
+ }
+
+ public void DisableUnsubscribe()
+ {
+ Header.Disable(this._filters["Unsubscribe"]);
+ }
+
+ public void DisableFooter()
+ {
+ Header.Disable(this._filters["Footer"]);
+ }
+
+ public void DisableGoogleAnalytics()
+ {
+ Header.Disable(this._filters["GoogleAnalytics"]);
+ }
+
+ public void DisableTemplate()
+ {
+ Header.Disable(this._filters["Template"]);
+ }
+
+ public void DisableBcc()
+ {
+ Header.Disable(this._filters["Bcc"]);
+ }
+
+ public void DisableBypassListManagement()
+ {
+ Header.Disable(this._filters["BypassListManagement"]);
+ }
+
+ public void EnableGravatar()
+ {
+ Header.Enable(this._filters["Gravatar"]);
+ }
+
+ public void EnableOpenTracking()
+ {
+ Header.Enable(this._filters["OpenTracking"]);
+ }
+
+ public void EnableClickTracking(String enableText = null)
+ {
+ var filter = this._filters["ClickTracking"];
+
+ Header.Enable(filter);
+ if (enableText != null)
+ {
+ Header.AddFilterSetting(filter, new List<string>() { "enable" }, enableText);
+ }
+ }
+
+ public void EnableSpamCheck(int score = 5, string url = null)
+ {
+ var filter = this._filters["SpamCheck"];
+
+ Header.Enable(filter);
+ Header.AddFilterSetting(filter, new List<string>(){ "score" }, score.ToString(CultureInfo.InvariantCulture));
+ 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");
+ }
+
+ Header.Enable(filter);
+ Header.AddFilterSetting(filter, new List<string>(){ "text" }, text);
+ Header.AddFilterSetting(filter, new List<string>(){ "html" }, html);
+ Header.AddFilterSetting(filter, new List<string>(){ "replace"}, replace);
+ Header.AddFilterSetting(filter, new List<string>(){ "url"}, url);
+ Header.AddFilterSetting(filter, new List<string>(){ "landing" }, landing);
+ }
+
+ public void EnableFooter(string text = null, string html = null)
+ {
+ var filter = this._filters["Footer"];
+
+ Header.Enable(filter);
+ Header.AddFilterSetting(filter, new List<string>(){ "text" }, text);
+ 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"];
+
+ Header.Enable(filter);
+ Header.AddFilterSetting(filter, new List<string>(){ "source" }, source);
+ Header.AddFilterSetting(filter, new List<string>(){ "medium" }, medium);
+ Header.AddFilterSetting(filter, new List<string>(){ "term" }, term);
+ Header.AddFilterSetting(filter, new List<string>(){ "content" }, content);
+ Header.AddFilterSetting(filter, new List<string>(){ "campaign" }, 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");
+ }
+
+ Header.Enable(filter);
+ Header.AddFilterSetting(filter, new List<string>(){ "html" }, html);
+ }
+
+ public void EnableBcc(string email)
+ {
+ var filter = this._filters["Bcc"];
+
+ Header.Enable(filter);
+ Header.AddFilterSetting(filter, new List<string>(){ "email" }, email);
+ }
+
+ public void EnableBypassListManagement()
+ {
+ Header.Enable(this._filters["BypassListManagement"]);
+ }
+ #endregion
+
+ public MailMessage CreateMimeMessage()
+ {
+ String smtpapi = Header.AsJson();
+
+ if (!String.IsNullOrEmpty(smtpapi))
+ message.Headers.Add("X-Smtpapi", smtpapi);
+
+ Headers.Keys.ToList().ForEach(k => message.Headers.Add(k, Headers[k]));
+
+ message.Attachments.Clear();
+ message.AlternateViews.Clear();
+
+ if(Attachments != null)
+ {
+ foreach (var attachment in Attachments)
+ {
+ message.Attachments.Add(new Attachment(attachment, MediaTypeNames.Application.Octet));
+ }
+ }
+
+ if (Text != null)
+ {
+ AlternateView plainView = AlternateView.CreateAlternateViewFromString(Text, null, "text/plain");
+ message.AlternateViews.Add(plainView);
+ }
+
+ if (Html != null)
+ {
+ AlternateView htmlView = AlternateView.CreateAlternateViewFromString(Html, null, "text/html");
+ message.AlternateViews.Add(htmlView);
+ }
+
+ //message.SubjectEncoding = Encoding.GetEncoding(charset);
+ //message.BodyEncoding = Encoding.GetEncoding(charset);
+
+ return message;
+ }
+
+ /// <summary>
+ /// Helper function lets us look at the mime before it is sent
+ /// </summary>
+ /// <param name="directory">directory in which we store this mime message</param>
+ internal void SaveMessage(String directory)
+ {
+ var client = new SmtpClient("localhost")
+ {
+ DeliveryMethod = SmtpDeliveryMethod.SpecifiedPickupDirectory,
+ PickupDirectoryLocation = @"C:\temp"
+ };
+ var msg = CreateMimeMessage();
+ client.Send(msg);
+ }
+
+ public void Mail(NetworkCredential credentials)
+ {
+ ITransport transport;
+ switch (Transport)
+ {
+ case TransportType.SMTP:
+ transport = SMTP.GenerateInstance(credentials);
+ break;
+ case TransportType.REST:
+ transport = REST.GetInstance(credentials);
+ break;
+ default:
+ throw new ArgumentException("Transport method not specified");
+ }
+ transport.Deliver(this);
+ }
+ }
+}
diff --git a/SendGrid/SendGridMail/Transport/ITransport.cs b/SendGrid/SendGridMail/Transport/ITransport.cs
new file mode 100755
index 0000000..26fccf4
--- /dev/null
+++ b/SendGrid/SendGridMail/Transport/ITransport.cs
@@ -0,0 +1,14 @@
+namespace SendGridMail.Transport
+{
+ /// <summary>
+ ///
+ /// </summary>
+ public interface ITransport
+ {
+ /// <summary>
+ /// Delivers a message using the protocol of the derived class
+ /// </summary>
+ /// <param name="message">the message to be delivered</param>
+ void Deliver(ISendGrid message);
+ }
+}
diff --git a/SendGrid/SendGridMail/Transport/REST.cs b/SendGrid/SendGridMail/Transport/REST.cs
new file mode 100755
index 0000000..f96fa21
--- /dev/null
+++ b/SendGrid/SendGridMail/Transport/REST.cs
@@ -0,0 +1,136 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Net.Mail;
+using System.Text;
+using System.Web;
+using System.Xml;
+using CodeScales.Http;
+using CodeScales.Http.Entity;
+using CodeScales.Http.Entity.Mime;
+using CodeScales.Http.Methods;
+using HttpResponse = System.Web.HttpResponse;
+
+namespace SendGridMail.Transport
+{
+ public class REST : ITransport
+ {
+ // REST delivery settings
+ public const String Endpoint = "http://sendgrid.com/api/mail.send";
+ public const String JsonFormat = "json";
+ public const String XmlFormat = "xml";
+
+ private readonly List<KeyValuePair<String, String>> _query;
+ private readonly NetworkCredential _credentials;
+ private readonly NameValueCollection _queryParameters;
+ private readonly String _restEndpoint;
+ private readonly String _format;
+
+ private WebFileUpload _fileUpload;
+
+ public static REST GetInstance(NetworkCredential credentials, String url = Endpoint)
+ {
+ return new REST(credentials, url);
+ }
+
+ internal REST(NetworkCredential credentials, String url = Endpoint)
+ {
+ _credentials = credentials;
+
+ _format = XmlFormat;
+ _restEndpoint = url + "." + _format;
+ }
+
+ private List<KeyValuePair<String, String>> FetchFormParams(ISendGrid message)
+ {
+ var result = new List<KeyValuePair<string, string>>()
+ {
+ new KeyValuePair<String, String>("api_user", _credentials.UserName),
+ new KeyValuePair<String, String>("api_key", _credentials.Password),
+ new KeyValuePair<String, String>("headers", message.Headers.Count == 0 ? null : Utils.SerializeDictionary(message.Headers)),
+ new KeyValuePair<String, String>("replyto", message.ReplyTo.Length == 0 ? null : message.ReplyTo.ToList().First().Address),
+ new KeyValuePair<String, String>("from", message.From.Address),
+ new KeyValuePair<String, String>("fromname", message.From.DisplayName),
+ new KeyValuePair<String, String>("subject", message.Subject),
+ new KeyValuePair<String, String>("text", message.Text),
+ new KeyValuePair<String, String>("html", message.Html),
+ new KeyValuePair<String, String>("x-smtpapi", message.Header.AsJson())
+ };
+ if(message.To != null)
+ {
+ result = result.Concat(message.To.ToList().Select(a => new KeyValuePair<String, String>("to[]", a.Address)))
+ .Concat(message.To.ToList().Select(a => new KeyValuePair<String, String>("toname[]", a.DisplayName)))
+ .ToList();
+ }
+ if(message.Bcc != null)
+ {
+ result = result.Concat(message.Bcc.ToList().Select(a => new KeyValuePair<String, String>("bcc[]", a.Address)))
+ .ToList();
+ }
+ if(message.Cc != null)
+ {
+ result = result.Concat(message.Cc.ToList().Select(a => new KeyValuePair<String, String>("cc[]", a.Address)))
+ .ToList();
+ }
+ return result.Where(r => !String.IsNullOrEmpty(r.Value)).ToList();
+ }
+
+ private List<KeyValuePair<String, FileInfo>> FetchFileBodies(ISendGrid message)
+ {
+ if(message.Attachments == null)
+ return new List<KeyValuePair<string, FileInfo>>();
+ return message.Attachments.Select(name => new KeyValuePair<String, FileInfo>(name, new FileInfo(name))).ToList();
+ }
+
+ public void Deliver(ISendGrid message)
+ {
+ var client = new HttpClient();
+ var postMethod = new HttpPost(new Uri(_restEndpoint));
+
+ var multipartEntity = new MultipartEntity();
+ postMethod.Entity = multipartEntity;
+
+ var formParams = FetchFormParams(message);
+
+ formParams.ForEach(kvp => multipartEntity.AddBody(new StringBody(Encoding.UTF8, kvp.Key, kvp.Value)));
+
+ var files = FetchFileBodies(message);
+ files.ForEach(kvp => multipartEntity.AddBody(new FileBody("files["+kvp.Key+"]", kvp.Key, kvp.Value)));
+
+ CodeScales.Http.Methods.HttpResponse response = client.Execute(postMethod);
+
+ Console.WriteLine("Response Code: " + response.ResponseCode);
+ Console.WriteLine("Response Content: " + EntityUtils.ToString(response.Entity));
+
+ Console.WriteLine("Res");
+
+ var status = EntityUtils.ToString(response.Entity);
+ var stream = new MemoryStream(Encoding.UTF8.GetBytes(status));
+
+
+ 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/SendGridMail/Transport/SMTP.cs b/SendGrid/SendGridMail/Transport/SMTP.cs
new file mode 100755
index 0000000..606afcd
--- /dev/null
+++ b/SendGrid/SendGridMail/Transport/SMTP.cs
@@ -0,0 +1,132 @@
+using System;
+using System.Net;
+using System.Net.Mail;
+
+namespace SendGridMail.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 GenerateInstance(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>
+ /// For Unit Testing Only!
+ /// </summary>
+ /// <param name="client"></param>
+ /// <param name="credentials"></param>
+ /// <param name="host"></param>
+ /// <param name="port"></param>
+ /// <returns></returns>
+ internal static SMTP GenerateInstance(ISmtpClient client, NetworkCredential credentials, String host = SmtpServer, Int32 port = Port)
+ {
+ return new SMTP(client, credentials, host, port);
+ }
+
+ /// <summary>
+ /// Interface to allow testing
+ /// </summary>
+ internal interface ISmtpClient
+ {
+ bool EnableSsl { get; set; }
+ void Send(MailMessage mime);
+ }
+
+ /// <summary>
+ /// Implementation of SmtpClient wrapper, separated to allow dependency injection
+ /// </summary>
+ internal 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/SendGridMail/Utils.cs b/SendGrid/SendGridMail/Utils.cs
new file mode 100755
index 0000000..cb6413c
--- /dev/null
+++ b/SendGrid/SendGridMail/Utils.cs
@@ -0,0 +1,52 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.IO.Pipes;
+using System.Linq;
+using System.Net;
+using System.Net.Mail;
+using System.Runtime.Serialization.Json;
+using System.Text;
+
+namespace SendGridMail
+{
+ public class Utils
+ {
+ public static string Serialize<T>(T obj)
+ {
+ var serializer = new DataContractJsonSerializer(obj.GetType());
+ using (var stream = new MemoryStream())
+ {
+ serializer.WriteObject(stream, obj);
+ var jsonData = Encoding.UTF8.GetString(stream.ToArray(), 0, (int)stream.Length);
+ return jsonData;
+ }
+ }
+
+ public static string SerializeDictionary(IDictionary<String, String> dic)
+ {
+ return "{"+String.Join(",",dic.Select(kvp => Serialize(kvp.Key) + ":" + Serialize(kvp.Value)))+"}";
+ }
+
+ public static Dictionary<String, Stream> PrepareAttachments()
+ {
+ var attach = new Attachment("D:/att_proj/21.jpg");
+ Console.WriteLine("preparing message attachment");
+ var sr = new StreamReader(attach.ContentStream);
+
+ Console.WriteLine(sr.ReadToEnd());
+
+ Console.WriteLine(":D");
+ var request = (HttpWebRequest)WebRequest.Create("");
+
+
+ //attach.ContentStream.CopyTo(request.GetRequestStream());
+
+ Console.WriteLine("attachment: ");
+
+ Console.WriteLine("DONE");
+
+ return new Dictionary<string, Stream>();
+ }
+ }
+}
diff --git a/SendGrid/SendGridMail/Web/IWebApi.cs b/SendGrid/SendGridMail/Web/IWebApi.cs
new file mode 100755
index 0000000..52d4cb2
--- /dev/null
+++ b/SendGrid/SendGridMail/Web/IWebApi.cs
@@ -0,0 +1,45 @@
+using System;
+using System.Collections.Generic;
+
+namespace SendGridMail.Web
+{
+ interface IWebApi
+ {
+ String user { get; set; }
+ String pass { get; set; }
+
+ String GetBounces(int date, String days, DateTime start_date, DateTime end_date, int limit, int offset, int type, String email);
+ void DeleteBounces(DateTime start_date, DateTime end_date, String type, String email);
+ String GetBlocks(int days, DateTime start_date, DateTime end_date, String email);
+ void DeleteBlocks(String email);
+ String GetEmailParse(String hostname, String url);
+ void SetEmailParse(String hostname, String url);
+ void EditEmailParse(String hostname, String url);
+ void DeleteEmailParse(String hostname);
+ String GetNotificationUrl();
+ void SetNotificationUrl(String url);
+ void DeleteNotificationUrl();
+ String GetFilter();
+ void ActivateFilter(String name);
+ void DeactivateFilter(String name);
+ void SetupFilter(String user, String password, Dictionary<String, String> args);
+ String GetFilterSettings(String name);
+ void GetInvalidEmails(int date, int days, DateTime start_date, DateTime end_date, int limit, int offset, String email);
+ void DeleteInvalidEmails(DateTime start_date, DateTime end_date, String email);
+ String CountInvalidEmails(DateTime start_date, DateTime end_date);
+ String GetProfile();
+ void UpdateProfile(String First_name, String last_name, String address, String city, String state, String country, int zip, int phone, String website);
+ void SetUsername(String username);
+ void SetPassword(String password, String confpass);
+ void SetEmail(String email);
+ String GetSpamReports(int date, int days, DateTime start_date, DateTime end_date, int limit, int offset, String email);
+ void DeleteSpamReports(DateTime start_date, DateTime end_date, String email);
+ String GetStats(int days, DateTime start_date, DateTime end_date);
+ String GetAggregateStats();
+ String GetCategoryStats();
+ String GetCategoryStats(String category, int days, DateTime start_date, DateTime end_date);
+ String GetUnsubscribes(int date, int days, DateTime start_date, DateTime end_date, int limit, int offset, String email);
+ void DeleteUnsubscribes(DateTime start_date, DateTime end_date, String email);
+ void AddUnsubscribes(String email);
+ }
+}
diff --git a/SendGrid/SendGridMail/WebFileUpload.cs b/SendGrid/SendGridMail/WebFileUpload.cs
new file mode 100755
index 0000000..b6e0faf
--- /dev/null
+++ b/SendGrid/SendGridMail/WebFileUpload.cs
@@ -0,0 +1,114 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.IO;
+using System.IO.Pipes;
+using System.Linq;
+using System.Net;
+using System.Net.Mail;
+using System.Text;
+using CodeScales.Http;
+using CodeScales.Http.Common;
+using CodeScales.Http.Entity;
+using CodeScales.Http.Entity.Mime;
+using CodeScales.Http.Methods;
+
+namespace SendGridMail
+{
+ internal class WebFileUpload
+ {
+ private HttpWebRequest _request;
+ private List<Attachment> _attachments;
+
+ private String newline = "\r\n";
+
+ private byte[] _boundaryBytes;
+
+ private String _boundary;
+
+ public WebFileUpload(HttpWebRequest request)
+ {
+
+ }
+
+ public void SendAttachments()
+ {
+ HttpClient client = new HttpClient();
+ //https://sendgrid.com/api/mail.send
+ var url = "http://sendgrid.com/api/mail.send.xml";
+ var notUrl = "http://www.postbin.org/1hv8rbe";
+ HttpPost postMethod = new HttpPost(new Uri(url));
+
+
+
+ //UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(nameValuePairList, Encoding.UTF8);
+ //postMethod.Entity = formEntity;
+
+
+
+ MultipartEntity multipartEntity = new MultipartEntity();
+ postMethod.Entity = multipartEntity;
+
+
+
+ FileInfo fileInfo = new FileInfo(@"D:\att_proj\2.JPG");
+ FileBody fileBody = new FileBody("files[file1.jpg]", "myfile.jpg", fileInfo);
+
+ multipartEntity.AddBody(fileBody);
+
+ HttpResponse response = client.Execute(postMethod);
+
+ Console.WriteLine("Response Code: " + response.ResponseCode);
+ Console.WriteLine("Response Content: " + EntityUtils.ToString(response.Entity));
+
+ Console.WriteLine("done");
+ }
+
+ /*public void TestAddAttachment(Attachment attachment)
+ {
+ WebClient myWebClient = new WebClient();
+ NameValueCollection collection = new NameValueCollection();
+
+ StreamReader sr = new StreamReader(attachment.ContentStream);
+ var data = sr.ReadToEnd();
+ byte[] bytes = new byte[attachment.ContentStream.Length];
+
+ byte[] responseArray = myWebClient.UploadValues("https://sendgrid.com/api/mail.send.xml", collection);
+ Console.WriteLine("\nResponse received was :\n{0}", Encoding.ASCII.GetString(responseArray));
+ }*/
+
+ public void AddAttachment(String filename)
+ {
+ _attachments.Add(new Attachment(filename));
+ }
+
+ public void AddAttachments(List<Attachment> attachments)
+ {
+ _attachments = attachments;
+ }
+
+ public List<Attachment> GetAttachments()
+ {
+ return _attachments;
+ }
+
+ /*public void SendAttachments()
+ {
+ WebResponse _response = null;
+
+ try
+ {
+ _response = _request.GetResponse();
+
+ //Stream stream = _response.GetResponseStream();
+ //StreamReader reader = new StreamReader(stream);
+ }
+ catch (Exception ex)
+ {
+ throw new Exception("Unable to send attachments :: " + ex.Message);
+ }
+
+ _response.Close();
+ }*/
+ }
+}
diff --git a/SendGrid/Tests/TestHeader.cs b/SendGrid/Tests/TestHeader.cs
index 323e394..8a130e9 100755
--- a/SendGrid/Tests/TestHeader.cs
+++ b/SendGrid/Tests/TestHeader.cs
@@ -1,10 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Net.Mail;
using System.Text;
using Moq;
using NUnit.Framework;
-using SendGrid;
+using SendGridMail;
namespace Tests
{
@@ -12,14 +13,82 @@ namespace Tests
public class TestHeader
{
[Test]
- public void TestAddTo()
+ public void TestAddSubVal()
{
- var foo = new Mock<IHeader>();
- foo.Setup(m => m.Enable("foo"));
+ var test = new Header();
+ test.AddSubVal("foo", new List<string>{"bar", "raz"});
+ var result = test.AsJson();
+ Assert.AreEqual("{\"sub\" : {\"foo\" : [\"bar\", \"raz\"]}}", result);
+ }
+
+ [Test]
+ public void TestAddUniqueIdentifier()
+ {
+ var test = new Header();
+ test.AddUniqueIdentifier(new Dictionary<string, string>(){{"foo", "bar"}});
+ var result = test.AsJson();
+ Assert.AreEqual("{\"unique_args\" : {\"foo\" : \"bar\"}}", result);
+ }
+
+ [Test]
+ public void TestSetCategory()
+ {
+ var test = new Header();
+ test.SetCategory("foo");
+ var result = test.AsJson();
+ Assert.AreEqual("{\"category\" : \"foo\"}", result);
+ }
- var bar = new SendGrid.SendGrid(foo.Object);
- Assert.AreEqual(1, 2, "I suck");
+ [Test]
+ public void TestEnable()
+ {
+ var test = new Header();
+ test.Enable("foo");
+ var result = test.AsJson();
+ Assert.AreEqual("{\"filters\" : {\"foo\" : {\"settings\" : {\"enable\" : \"1\"}}}}", result);
+ }
+
+ [Test]
+ public void TestDisable()
+ {
+ var test = new Header();
+ test.Disable("foo");
+ var result = test.AsJson();
+ Assert.AreEqual("{\"filters\" : {\"foo\" : {\"settings\" : {\"enable\" : \"0\"}}}}", result);
+ }
+
+ [Test]
+ public void TestAddFilterSetting()
+ {
+ var test = new Header();
+ test.AddFilterSetting("foo", new List<string> { "a", "b" }, "bar");
+ var result = test.AsJson();
+ Assert.AreEqual("{\"filters\" : {\"foo\" : {\"settings\" : {\"a\" : {\"b\" : \"bar\"}}}}}", result);
+
+ }
+
+ [Test]
+ public void TestAddHeader()
+ {
+ var test = new Header();
+ test.AddSubVal("foo", new List<string> { "a", "b" });
+ var mime = new MailMessage();
+ test.AddHeader(mime);
+ var result = mime.Headers.Get("x-smtpapi");
+ Assert.AreEqual("{\"sub\" : {\"foo\" : [\"a\", \"b\"]}}", result);
+ }
+
+ [Test]
+ public void TestAsJson()
+ {
+ var test = new Header();
+ var result = test.AsJson();
+ Assert.AreEqual("", result);
+ test = new Header();
+ test.AddSubVal("foo", new List<string>{"a", "b"});
+ result = test.AsJson();
+ Assert.AreEqual("{\"sub\" : {\"foo\" : [\"a\", \"b\"]}}", result);
}
}
}
diff --git a/SendGrid/Tests/TestJsonUtils.cs b/SendGrid/Tests/TestJsonUtils.cs
new file mode 100755
index 0000000..fee990d
--- /dev/null
+++ b/SendGrid/Tests/TestJsonUtils.cs
@@ -0,0 +1,17 @@
+using System.Text;
+using NUnit.Framework;
+using SendGridMail;
+
+namespace Tests
+{
+ [TestFixture]
+ public class TestJsonUtils
+ {
+ [Test]
+ public void TestSerialize()
+ {
+ Assert.AreEqual("1", Utils.Serialize(1));
+ Assert.AreEqual("\"\\\"foo\\\"\"", Utils.Serialize("\"foo\""));
+ }
+ }
+}
diff --git a/SendGrid/Tests/TestSendgrid.cs b/SendGrid/Tests/TestSendgrid.cs
new file mode 100755
index 0000000..22e8bb7
--- /dev/null
+++ b/SendGrid/Tests/TestSendgrid.cs
@@ -0,0 +1,289 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using NUnit.Framework;
+using SendGridMail;
+
+namespace Tests
+{
+ [TestFixture]
+ class TestSendgrid
+ {
+ [Test]
+ public void TestDisableGravatar()
+ {
+ var header = new Header();
+ var sendgrid = new SendGrid(header);
+
+ sendgrid.DisableGravatar();
+
+ String json = header.AsJson();
+ Assert.AreEqual("{\"filters\" : {\"gravatar\" : {\"settings\" : {\"enable\" : \"0\"}}}}", json);
+ }
+
+ [Test]
+ public void TestDisableOpenTracking()
+ {
+ var header = new Header();
+ var sendgrid = new SendGrid(header);
+
+ sendgrid.DisableOpenTracking();
+
+ String json = header.AsJson();
+ Assert.AreEqual("{\"filters\" : {\"opentrack\" : {\"settings\" : {\"enable\" : \"0\"}}}}", json);
+ }
+
+ [Test]
+ public void DisableClickTracking()
+ {
+ var header = new Header();
+ var sendgrid = new SendGrid(header);
+
+ sendgrid.DisableClickTracking();
+
+ String json = header.AsJson();
+ Assert.AreEqual("{\"filters\" : {\"clicktrack\" : {\"settings\" : {\"enable\" : \"0\"}}}}", json);
+ }
+
+ [Test]
+ public void DisableSpamCheck()
+ {
+ var header = new Header();
+ var sendgrid = new SendGrid(header);
+
+ sendgrid.DisableSpamCheck();
+
+ String json = header.AsJson();
+ Assert.AreEqual("{\"filters\" : {\"spamcheck\" : {\"settings\" : {\"enable\" : \"0\"}}}}", json);
+ }
+
+ [Test]
+ public void DisableUnsubscribe()
+ {
+ var header = new Header();
+ var sendgrid = new SendGrid(header);
+
+ sendgrid.DisableUnsubscribe();
+
+ String json = header.AsJson();
+ Assert.AreEqual("{\"filters\" : {\"subscriptiontrack\" : {\"settings\" : {\"enable\" : \"0\"}}}}", json);
+ }
+
+ [Test]
+ public void DisableFooter()
+ {
+ var header = new Header();
+ var sendgrid = new SendGrid(header);
+
+ sendgrid.DisableFooter();
+
+ String json = header.AsJson();
+ Assert.AreEqual("{\"filters\" : {\"footer\" : {\"settings\" : {\"enable\" : \"0\"}}}}", json);
+ }
+
+ [Test]
+ public void DisableGoogleAnalytics()
+ {
+ var header = new Header();
+ var sendgrid = new SendGrid(header);
+
+ sendgrid.DisableGoogleAnalytics();
+
+ String json = header.AsJson();
+ Assert.AreEqual("{\"filters\" : {\"ganalytics\" : {\"settings\" : {\"enable\" : \"0\"}}}}", json);
+ }
+
+ [Test]
+ public void DisableTemplate()
+ {
+ var header = new Header();
+ var sendgrid = new SendGrid(header);
+
+ sendgrid.DisableTemplate();
+
+ String json = header.AsJson();
+ Assert.AreEqual("{\"filters\" : {\"template\" : {\"settings\" : {\"enable\" : \"0\"}}}}", json);
+ }
+
+ [Test]
+ public void DisableBcc()
+ {
+ var header = new Header();
+ var sendgrid = new SendGrid(header);
+
+ sendgrid.DisableBcc();
+
+ String json = header.AsJson();
+ Assert.AreEqual("{\"filters\" : {\"bcc\" : {\"settings\" : {\"enable\" : \"0\"}}}}", json);
+ }
+
+ [Test]
+ public void DisableBypassListManagement()
+ {
+ var header = new Header();
+ var sendgrid = new SendGrid(header);
+
+ sendgrid.DisableBypassListManagement();
+
+ String json = header.AsJson();
+ Assert.AreEqual("{\"filters\" : {\"bypass_list_management\" : {\"settings\" : {\"enable\" : \"0\"}}}}", json);
+ }
+
+ [Test]
+ public void EnableGravatar()
+ {
+ var header = new Header();
+ var sendgrid = new SendGrid(header);
+
+ sendgrid.EnableGravatar();
+
+ String json = header.AsJson();
+ Assert.AreEqual("{\"filters\" : {\"gravatar\" : {\"settings\" : {\"enable\" : \"1\"}}}}", json);
+ }
+
+ [Test]
+ public void EnableOpenTracking()
+ {
+ var header = new Header();
+ var sendgrid = new SendGrid(header);
+
+ sendgrid.EnableOpenTracking();
+
+ String json = header.AsJson();
+ Assert.AreEqual("{\"filters\" : {\"opentrack\" : {\"settings\" : {\"enable\" : \"1\"}}}}", json);
+ }
+
+ [Test]
+ public void EnableClickTracking()
+ {
+ var header = new Header();
+ var sendgrid = new SendGrid(header);
+ var text = "hello world";
+ sendgrid.EnableClickTracking(text);
+
+ String json = header.AsJson();
+ Assert.AreEqual("{\"filters\" : {\"clicktrack\" : {\"settings\" : {\"enable\" : \"1\",\"text\" : \"hello world\"}}}}", json);
+ }
+
+ [Test]
+ public void EnableSpamCheck()
+ {
+ var header = new Header();
+ var sendgrid = new SendGrid(header);
+
+ var score = 5;
+ var url = "http://www.example.com";
+ sendgrid.EnableSpamCheck(score, url);
+
+ String json = header.AsJson();
+ Assert.AreEqual("{\"filters\" : {\"spamcheck\" : {\"settings\" : {\"enable\" : \"1\",\"score\" : \"5\",\"url\" : \"http:\\/\\/www.example.com\"}}}}", json);
+ }
+
+ [Test]
+ public void EnableUnsubscribe()
+ {
+ var header = new Header();
+ var sendgrid = new SendGrid(header);
+
+ var text = "<% %>";
+ var html = "<% name %>";
+ var replace = "John";
+ var url = "http://www.example.com";
+ var landing = "this_landing";
+ sendgrid.EnableUnsubscribe(text, html, replace, url, landing);
+
+ var jsonText = "\"text\" : \""+text+"\"";
+ var jsonHtml = "\"html\" : \""+html+"\"";
+ var jsonReplace = "\"replace\" : \""+replace+"\"";
+ var jsonUrl = "\"url\" : \"http:\\/\\/www.example.com\"";
+ var jsonLanding = "\"landing\" : \""+landing+"\"";
+
+ String json = header.AsJson();
+ Assert.AreEqual("{\"filters\" : {\"subscriptiontrack\" : {\"settings\" : {\"enable\" : \"1\","+
+ jsonText+","+jsonHtml+","+jsonReplace+","+jsonUrl+","+jsonLanding+"}}}}", json);
+
+ }
+
+ [Test]
+ public void EnableFooter()
+ {
+ var header = new Header();
+ var sendgrid = new SendGrid(header);
+
+ var text = "My Text";
+ var html = "<body><p>hello, <% name %></p></body>";
+ var escHtml = "<body><p>hello, <% name %><\\/p><\\/body>";
+
+ sendgrid.EnableFooter(text, html);
+
+ String json = header.AsJson();
+ Assert.AreEqual("{\"filters\" : {\"footer\" : {\"settings\" : {\"enable\" : \"1\",\"text\" : \""+text+"\",\"html\" : \""+escHtml+"\"}}}}", json);
+ }
+
+ [Test]
+ public void EnableGoogleAnalytics()
+ {
+ var header = new Header();
+ var sendgrid = new SendGrid(header);
+
+ var source = "SomeDomain.com";
+ var medium = "Email";
+ var term = "keyword1, keyword2, keyword3";
+ var content = "PG, PG13";
+ var campaign = "my_campaign";
+
+ sendgrid.EnableGoogleAnalytics(source, medium, term, content, campaign);
+
+ var jsonSource = "\"source\" : \"SomeDomain.com\"";
+ var jsonMedium = "\"medium\" : \""+medium+"\"";
+ var jsonTerm = "\"term\" : \""+term+"\"";
+ var jsonContent = "\"content\" : \""+content+"\"";
+ var jsonCampaign = "\"campaign\" : \""+campaign+"\"";
+
+ String json = header.AsJson();
+ Assert.AreEqual("{\"filters\" : {\"ganalytics\" : {\"settings\" : {\"enable\" : \"1\","+
+ jsonSource+","+jsonMedium+","+jsonTerm+","+jsonContent+","+jsonCampaign+"}}}}", json);
+ }
+
+ [Test]
+ public void EnableTemplate()
+ {
+ var header = new Header();
+ var sendgrid = new SendGrid(header);
+ var html = "<% hadhdhd %>";
+
+ var escHtml = "<% hadhdhd %>";
+ sendgrid.EnableTemplate(html);
+
+ String json = header.AsJson();
+ Assert.AreEqual("{\"filters\" : {\"template\" : {\"settings\" : {\"enable\" : \"1\",\"html\" : \""+escHtml+"\"}}}}", json);
+ }
+
+ [Test]
+ public void EnableBcc()
+ {
+ var header = new Header();
+ var sendgrid = new SendGrid(header);
+
+ var email = "somebody@someplace.com";
+ sendgrid.EnableBcc(email);
+
+ String json = header.AsJson();
+ Assert.AreEqual("{\"filters\" : {\"bcc\" : {\"settings\" : {\"enable\" : \"1\",\"email\" : \"" + email + "\"}}}}", json);
+ }
+
+ [Test]
+ public void EnableBypassListManagement()
+ {
+ var header = new Header();
+ var sendgrid = new SendGrid(header);
+
+ sendgrid.EnableBypassListManagement();
+
+ String json = header.AsJson();
+ Assert.AreEqual("{\"filters\" : {\"bypass_list_management\" : {\"settings\" : {\"enable\" : \"1\"}}}}", json);
+ }
+ }
+}
diff --git a/SendGrid/Tests/TestSendgridMessageSetup.cs b/SendGrid/Tests/TestSendgridMessageSetup.cs
new file mode 100755
index 0000000..efbb853
--- /dev/null
+++ b/SendGrid/Tests/TestSendgridMessageSetup.cs
@@ -0,0 +1,162 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net.Mail;
+using System.Net.Mime;
+using Moq;
+using NUnit.Framework;
+using SendGridMail;
+
+namespace Tests
+{
+ [TestFixture]
+ public class TestSendgridMessageSetup
+ {
+ [Test]
+ public void TestAddTo()
+ {
+ var foo = new Mock<IHeader>();
+
+ var sg = new SendGrid(foo.Object);
+ sg.AddTo("eric@sendgrid.com");
+ Assert.AreEqual("eric@sendgrid.com", sg.To.First().ToString(), "Single To Address" );
+
+ sg = new SendGrid(foo.Object);
+ var strings = new String[2];
+ strings[0] = "eric@sendgrid.com";
+ strings[1] = "tyler@sendgrid.com";
+ sg.AddTo(strings);
+ Assert.AreEqual("eric@sendgrid.com", sg.To[0].ToString(), "Multiple To addresses, check first one");
+ Assert.AreEqual("tyler@sendgrid.com", sg.To[1].ToString(), "Multiple To addresses, check second one");
+
+ sg = new SendGrid(foo.Object);
+ var a = new Dictionary<String, String>();
+ a.Add("DisplayName", "Eric");
+ var datastruct = new Dictionary<string, IDictionary<string, string>> {{"eric@sendgrid.com", a}};
+ sg.AddTo(datastruct);
+ Assert.AreEqual("Eric", sg.To.First().DisplayName, "Single address with args");
+ }
+
+ [Test]
+ public void TestAddCc()
+ {
+ var foo = new Mock<IHeader>();
+
+ var sg = new SendGrid(foo.Object);
+ sg.AddCc("eric@sendgrid.com");
+ Assert.AreEqual("eric@sendgrid.com", sg.Cc.First().ToString(), "Single CC Address");
+
+ sg = new SendGrid(foo.Object);
+ var strings = new String[2];
+ strings[0] = "eric@sendgrid.com";
+ strings[1] = "tyler@sendgrid.com";
+ sg.AddCc(strings);
+ Assert.AreEqual("eric@sendgrid.com", sg.Cc[0].ToString(), "Multiple CC addresses, check first one");
+ Assert.AreEqual("tyler@sendgrid.com", sg.Cc[1].ToString(), "Multiple CC addresses, check second one");
+
+ sg = new SendGrid(foo.Object);
+ var a = new Dictionary<String, String>();
+ a.Add("DisplayName", "Eric");
+ var datastruct = new Dictionary<string, IDictionary<string, string>> { { "eric@sendgrid.com", a } };
+ sg.AddCc(datastruct);
+ Assert.AreEqual("Eric", sg.Cc.First().DisplayName, "Single CC address with args");
+ }
+
+ [Test]
+ public void TestAddBcc()
+ {
+ var foo = new Mock<IHeader>();
+
+ var sg = new SendGrid(foo.Object);
+ sg.AddBcc("eric@sendgrid.com");
+ Assert.AreEqual("eric@sendgrid.com", sg.Bcc.First().ToString(), "Single Bcc Address");
+
+ sg = new SendGrid(foo.Object);
+ var strings = new String[2];
+ strings[0] = "eric@sendgrid.com";
+ strings[1] = "tyler@sendgrid.com";
+ sg.AddBcc(strings);
+ Assert.AreEqual("eric@sendgrid.com", sg.Bcc[0].ToString(), "Multiple addresses, check first one");
+ Assert.AreEqual("tyler@sendgrid.com", sg.Bcc[1].ToString(), "Multiple addresses, check second one");
+
+ sg = new SendGrid(foo.Object);
+ var a = new Dictionary<String, String>();
+ a.Add("DisplayName", "Eric");
+ var datastruct = new Dictionary<string, IDictionary<string, string>> { { "eric@sendgrid.com", a } };
+ sg.AddBcc(datastruct);
+ Assert.AreEqual("Eric", sg.Bcc.First().DisplayName, "Single address with args");
+ }
+
+ [Test]
+ public void TestSGHeader()
+ {
+ var foo = new Mock<IHeader>();
+ var sg = new SendGrid(foo.Object);
+
+ sg.Subject = "New Test Subject";
+ Assert.AreEqual("New Test Subject", sg.Subject, "Subject set ok");
+ sg.Subject = null;
+ Assert.AreEqual("New Test Subject", sg.Subject, "null subject does not overide previous subject");
+ }
+
+ /*
+ [Test]
+ public void TestAddSubVal()
+ {
+ var header = new Header();
+ var sg = new SendGrid(header);
+
+ var datastruct = new String[2];
+ datastruct[0] = "eric";
+ datastruct[1] = "tyler";
+
+ sg.AddSubVal("-name-", datastruct);
+ Assert.AreEqual("test", sg.Header);
+ }
+ */
+
+
+ [Test]
+ public void TestGetRcpts()
+ {
+ var foo = new Mock<IHeader>();
+ var sg = new SendGrid(foo.Object);
+
+ sg.AddTo("eric@sendgrid.com");
+ sg.AddCc("tyler@sendgrid.com");
+ sg.AddBcc("cj@sendgrid.com");
+ sg.AddBcc("foo@sendgrid.com");
+
+ var rcpts = sg.GetRecipients();
+ Assert.AreEqual("eric@sendgrid.com", rcpts.First(), "getRecipients check To");
+ Assert.AreEqual("tyler@sendgrid.com", rcpts.Skip(1).First(), "getRecipients check Cc");
+ Assert.AreEqual("cj@sendgrid.com", rcpts.Skip(2).First(), "getRecipients check Bcc");
+ Assert.AreEqual("foo@sendgrid.com", rcpts.Skip(3).First(), "getRecipients check Bcc x2");
+ }
+
+ [Test]
+ public void TestAddAttachment()
+ {
+ var foo = new Mock<IHeader>();
+ var sg = new SendGrid(foo.Object);
+
+ var data = new Attachment("pnunit.framework.dll", MediaTypeNames.Application.Octet);
+ sg.AddAttachment("pnunit.framework.dll");
+ sg.AddAttachment("pnunit.framework.dll");
+ //Assert.AreEqual(data.ContentStream, sg.Attachments.First().ContentStream, "Attach via path");
+ //Assert.AreEqual(data.ContentStream, sg.Attachments.Skip(1).First().ContentStream, "Attach via path x2");
+
+ sg = new SendGrid(foo.Object);
+ //sg.AddAttachment(data);
+ //sg.AddAttachment(data);
+ //Assert.AreEqual(data.ContentStream, sg.Attachments.First().ContentStream, "Attach via attachment");
+ //Assert.AreEqual(data.ContentStream, sg.Attachments.Skip(1).First().ContentStream, "Attach via attachment x2");
+
+ sg = new SendGrid(foo.Object);
+ //sg.AddAttachment(data.ContentStream, data.ContentType);
+ //sg.AddAttachment(data.ContentStream, data.ContentType);
+ //Assert.AreEqual(data.ContentStream, sg.Attachments.First().ContentStream, "Attach via stream");
+ //Assert.AreEqual(data.ContentStream, sg.Attachments.Skip(1).First().ContentStream, "Attach via stream x2");
+ }
+ }
+}
diff --git a/SendGrid/Tests/TestTreeNode.cs b/SendGrid/Tests/TestTreeNode.cs
new file mode 100755
index 0000000..1701d74
--- /dev/null
+++ b/SendGrid/Tests/TestTreeNode.cs
@@ -0,0 +1,100 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using NUnit.Framework;
+using SendGridMail;
+
+namespace Tests
+{
+ [TestFixture]
+ public class TestTreeNode
+ {
+ [Test]
+ public void TestAddSetting()
+ {
+ var test = new Header.HeaderSettingsNode();
+ test.AddSetting(new List<string>(), "foo");
+ Assert.AreEqual("foo", test.GetLeaf(), "Get the leaf of the first node");
+
+ test = new Header.HeaderSettingsNode();
+ test.AddSetting(new List<string> { "foo" }, "bar");
+ Assert.AreEqual("bar", test.GetSetting(new List<string>(){"foo"}), "Get the item in the first branch 'foo', make sure its set to 'bar'");
+
+ test = new Header.HeaderSettingsNode();
+ test.AddSetting(new List<string> {"foo"}, "bar");
+ Assert.AreEqual("bar", test.GetSetting("foo"), "tests the convienence get setting function that omits the lists stuff...");
+
+ test = new Header.HeaderSettingsNode();
+ test.AddSetting(new List<string> { "foo", "bar", "raz" }, "foobar");
+ Assert.AreEqual("foobar", test.GetSetting("foo", "bar", "raz"), "tests a tree that is multiple branches deep");
+
+ test = new Header.HeaderSettingsNode();
+ test.AddSetting(new List<string> { "foo", "bar", "raz" }, "foobar");
+ test.AddSetting(new List<string> { "barfoo", "barbar", "barraz" }, "barfoobar");
+ Assert.AreEqual("foobar", test.GetSetting("foo", "bar", "raz"), "tests a tree that has multiple branches");
+ Assert.AreEqual("barfoobar", test.GetSetting("barfoo", "barbar", "barraz"), "tests the other branch");
+
+ test = new Header.HeaderSettingsNode();
+ test.AddSetting(new List<string> { "foo" }, "bar");
+ try
+ {
+ test.AddSetting(new List<string> {"foo", "raz"}, "blam");
+ Assert.Fail("exception not thrown");
+ }
+ catch (ArgumentException ex)
+ {
+ Assert.AreEqual("Attempt to overwrite setting", ex.Message);
+ }
+
+ }
+
+ [Test]
+ public void TestToJSON()
+ {
+ var test = new Header.HeaderSettingsNode();
+ test.AddSetting(new List<string>() { "foo", "bar", "raz" }, "foobar");
+
+ var result = test.ToJson();
+ Assert.AreEqual("{\"foo\" : {\"bar\" : {\"raz\" : \"foobar\"}}}", result);
+
+ test = new Header.HeaderSettingsNode();
+ test.AddSetting(new List<string>() { "foo", "bar", "raz" }, "foobar");
+ test.AddSetting(new List<string>() { "barfoo", "barbar", "barraz" }, "barfoobar");
+
+ result = test.ToJson();
+ Assert.AreEqual("{\"foo\" : {\"bar\" : {\"raz\" : \"foobar\"}},\"barfoo\" : {\"barbar\" : {\"barraz\" : \"barfoobar\"}}}", result);
+
+ test = new Header.HeaderSettingsNode();
+ test.AddArray(new List<string>{"foo"}, new List<string>{"bar", "raz"});
+ result = test.ToJson();
+ Assert.AreEqual("{\"foo\" : [\"bar\", \"raz\"]}", result);
+
+ }
+
+ [Test]
+ public void TestAddArray()
+ {
+ var test = new Header.HeaderSettingsNode();
+ test.AddArray(new List<string>{"foo", "bar"}, new string[]{"raz", "blam"});
+ var result = test.GetArray("foo", "bar");
+ Assert.AreEqual(result.ToList()[0], "raz");
+ Assert.AreEqual(result.ToList()[1], "blam");
+ }
+
+ [Test]
+ public void TestIsEmpty()
+ {
+ var test = new Header.HeaderSettingsNode();
+ Assert.IsTrue(test.IsEmpty());
+
+ test = new Header.HeaderSettingsNode();
+ test.AddSetting(new List<string>{"foo"}, "bar");
+ Assert.IsFalse(test.IsEmpty());
+
+ test = new Header.HeaderSettingsNode();
+ test.AddArray(new List<string> { "raz" }, new List<string>{"blam"});
+ Assert.IsFalse(test.IsEmpty());
+
+ }
+ }
+}
diff --git a/SendGrid/Tests/Tests.csproj b/SendGrid/Tests/Tests.csproj
index 0fcdc86..8009274 100755
--- a/SendGrid/Tests/Tests.csproj
+++ b/SendGrid/Tests/Tests.csproj
@@ -54,16 +54,25 @@
<ItemGroup>
<Compile Include="TestHeader.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="TestJsonUtils.cs" />
+ <Compile Include="TestSendgrid.cs" />
+ <Compile Include="TestSendgridMessageSetup.cs" />
+ <Compile Include="TestTreeNode.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">
+ <ProjectReference Include="..\SendGridMail\Mail.csproj">
<Project>{3C687BEF-FF50-44AD-8315-2D4237281AF8}</Project>
<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..ccbab48
--- /dev/null
+++ b/SendGrid/Tests/Transport/TestREST.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using NUnit.Framework;
+
+namespace Tests.Transport
+{
+ [TestFixture]
+ class TestREST
+ {
+ [Test]
+ public void TestDeliver()
+ {
+
+ }
+
+ [Test]
+ public void TestConstructor()
+ {
+
+ }
+ }
+}
diff --git a/SendGrid/Tests/Transport/TestSMTP.cs b/SendGrid/Tests/Transport/TestSMTP.cs
new file mode 100755
index 0000000..e0e4fe5
--- /dev/null
+++ b/SendGrid/Tests/Transport/TestSMTP.cs
@@ -0,0 +1,68 @@
+using System;
+using System.Net;
+using System.Net.Mail;
+using Moq;
+using NUnit.Framework;
+using SendGridMail;
+using SendGridMail.Transport;
+
+namespace Tests.Transport
+{
+ [TestFixture]
+ public class TestSMTP
+ {
+ [Test]
+ public void TestDeliver()
+ {
+ var mockMessage = new Mock<ISendGrid>();
+ var mime = new MailMessage("test-from@sendgrid.com", "test-to@sendgrid.com", "this is a test", "it is only a test");
+ mockMessage.Setup(foo => foo.CreateMimeMessage()).Returns(mime);
+ var message = mockMessage.Object;
+
+ var mockClient = new Mock<SMTP.ISmtpClient>();
+ mockClient.Setup(foo => foo.Send(mime));
+ var client = mockClient.Object;
+ var credentials = new NetworkCredential("username", "password");
+ var test = SMTP.GenerateInstance(client, credentials);
+ test.Deliver(message);
+
+ mockClient.Verify(foo => foo.Send(mime), Times.Once());
+ mockMessage.Verify(foo => foo.CreateMimeMessage(), Times.Once());
+ }
+
+ [Test]
+ public void TestConstructor()
+ {
+ //Test on defaults of port 25 and
+ var mock = new Mock<SMTP.ISmtpClient>();
+ mock.SetupProperty(foo => foo.EnableSsl);
+ var client = mock.Object;
+ var credentials = new NetworkCredential("username", "password");
+ var test = SMTP.GenerateInstance(client, credentials);
+ mock.Verify(foo => foo.EnableSsl, Times.Never());
+
+ mock = new Mock<SMTP.ISmtpClient>();
+ mock.SetupProperty(foo => foo.EnableSsl);
+ client = mock.Object;
+ credentials = new NetworkCredential("username", "password");
+ test = SMTP.GenerateInstance(client, credentials, port:SMTP.SslPort);
+ mock.VerifySet(foo => foo.EnableSsl = true);
+
+ mock = new Mock<SMTP.ISmtpClient>();
+ mock.SetupProperty(foo => foo.EnableSsl);
+ client = mock.Object;
+ credentials = new NetworkCredential("username", "password");
+ try
+ {
+ test = SMTP.GenerateInstance(client, credentials, port: SMTP.TlsPort);
+ Assert.Fail("should have thrown an unsupported port exception");
+ }
+ catch (NotSupportedException ex)
+ {
+ Assert.AreEqual("TLS not supported", ex.Message);
+ }
+
+
+ }
+ }
+}
diff --git a/SendGrid/packages/CodeScales.Http.dll b/SendGrid/packages/CodeScales.Http.dll
new file mode 100755
index 0000000..2509b52
--- /dev/null
+++ b/SendGrid/packages/CodeScales.Http.dll
Binary files differ