Elixir library for Standard Webhooks

Example

Verifying a webhook payload:

StandardWebhooks.verify(webhook_payload, plug_conn, webhook_secret)

Note: Plug contains the request headers.

The payload must be the raw request body, exactly as received, as bytes or a string. Don't pass the parsed and re-encoded JSON, as even minor differences in serialization will make verification fail. Since Plug.Parsers consumes the body, keep a copy of the raw body using a custom :body_reader, for example:

defmodule MyAppWeb.CacheBodyReader do
  def read_body(conn, opts) do
    {:ok, body, conn} = Plug.Conn.read_body(conn, opts)
    conn = Plug.Conn.assign(conn, :raw_body, body)
    {:ok, body, conn}
  end
end

# In your endpoint
plug Plug.Parsers,
  parsers: [:json],
  body_reader: {MyAppWeb.CacheBodyReader, :read_body, []},
  json_decoder: Jason

# Then
StandardWebhooks.verify(conn.assigns.raw_body, conn, webhook_secret)

Signing a webhook (the payload is signed byte for byte, so pass the exact body that will be sent):

StandardWebhooks.sign(webhook_id, webhook_timestamp, webhook_payload, webhook_secret)

Responding to endpoint verification:

case Plug.Conn.get_req_header(conn, "webhook-challenge") do
  [challenge] ->
    response = StandardWebhooks.endpoint_verification_response(challenge, webhook_secret)

    # Not a webhook delivery: respond without processing the body
    conn
    |> Plug.Conn.put_resp_header("webhook-challenge-response", response)
    |> Plug.Conn.send_resp(204, "")
    |> Plug.Conn.halt()

  _ ->
    # Not a challenge: verify and process the webhook as usual
    handle_webhook(conn)
end

Producers can verify the webhook-challenge-response header with StandardWebhooks.verify_endpoint_verification_response(challenge, header, webhook_secret).

Development

Installation

The package can be installed by adding standard_webhooks to your list of dependencies in mix.exs:

def deps do
  [
    # ... your other deps
    {:standard_webhooks, "~> 0.1.0"}
  ]
end

Then run:

mix deps.get

Elixir Console

iex -S mix

Running Tests

Simply run:

mix test

Code Quality

mix quality