Skip to content

Webhooks

A webhook gives a script its own web address. When another system calls it, the script runs and what it returns goes back to the caller. Use one to receive a payment notice, to answer a form on another site, or to give a short-lived tool a button.

  1. Open Settings > MaSH > Webhooks.
  2. Choose Add webhook.
  3. Pick the Script. Add a Description.
  4. Optionally set a Username and Password. These are HTTP Basic Auth credentials, and the caller must send them.
  5. Choose Save. The URL column of the list now shows the address, with a copy button.

The address looks like https://<your-foldr-address>/hooks/<32-character key>. You can add more path after the key (/hooks/<key>/orders/17), and the script can read it. Both GET and POST work.

The key in the address is the secret. Anyone who has it can call the webhook, so don’t paste it where others can read it.

  • If it leaks, choose Create new URL on the webhook. The old address stops working at once. Forms in Foldr that point at this webhook are moved to the new key for you. Anything outside Foldr that calls the old address needs the new one.
  • A webhook made before keys were random still shows the label Old URL and a warning, because that address can be guessed. Open it and choose Create new URL.
  • With a Username and Password set, a request without the right ones is refused. Without them, the key is the only protection.
  • Foldr’s IP filter and rate limit apply to webhooks as to any other request.

Hide parameters you don’t want in the log. Foldr masks query and form values in its webhook log. Set a script setting named MASH_WEBHOOK_DEBUG to a true value only when you are debugging, because it turns the masking off.

Query-string and form values are fields on mash.event.input. The request itself is mash.event.input.foldr_request. Its headers, body and path are readable:

input = mash.event.input
req = input.foldr_request
printline req.getMethod() # POST
printline input.name # a query or form value
printline req.headers["x-signature"][0] # headers are lists
printline req.path # /hooks/<key>/orders/17
body = mash.json.decode(req.content, true)
printline body["order"]

A few details that catch people out:

  • req.headers and req.query are collections. A header holds a list, so take [0].
  • req.content is the raw body as text. Decode JSON yourself with mash.json.decode.
  • req.files holds uploaded files, keyed by their original file name.
  • Only reading methods work on the request (getMethod(), isSecure(), getClientIp() and so on). Anything that would change it is refused.
  • The request object is documented at Request.
  • There is no mash.request. Some older notes mention it. It doesn’t exist.

If a person is signed in on the call (they sent a valid session or token), mash.event.user is that person. For an anonymous call it is empty.

What the script returns is the response.

The script returnsThe caller gets
nothingwhatever the script printed, as the body
a stringthat string
a dictionary or listJSON
a dictionary with a body keya response you control (below)
a filethe file, as a download

If the script ends with an error, the caller gets status 500 and {"error": "…"}. A webhook that ends in an error is not retried by Foldr. The caller decides.

For full control, return a dictionary with body, and optionally status, type and headers:

return {
"status": 201,
"type": "json",
"headers": {"X-Order": "17"},
"body": {"ok": true, "id": 17}
}

type: "json" sends the body as JSON. Any other type sends it as plain text. Headers that could break the browser’s protections or set cookies are refused, and a blocked one is noted in the webhook log.

Every webhook response is served inside a browser sandbox. A page a webhook returns can run its own scripts and forms, but it can’t read your cookies or storage. That keeps a hook’s page from acting as the person who opens it.

A webhook script runs inside the web request, so it has the interactive time limit: 60 seconds on Foldr Cloud, 300 seconds on an appliance. See Limits. It runs as its owner, see Who a script runs as.

A form can also call a webhook as one of its on-submit actions. See Forms, signing and reviews.