docusign-example (empty) → 0.1.0.0
raw patch · 3 files changed
+216/−0 lines, 3 filesdep +basedep +bytestringdep +docusign-base
Dependencies added: base, bytestring, docusign-base, docusign-client, exceptions, filepath, optparse-generic, text, uuid
Files
- LICENSE +30/−0
- app/Main.hs +149/−0
- docusign-example.cabal +37/−0
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright Capital Match (c) 2018++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++ * Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++ * Redistributions in binary form must reproduce the above+ copyright notice, this list of conditions and the following+ disclaimer in the documentation and/or other materials provided+ with the distribution.++ * Neither the name of Jonathan Knowles nor the names of other+ contributors may be used to endorse or promote products derived+ from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ app/Main.hs view
@@ -0,0 +1,149 @@+{-# OPTIONS_GHC -fno-warn-orphans #-}++{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeOperators #-}++{-| A demonstration of basic functionality provided by the DocuSign Client. -}+module Main where++import Control.Monad ( void )+import Control.Monad.IO.Class ( MonadIO, liftIO )+import Data.Text ( Text )+import Data.UUID ( UUID )+import DocuSign.Client ( DocuSignClient (..)+ , docuSignClient+ , runClient )+import DocuSign.Client.Configuration ( Config (..)+ , AccountConfig (..)+ , ServerConfig (..) )+import DocuSign.Client.Types ( Document (..)+ , DocumentId+ , Envelope (..)+ , Recipient (..)+ , Uri )+import GHC.Generics ( Generic )+import Options.Generic ( ParseField+ , ParseFields+ , ParseRecord+ , type (<?>) (..) )+import System.FilePath ( takeFileName )++import qualified Data.ByteString as B+import qualified Data.Text as T+import qualified DocuSign.Base.ContentTypes as DC+import qualified DocuSign.Client.Types as DT+import qualified Options.Generic as O++data CommandLineOptions = CommandLineOptions+ { host :: Text <?> "DocuSign server hostname"+ , port :: Word <?> "DocuSign server port"+ , account :: Word <?> "DocuSign account ID"+ , key :: UUID <?> "DocuSign account key"+ , username :: Text <?> "DocuSign account username (email address)"+ , password :: Text <?> "DocuSign account password"+ , anchor :: Text <?> "Anchor text to determine signature location"+ , input :: FilePath <?> "Path to unsigned document (PDF)"+ , output :: FilePath <?> "Path to write signed document (PDF)"+ } deriving (Generic, Show)++main :: IO ()+main = runExample =<< O.getRecord "docusign-example"++runExample :: CommandLineOptions -> IO ()+runExample options =+ runClient (makeDocuSignConfig options) (example docuSignClient options) >>=+ either+ (\e -> putStrLn "Error:" >> print e)+ (const $ pure ())++-- | A simple example of embedded document signing.+--+-- See the following guide for further details:+--+-- https://developers.docusign.com/esign-rest-api/guides/embedded-signing+--+example :: MonadIO m => DocuSignClient m -> CommandLineOptions -> m ()+example DocuSignClient {..} options@CommandLineOptions {..} = do++ liftIO $ putStrLn "Loading document ..."+ doc <- liftIO $ readInputDocument options++ liftIO $ putStrLn "Sending document to DocuSign ..."+ let aid = DT.mkAccountId $ fromIntegral $ getOption account+ (eid, url) <- postDocumentsForRedirectionBasedSigning+ aid [doc] defaultEnvelope+ (makeRecipient options) (const postSigningUri)++ liftIO $ do+ putStrLn "A new envelope was created with the following ID:"+ print eid+ putStrLn "Your document is now ready for signing at the link below:"+ print url+ putStrLn "After you've signed the document, press [Enter]."+ void getLine++ liftIO $ putStrLn "Fetching signed document ..."+ signedDoc <- fetchDocument aid eid defaultDocumentId++ liftIO $ do+ putStrLn "Saving signed document ..."+ B.writeFile (getOption output) (DC.toBytes signedDoc)+ putStrLn "Finished!"++defaultDocumentId :: DocumentId+defaultDocumentId = DT.mkDocumentId 1++defaultEnvelope :: Envelope+defaultEnvelope = Envelope+ { envelopeSubject = "Please sign this document"+ , envelopeMessage = "Please sign this document" }++makeDocuSignConfig :: CommandLineOptions -> Config+makeDocuSignConfig CommandLineOptions {..} =+ Config AccountConfig {..} ServerConfig {..}+ where+ accountId = DT.mkAccountId $ fromIntegral $ getOption account+ accountKey = getOption key+ accountUsername = getOption username+ accountPassword = getOption password+ serverHost = getOption host+ serverPort = fromIntegral $ getOption port++makeRecipient :: CommandLineOptions -> Recipient+makeRecipient CommandLineOptions {..} = Recipient+ { recipientClientUserId = DT.mkUserId "TestUserId"+ , recipientEmailAddress = DT.mkEmailAddress "test@example.com"+ , recipientName = "Test Recipient"+ , recipientSignatureAnchorText = pure $ getOption anchor }++postSigningUri :: Uri+postSigningUri = DT.mkUri "http://httpbin.org/get"++readInputDocument :: CommandLineOptions -> IO Document+readInputDocument options = do+ let inputPath = getOption $ input options+ content <- B.readFile inputPath+ pure Document+ { documentContent = DC.fromBytes content+ , documentName = T.pack $ takeFileName inputPath+ , documentId = defaultDocumentId }++-- Generic option parsing instances:++instance ParseRecord CommandLineOptions++instance ParseField Word+instance ParseFields Word+instance ParseRecord Word where parseRecord = fmap O.getOnly O.parseRecord++instance ParseField UUID+instance ParseFields UUID+instance ParseRecord UUID where parseRecord = fmap O.getOnly O.parseRecord++getOption :: (field <?> help) -> field+getOption = O.unHelpful+
+ docusign-example.cabal view
@@ -0,0 +1,37 @@+name: docusign-example+version: 0.1.0.0+synopsis: DocuSign examples+description: This package provides a basic demonstration of how to use the Haskell docusign-client package+category: Business+homepage: https://github.com/capital-match/docusign-example#readme+bug-reports: https://github.com/capital-match/docusign-example/issues+author: Jonathan Knowles+maintainer: dev@capital-match.com+copyright: Capital Match+license: BSD3+license-file: LICENSE+build-type: Simple+cabal-version: >= 1.10++source-repository head+ type: git+ location: https://github.com/capital-match/docusign-example++executable docusign-example+ main-is: Main.hs+ other-modules:+ Paths_docusign_example+ hs-source-dirs:+ app+ ghc-options: -Wall -threaded -rtsopts -with-rtsopts=-N+ build-depends:+ base >=4.7 && <1000+ , bytestring+ , docusign-base+ , docusign-client+ , exceptions+ , filepath+ , optparse-generic+ , text+ , uuid+ default-language: Haskell2010