Description

Turn a page into a button that sends a webhook payload to an endpoint and displays the response.

Additional Information

Links:
Maintainers: itsthejoker
Version:1.0.2
Minimum app version:3.7
Downloads: This version:5
Last updated:2026-09-21T22:16:52Z

Webhook Button

Webhook Button turns a fenced block in a Joplin note into a button. Clicking the rendered button sends an HTTP POST webhook and shows the result in the note. This makes a note a lightweight, explicit trigger for an automation without leaving Joplin.

Install

Webhook Button requires Joplin Desktop 3.7 or later. From a fresh clone, install the locked dependencies before building the plugin:

npm ci
npm run dist

In Joplin, open Settings/Options → Plugins → Install from file, choose publish/com.joekaufeld.sendwebhook.jpl, then restart Joplin or enable the plugin if Joplin asks you to do so.

Create a button

Add an exact webhook-settings fenced block to a Markdown note. For example:

```webhook-settings
url=https://example.com/hooks/deploy
headers={"Authorization":"Bearer example-token","X-Source":"joplin"}
data={"environment":"production","action":"deploy"}
success_confetti=true
print_response=true
button_text=Deploy production
background_color=#2563eb
```

The rendered note shows a Deploy production button. It sends the JSON body and headers above with a POST request.

Each non-comment setting occupies one line and has the form key=value. The line is split at the first = only, so values may contain additional equals signs. Blank lines and lines beginning with # are ignored. Unknown, duplicate, or malformed settings leave the control disabled and display an inline error in the rendered note.

Plain text body

Use a value that is not valid JSON for a literal text payload:

```webhook-settings
url=https://example.com/hooks/notify
data=Deployment completed for production
button_text=Notify team
```

Use another note as the body

Prefix a Joplin note ID with @ to send that note's Markdown body:

```webhook-settings
url=https://example.com/hooks/archive
data=@0123456789abcdef0123456789abcdef
headers={"X-Document-Type":"text/markdown"}
button_text=Archive this document
```

Replace the illustrative 32-character ID with the ID of the source note.

Settings reference

Key Required / default Behavior
url Required Absolute http or https endpoint to receive the POST.
data Optional; no request body Valid JSON is serialized as JSON. Other text is sent literally. @noteID reads that note's Markdown body.
headers Optional; {} A JSON object whose keys and values are strings, for example {"Authorization":"Bearer token"}. Header names must be valid HTTP names and values cannot contain NUL, CR, or LF. Do not use a preformatted header string or a list.
success_confetti Optional; false Must be exactly true or false. true shows confetti after a successful response.
print_response Optional; false Must be exactly true or false. true displays the full textual response below the status.
button_text Optional; Send Webhook Label shown on the button; it cannot be empty.
background_color Optional Generated control area background. See supported color syntax.

Supported color syntax

background_color accepts only these forms:

  • A named CSS keyword, or #RGB, #RGBA, #RRGGBB, or #RRGGBBAA.
  • rgb(red, green, blue), where each component is a signed or unsigned decimal number or percentage; commas are required.
  • rgba(red, green, blue, alpha), with the same red, green, and blue components plus a numeric or percentage alpha; commas are required.
  • hsl(hue, saturation%, lightness%), where hue is numeric and saturation and lightness require %; commas are required.
  • hsla(hue, saturation%, lightness%, alpha), with the same hue, saturation, and lightness components plus a numeric or percentage alpha; commas are required.

CSS space-separated or slash-separated color forms are not supported.

The request body is always sent as raw text—there is no form encoding. When data is JSON, the plugin infers Content-Type: application/json; for literal text or a referenced note, it infers Content-Type: text/plain;charset=UTF-8. It adds an inferred content type only when headers does not already contain a Content-Type header (case-insensitive). With no data, it sends no body and does not infer a content type.

Result and safety

While a request is running, the button is disabled and shows Sending…. Afterward it is enabled again and the note receives a compact status: success for a successful HTTP response, or the response status for a non-successful one. print_response=true adds the full response as text, not rendered HTML. success_confetti=true adds a small success celebration only for successful responses and respects the system reduced-motion preference.

Webhook Button can send to arbitrary endpoints, including local-network addresses. Review notes received from other people before clicking a button: their configured headers and payload are sent to the endpoint. Response bodies are rendered as text and are not persisted by the plugin; requests have no automatic retry or persistence. Transport and other request failures use a safe generic error message rather than exposing underlying details. HTTPS is preferable when headers or payloads contain credentials. Do not put production secrets in notes that are shared or synced outside the intended trust boundary.

Development

For a fresh clone, run npm ci before the commands below:

npm ci
npm test
npm run dist

The distributable archive is written to publish/com.joekaufeld.sendwebhook.jpl.