View Source DocuSign.WebhookPlug (DocuSign v1.2.0)
Helper Plug
to process webhook events and send them to a custom handler.
Based on the excellent Stripe webhook plug: https://github.com/beam-community/stripity-stripe/blob/v3.1.1/lib/stripe/webhook_plug.ex
Installation
To handle webhook events, you must first configure your application's endpoint.
Add the following to endpoint.ex
, before Plug.Parsers
is loaded.
plug DocuSign.WebhookPlug,
at: "/webhook/docusign",
handler: MyAppWeb.DocuSign.WebhookHandler,
hmac_secret_key: fn -> Application.get_env(:myapp, :hmac_secret_key) end
If you have not yet added a webhook to your DocuSign account, you can do so by visiting the 'Settings > Connect'. Use the route you configured in the endpoint above and copy the HMAC secret key into your app's configuration.
Supported options
at
: The URL path your application should listen for DocuSign webhooks on. Configure this to match whatever you set in the webhook.handler
: Custom event handler module that acceptsmap()
payloads and processes them within your application. You must create this module.secret
: Webhook HMAC secret obtained from the DocuSign Connect dashboard. This can also be a function or a tuple for runtime configuration.
Handling events
You will need to create a custom event handler module to handle events.
Your event handler module should implement the DocuSign.Webhook.Handler
behavior, defining a handle_webhook/1
function which takes a map()
payload and returns either {:ok, term}
or :ok
. This will mark the event as
successfully processed. Alternatively handler can signal an error by returning
:error
or {:error, reason}
tuple, where reason is an atom or a string.
HTTP status code 400 will be used for errors.
Refer to https://developers.docusign.com/platform/webhooks/connect/json-sim-event-reference/ for the possible payloads you may receive. Note that these payloads can vary based on your Connect configuration.
Example
# lib/myapp_web/docusign_handler.ex
defmodule MyAppWeb.DocuSignHandler do
@behaviour DocuSign.Webhook.Handler
@impl true
def handle_webhook(%{"event" => "envelope-completed"} = event) do
# TODO: handle the envelope-completed event
end
@impl true
def handle_webhook(%{"event" => "envelope-discard"} = event) do
# TODO: handle the "envelope-discard" event
end
# Return HTTP 200 for unhandled events
@impl true
def handle_webhook(_event), do: :ok
end
Configuration
You can configure the HMAC secret key in your app's own config file. For example:
config :myapp,
# [...]
hmac_secret_key: "AB123_******"
You may then include the secret in your endpoint:
plug DocuSign.WebhookPlug,
at: "/webhook/docusign",
handler: MyAppWeb.DocuSign.WebhookHandler,
hmac_secret_key: Application.get_env(:myapp, :hmac_secret_key)
Runtime configuration
If you're loading config dynamically at runtime (eg with runtime.exs
or an OTP app) you must pass a tuple or function as the secret.
# With a tuple
plug DocuSign.WebhookPlug,
at: "/webhook/docusign",
handler: MyAppWeb.DocuSign.WebhookHandler,
secret: {Application, :get_env, [:myapp, :hmac_secret_key]}
# Or, with a function
plug DocuSign.WebhookPlug,
at: "/webhook/docusign",
handler: MyAppWeb.DocuSign.WebhookHandler,
secret: fn -> Application.get_env(:myapp, :hmac_secret_key) end
HMAC secret key
Only 1 HMAC secret key can be configured. It is assumed that to rotate the HMAC secret key:
- An additional HMAC secret key is added to the DocuSign Connect configuration.
- The HMAC secret key of the plug is updated to this new secret key.
- Finally the previous HMAC secret key is removed from the DocuSign Connect.
HMAC signatures
DocuSign can send up to 100 HMAC signatures, which would happen if you have configured 100 HMAC secret keys in your Connect dashboard. Although this is unlikely, the plug will check all of the signatures provided.