-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Easy-to-use wrapper for the hailgun package
--   
--   Please see README.md
@package hailgun-simple
@version 0.1.0.0


-- | This module provides a simple, easy-to-use wrapper around the
--   <a>hailgun</a> package. hailgun is a package providing a way to send
--   email using <a>Mailgun</a>.
--   
--   Here is a short example of how to use this package:
--   
--   <pre>
--   {-# LANGUAGE OverloadedStrings #-}
--   {-# LANGUAGE QuasiQuotes #-}
--   
--   module FooBar where
--   
--   import <a>Control.Monad.Reader</a> (<a>ReaderT</a>)
--   import <a>Data.Text</a> (<a>Text</a>)
--   import <a>Data.Text.Encoding</a> (<a>encodeUtf8</a>)
--   import <a>Text.Email.Validate</a> (<a>EmailAddress</a>)
--   import Text.Shakespeare.Text (sbt)
--   import <a>Mail.Hailgun.Simple</a>
--          (<a>MessageContent</a>(<a>TextOnly</a>), <a>Email</a>(..), <a>EmailError</a>,
--           <a>HailgunContext</a>, <a>ResponseFromMailgun</a>, <a>sendEmail</a>)
--   
--   -- This function will send a new user an email.
--   sendEmailToNewUser
--     :: <a>Text</a> -- ^ user's name
--     -&gt; <a>EmailAddress</a> -- ^ user's email address
--     -&gt; <tt>ReaderT</tt> <a>HailgunContext</a> <a>IO</a> (<a>Either</a> <a>EmailError</a> <a>ResponseFromMailgun</a>)
--   sendEmailToNewUser name emailaddress = do
--     let email = <a>Email</a>
--           { <a>emailSubject</a> = "Thanks for signing up!"
--           , <a>emailBody</a> = <a>TextOnly</a> $ <tt>encodeUtf8</tt> body
--           , <a>emailReplyTo</a> = myEmailAddress
--           , <a>emailRecipientsTo</a> = [emailaddress]
--           , <a>emailRecipientsCC</a> = []
--           , <a>emailRecipientsBCC</a> = []
--           , <a>emailAttachments</a> = []
--           }
--     <a>sendEmail</a> email
--     where
--       body :: <a>Text</a>
--       body = [sbt|Hi #{name}!
--                  |
--                  |Thanks for signing up to our service!
--                  |
--                  |From your friends at foobar.com :-)|]
--   
--   myEmailAddress :: <a>EmailAddress</a>
--   myEmailAddress = undefined
--   </pre>
module Mail.Hailgun.Simple

-- | Send an <a>Email</a>.
--   
--   Returns an <a>EmailErrorIncorrectEmailFormat</a> error if the format
--   of the email was not correct (for instance, if the email senders or
--   receivers were incorrect, or the attachments are specified
--   incorrectly). If you are constructing an <a>Email</a> by hand (and not
--   programatically), this error will indicate a programmer error.
--   
--   Returns an <a>EmailErrorSendError</a> if there was a problem with
--   actually sending the <a>Email</a>. This will usually be an error from
--   the Mailgun servers.
sendEmail :: forall r m. (HasHailgunContext r, MonadIO m, MonadReader r m) => Email -> m (Either EmailError ResponseFromMailgun)

-- | Datatype representing an email to send.
data Email
Email :: Text -> MessageContent -> EmailAddress -> [EmailAddress] -> [EmailAddress] -> [EmailAddress] -> [Attachment] -> Email
[emailSubject] :: Email -> Text
[emailBody] :: Email -> MessageContent
[emailReplyTo] :: Email -> EmailAddress
[emailRecipientsTo] :: Email -> [EmailAddress]
[emailRecipientsCC] :: Email -> [EmailAddress]
[emailRecipientsBCC] :: Email -> [EmailAddress]
[emailAttachments] :: Email -> [Attachment]

-- | Any email content that you wish to send should be encoded into these
--   types before it is sent. Currently, according to the API, you should
--   always send a Text Only part in the email and you can optionally add a
--   nicely formatted HTML version of that email to the sent message.
--   
--   <pre>
--   It is best to send multi-part emails using both text and HTML or text only. Sending HTML only
--   email is not well received by ESPs.
--   </pre>
--   
--   (<a>Source</a>)
--   
--   This API mirrors that advice so that you can always get it right.
data MessageContent :: *

-- | The Text only version of the message content.
TextOnly :: ByteString -> MessageContent

-- | The text content that you wish to send (please note that many clients
--   will take the HTML version first if it is present but that the text
--   version is a great fallback).
[textContent] :: MessageContent -> ByteString

-- | A message that contains both a Text version of the email content and a
--   HTML version of the email content.
TextAndHTML :: ByteString -> ByteString -> MessageContent

-- | The text content that you wish to send (please note that many clients
--   will take the HTML version first if it is present but that the text
--   version is a great fallback).
[textContent] :: MessageContent -> ByteString

-- | The HTML content that you wish to send.
[htmlContent] :: MessageContent -> ByteString

-- | Response returned from Mailgun's servers.
data ResponseFromMailgun
ResponseFromMailgun :: Text -> Text -> ResponseFromMailgun

-- | Freeform message from Mailgun
[mailgunMessage] :: ResponseFromMailgun -> Text

-- | ID of the message accepted by Mailgun
[mailgunId] :: ResponseFromMailgun -> Text

-- | When comunnicating to the Mailgun service you need to have some common
--   pieces of information to authenticate successfully. This context
--   encapsulates that required information.
data HailgunContext :: *
HailgunContext :: String -> String -> Maybe Proxy -> HailgunContext

-- | The domain of the mailgun account that you wish to send the emails
--   through.
[hailgunDomain] :: HailgunContext -> String

-- | The API key for the mailgun account so that you can successfully make
--   requests. Please note that it should include the <tt>key</tt> prefix.
[hailgunApiKey] :: HailgunContext -> String
[hailgunProxy] :: HailgunContext -> Maybe Proxy

-- | This class provides one layer (or multiple layers) of indirection. It
--   makes it possible to pass <a>sendEmail</a> a generic configuration
--   datatype that contains a <a>HailgunContext</a> instead of a
--   <a>HailgunContext</a> directly.
--   
--   For instance, imagine you had a configuration datatype like this:
--   
--   <pre>
--   data Config = Config
--     { configDatabasePool :: Pool
--     , configHailgunContext :: <a>HailgunContext</a>
--     }
--   </pre>
--   
--   You could create an instance of <a>HasHailgunContext</a> for
--   <tt>Config</tt> like this:
--   
--   <pre>
--   instance <a>HasHailgunContext</a> Config where
--     getHailgunContext :: Config -&gt; <a>HailgunContext</a>
--     getHailgunContext = configHailgunContext
--   </pre>
--   
--   Now, you can pass <tt>Config</tt> to <a>sendEmail</a> instead of a
--   <a>HailgunContext</a> directly.
class HasHailgunContext r
getHailgunContext :: HasHailgunContext r => r -> HailgunContext

-- | Datatype to represent possible errors with sending an email.
data EmailError

-- | Email was in incorrect format. Since we are creating emails by hand,
--   this error should never occur.
EmailErrorIncorrectEmailFormat :: Text -> EmailError

-- | Error from Mailgun when trying to send an email.
EmailErrorSendError :: Text -> EmailError

-- | Wrapper around <a>Mail.Hailgun</a>'s <a>hailgunMessage</a>.
emailToHailgunMessage :: Email -> Either EmailError HailgunMessage

-- | Wrapper around <a>Mail.Hailgun</a>'s <a>sendEmail</a>. Used by
--   <a>sendEmail</a>.
sendHailgunMessage :: forall r m. (HasHailgunContext r, MonadIO m, MonadReader r m) => HailgunMessage -> m (Either EmailError ResponseFromMailgun)
instance GHC.Show.Show Mail.Hailgun.Simple.ResponseFromMailgun
instance GHC.Generics.Generic Mail.Hailgun.Simple.ResponseFromMailgun
instance Data.Data.Data Mail.Hailgun.Simple.ResponseFromMailgun
instance GHC.Show.Show Mail.Hailgun.Simple.EmailError
instance GHC.Generics.Generic Mail.Hailgun.Simple.EmailError
instance Mail.Hailgun.Simple.HasHailgunContext Mail.Hailgun.Internal.Data.HailgunContext
