Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Standard Webhooks Support #4

Open
Nezteb opened this issue Dec 21, 2023 · 6 comments
Open

Standard Webhooks Support #4

Nezteb opened this issue Dec 21, 2023 · 6 comments
Labels

Comments

@Nezteb
Copy link

Nezteb commented Dec 21, 2023

tl;dr a few companies worked together to create a specification for webhooks: https://www.standardwebhooks.com/

It'd be cool for this project to somehow conform to the new spec. 😄

@cpursley
Copy link
Owner

cpursley commented Dec 21, 2023

Thanks @Nezteb, open to ideas and PRs on how to conform with their specs.

@Nezteb
Copy link
Author

Nezteb commented Dec 21, 2023

I actually started to make a new repo to build something myself, but then I realized I should make an issue here first, as I'd rather not re-invent the wheel. 😄

I had asked in the Elixir Slack #phoenix channel, but since it has limited history I'll copy-paste the relevant bits:

Nezteb
I want to build a Mix package that integrates with Phoenix, specifically one that helps people build webhooks that follow a new specification called "standard webhooks" https://www.standardwebhooks.com/
At first I figured it could be a Plug that Phoenix users would add to a pipeline, but reading more through the spec itself I'm not sure if this library should be more integrated into Phoenix than that. 🤔
Reading through https://mainmatter.com/blog/2018/02/14/handling-webhooks-in-phoenix/, most of which seems to still apply
I guess a plug and a series of functions that could be used from a controller? 🤔
The catalyst of my question: twitter.com/supabase/status/1735405662958424485
screenshot_2023-12-14_at_23 24 32@2x

Jeremy Brayton
I think the closest example to me is the auth generator. You don't need it for a normal scaffold and you can bolt it on later. I believe it started outside and was then "brought in the fold." I don't have any other examples of framework packages but considering it's a lot of sprinkles and clumps on plug, it probably doesn't need the extension points other frameworks have.
Neither of those seem to mention the approach I've adopted, take in a webhook and store it to respond with a 200/OK immediately. Then use a background process to do the work. The docs mention storing idempotency keys in Redis for 5 minutes so the event could sit in storage until it's processed + a timeout. That may be outside what you're looking to implement but I'd love a comprehensive set of defaults or guidance if I were to adopt it. I have a feeling if I didn't use this I'd be rolling my own and it gets tedious real quick.

@cpursley
Copy link
Owner

Thanks for the additional context! I'd love some help on this if you're up for it.

And I don't mind breaking changes as long as they are versioned correctly.

@cpursley
Copy link
Owner

cpursley commented Dec 21, 2023

I think the first thing to do is document the differences between the current version of webhoox and how they differ from standardwebhooks.

@cpursley
Copy link
Owner

cpursley commented Dec 25, 2023

@Nezteb Have you figured out how to create the proper Standard Webhooks signature using Elixir?

expected_signature =  "v1,6QrvW80BV1T1hZESsZOhKSqc3uaKGE2ceF9RRP2Et28="

id = "msg_p5jXN8AQM9LWM0D4loKWxJek"
timestamp = 1674087231
payload = Jason.encode!(%{"event_type" => "ping", "data" => %{"success" => true}})
signature = "#{id}.#{timestamp}.#{payload}" |> IO.inspect()
"msg_p5jXN8AQM9LWM0D4loKWxJek.1674087231.{\"data\":{\"success\":true},\"event_type\":\"ping\"}"

secret = "MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw"  
encoded_signature = :crypto.mac(:hmac, :sha256, secret, signature) |> Base.encode64() |> String.trim() |> IO.inspect()
"9SzW0S/o+gbH+/OiAFy1dAxAXeWmKiK/gClIRhFhF7Y="

signature_with_version = "v1,#{encoded_signature}" |> IO.inspect()
"v1,9SzW0S/o+gbH+/OiAFy1dAxAXeWmKiK/gClIRhFhF7Y="
 
expected_signature == signature_with_version
false

I've tried this but it does not seem to verify over at: https://www.standardwebhooks.com/verify

Any ideas?

@cpursley
Copy link
Owner

@Nezteb

I've been working on adding Standard Webhooks support for webhoox here (tests here).

I'd be glad to bring the relevant parts over into this repo. And invite you to review before doing so. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants