A plug that receives Unicom360 webhooks: it verifies the signature, parses the event and calls your handler.
# In a Phoenix router (or a Plug.Router):
forward "/webhooks/unicom360/whatsapp", Unicom360.Webhook.Plug,
secret: {MyApp.Config, :unicom360_webhook_secret, []},
handler: MyApp.WhatsAppEventsOptions:
:secret(required) - the 43-character string from the portal, or{module, function, args}called on each request. Prefer the tuple, so the secret is not compiled into your router. A value that isnil, empty or only whitespace makesinit/1raiseUnicom360.Error(:configuration_error); a tuple that returns one answers 500 (below).:handler(required) - a module implementingUnicom360.Webhook.Handler.:tolerance- the largest clock skew accepted, in milliseconds. Default300_000.
It answers:
- 200 when the handler returns
:ok; - 401 with the failure's reason as the body, when verification fails;
- 400 when the body cannot be read, or a verified body is not a JSON object with an event;
- 413 when the body is over 1 MiB (only when this plug reads the body itself);
- 500 when the handler returns anything else;
- 500, without reading the body or calling the handler, and with a log line, when an
{m, f, a}secret returnsnil, an empty string or only whitespace: anyone can forge a signature with an empty key, and it is a fault in your configuration, not a failed verification.
The raw body
Signatures cover the exact bytes received. Mount this plug ahead of Plug.Parsers and it
reads the body itself. Behind Plug.Parsers, add Unicom360.Webhook.BodyReader as the
parsers' :body_reader, and this plug uses conn.assigns.raw_body.