Optional Plug-compatible Dropbox webhook endpoint. The consumer supplies Plug; Magpie keeps it test-only, just as Phoenix integrations have no runtime dependency.
Install before Plug.Parsers or anything that reads request bodies:
plug Magpie.Webhook.Plug,
path: "/webhooks/dropbox",
app_secret: &MyApp.DropboxConfig.app_secret/0,
notify: &MyApp.DropboxJobs.enqueue/1Options: :path (required exact request path), :app_secret (non-empty binary
or zero-arity function), :notify (function receiving the entire account list,
returning :ok after durable enqueue, or {:error, reason}), and
:max_body_bytes (positive integer, default 1 MiB). Callbacks run synchronously:
enqueue only, never scan Dropbox in the callback. With compile-time Plug
initialization use remote captures (&Module.function/arity), since anonymous
functions cannot be escaped into compiled pipeline options. A secret function
must return a non-empty binary; invalid resolved secrets raise ArgumentError.
Unexpected callback returns also raise ArgumentError, without exposing values.
Exceptions propagate so the application can observe configuration/programming
failures; returned enqueue failures send 503 for retry.
Matching GETs echo the challenge with safe headers. POSTs read the untouched
body in chunks, reject missing/duplicate/invalid signatures with 403, malformed
signed JSON with 400, oversized bodies with 413 and read failures with 400.
Successful enqueue returns 200. Empty account lists and signed JSON objects
without list_folder return 200 without calling :notify. Ignored formats set
conn.private[:magpie_webhook_notification] to :ignored for observation.
Other methods return 405. Matching requests
are halted; other paths pass through. The raw body is stored in
conn.private[:magpie_webhook_raw_body] for successful reads, without reencoding.
It is never logged or retained by Magpie after the request.