From 1be4549531d73cf89b4bebd2dac003937a1661df Mon Sep 17 00:00:00 2001 From: Tyler Bischel Date: Tue, 24 Jan 2012 14:57:47 -0800 Subject: [PATCH 1/7] renamed REST transport to Web --- SendGrid/Example/Example.csproj | 2 +- SendGrid/Example/Program.cs | 6 +-- SendGrid/Example/{RESTAPI.cs => WEBAPI.cs} | 48 +++++++++---------- SendGrid/SendGridMail/ISendGrid.cs | 2 +- SendGrid/SendGridMail/Mail.csproj | 2 +- SendGrid/SendGridMail/SendGrid.cs | 4 +- .../Transport/{REST.cs => Web.cs} | 18 +++---- SendGrid/Tests/Tests.csproj | 2 +- .../Transport/{TestREST.cs => TestWeb.cs} | 6 +-- 9 files changed, 45 insertions(+), 45 deletions(-) rename SendGrid/Example/{RESTAPI.cs => WEBAPI.cs} (84%) rename SendGrid/SendGridMail/Transport/{REST.cs => Web.cs} (88%) rename SendGrid/Tests/Transport/{TestREST.cs => TestWeb.cs} (91%) diff --git a/SendGrid/Example/Example.csproj b/SendGrid/Example/Example.csproj index cb778d1e2..1f85cc2fa 100755 --- a/SendGrid/Example/Example.csproj +++ b/SendGrid/Example/Example.csproj @@ -47,7 +47,7 @@ - + diff --git a/SendGrid/Example/Program.cs b/SendGrid/Example/Program.cs index c1815b72a..a4295107b 100755 --- a/SendGrid/Example/Program.cs +++ b/SendGrid/Example/Program.cs @@ -19,14 +19,14 @@ static void Main(string[] args) var from = "cj.buchmann@sendgrid.com"; var to = new List { - "cj.buchmann@sendgrid.com" + "foo@bar.com" }; //initialize the SMTPAPI example class var smtpapi = new SMTPAPI(username, password, from, to); - var restapi = new RESTAPI(username, password, from, to); + var restapi = new WEBAPI(username, password, from, to); - //use this section to test out our REST and SMTP examples! + //use this section to test out our Web and SMTP examples! restapi.EnableTemplateEmail(); Console.WriteLine("Done!"); diff --git a/SendGrid/Example/RESTAPI.cs b/SendGrid/Example/WEBAPI.cs similarity index 84% rename from SendGrid/Example/RESTAPI.cs rename to SendGrid/Example/WEBAPI.cs index 8c15800d1..adfd75637 100755 --- a/SendGrid/Example/RESTAPI.cs +++ b/SendGrid/Example/WEBAPI.cs @@ -8,14 +8,14 @@ namespace Example { - class RESTAPI + class WEBAPI { private String _username; private String _password; private String _from; private IEnumerable _to; - public RESTAPI(String username, String password, String from, IEnumerable recipients) + public WEBAPI(String username, String password, String from, IEnumerable recipients) { _username = username; _password = password; @@ -46,8 +46,8 @@ public void SimpleHTMLEmail() //set the message subject message.Subject = "Hello World HTML Test"; - //create an instance of the REST transport mechanism - var transportInstance = REST.GetInstance(new NetworkCredential(_username, _password)); + //create an instance of the Web transport mechanism + var transportInstance = Web.GetInstance(new NetworkCredential(_username, _password)); //send the mail transportInstance.Deliver(message); @@ -76,8 +76,8 @@ public void SimplePlaintextEmail() //set the message subject message.Subject = "Hello World Plain Text Test"; - //create an instance of the REST transport mechanism - var transportInstance = REST.GetInstance(new NetworkCredential(_username, _password)); + //create an instance of the Web transport mechanism + var transportInstance = Web.GetInstance(new NetworkCredential(_username, _password)); //send the mail transportInstance.Deliver(message); @@ -108,8 +108,8 @@ public void EnableGravatarEmail() //set the message subject message.Subject = "Hello World Gravatar Test"; - //create an instance of the REST transport mechanism - var transportInstance = REST.GetInstance(new NetworkCredential(_username, _password)); + //create an instance of the Web transport mechanism + var transportInstance = Web.GetInstance(new NetworkCredential(_username, _password)); //enable gravatar message.EnableGravatar(); @@ -142,8 +142,8 @@ public void EnableOpenTrackingEmail() //set the message subject message.Subject = "Hello World Open Tracking Test"; - //create an instance of the REST transport mechanism - var transportInstance = REST.GetInstance(new NetworkCredential(_username, _password)); + //create an instance of the Web transport mechanism + var transportInstance = Web.GetInstance(new NetworkCredential(_username, _password)); //enable gravatar message.EnableOpenTracking(); @@ -181,8 +181,8 @@ public void EnableClickTrackingEmail() //set the message subject message.Subject = "Hello World Click Tracking Test"; - //create an instance of the REST transport mechanism - var transportInstance = REST.GetInstance(new NetworkCredential(_username, _password)); + //create an instance of the Web transport mechanism + var transportInstance = Web.GetInstance(new NetworkCredential(_username, _password)); //enable clicktracking message.EnableClickTracking(false); @@ -218,8 +218,8 @@ public void EnableSpamCheckEmail() //set the message subject message.Subject = "WIN A MILLION DOLLARS TODAY! WORK FROM HOME! A NIGERIAN PRINCE WANTS YOU!"; - //create an instance of the REST transport mechanism - var transportInstance = REST.GetInstance(new NetworkCredential(_username, _password)); + //create an instance of the Web transport mechanism + var transportInstance = Web.GetInstance(new NetworkCredential(_username, _password)); //enable spamcheck message.EnableSpamCheck(); @@ -255,8 +255,8 @@ public void EnableUnsubscribeEmail() //set the message subject message.Subject = "Hello World Unsubscribe Test"; - //create an instance of the REST transport mechanism - var transportInstance = REST.GetInstance(new NetworkCredential(_username, _password)); + //create an instance of the Web transport mechanism + var transportInstance = Web.GetInstance(new NetworkCredential(_username, _password)); //enable spamcheck //or optionally, you can specify 'replace' instead of the text and html in order to @@ -295,8 +295,8 @@ public void EnableFooterEmail() //set the message subject message.Subject = "Hello World Footer Test"; - //create an instance of the REST transport mechanism - var transportInstance = REST.GetInstance(new NetworkCredential(_username, _password)); + //create an instance of the Web transport mechanism + var transportInstance = Web.GetInstance(new NetworkCredential(_username, _password)); //Enable Footer message.EnableFooter("PLAIN TEXT FOOTER", "

