https://github.com/michalmuskala/plug_webhook
Simple tool for building plugs that handle wehbooks and verify signature.
https://github.com/michalmuskala/plug_webhook
Last synced: about 2 months ago
JSON representation
Simple tool for building plugs that handle wehbooks and verify signature.
- Host: GitHub
- URL: https://github.com/michalmuskala/plug_webhook
- Owner: michalmuskala
- License: other
- Created: 2018-07-29T18:01:16.000Z (almost 7 years ago)
- Default Branch: master
- Last Pushed: 2018-08-30T16:09:18.000Z (over 6 years ago)
- Last Synced: 2025-02-24T20:39:57.823Z (2 months ago)
- Language: Elixir
- Size: 12.7 KB
- Stars: 24
- Watchers: 5
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# PlugWebhook
Simple tool for building plugs that handle wehbooks and verify signature.
As a design decision, this library, similar to Plug itself, does not
store the request body for a long time - the whole body is stored only
for the signature verification and parsing.## Example
This is how a simple webhook router that verifies signature for
GithHub webhooks could look like:```elixir
defmodule MyWebhookHandler do
@behaviour Plug
@behaviour PlugWebhookdef init(opts), do: opts
def verify_signature(conn, body, _opts) do
token = ## get github token, e.g. System.get_env("GITHUB_TOKEN")
signature = "sha1=" <> Base.encode16(:crypto.hmac(:sha, token, body))
[verify_against] = get_req_header(conn, "x-hub-signature")
if Plug.Crypto.secure_compare(signature, verify_against) do
conn
else
conn
|> send_resp(400, "bad signature")
|> halt() # remeber to always halt if signature doesn't match
end
enddef call(conn, _opts) do
[event_type] = get_req_header(conn, "x-github-event")
handle(event_type, conn, conn.body_params)
enddefp handle("issues", conn, %{"action" => "opened"} = payload) do
# handle opened issue
send_resp(conn, 200, "ok")
enddefp handle(_, conn, _) do
# pass through other events
send_resp(conn, 200, "ok")
end
end
```With such definition, we can add this handler into our application using:
```elixir
plug PlugWebhook, handler: MyWebhookHandler, parser_opts: ...
```Where `:parser_opts` would be the options, you'd usually pass to `Plug.Parsers`.
It's important to add the `PlugWebhook` before parsers themselves.
For example, in a Phoenix application, this could look as (in the endpoint module):```elixir
parser_opts = [
parsers: [:urlencoded, :multipart, :json],
pass: ["*/*"],
json_decoder: Phoenix.json_library()
]plug PlugWebhook,
at: "/github_webhook",
parser_opts: parser_opts,
handler: MyWebhookHandlerplug Plug.Parsers, parser_opts
```## Installation
The package can be installed by adding `plug_webhook` to your list of dependencies in `mix.exs`:
```elixir
def deps do
[
{:plug_webhook, "~> 0.1.0"}
]
end
```## License
This library is released under the Apache 2.0 License - see the [LICENSE](LICENSE) file.