diff options
Diffstat (limited to 'SendGrid/SendGridMail')
-rwxr-xr-x | SendGrid/SendGridMail/Header.cs | 173 | ||||
-rwxr-xr-x | SendGrid/SendGridMail/IHeader.cs | 69 | ||||
-rwxr-xr-x | SendGrid/SendGridMail/ISendGrid.cs | 163 | ||||
-rwxr-xr-x | SendGrid/SendGridMail/Mail.csproj | 69 | ||||
-rwxr-xr-x | SendGrid/SendGridMail/Properties/AssemblyInfo.cs | 45 | ||||
-rwxr-xr-x | SendGrid/SendGridMail/SendGrid.cs | 540 | ||||
-rwxr-xr-x | SendGrid/SendGridMail/Transport/ITransport.cs | 14 | ||||
-rwxr-xr-x | SendGrid/SendGridMail/Transport/REST.cs | 136 | ||||
-rwxr-xr-x | SendGrid/SendGridMail/Transport/SMTP.cs | 132 | ||||
-rwxr-xr-x | SendGrid/SendGridMail/Utils.cs | 52 | ||||
-rwxr-xr-x | SendGrid/SendGridMail/Web/IWebApi.cs | 45 | ||||
-rwxr-xr-x | SendGrid/SendGridMail/WebFileUpload.cs | 114 |
12 files changed, 1552 insertions, 0 deletions
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/SendGridMail/Mail.csproj b/SendGrid/SendGridMail/Mail.csproj new file mode 100755 index 0000000..f333f36 --- /dev/null +++ b/SendGrid/SendGridMail/Mail.csproj @@ -0,0 +1,69 @@ +<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>8.0.30703</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{3C687BEF-FF50-44AD-8315-2D4237281AF8}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>SendGridMail</RootNamespace>
+ <AssemblyName>SendGridMail</AssemblyName>
+ <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <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" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Header.cs" />
+ <Compile Include="IHeader.cs" />
+ <Compile Include="ISendGrid.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="SendGrid.cs" />
+ <Compile Include="Transport\ITransport.cs" />
+ <Compile Include="Transport\REST.cs" />
+ <Compile Include="Transport\SMTP.cs" />
+ <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.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
\ No newline at end of file diff --git a/SendGrid/SendGridMail/Properties/AssemblyInfo.cs b/SendGrid/SendGridMail/Properties/AssemblyInfo.cs new file mode 100755 index 0000000..0108aa9 --- /dev/null +++ b/SendGrid/SendGridMail/Properties/AssemblyInfo.cs @@ -0,0 +1,45 @@ +using System.Reflection;
+using System.Runtime.CompilerServices;
+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("SendGridMail")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("SendGridMail")]
+[assembly: AssemblyCopyright("Copyright © 2012")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// 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
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
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();
+ }*/
+ }
+}
|