HTML FOOTER TEXT

"); @@ -334,8 +334,8 @@ public void EnableGoogleAnalytics() //set the message subject message.Subject = "Hello World Footer Test"; - //create an instance of the REST transport mechanism - var transportInstance = REST.GetInstance(new NetworkCredential(_username, _password)); + //create an instance of the Web transport mechanism + var transportInstance = Web.GetInstance(new NetworkCredential(_username, _password)); //enable Google Analytics message.EnableGoogleAnalytics("SendGridTest", "EMAIL", "Sendgrid", "ad-one", "My SG Campaign"); @@ -373,8 +373,8 @@ public void EnableTemplateEmail() //set the message subject message.Subject = "Hello World Template Test"; - //create an instance of the REST transport mechanism - var transportInstance = REST.GetInstance(new NetworkCredential(_username, _password)); + //create an instance of the Web transport mechanism + var transportInstance = Web.GetInstance(new NetworkCredential(_username, _password)); //enable template message.EnableTemplate("

My Email Template <% body %> is awesome!

"); @@ -412,8 +412,8 @@ public void EnableBypassListManagementEmail() //set the message subject message.Subject = "Hello World Bypass List Management Test"; - //create an instance of the REST transport mechanism - var transportInstance = REST.GetInstance(new NetworkCredential(_username, _password)); + //create an instance of the Web transport mechanism + var transportInstance = Web.GetInstance(new NetworkCredential(_username, _password)); //enable bypass list management message.EnableBypassListManagement(); diff --git a/SendGrid/SendGridMail/ISendGrid.cs b/SendGrid/SendGridMail/ISendGrid.cs index 08d109cf5..f868e2d48 100755 --- a/SendGrid/SendGridMail/ISendGrid.cs +++ b/SendGrid/SendGridMail/ISendGrid.cs @@ -7,7 +7,7 @@ namespace SendGridMail { /// /// Internal object to represent the way in which email may be sent. - /// The library supports sending through either SMTP or REST interfaces. + /// The library supports sending through either SMTP or Web interfaces. /// public enum TransportType { diff --git a/SendGrid/SendGridMail/Mail.csproj b/SendGrid/SendGridMail/Mail.csproj index bd1dc7a99..f1bf7f6bf 100755 --- a/SendGrid/SendGridMail/Mail.csproj +++ b/SendGrid/SendGridMail/Mail.csproj @@ -54,7 +54,7 @@ - +
diff --git a/SendGrid/SendGridMail/SendGrid.cs b/SendGrid/SendGridMail/SendGrid.cs index 59d7976ec..108c930e6 100755 --- a/SendGrid/SendGridMail/SendGrid.cs +++ b/SendGrid/SendGridMail/SendGrid.cs @@ -41,7 +41,7 @@ public static SendGrid GetInstance() /// /// The email address of the sender /// An array of the recipients - /// Supported over SMTP, with future plans for support in the REST transport + /// Supported over SMTP, with future plans for support in the Web transport /// Blind recipients /// The subject of the message /// the html content for the message @@ -531,7 +531,7 @@ public void Mail(NetworkCredential credentials) transport = SMTP.GetInstance(credentials); break; case TransportType.REST: - transport = REST.GetInstance(credentials); + transport = Web.GetInstance(credentials); break; default: throw new ArgumentException("Transport method not specified"); diff --git a/SendGrid/SendGridMail/Transport/REST.cs b/SendGrid/SendGridMail/Transport/Web.cs similarity index 88% rename from SendGrid/SendGridMail/Transport/REST.cs rename to SendGrid/SendGridMail/Transport/Web.cs index 614e024fd..8e0c51221 100755 --- a/SendGrid/SendGridMail/Transport/REST.cs +++ b/SendGrid/SendGridMail/Transport/Web.cs @@ -12,7 +12,7 @@ namespace SendGridMail.Transport { - public class REST : ITransport + public class Web : ITransport { #region Properties public const String Endpoint = "http://sendgrid.com/api/mail.send"; @@ -25,22 +25,22 @@ public class REST : ITransport #endregion /// - /// Factory method for REST transport of sendgrid messages + /// Factory method for Web transport of sendgrid messages /// /// SendGrid credentials for sending mail messages - /// The uri of the REST endpoint + /// The uri of the Web endpoint /// New instance of the transport mechanism - public static REST GetInstance(NetworkCredential credentials, String url = Endpoint) + public static Web GetInstance(NetworkCredential credentials, String url = Endpoint) { - return new REST(credentials, url); + return new Web(credentials, url); } /// - /// Creates a new REST interface for sending mail. Preference is using the Factory method. + /// Creates a new Web interface for sending mail. Preference is using the Factory method. /// /// SendGrid user parameters - /// The uri of the REST endpoint - internal REST(NetworkCredential credentials, String url = Endpoint) + /// The uri of the Web endpoint + internal Web(NetworkCredential credentials, String url = Endpoint) { _credentials = credentials; @@ -49,7 +49,7 @@ internal REST(NetworkCredential credentials, String url = Endpoint) } /// - /// Delivers a message over SendGrid's REST interface + /// Delivers a message over SendGrid's Web interface /// /// public void Deliver(ISendGrid message) diff --git a/SendGrid/Tests/Tests.csproj b/SendGrid/Tests/Tests.csproj index cd43bd12e..c75563a52 100755 --- a/SendGrid/Tests/Tests.csproj +++ b/SendGrid/Tests/Tests.csproj @@ -59,7 +59,7 @@ - + diff --git a/SendGrid/Tests/Transport/TestREST.cs b/SendGrid/Tests/Transport/TestWeb.cs similarity index 91% rename from SendGrid/Tests/Transport/TestREST.cs rename to SendGrid/Tests/Transport/TestWeb.cs index e9cc909fa..ac69dd244 100755 --- a/SendGrid/Tests/Transport/TestREST.cs +++ b/SendGrid/Tests/Transport/TestWeb.cs @@ -12,12 +12,12 @@ namespace Tests.Transport { [TestFixture] - class TestREST + class TestWeb { [Test] public void TestFetchFileBodies() { - var test = REST.GetInstance(new NetworkCredential("foo", "bar")); + var test = Web.GetInstance(new NetworkCredential("foo", "bar")); var message = new Mock(); message.SetupProperty(foo => foo.Attachments, null); var result = test.FetchFileBodies(message.Object); @@ -37,7 +37,7 @@ public void TestFetchFileBodies() [Test] public void TestFetchFormParams() { - var bar = REST.GetInstance(new NetworkCredential("usr", "psswd")); + var bar = Web.GetInstance(new NetworkCredential("usr", "psswd")); var message = SendGrid.GetInstance(); message.AddTo("foo@bar.com"); message.AddCc("cc@bar.com"); From bfae82588ff323974edd18214c274b0f5dba4bf0 Mon Sep 17 00:00:00 2001 From: Tyler Bischel Date: Tue, 24 Jan 2012 15:37:39 -0800 Subject: [PATCH 2/7] updated the tests for AddSubVal and mapped some header functionality to the SendGrid object --- SendGrid/SendGridMail/ISendGrid.cs | 54 ++++++------ SendGrid/SendGridMail/SendGrid.cs | 96 ++++++++++------------ SendGrid/Tests/TestSendgridMessageSetup.cs | 14 ++-- 3 files changed, 73 insertions(+), 91 deletions(-) diff --git a/SendGrid/SendGridMail/ISendGrid.cs b/SendGrid/SendGridMail/ISendGrid.cs index f868e2d48..724d1456a 100755 --- a/SendGrid/SendGridMail/ISendGrid.cs +++ b/SendGrid/SendGridMail/ISendGrid.cs @@ -5,16 +5,6 @@ namespace SendGridMail { - /// - /// Internal object to represent the way in which email may be sent. - /// The library supports sending through either SMTP or Web interfaces. - /// - public enum TransportType - { - SMTP, - REST - }; - /// /// Represents the basic set of functions that will be called by the user /// includes basic message data manipulation and filter settings @@ -33,7 +23,6 @@ public interface ISendGrid IHeader Header { get; set; } String Html { get; set; } String Text { get; set; } - TransportType Transport { get; set; } #endregion #region Interface for ITransport @@ -42,13 +31,6 @@ public interface ISendGrid /// /// MIME to be sent MailMessage CreateMimeMessage(); - - /// - /// Creates a new transport object, and sends this message out. - /// - /// Sendgrid user credentials - void Mail(NetworkCredential credentials); - #endregion #region Methods for setting data @@ -68,7 +50,7 @@ public interface ISendGrid /// Add to the 'To' address. /// /// the dictionary keys are the email addresses, which points to a dictionary of - /// key value pairs mapping to other address codes, such as { foo@bar.com => { 'DisplayName' => 'Mr Foo' } } + /// key substitutionValues pairs mapping to other address codes, such as { foo@bar.com => { 'DisplayName' => 'Mr Foo' } } void AddTo(IDictionary> addresssInfo); /// @@ -87,7 +69,7 @@ public interface ISendGrid /// Add to the 'CC' address. /// /// the dictionary keys are the email addresses, which points to a dictionary of - /// key value pairs mapping to other address codes, such as { foo@bar.com => { 'DisplayName' => 'Mr Foo' } } + /// key substitutionValues pairs mapping to other address codes, such as { foo@bar.com => { 'DisplayName' => 'Mr Foo' } } void AddCc(IDictionary> addresssInfo); /// @@ -106,16 +88,30 @@ public interface ISendGrid /// Add to the 'Bcc' address. /// /// the dictionary keys are the email addresses, which points to a dictionary of - /// key value pairs mapping to other address codes, such as { foo@bar.com => { 'DisplayName' => 'Mr Foo' } } + /// key substitutionValues pairs mapping to other address codes, such as { foo@bar.com => { 'DisplayName' => 'Mr Foo' } } void AddBcc(IDictionary> addresssInfo); /// - /// Adds a substitution value to be used during the mail merge. Substitutions will happen in the order - /// added, so calls to this should match calls to addTo. + /// Defines a mapping between a replacement string in the text of the message to a list of + /// substitution values to be used, one per each recipient, in the same order as the recipients were added. + /// + /// the string in the email that you'll replace eg. '-name-' + /// a list of values that will be substituted in for the replacementTag, one for each recipient + void AddSubVal(String replacementTag, List substitutionValues); + + /// + /// This adds parameters and values that will be bassed back through SendGrid's + /// Event API if an event notification is triggered by this email. + /// + /// parameter substitutionValues pairs to be passed back on event notification + void AddUniqueIdentifier(IDictionary identifiers); + + /// + /// 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. /// - /// the string in the email that you'll replace eg. '-name-' - /// a list of values that will be substituted in for the tag, one for each recipient - void AddSubVal(String tag, params String[] value); + /// categories applied to the message + void SetCategory(String category); /// /// Add an attachment to the message. @@ -132,7 +128,7 @@ public interface ISendGrid /// /// Add custom headers to the message /// - /// key value pairs + /// key substitutionValues pairs void AddHeaders(IDictionary headers); #endregion @@ -206,7 +202,7 @@ public interface ISendGrid /// /// Provides notification when emails are deteched that exceed a predefined spam threshold. /// - /// Emails with a SpamAssassin score over this value will be considered spam and not be delivered. + /// Emails with a SpamAssassin score over this substitutionValues will be considered spam and not be delivered. /// SendGrid will send an HTTP POST request to this url when a message is detected as spam void EnableSpamCheck(int score = 5, String url = null); @@ -243,7 +239,7 @@ public interface ISendGrid /// /// Wraps an HTML template around your email content. /// - /// HTML that your emails will be wrapped in, containing a body tag. + /// HTML that your emails will be wrapped in, containing a body replacementTag. void EnableTemplate(String html = null); /// diff --git a/SendGrid/SendGridMail/SendGrid.cs b/SendGrid/SendGridMail/SendGrid.cs index 108c930e6..5f847dc97 100755 --- a/SendGrid/SendGridMail/SendGrid.cs +++ b/SendGrid/SendGridMail/SendGrid.cs @@ -13,7 +13,7 @@ public class SendGrid : ISendGrid { #region constants/vars //private/constant vars: - private Dictionary _filters; + private static readonly Dictionary Filters = InitializeFilters(); private MailMessage message; // TODO find appropriate types for these @@ -49,14 +49,14 @@ public static SendGrid GetInstance() /// Transport class to use for sending the message /// public static SendGrid GetInstance(MailAddress from, MailAddress[] to, MailAddress[] cc, MailAddress[] bcc, - String subject, String html, String text, TransportType transport) + String subject, String html, String text) { var header = new Header(); - return new SendGrid(from, to, cc, bcc, subject, html, text, transport, header); + return new SendGrid(from, to, cc, bcc, subject, html, text, header); } internal SendGrid(MailAddress from, MailAddress[] to, MailAddress[] cc, MailAddress[] bcc, - String subject, String html, String text, TransportType transport, IHeader header = null ) : this(header) + String subject, String html, String text, IHeader header = null ) : this(header) { From = from; To = to; @@ -74,14 +74,11 @@ internal SendGrid(IHeader header) message = new MailMessage(); Header = header; Headers = new Dictionary(); - - //initialize the filters, for use within the library - this.InitializeFilters(); } - public void InitializeFilters() + private static Dictionary InitializeFilters() { - this._filters = + return new Dictionary { {"Gravatar", "gravatar"}, @@ -191,7 +188,6 @@ public String Subject 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 @@ -286,12 +282,23 @@ public String[] Attachments set { _attachments = value.ToList(); } } - public void AddSubVal(String tag, params String[] value) + public void AddSubVal(String replacementTag, List substitutionValues) { //let the system complain if they do something bad, since the function returns null - Header.AddSubVal(tag, value); + Header.AddSubVal(replacementTag, substitutionValues); + } + + public void AddUniqueIdentifier(IDictionary identifiers) + { + Header.AddUniqueIdentifier(identifiers); + } + + public void SetCategory(String category) + { + Header.SetCategory(category); } + public void AddAttachment(String filePath) { _attachments.Add(filePath); @@ -316,67 +323,67 @@ public void AddHeaders(IDictionary headers) #region SMTP API Functions public void DisableGravatar() { - Header.Disable(_filters["Gravatar"]); + Header.Disable(Filters["Gravatar"]); } public void DisableOpenTracking() { - Header.Disable(_filters["OpenTracking"]); + Header.Disable(Filters["OpenTracking"]); } public void DisableClickTracking() { - Header.Disable(_filters["ClickTracking"]); + Header.Disable(Filters["ClickTracking"]); } public void DisableSpamCheck() { - Header.Disable(_filters["SpamCheck"]); + Header.Disable(Filters["SpamCheck"]); } public void DisableUnsubscribe() { - Header.Disable(_filters["Unsubscribe"]); + Header.Disable(Filters["Unsubscribe"]); } public void DisableFooter() { - Header.Disable(_filters["Footer"]); + Header.Disable(Filters["Footer"]); } public void DisableGoogleAnalytics() { - Header.Disable(_filters["GoogleAnalytics"]); + Header.Disable(Filters["GoogleAnalytics"]); } public void DisableTemplate() { - Header.Disable(_filters["Template"]); + Header.Disable(Filters["Template"]); } public void DisableBcc() { - Header.Disable(_filters["Bcc"]); + Header.Disable(Filters["Bcc"]); } public void DisableBypassListManagement() { - Header.Disable(_filters["BypassListManagement"]); + Header.Disable(Filters["BypassListManagement"]); } public void EnableGravatar() { - Header.Enable(_filters["Gravatar"]); + Header.Enable(Filters["Gravatar"]); } public void EnableOpenTracking() { - Header.Enable(_filters["OpenTracking"]); + Header.Enable(Filters["OpenTracking"]); } public void EnableClickTracking(bool includePlainText = false) { - var filter = _filters["ClickTracking"]; + var filter = Filters["ClickTracking"]; Header.Enable(filter); if (includePlainText) @@ -387,7 +394,7 @@ public void EnableClickTracking(bool includePlainText = false) public void EnableSpamCheck(int score = 5, string url = null) { - var filter = _filters["SpamCheck"]; + var filter = Filters["SpamCheck"]; Header.Enable(filter); Header.AddFilterSetting(filter, new List { "maxscore" }, score.ToString(CultureInfo.InvariantCulture)); @@ -396,16 +403,16 @@ public void EnableSpamCheck(int score = 5, string url = null) public void EnableUnsubscribe(string text, string html) { - var filter = _filters["Unsubscribe"]; + var filter = Filters["Unsubscribe"]; if(!System.Text.RegularExpressions.Regex.IsMatch(text, ReText)) { - throw new Exception("Missing substitution tag in text"); + throw new Exception("Missing substitution replacementTag in text"); } if(!System.Text.RegularExpressions.Regex.IsMatch(html, ReHtml)) { - throw new Exception("Missing substitution tag in html"); + throw new Exception("Missing substitution replacementTag in html"); } Header.Enable(filter); @@ -415,7 +422,7 @@ public void EnableUnsubscribe(string text, string html) public void EnableUnsubscribe(string replace) { - var filter = _filters["Unsubscribe"]; + var filter = Filters["Unsubscribe"]; Header.Enable(filter); Header.AddFilterSetting(filter, new List { "replace" }, replace); @@ -423,7 +430,7 @@ public void EnableUnsubscribe(string replace) public void EnableFooter(string text = null, string html = null) { - var filter = _filters["Footer"]; + var filter = Filters["Footer"]; Header.Enable(filter); Header.AddFilterSetting(filter, new List { "text/plain" }, text); @@ -432,7 +439,7 @@ public void EnableFooter(string text = null, string html = null) public void EnableGoogleAnalytics(string source, string medium, string term, string content = null, string campaign = null) { - var filter = _filters["GoogleAnalytics"]; + var filter = Filters["GoogleAnalytics"]; Header.Enable(filter); Header.AddFilterSetting(filter, new List { "utm_source" }, source); @@ -444,11 +451,11 @@ public void EnableGoogleAnalytics(string source, string medium, string term, str public void EnableTemplate(string html) { - var filter = _filters["Template"]; + var filter = Filters["Template"]; if (!System.Text.RegularExpressions.Regex.IsMatch(html, ReHtml)) { - throw new Exception("Missing substitution tag in html"); + throw new Exception("Missing substitution replacementTag in html"); } Header.Enable(filter); @@ -457,7 +464,7 @@ public void EnableTemplate(string html) public void EnableBcc(string email) { - var filter = _filters["Bcc"]; + var filter = Filters["Bcc"]; Header.Enable(filter); Header.AddFilterSetting(filter, new List { "email" }, email); @@ -465,7 +472,7 @@ public void EnableBcc(string email) public void EnableBypassListManagement() { - Header.Enable(_filters["BypassListManagement"]); + Header.Enable(Filters["BypassListManagement"]); } #endregion @@ -521,22 +528,5 @@ public void SaveMessage(String directory) var msg = CreateMimeMessage(); client.Send(msg); } - - public void Mail(NetworkCredential credentials) - { - ITransport transport; - switch (Transport) - { - case TransportType.SMTP: - transport = SMTP.GetInstance(credentials); - break; - case TransportType.REST: - transport = Web.GetInstance(credentials); - break; - default: - throw new ArgumentException("Transport method not specified"); - } - transport.Deliver(this); - } } } diff --git a/SendGrid/Tests/TestSendgridMessageSetup.cs b/SendGrid/Tests/TestSendgridMessageSetup.cs index efbb85398..b02729d40 100755 --- a/SendGrid/Tests/TestSendgridMessageSetup.cs +++ b/SendGrid/Tests/TestSendgridMessageSetup.cs @@ -99,21 +99,17 @@ public void TestSGHeader() 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 substitutionStrings = new List {"foo", "bar", "beer"}; + var mock = new Mock(); - var datastruct = new String[2]; - datastruct[0] = "eric"; - datastruct[1] = "tyler"; + var sg = new SendGrid(mock.Object); + sg.AddSubVal("-name-", substitutionStrings); - sg.AddSubVal("-name-", datastruct); - Assert.AreEqual("test", sg.Header); + mock.Verify(foo => foo.AddSubVal("-name-", substitutionStrings)); } - */ [Test] From a4c59ce574fa71bd7d2096b4a142e8d54670ea3c Mon Sep 17 00:00:00 2001 From: Tyler Bischel Date: Tue, 24 Jan 2012 15:45:18 -0800 Subject: [PATCH 3/7] added test coverage to two functions in SendGrid.cs --- SendGrid/Tests/TestSendgridMessageSetup.cs | 24 ++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/SendGrid/Tests/TestSendgridMessageSetup.cs b/SendGrid/Tests/TestSendgridMessageSetup.cs index b02729d40..474b03f8a 100755 --- a/SendGrid/Tests/TestSendgridMessageSetup.cs +++ b/SendGrid/Tests/TestSendgridMessageSetup.cs @@ -111,6 +111,30 @@ public void TestAddSubVal() mock.Verify(foo => foo.AddSubVal("-name-", substitutionStrings)); } + [Test] + public void TestAddUniqueIdentifier() + { + + var kvp = new Dictionary { {"foo", "bar"}, {"beer", "good"} }; + var mock = new Mock(); + + var sg = new SendGrid(mock.Object); + sg.AddUniqueIdentifier(kvp); + + mock.Verify(foo => foo.AddUniqueIdentifier(kvp)); + } + + [Test] + public void TestSetCategory() + { + var cat = "foo"; + var mock = new Mock(); + + var sg = new SendGrid(mock.Object); + sg.SetCategory(cat); + + mock.Verify(foo => foo.SetCategory(cat)); + } [Test] public void TestGetRcpts() From 9b04e9c45445883508b699af481fd7c076ee0d17 Mon Sep 17 00:00:00 2001 From: Tyler Bischel Date: Tue, 24 Jan 2012 16:30:29 -0800 Subject: [PATCH 4/7] added examples based on user feedback --- SendGrid/Example/Program.cs | 7 +- SendGrid/Example/SMTPAPI.cs | 121 ++++++++++++++++++++ SendGrid/Example/WEBAPI.cs | 123 +++++++++++++++++++++ SendGrid/SendGridMail/ISendGrid.cs | 2 +- SendGrid/SendGridMail/SendGrid.cs | 2 +- SendGrid/Tests/TestSendgridMessageSetup.cs | 2 +- 6 files changed, 251 insertions(+), 6 deletions(-) diff --git a/SendGrid/Example/Program.cs b/SendGrid/Example/Program.cs index a4295107b..edec5c922 100755 --- a/SendGrid/Example/Program.cs +++ b/SendGrid/Example/Program.cs @@ -16,10 +16,11 @@ static void Main(string[] args) { var username = "sgrid_username"; var password = "sgrid_password"; - var from = "cj.buchmann@sendgrid.com"; + var from = "bar@domain.com"; var to = new List { - "foo@bar.com" + "foo@domain.com", + "raz@domain.com" }; //initialize the SMTPAPI example class @@ -27,7 +28,7 @@ static void Main(string[] args) var restapi = new WEBAPI(username, password, from, to); //use this section to test out our Web and SMTP examples! - restapi.EnableTemplateEmail(); + smtpapi.SimpleHTMLEmail(); Console.WriteLine("Done!"); Console.ReadLine(); diff --git a/SendGrid/Example/SMTPAPI.cs b/SendGrid/Example/SMTPAPI.cs index ca80f69f7..d9ab1546d 100755 --- a/SendGrid/Example/SMTPAPI.cs +++ b/SendGrid/Example/SMTPAPI.cs @@ -421,5 +421,126 @@ public void EnableBypassListManagementEmail() transportInstance.Deliver(message); } + /// + /// This feature allows you to create a message template, and specify different replacement + /// strings for each specific recipient + /// + public void AddSubstitutionValues() + { + //create a new message object + var message = SendGrid.GetInstance(); + + //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 = "Hi %name%! Pleased to meet you!"; + + //set the message subject + message.Subject = "Testing Substitution Values"; + + //This replacement key must exist in the message body + var replacementKey = "%name%"; + + //There should be one value for each recipient in the To list + var substitutionValues = new List {"Mr Foo", "Mrs Raz"}; + + message.AddSubVal(replacementKey, substitutionValues); + + //create an instance of the SMTP transport mechanism + var transportInstance = SMTP.GetInstance(new NetworkCredential(_username, _password)); + + //enable bypass list management + message.EnableBypassListManagement(); + + //send the mail + transportInstance.Deliver(message); + } + + /// + /// This feature adds key value identifiers to be sent back as arguments over the event api for + /// various events + /// + public void AddUniqueIdentifiers() + { + //create a new message object + var message = SendGrid.GetInstance(); + + //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"; + + //set the message subject + message.Subject = "Testing Unique Identifiers"; + + var identifiers = new Dictionary(); + identifiers["customer"] = "someone"; + identifiers["location"] = "somewhere"; + + message.AddUniqueIdentifiers(identifiers); + + //create an instance of the SMTP transport mechanism + var transportInstance = SMTP.GetInstance(new NetworkCredential(_username, _password)); + + //enable bypass list management + message.EnableBypassListManagement(); + + //send the mail + transportInstance.Deliver(message); + + } + + /// + /// This feature tags the message with a specific tracking category, which will have aggregated stats + /// viewable from your SendGrid account page. + /// + public void SetCategory() + { + //create a new message object + var message = SendGrid.GetInstance(); + + //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"; + + //set the message subject + message.Subject = "Testing Categories"; + + var category = "vipCustomers"; + + message.SetCategory(category); + + //create an instance of the SMTP transport mechanism + var transportInstance = SMTP.GetInstance(new NetworkCredential(_username, _password)); + + //enable bypass list management + message.EnableBypassListManagement(); + + //send the mail + transportInstance.Deliver(message); + } + } } diff --git a/SendGrid/Example/WEBAPI.cs b/SendGrid/Example/WEBAPI.cs index adfd75637..985005d90 100755 --- a/SendGrid/Example/WEBAPI.cs +++ b/SendGrid/Example/WEBAPI.cs @@ -421,5 +421,128 @@ public void EnableBypassListManagementEmail() //send the mail transportInstance.Deliver(message); } + + + /// + /// This feature allows you to create a message template, and specify different replacement + /// strings for each specific recipient + /// + public void AddSubstitutionValues() + { + //create a new message object + var message = SendGrid.GetInstance(); + + //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 = "Hi %name%! Pleased to meet you!"; + + //set the message subject + message.Subject = "Testing Substitution Values"; + + //This replacement key must exist in the message body + var replacementKey = "%name%"; + + //There should be one value for each recipient in the To list + var substitutionValues = new List { "Mr Foo", "Mrs Raz" }; + + message.AddSubVal(replacementKey, substitutionValues); + + //create an instance of the SMTP transport mechanism + var transportInstance = Web.GetInstance(new NetworkCredential(_username, _password)); + + //enable bypass list management + message.EnableBypassListManagement(); + + //send the mail + transportInstance.Deliver(message); + } + + /// + /// This feature adds key value identifiers to be sent back as arguments over the event api for + /// various events + /// + public void AddUniqueIdentifiers() + { + //create a new message object + var message = SendGrid.GetInstance(); + + //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"; + + //set the message subject + message.Subject = "Testing Unique Identifiers"; + + var identifiers = new Dictionary(); + identifiers["customer"] = "someone"; + identifiers["location"] = "somewhere"; + + message.AddUniqueIdentifiers(identifiers); + + //create an instance of the SMTP transport mechanism + var transportInstance = Web.GetInstance(new NetworkCredential(_username, _password)); + + //enable bypass list management + message.EnableBypassListManagement(); + + //send the mail + transportInstance.Deliver(message); + + } + + /// + /// This feature tags the message with a specific tracking category, which will have aggregated stats + /// viewable from your SendGrid account page. + /// + public void SetCategory() + { + //create a new message object + var message = SendGrid.GetInstance(); + + //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"; + + //set the message subject + message.Subject = "Testing Categories"; + + var category = "vipCustomers"; + + message.SetCategory(category); + + //create an instance of the SMTP transport mechanism + var transportInstance = Web.GetInstance(new NetworkCredential(_username, _password)); + + //enable bypass list management + message.EnableBypassListManagement(); + + //send the mail + transportInstance.Deliver(message); + } + } } diff --git a/SendGrid/SendGridMail/ISendGrid.cs b/SendGrid/SendGridMail/ISendGrid.cs index 724d1456a..10f082602 100755 --- a/SendGrid/SendGridMail/ISendGrid.cs +++ b/SendGrid/SendGridMail/ISendGrid.cs @@ -104,7 +104,7 @@ public interface ISendGrid /// Event API if an event notification is triggered by this email. /// /// parameter substitutionValues pairs to be passed back on event notification - void AddUniqueIdentifier(IDictionary identifiers); + void AddUniqueIdentifiers(IDictionary identifiers); /// /// This sets the category for this email. Statistics are stored on a per category diff --git a/SendGrid/SendGridMail/SendGrid.cs b/SendGrid/SendGridMail/SendGrid.cs index 5f847dc97..e3b992f89 100755 --- a/SendGrid/SendGridMail/SendGrid.cs +++ b/SendGrid/SendGridMail/SendGrid.cs @@ -288,7 +288,7 @@ public void AddSubVal(String replacementTag, List substitutionValues) Header.AddSubVal(replacementTag, substitutionValues); } - public void AddUniqueIdentifier(IDictionary identifiers) + public void AddUniqueIdentifiers(IDictionary identifiers) { Header.AddUniqueIdentifier(identifiers); } diff --git a/SendGrid/Tests/TestSendgridMessageSetup.cs b/SendGrid/Tests/TestSendgridMessageSetup.cs index 474b03f8a..fa3db7204 100755 --- a/SendGrid/Tests/TestSendgridMessageSetup.cs +++ b/SendGrid/Tests/TestSendgridMessageSetup.cs @@ -119,7 +119,7 @@ public void TestAddUniqueIdentifier() var mock = new Mock(); var sg = new SendGrid(mock.Object); - sg.AddUniqueIdentifier(kvp); + sg.AddUniqueIdentifiers(kvp); mock.Verify(foo => foo.AddUniqueIdentifier(kvp)); } From cf275fca7c7c78364bf5031d0ab7dc01afdd51c4 Mon Sep 17 00:00:00 2001 From: Tyler Bischel Date: Tue, 24 Jan 2012 16:52:22 -0800 Subject: [PATCH 5/7] changed the access for the save message function, which is for internal use only --- SendGrid/SendGridMail/SendGrid.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SendGrid/SendGridMail/SendGrid.cs b/SendGrid/SendGridMail/SendGrid.cs index e3b992f89..42214b7dd 100755 --- a/SendGrid/SendGridMail/SendGrid.cs +++ b/SendGrid/SendGridMail/SendGrid.cs @@ -518,7 +518,7 @@ public MailMessage CreateMimeMessage() /// Helper function lets us look at the mime before it is sent /// /// directory in which we store this mime message - public void SaveMessage(String directory) + internal void SaveMessage(String directory) { var client = new SmtpClient("localhost") { From cc1953ef91a3b34f7ae338a8a1d976cf93583b57 Mon Sep 17 00:00:00 2001 From: Tyler Bischel Date: Wed, 25 Apr 2012 15:51:54 -0700 Subject: [PATCH 6/7] added support for attachments by streams, and made the REST call truncate to onl the file name, not the full path --- SendGrid/Example/Program.cs | 2 ++ SendGrid/SendGridMail/ISendGrid.cs | 9 +++++ SendGrid/SendGridMail/Mail.csproj | 1 + SendGrid/SendGridMail/SendGrid.cs | 23 +++++++++++++ SendGrid/SendGridMail/StreamedFileBody.cs | 42 +++++++++++++++++++++++ SendGrid/SendGridMail/Transport/Web.cs | 10 +++++- 6 files changed, 86 insertions(+), 1 deletion(-) create mode 100755 SendGrid/SendGridMail/StreamedFileBody.cs diff --git a/SendGrid/Example/Program.cs b/SendGrid/Example/Program.cs index edec5c922..1debf2ea0 100755 --- a/SendGrid/Example/Program.cs +++ b/SendGrid/Example/Program.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Net; using System.Net.Mail; @@ -33,5 +34,6 @@ static void Main(string[] args) Console.WriteLine("Done!"); Console.ReadLine(); } + } } diff --git a/SendGrid/SendGridMail/ISendGrid.cs b/SendGrid/SendGridMail/ISendGrid.cs index 10f082602..a96e93c5f 100755 --- a/SendGrid/SendGridMail/ISendGrid.cs +++ b/SendGrid/SendGridMail/ISendGrid.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.IO; using System.Net; using System.Net.Mail; @@ -17,6 +18,7 @@ public interface ISendGrid MailAddress[] Cc { get; } MailAddress[] Bcc { get; } MailAddress[] ReplyTo { get; set; } + Dictionary StreamedAttachments { get; set; } String[] Attachments { get; set; } String Subject { get; set; } Dictionary Headers { get; set; } @@ -119,6 +121,13 @@ public interface ISendGrid /// a fully qualified file path as a string void AddAttachment(String filePath); + /// + /// Add a stream as an attachment to the message + /// + /// Stream of file to be attached + /// Name of file to be attached + void AddAttachment(Stream stream, String name); + /// /// GetRecipients returns a list of all the recepients by retrieving the to, cc, and bcc lists. /// diff --git a/SendGrid/SendGridMail/Mail.csproj b/SendGrid/SendGridMail/Mail.csproj index f1bf7f6bf..91d3b9192 100755 --- a/SendGrid/SendGridMail/Mail.csproj +++ b/SendGrid/SendGridMail/Mail.csproj @@ -53,6 +53,7 @@ + diff --git a/SendGrid/SendGridMail/SendGrid.cs b/SendGrid/SendGridMail/SendGrid.cs index 42214b7dd..4a1421110 100755 --- a/SendGrid/SendGridMail/SendGrid.cs +++ b/SendGrid/SendGridMail/SendGrid.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Globalization; +using System.IO; using System.Linq; using System.Net; using System.Net.Mail; @@ -275,6 +276,13 @@ public void AddBcc(IDictionary> addresssInfo } } + private Dictionary _streamedAttachments = new Dictionary(); + public Dictionary StreamedAttachments + { + get { return _streamedAttachments; } + set { _streamedAttachments = value; } + } + private List _attachments = new List(); public String[] Attachments { @@ -298,6 +306,12 @@ public void SetCategory(String category) Header.SetCategory(category); } + public void AddAttachment(Stream stream, String name) + { + MemoryStream ms = new MemoryStream(); + stream.CopyTo(ms); + StreamedAttachments[name] = ms; + } public void AddAttachment(String filePath) { @@ -496,6 +510,15 @@ public MailMessage CreateMimeMessage() } } + if(StreamedAttachments != null) + { + foreach (var attachment in StreamedAttachments) + { + attachment.Value.Position = 0; + message.Attachments.Add(new Attachment(attachment.Value, attachment.Key)); + } + } + if (Text != null) { AlternateView plainView = AlternateView.CreateAlternateViewFromString(Text, null, "text/plain"); diff --git a/SendGrid/SendGridMail/StreamedFileBody.cs b/SendGrid/SendGridMail/StreamedFileBody.cs new file mode 100755 index 000000000..6bb5ec1ce --- /dev/null +++ b/SendGrid/SendGridMail/StreamedFileBody.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using CodeScales.Http.Entity.Mime; +using CodeScales.Http.Network; + +namespace SendGridMail +{ + public class StreamedFileBody : Body + { + private string _name; + private string _filename; + private byte[] _content; + + public StreamedFileBody(MemoryStream stream, String name) + { + if (stream == null) throw new ArgumentException("Invalid attachment stream"); + if (String.IsNullOrEmpty(name)) throw new ArgumentException("Invalid attachment name"); + + _name = "files[" + Path.GetFileName(name) + "]"; + _filename = name; + _content = stream.ToArray(); + } + + public byte[] GetContent(string boundry) + { + var bytes = new List(); + + string paramBoundry = "--" + boundry + "\r\n"; + string stringParam = "Content-Disposition: form-data; name=\"" + _name + "\"; filename=\"" + _filename + "\"\r\n"; + string paramEnd = "Content-Type: image/png\r\n\r\n"; + string foo = paramBoundry + stringParam + paramEnd; + + bytes.AddRange(Encoding.ASCII.GetBytes(paramBoundry + stringParam + paramEnd)); + bytes.AddRange(_content); + bytes.AddRange(Encoding.ASCII.GetBytes("\r\n")); + return bytes.ToArray(); + } + } +} diff --git a/SendGrid/SendGridMail/Transport/Web.cs b/SendGrid/SendGridMail/Transport/Web.cs index 8e0c51221..f3448ad32 100755 --- a/SendGrid/SendGridMail/Transport/Web.cs +++ b/SendGrid/SendGridMail/Transport/Web.cs @@ -85,7 +85,10 @@ private void AttachFormParams(ISendGrid message, MultipartEntity multipartEntity private void AttachFiles(ISendGrid message, MultipartEntity multipartEntity) { var files = FetchFileBodies(message); - files.ForEach(kvp => multipartEntity.AddBody(new FileBody("files[" + kvp.Key + "]", kvp.Key, kvp.Value))); + files.ForEach(kvp => multipartEntity.AddBody(new FileBody("files[" + Path.GetFileName(kvp.Key) + "]", kvp.Key, kvp.Value))); + + var streamingFiles = FetchStreamingFileBodies(message); + streamingFiles.ForEach(kvp => multipartEntity.AddBody(new StreamedFileBody(kvp.Value, kvp.Key))); } private void CheckForErrors(CodeScales.Http.Methods.HttpResponse response) @@ -148,6 +151,11 @@ internal List> FetchFormParams(ISendGrid message) } return result.Where(r => !String.IsNullOrEmpty(r.Value)).ToList(); } + + internal List> FetchStreamingFileBodies(ISendGrid message) + { + return message.StreamedAttachments.Select(kvp => kvp).ToList(); + } internal List> FetchFileBodies(ISendGrid message) { From 1112ba4c4ac77b63ad63b729d68e3c816093c701 Mon Sep 17 00:00:00 2001 From: Tyler Bischel Date: Thu, 26 Apr 2012 14:21:57 -0700 Subject: [PATCH 7/7] tests for streaming attachments via rest --- SendGrid/Tests/TestStreamedFileBody.cs | 35 ++++++++++++++++++++++++++ SendGrid/Tests/Tests.csproj | 5 ++++ 2 files changed, 40 insertions(+) create mode 100755 SendGrid/Tests/TestStreamedFileBody.cs diff --git a/SendGrid/Tests/TestStreamedFileBody.cs b/SendGrid/Tests/TestStreamedFileBody.cs new file mode 100755 index 000000000..60d43b83e --- /dev/null +++ b/SendGrid/Tests/TestStreamedFileBody.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using NUnit.Framework; +using SendGridMail; + +namespace Tests +{ + [TestFixture] + public class TestStreamedFileBody + { + [Test] + public void TestGetContent() + { + var name = "foo"; + var file = "bar"; + var boundary = "raz"; + + var memoryStream = new MemoryStream(); + var stream = new StreamWriter(memoryStream); + stream.Write(file); + stream.Flush(); + stream.Close(); + + var streamedFile = new StreamedFileBody(memoryStream, name); + var bytes = streamedFile.GetContent(boundary); + var result = System.Text.Encoding.ASCII.GetString(bytes); + var expected = "--raz\r\nContent-Disposition: form-data; name=\"files[foo]\"; filename=\"foo\"\r\nContent-Type: image/png\r\n\r\nbar\r\n"; + Assert.AreEqual(expected, result, "message formated correctly"); + + } + } +} diff --git a/SendGrid/Tests/Tests.csproj b/SendGrid/Tests/Tests.csproj index c75563a52..cdfd9b73a 100755 --- a/SendGrid/Tests/Tests.csproj +++ b/SendGrid/Tests/Tests.csproj @@ -31,6 +31,10 @@ 4 + + False + ..\SendGridMail\lib\CodeScales.Http.dll + ..\packages\Moq.4.0.10827\lib\NET40\Moq.dll @@ -57,6 +61,7 @@ +