diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/404.html b/404.html new file mode 100644 index 0000000..882005e --- /dev/null +++ b/404.html @@ -0,0 +1,941 @@ + + + + + + + + + + + + + + + + + + Webhook.site Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ +

404 - Not found

+ +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/CNAME b/CNAME new file mode 100644 index 0000000..9d35a6e --- /dev/null +++ b/CNAME @@ -0,0 +1 @@ +docs.webhook.site diff --git a/api.html b/api.html new file mode 100644 index 0000000..62388a8 --- /dev/null +++ b/api.html @@ -0,0 +1,15 @@ + + + + + + Redirecting... + + + + + + +Redirecting... + + diff --git a/api/about.html b/api/about.html new file mode 100644 index 0000000..864f267 --- /dev/null +++ b/api/about.html @@ -0,0 +1,1199 @@ + + + + + + + + + + + + + + + + + + + + + + + + Usage & Authentication - Webhook.site Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + + + + + + +

Webhook.site API

+

The Webhook.site API is public, free to use, doesn't require authentication and is relatively easy to use.

+

General Usage

+

Base URL: https://webhook.site.

+

You must set the Accept and Content-Type headers to application/json.

+

Things to Note

+
    +
  • In all examples in this API documentation, URL parameters are prefixed with : (colon) to show which parameters must be changed by the user. You must not include this character in the URL.
  • +
  • A Token ID refers to the ID of the Webhook.site URL/e-mail address, i.e., when your Webhook.site URL is https://webhook.site/00000000-0000-0000-0000-000000000000, the Token ID is then 00000000-0000-0000-0000-000000000000.
  • +
  • In API URLs, you cannot use Token Aliases in place of the Token ID.
  • +
  • Webhook.site API Keys must be specified using the Api-Key HTTP header.
  • +
  • Fair use guidelines, rate limits, and other limitations apply as described by the Terms of Service.
  • +
+

Authentication

+

While many endpoints of the Webhook.site API are public and work without any authentication, some endpoints do require authentication, or will return a 401 Unauthorized status code.

+

API Key

+

An API Key can be generated in the Control Panel, and provides access to Tokens that are either a) password protected or b) require login.

+

API Keys must be specified in the Api-Key HTTP header.

+ + +

Password

+

If you have set a password on a Webhook.site URL/token, to access the API resources for that token, you can use either of the following methods:

+
    +
  1. Specify the password using the password query string: ?password=[your password]
  2. +
  3. Set the password using HTTP Basic Auth, using the Authorization header. More info
  4. +
+

Common Usages

+

Get data sent to URL

+

To retrieve the data that's sent to a Webhook.site URL or Email, you'll want to use the Get Requests endpoint.

+

Create new URL/email address

+

To create a new token programmatically, you can use the API like this:

+
$ curl -X POST https://webhook.site/token
+
+

This will return information about the token in JSON format, including its UUID. Your URL will be available at the endpoint https://webhook.site/[token uuid].

+

If you are a Webhook.site Pro or Enterprise customer, you should provide an API key in order to associate the created token with your account automatically:

+
$ curl -X POST -H 'Api-Key: 00000000-0000-0000-0000-000000000000' https://webhook.site/token
+
+

More info here.

+ +
+
+ + + Last update: + April 6, 2024 10:34:57 + + + +
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/api/action-types.html b/api/action-types.html new file mode 100644 index 0000000..283598b --- /dev/null +++ b/api/action-types.html @@ -0,0 +1,1741 @@ + + + + + + + + + + + + + + + + + + + + Action types - Webhook.site Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + + + + + + +

Action types

+ +

The following is a list of the API names for Action Types, along with a list of parameters, and their validation requirements.

+

auto_json

+
    +
  • source: string
  • +
  • jsonpath: string
  • +
  • variable_name: required, string
  • +
+

aws_cf_invalidate

+
    +
  • provider_id: required, int
  • +
  • distribution_id: required, string
  • +
  • paths: required, string
  • +
+

aws_s3_create_bucket

+
    +
  • provider_id: string, required
  • +
  • region: string, required
  • +
  • bucket_name: string, required
  • +
  • canned_acl: string, in:private,public-read,public-read-write,authenticated-read
  • +
+

aws_s3_delete_object

+
    +
  • provider_id: string, required
  • +
  • region: string
  • +
  • bucket_name: string, required
  • +
  • object_key: string, required
  • +
+

aws_s3_get_object

+
    +
  • provider_id: string, required
  • +
  • region: string
  • +
  • bucket_name: string, required
  • +
  • object_key: string, required
  • +
  • variable_name: string, required, min:1
  • +
+

aws_s3_put_object

+
    +
  • provider_id: string, required
  • +
  • region: string, required
  • +
  • bucket_name: string
  • +
  • object_key: string, required
  • +
  • body: string, required
  • +
  • canned_acl: string, in:private,public-read,public-read-write,authenticated-read
  • +
+

condition

+
    +
  • input: string
  • +
  • operator: required, string, in:eq,neq,sw,ew,ct,nct,gt,gte,lt,lte
  • +
  • value: string
  • +
  • action: required, string, in:stop,continue,noop
  • +
+

conditions

+
    +
  • conditions: required, array
  • +
  • mode: required, string, in:one,all,none
  • +
  • action: required, string, in:stop,continue,noop
  • +
+

database

+
    +
  • type: required, in:mysql,pgsql
  • +
  • host: required, string
  • +
  • port: number, min:1, max:65535
  • +
  • database: required, string
  • +
  • password: string
  • +
  • username: required, string
  • +
  • statement: required, string
  • +
  • params: array
  • +
  • variable_name: string
  • +
  • charset: string
  • +
+

discord_send_message

+
    +
  • provider_id: required, string
  • +
  • content: required, string
  • +
  • username: string
  • +
  • avatar_url: url
  • +
  • embed_type: string, in:link,image,video
  • +
  • embed_url: url
  • +
+

dont_save

+

No parameters for dont_save.

+

dropbox_create_folder

+
    +
  • provider_id: string, required
  • +
  • path: string, required
  • +
+

dropbox_delete

+
    +
  • provider_id: string, required
  • +
  • path: string, required
  • +
+

dropbox_download_file

+
    +
  • provider_id: string, required
  • +
  • path: string, required
  • +
  • variable_name: string, required
  • +
+ +
    +
  • provider_id: string, required
  • +
  • path: string, required
  • +
  • variable_name: string, required
  • +
+

dropbox_upload_file

+
    +
  • provider_id: string, required
  • +
  • path: string, required
  • +
  • body: string, required
  • +
  • mode: string, required, in:add,overwrite,update
  • +
+

extract_jsonpath

+
    +
  • jsonpath: required, string
  • +
  • variable_name: required, string
  • +
  • source: string
  • +
  • default: string
  • +
  • repeat: boolean
  • +
+

extract_regex

+
    +
  • regex: required, string
  • +
  • variable_name: required, string
  • +
  • source: string
  • +
  • default: string
  • +
  • repeat: boolean
  • +
+

extract_xpath

+
    +
  • xpath: required, string
  • +
  • variable_name: required, string
  • +
  • source: string
  • +
  • default: string
  • +
+

ftp_upload

+
    +
  • host: required, string
  • +
  • port: number, min:1, max:65535
  • +
  • password: required, string
  • +
  • username: required, string
  • +
  • path: required, string
  • +
  • content: required, string
  • +
  • ssl: bool
  • +
  • passive: bool
  • +
+

google_sheets_add_row

+
    +
  • provider_id: string, required
  • +
  • spreadsheet_id: string, required
  • +
  • range: string, required
  • +
  • values: string, required
  • +
  • formula_mode: bool
  • +
+

google_sheets_get_values

+
    +
  • provider_id: string, required
  • +
  • spreadsheet_id: string, required
  • +
  • range: string, required
  • +
  • variable_name: required, string
  • +
+

google_sheets_update_row

+
    +
  • provider_id: string, required
  • +
  • spreadsheet_id: string, required
  • +
  • range: string, required
  • +
  • values: string, required
  • +
  • formula_mode: bool
  • +
+

http

+
    +
  • url: required, string
  • +
  • content: nullable, string
  • +
  • method: nullable, in:POST,GET,OPTIONS,PUT,DELETE,PATCH,TRACE
  • +
  • mode: nullable, in:text,json,multipart,urlencoded,forward
  • +
  • auth: nullable, object
  • +
  • auth.mode: string, in:basic,digest,ntlm
  • +
  • auth.username: string
  • +
  • auth.password: string
  • +
  • multipart: array, required_if:mode,multipart
  • +
  • multipart.*.name: string
  • +
  • multipart.*.filename: string
  • +
  • multipart.*.content-type: string
  • +
  • multipart.*.content: string
  • +
  • urlencoded: array
  • +
  • urlencoded.*.name: string, required_if:mode,urlencoded
  • +
  • urlencoded.*.value: string, required_if:mode,urlencoded
  • +
  • headers: nullable, string
  • +
  • skip_ssl_verification: nullable, bool
  • +
  • variable_name: string
  • +
  • timeout: nullable, numeric, max:15
  • +
+

image_resize

+
    +
  • source: string, required
  • +
  • width: string, required_without:height
  • +
  • height: string, required_without:width
  • +
  • aspect_ratio: bool, required
  • +
  • variable_name: string, required
  • +
+

javascript

+
    +
  • script: required, string
  • +
+

log

+
    +
  • text: required, string
  • +
+

microsoft_drive_download

+
    +
  • provider_id: required, string
  • +
  • path: required, string
  • +
  • variable_name: string
  • +
+

microsoft_drive_upload

+
    +
  • provider_id: required, string
  • +
  • path: required, string
  • +
  • content_type: string
  • +
  • content: string
  • +
  • variable_name: string
  • +
+

microsoft_excel_add_rows

+
    +
  • provider_id: required, string
  • +
  • path: string
  • +
  • table: string
  • +
  • index: int
  • +
  • values: required, array
  • +
+

microsoft_excel_get_values

+
    +
  • provider_id: required, string
  • +
  • path: required, string
  • +
  • worksheet: required, string
  • +
  • range: required, string
  • +
  • variable_name: required, string
  • +
+

modify_response

+
    +
  • content: string
  • +
  • status: string
  • +
  • headers: string
  • +
  • stop: bool
  • +
+

ntfy

+
    +
  • topic: string, required
  • +
  • title: string
  • +
  • message: string, required
  • +
+

pushed_send

+
    +
  • app_key: string, required
  • +
  • app_secret: string, required
  • +
  • target_type: string, required
  • +
  • target: string, required
  • +
  • message: string, required
  • +
+

rabbitmq_get

+
    +
  • host: string, required
  • +
  • port: int
  • +
  • username: string, required
  • +
  • password: string, required
  • +
  • vhost: string
  • +
  • queue: string, required
  • +
  • ssl: boolean
  • +
  • variable_name: string
  • +
+

rabbitmq_publish

+
    +
  • host: string, required
  • +
  • port: int
  • +
  • username: string, required
  • +
  • password: string, required
  • +
  • vhost: string
  • +
  • queue: string, required
  • +
  • ssl: boolean
  • +
  • message: string, required
  • +
+

rate_limit

+
    +
  • period: required, int
  • +
  • count: required, int
  • +
  • key: string
  • +
+

script

+
    +
  • script: required, string
  • +
+

send_email

+
    +
  • sender: string
  • +
  • recipient: required, string
  • +
  • content: string
  • +
  • is_html: boolean
  • +
  • subject: required, string
  • +
  • attachments: array
  • +
+

send_email_smtp

+
    +
  • sender_name: string
  • +
  • sender_email: string
  • +
  • recipient: required, string
  • +
  • content: string
  • +
  • is_html: boolean
  • +
  • subject: required, string
  • +
  • encryption: string, in:none,ssl,tls
  • +
  • port: int
  • +
  • username: string, required
  • +
  • password: string, required
  • +
  • host: string_required
  • +
  • attachments: array
  • +
+

send_request

+
    +
  • url: required, string
  • +
  • content: nullable, string
  • +
  • method: nullable, in:POST,GET,OPTIONS,PUT,DELETE
  • +
  • headers: nullable, string
  • +
  • skip_ssl_verification: nullable, bool
  • +
  • variable_name: string
  • +
  • timeout: nullable, numeric, max:30
  • +
+

set_variable

+
    +
  • name: required, string
  • +
  • value: nullable, string
  • +
+

sftp_upload

+
    +
  • provider_id: string
  • +
  • host: required, string
  • +
  • port: number, min:1, max:65535
  • +
  • username: required, string
  • +
  • password: string
  • +
  • path: required, string
  • +
  • content: required, string
  • +
+

slack_send_message

+
    +
  • webhook_url: required, url
  • +
  • raw: bool
  • +
  • content: required, string
  • +
+

ssh_run_command

+
    +
  • provider_id: string
  • +
  • host: required, string
  • +
  • port: number, min:1, max:65535
  • +
  • username: required, string
  • +
  • password: string
  • +
  • command: required, string
  • +
  • variable_name: string
  • +
+

stop

+

No parameters for stop.

+

store_global_variable

+
    +
  • name: required, string
  • +
  • value: nullable, string
  • +
+

template

+
    +
  • template_id: required, int
  • +
  • variables: array
  • +
+

text_map

+
    +
  • source: required, string
  • +
  • operator: required, string
  • +
  • variable_name: required, string
  • +
  • default: required, string
  • +
  • mappings: required, array
  • +
+

text_replace

+
    +
  • source: required, string
  • +
  • variable_name: required, string
  • +
  • replacements: required, array
  • +
+

text_split

+
    +
  • delimiter: required, string
  • +
  • source: required, string
  • +
  • variable_name: required, string
  • +
  • repeat: boolean
  • +
+

twitter_tweet

+
    +
  • provider_id: required, string
  • +
  • tweet: required, string
  • +
+ +
+
+ + + Last update: + April 6, 2024 10:34:57 + + + +
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/api/custom-actions.html b/api/custom-actions.html new file mode 100644 index 0000000..2fb82de --- /dev/null +++ b/api/custom-actions.html @@ -0,0 +1,1589 @@ + + + + + + + + + + + + + + + + + + + + + + + + Custom Actions - Webhook.site Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + + + + + + +

API Endpoints: Custom Actions

+

The Custom Actions API allows you to manage the Custom Actions associated with a given Token. More info about Custom Actions.

+

List of the API names and parameters for Action Types.

+

Actions

+

Create Custom Action

+
    +
  • Can require authentication.
  • +
+

POST /token/:token_id/actions

+
    +
  • type (string) is the name of an Action Type.
  • +
  • order (int) specified which order the action is executed in.
  • +
  • parameters (object) can vary depending on the Action Type.
  • +
  • disabled (bool) if set to true, the action is skipped upon execution.
  • +
  • queue (bool) If set to true, the action is run asynchronously. More info here
  • +
  • delay (int, max 86400) If set (along with queue to true), Webhook.site waits the specified amount of seconds to run the action.
  • +
  • condition (uuid) If set to an ID of a Conditions action, the action will only run if the condition passes, and is otherwise skipped.
  • +
+

Request

+
Example 1: Condition action
+
{
+  "type": "condition",
+  "order": 3,
+  "disabled": false,
+  "parameters": {
+    "input": "$request.content$",
+    "operator": "eq",
+    "value": "",
+    "action": "stop"
+  }
+}
+
+
Example 2: WebhookScript action
+
{
+    "type": "script",
+    "order": 1,
+    "parameters": {
+        "script": "expiry = '2021-08-01T00:00:00.000000Z'\nnow = to_date('now')\n\nif (date_interval(now, expiry) < 0) {\n    // Respond with 410 Gone\n    respond('This content is no longer available.', 410)\n}\n"
+    }
+}
+
+
Example 3: Creating WebhookScript action with Python 3
+

Same script as Example 2. Requires the requests module, which can be installed using pip install requests.

+
import requests
+
+script = """
+expiry = '2021-08-01T00:00:00.000000Z'
+now = to_date('now')
+
+if (date_interval(now, expiry) < 0) {
+    // Respond with 410 Gone
+    respond('This content is no longer available.', 410)
+}
+"""
+
+data = {
+    "type": "script",
+    "order": 1,
+    "parameters": {
+        "script": script
+    }
+}
+
+r = requests.post('https://webhook.site/token/7d63959e-4fec-49bd-90dc-a4615722825e/actions', json=data)
+
+

Response

+
{
+    "uuid": "7ae324d6-c65b-416b-8f83-18fb89e0c740",
+    "token_id": "fe18d303-631d-4620-acb3-5c0b1b0b876d",
+    "type": "condition",
+    "order": 3,
+    "disabled": null,
+    "parameters": {
+        "input": "$request.content$",
+        "operator": "eq",
+        "value": "",
+        "action": "stop"
+    }
+}
+
+

Get Custom Actions

+
    +
  • Can require authentication.
  • +
+

GET /token/:token_id/actions

+

Response

+

200 OK

+
{
+  "data": [
+    {
+      "uuid": "52055928-099a-44dc-ba31-e8d808b98ea1",
+      "token_id": "fe18d303-631d-4620-acb3-5c0b1b0b876d",
+      "type": "condition",
+      "order": 1,
+      "disabled": false,
+      "parameters": {
+        "input": "$request.header.content-type$",
+        "operator": "nct",
+        "value": "application/json",
+        "action": "stop"
+      }
+    },
+    {
+      "uuid": "27b07ca7-ea83-48f5-b376-2372cf25d3a1",
+      "token_id": "fe18d303-631d-4620-acb3-5c0b1b0b876d",
+      "type": "condition",
+      "order": 2,
+      "disabled": null,
+      "parameters": {
+        "input": "$request.content$",
+        "operator": "eq",
+        "value": "",
+        "action": "stop"
+      }
+    }
+  ]
+}
+
+

Update Custom Action

+
    +
  • Can require authentication.
  • +
+

PUT /token/:token_id/actions/:action_id

+

Request

+

See Create Custom Action endpoint.

+

Response

+

See Create Custom Action endpoint.

+

Test Custom Action

+
    +
  • Can require authentication.
  • +
+

Request

+

POST /token/:token_id/test-action

+
Query string parameters
+
    +
  • request_id: A request ID to base the test run on. If not set, uses default request variables.
  • +
  • action_id: When set, overwrites the parameters of an existing action. If not, tests a temporary new, empty action with ID 00000000-0000-4000-0000-000000000000.
  • +
+
{
+  "type": "script",
+  "order": 2,
+  "parameters": {
+    "script": "echo('hello world')"
+  }
+}
+
+

Response

+

200 OK

+
{
+  "success": true,
+  "result": {
+    "output": {
+      "08529a4f-ad84-450b-977a-1d126d6ca6b7": [
+        "Set runtime variable $aaa$ to \"example\""
+      ],
+      "00000000-0000-4000-0000-000000000000": [
+        "hello world"
+      ]
+    },
+    "response": {
+      "content": null,
+      "status": null,
+      "headers": null
+    },
+    "variables": {
+      "request.header.content-length": "57362",
+      "request.header.user-agent": "Paw/3.3.5 (Macintosh; OS X/11.6.2) GCDHTTPRequest",
+      "request.header.connection": "close",
+      "request.header.host": "webhook.site",
+      "request.header.content-type": "application/json",
+      "request.uuid": "87240a26-1426-45dd-9b4c-961a323652a9",
+      "request.token_id": "7fc77812-9efe-41b6-9365-e2c1fb5feb62",
+      "request.content": "",
+      "request.date": "2022-03-20 10:18:58",
+      "request.timestamp": 1647771538,
+      "request.hostname": "webhook.site",
+      "request.size": 0,
+      "request.type": "web",
+      "request.ip": "86.52.35.76",
+      "request.user_agent": "Paw/3.3.5 (Macintosh; OS X/11.6.2) GCDHTTPRequest",
+      "request.url": "https://webhook.site/7fc77812-9efe-41b6-9365-e2c1fb5feb62",
+      "request.method": "POST",
+      "aaa": "example"
+    }
+  }
+}
+
+

Delete Custom Action

+
    +
  • Can require authentication.
  • +
+

DELETE /token/:token_id/actions/:action_id

+

Toggle Custom Actions

+
    +
  • Can require authentication.
  • +
+

PUT /token/:token_id/actions/toggle

+

This endpoint toggles whether actions are enabled on a specific token.

+

Response

+

200 OK

+
{
+    "enabled": true
+}
+
+ +
+
+ + + Last update: + April 6, 2024 10:34:57 + + + +
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/api/date-expressions.html b/api/date-expressions.html new file mode 100644 index 0000000..71be2d4 --- /dev/null +++ b/api/date-expressions.html @@ -0,0 +1,1056 @@ + + + + + + + + + + + + + + + + + + + + API Endpoints: Query string date expressions - Webhook.site Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + + + + + + +

API Endpoints: Query string date expressions

+

Date expressions can be used in the query parameter when retreiving and filtering Requests from the API.

+

The expression starts with an anchor date, which can either be now (or *), or a date string ending with || (two pipe characters).

+

This anchor date can optionally be followed by one or more maths expressions:

+
    +
  • +1h – Add one hour
  • +
  • -1d – Subtract one day
  • +
  • /d – Round down to the nearest day
  • +
+

The supported time units differ from those supported by time units for durations. The supported units are:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SymbolMeaning
yYears
MMonths
wWeeks
dDays
hHours
HHours
mMinutes
sSeconds
+

Assuming now is 2001-01-01 12:00:00, some examples are:

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ExampleResolves to
now+1hnow in milliseconds plus one hour. Resolves to: 2001-01-01 13:00:00
now-1hnow in milliseconds minus one hour. Resolves to: 2001-01-01 11:00:00
now-1h/dnow in milliseconds minus one hour, rounded down to UTC 00:00. Resolves to: 2001-01-01 00:00:00
2001.02.01||+1M/d2001-02-01 in milliseconds plus one month. Resolves to: 2001-03-01 00:00:00
+ +
+
+ + + Last update: + April 6, 2024 10:34:57 + + + +
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/api/examples.html b/api/examples.html new file mode 100644 index 0000000..976b4bd --- /dev/null +++ b/api/examples.html @@ -0,0 +1,1440 @@ + + + + + + + + + + + + + + + + + + + + + + + + Examples - Webhook.site Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + + + + + + +

API Examples

+

If you have a Webhook.site account, before using the API, please first create an API key here. The examples below can also be used without an account, but in that case you should remove the API key header.

+

Don't have an account yet? Sign up here.

+

cURL

+

Send JSON data to URL

+
curl -X POST 'https://webhook.site/00000000-0000-0000-0000-000000000000' \
+  -H 'content-type: application/json' \
+  -d $'{"id": 7, "name": "Jack Daniels", "position": "Assistant"}'
+
+

Get data of last request sent to URL

+
curl 'https://webhook.site/token/00000000-0000-0000-0000-000000000000/request/latest/raw' \
+  -H 'accept: application/json' \
+  -H 'api-key: 00000000-0000-0000-0000-000000000000'
+
+

Output:

+
{"id": 7, "name": "Jack Daniels", "position": "Assistant"}
+
+

Send file to URL

+

Uploads the file example.png from the current directory.

+
curl -F 'file=@example.png' https://webhook.site/00000000-0000-0000-0000-000000000000
+
+

To download the file, click the Download link in the Webhook.site interface, or via the API, use the download endpoint.

+

Python

+

Fetch latest data

+

Requires the requests module, which can be installed using pip install requests.

+

Prints the 50 latest requests sent to a given URL to console.

+
import requests
+
+token_id = "00000000-0000-0000-0000-000000000000"
+headers = {"api-key": "00000000-0000-0000-0000-000000000000"}
+
+r = requests.get('https://webhook.site/token/'+ token_id +'/requests?sorting=newest', headers=headers)
+
+for request in r.json()['data']:
+    print(request)
+
+

Create URL/Email address

+

Requires the requests module, which can be installed using pip install requests.

+

You'll also need to replace the API key.

+
import requests
+
+json = {
+  "default_status": 200,
+  "default_content": "Hello world!",
+  "default_content_type": "text/html",
+}
+
+headers = {
+    "api-key": "00000000-0000-0000-0000-000000000000"
+}
+
+r = requests.post('https://webhook.site/token', json=json, headers=headers)
+
+print('URL Created: https://webhook.site/' + r.json()['uuid'])
+
+

PHP

+

Create Token (URL/Email address)

+

Creates a Webhook.site Token and outputs its Web URL. You'll need to replace the API key.

+
<?php
+$apiKey = '00000000-0000-0000-0000-000000000000';
+
+// Create a stream context
+$context = stream_context_create(['http' => [
+    'method' => 'POST',
+    'header' => "Api-Key: $apiKey\r\n"
+]]);
+
+// Send API request
+$response = json_decode(file_get_contents('https://webhook.site/token', false, $context), true);
+
+echo "URL Created: https://webhook.site/{$response['uuid']}";
+
+

Fetch latest data

+

Simple example of how to loop through the latest requests or emails sent to a Webhook.site URL or email and display in a friendly manner.

+

You'll need to replace the API key (if you have a Webhook.site account, otherwise leave it out) and token ID.

+
<?php
+$apiKey = '00000000-0000-0000-0000-000000000000';
+$tokenId = '00000000-0000-0000-0000-000000000000';
+
+$url = "https://webhook.site/token/$tokenId/requests?sorting=newest";
+
+$context = stream_context_create(['http' => ['header' => "Api-Key: $apiKey\r\n"]]);
+
+$response = json_decode(file_get_contents($url, false, $context), true);
+
+foreach ($response['data'] as $req) {
+    echo "\n";
+    echo json_encode([
+        'method' => $req['method'],
+        'body' => $req['content'],
+        'date' => $req['created_at'],
+    ], \JSON_PRETTY_PRINT);
+}
+
+

Example output when running the script after running e.g. curl -X POST https://webhook.site/00000000-0000-0000-0000-000000000000 -d "Hello world":

+
{
+    "method": "POST",
+    "body": "Hello world",
+    "date": "2023-06-08 13:04:33"
+}
+{
+    "method": "POST",
+    "body": "just testing",
+    "date": "2023-06-08 13:03:57"
+}
+
+

Download all request data as files

+

Per default, this script saves the body content of all requests or emails sent to a URL as .json files in the /requests directory relative to the script file location.

+
<?php
+$directory = __DIR__ . '/requests';
+//$apiKey = '00000000-0000-0000-0000-000000000000';
+$tokenId = '00000000-0000-0000-0000-000000000000';
+
+if (!is_dir($directory) || !is_writable($directory)) {
+    throw new Exception(sprintf('%s not writable, directory missing or rights issue.', $directory));
+}
+
+$context = stream_context_create(['http' =>
+    isset($apiKey) ? ['header' => "Api-Key: $apiKey\r\n"] : [],
+]);
+
+$page = 1;
+
+do {
+    $url = sprintf('https://webhook.site/token/%s/requests?sorting=newest&page=%d', $tokenId, $page);
+    $response = json_decode(file_get_contents($url, false, $context), true);
+
+    foreach ($response['data'] as $req) {
+        file_put_contents(
+            sprintf('/%s/%s.json', $directory, $req['uuid']),
+            $req['content']
+        );
+        echo(sprintf(
+            "[Page %3d] Downloaded request %s sent at %s (%d bytes)\n",
+            $page, $req['uuid'], $req['created_at'], $req['size']
+        ));
+    }
+
+    $page++;
+    sleep(1);
+} while (!$response['is_last_page'] && isset($response['data']));
+
+

Node.js

+

Fetch latest data

+

This script outputs the data sent to a Webhook.site URL in the last 2 hours.

+

To do this, the script uses the query parameter (more info here) in conjunction with a created_at filter.

+

Before running the script, you should install dependencies by running npm install axios moment.

+
import axios from 'axios';
+import moment from 'moment';
+
+// Change these!
+const apiKey = '00000000-0000-0000-0000-000000000000';
+const tokenId = '00000000-0000-0000-0000-000000000000';
+
+async function getData(apiKey, tokenId) {
+  let date = moment.utc().subtract(2, 'hours').format('YYYY-MM-DD hh:mm:ss');  
+  let dateQuery = `created_at:["${date}" TO "*"]`
+
+  try {
+    const response = await axios.get(`https://webhook.site/token/${tokenId}/requests`, {
+      params: {
+        query: dateQuery,
+      },
+      headers: {
+        'Api-Key': apiKey,
+        'Accept': 'application/json',
+      }
+    });
+
+    return response.data;
+  } catch (error) {
+    console.error(error);
+  }
+}
+
+const requests = await getData(apiKey, tokenId);
+
+console.log(`${requests.total} requests found:`);
+
+for (const request of requests.data) {
+  console.log({
+    method: request.method, 
+    body: request.content,
+    date: request.created_at,
+  });
+}
+
+ +
+
+ + + Last update: + April 6, 2024 10:34:57 + + + +
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/api/global-variables.html b/api/global-variables.html new file mode 100644 index 0000000..3e603e5 --- /dev/null +++ b/api/global-variables.html @@ -0,0 +1,1366 @@ + + + + + + + + + + + + + + + + + + + + + + + + Global Variables - Webhook.site Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + + + + + + +

API Endpoints: Global Variables

+

With Global Variables, you can store data permanently that can be shared between your URLs. Global Variables can be used when creating Custom Actions and in Schedules. More about Global Variables

+

Create Global Variable

+
    +
  • Requires authentication.
  • +
+

After creating, the variable $name$ will be available in Custom Actions.

+

Request

+

POST /global-variables

+
    +
  • name (string) The name of the variable.
  • +
  • value (string) The value of the variable.
  • +
+
{
+  "name": "content_type",
+  "value": "application/json"
+}
+
+

Response

+
{
+  "id": 598297,
+  "name": "content_type",
+  "team_id": 1,
+  "value": "application\/json",
+  "updated_at": "2024-04-15T11:20:02.000000Z",
+  "created_at": "2024-04-15T11:20:02.000000Z"
+}
+
+

Get all Global Variables

+
    +
  • Requires authentication.
  • +
+

Request

+

GET /global-variables

+

Query string parameters

+
    +
  • per_page (int) - amount of requests returned, defaults to 50 (max 100)
  • +
  • page (int) - page number to retrieve (default 1)
  • +
  • search (string) - filter variables by name
  • +
+

Response

+
{
+  "current_page": 1,
+  "data": [
+    {
+      "id": 598297,
+      "user_id": 0,
+      "team_id": 1,
+      "name": "content_type",
+      "value": "application\/json",
+      "created_at": "2024-04-15T11:20:02.000000Z",
+      "updated_at": "2024-04-15T11:20:02.000000Z"
+    },
+    {
+      "id": 598294,
+      "user_id": 0,
+      "team_id": 1,
+      "name": "test",
+      "value": "\ud83e\udd72",
+      "created_at": "2024-04-14T13:21:24.000000Z",
+      "updated_at": "2024-04-14T13:21:24.000000Z"
+    }
+  ],
+  "first_page_url": "https:\/\/webhook.test\/global-variables?page=1",
+  "from": 1,
+  "last_page": 21992,
+  "last_page_url": "https:\/\/webhook.test\/global-variables?page=21992",
+  "links": [
+    {
+      "url": null,
+      "label": "&laquo; Previous",
+      "active": false
+    },
+    {
+      "url": "https:\/\/webhook.test\/global-variables?page=1",
+      "label": "1",
+      "active": true
+    },
+    {
+      "url": null,
+      "label": "...",
+      "active": false
+    },
+    {
+      "url": "https:\/\/webhook.test\/global-variables?page=21991",
+      "label": "21991",
+      "active": false
+    },
+    {
+      "url": "https:\/\/webhook.test\/global-variables?page=2",
+      "label": "Next &raquo;",
+      "active": false
+    }
+  ],
+  "next_page_url": "https:\/\/webhook.test\/global-variables?page=2",
+  "path": "https:\/\/webhook.test\/global-variables",
+  "per_page": 15,
+  "prev_page_url": null,
+  "to": 15,
+  "total": 329870
+}
+
+

Update Global Variable

+

Request

+

PUT /global-variables/:globalVariableId

+

(See Create Global Variable above for request.)

+

Response

+

(See Create Global Variable above for response.)

+

Delete Global Variable

+

Request

+

DELETE /global-variables/:globalVariableId

+

Response

+

204 No content

+ +
+
+ + + Last update: + April 15, 2024 11:25:37 + + + +
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/api/groups.html b/api/groups.html new file mode 100644 index 0000000..c76ae8f --- /dev/null +++ b/api/groups.html @@ -0,0 +1,1311 @@ + + + + + + + + + + + + + + + + + + + + + + + + Groups - Webhook.site Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + + + + + + +

API Endpoints: Groups

+

Webhook.site Groups allows you to organize your Tokens. Each Group is a container for multiple Tokens.

+

Create Group

+
    +
  • Requires authentication.
  • +
+

Request

+

POST /groups

+
    +
  • name (string) The name of the group.
  • +
+
{
+  "name": "My Group"
+}
+
+

Response

+
{
+  "id": 3498,
+  "team_id": 12098,
+  "name": "My Group",
+  "updated_at": "2023-04-26 18:43:46",
+  "created_at": "2023-04-26 18:43:46"
+}
+
+

Get all Groups

+
    +
  • Requires authentication.
  • +
+

Request

+

GET /groups

+

Response

+
{
+   "current_page": 1,
+   "data": [
+      {
+         "id": 3498,
+         "team_id": 12098,
+         "name": "My Group",
+         "created_at": "2022-10-26 14:25:11",
+         "updated_at": "2022-10-26 14:25:11"
+      },
+      {
+         "id": 3499,
+         "team_id": 12098,
+         "name": "My nice group",
+         "created_at": "2023-04-26 09:57:40",
+         "updated_at": "2023-04-26 09:57:40"
+      }
+   ],
+   "first_page_url": "https:\/\/webhook.site\/groups?page=1",
+   "from": 1,
+   "last_page": 1,
+   "last_page_url": "https:\/\/webhook.site\/groups?page=1",
+   "next_page_url": null,
+   "path": "https:\/\/webhook.site\/groups",
+   "per_page": "2",
+   "prev_page_url": null,
+   "to": 2,
+   "total": 2
+}
+
+

Update Group

+

Request

+

PUT /groups/:groupId

+

(See Create Group above for request.)

+

Response

+

(See Create Group above for response.)

+

Delete Group

+

Request

+

DELETE /groups/:groupId

+

Response

+

204 No content

+ +
+
+ + + Last update: + April 6, 2024 10:34:57 + + + +
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/api/requests.html b/api/requests.html new file mode 100644 index 0000000..5bf5208 --- /dev/null +++ b/api/requests.html @@ -0,0 +1,1560 @@ + + + + + + + + + + + + + + + + + + + + + + + + Requests - Webhook.site Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + + + + + + +

API Endpoints: Requests

+

The Requests API is used to retrieve, manipulate and delete data sent to a given Webhook.site token (URL, E-mail Address or DNSHook.)

+

Capture request

+

any method /:tokenId
+any method /:tokenId/:statusCode
+any method /:tokenId/(anything)

+

If statusCode is valid, that HTTP status will be used in the response (instead of the default.)

+

Instead of tokenId, an the alias of the token can also be supplied. Multiple subpaths, e.g. /:tokenId/api/v1/users, will also be captured.

+

If the Token has a timeout value, there is a dynamic rate limit of 100 ÷ timeout requests per minute, e.g. a timeout of 30 allows for 3 requests per minute, and 1 second allows for 100 requests per minute.

+

Response

+

The default response (or a response set with e.g. the Modify Response Custom Action) of the Token will be returned.

+

Get requests

+
    +
  • Can require authentication.
  • +
  • Rate limit: 120 requests per minute.
  • +
+

GET /token/:token_id/requests

+

Lists all request sent to a token.

+

Query string parameters

+
    +
  • sorting (string) - either newest or oldest (default)
  • +
  • per_page (int) - amount of requests returned, defaults to 50 (max 100)
  • +
  • page (int) - page number to retrieve (default 1)
  • +
  • date_from, date_to (date string) - filter requests by date, format yyyy-MM-dd HH:mm:ss
  • +
  • query (string) - filter requests by a query string search (see below for examples)
  • +
+

Search query examples

+

The following fields can be used to filter via the query parameter:

+
    +
  • uuid
  • +
  • token_id
  • +
  • team_id
  • +
  • type
  • +
  • hostname
  • +
  • size
  • +
  • content
  • +
  • time
  • +
  • created_at
  • +
  • updated_at
  • +
  • custom_action_output
  • +
  • files.[id]
  • +
  • headers.[header]
  • +
  • method - type web only
  • +
  • user_agent - type web only
  • +
  • url - type web only
  • +
  • ip - type web only
  • +
  • query.[field] - type web only
  • +
  • request.[field] - type webonly (form fields)
  • +
  • sender - type email only
  • +
  • text_content - type email only
  • +
  • message_id - type email only
  • +
  • checks.[type] - type email only
  • +
  • destinations] - type email only
  • +
+

You can filter requests by the following syntax:

+
    +
  • foobar - returns requests or emails with body contents containing the word foobar
  • +
  • content:foobar - returns requests or emails with body contents containing the word foobar
  • +
  • method:GET - returns all requests with method GET
  • +
  • headers.user-agent:"Paw/3.3.5 (Macintosh; OS X/11.6.2) GCDHTTPRequest" - search value of user-agent header
  • +
  • query.action:create - returns requests that have the query string action set to create.
  • +
  • _exists_:query.action - returns requests where the action query parameter exists
  • +
  • type:web / type:email - returns either Web requests or emails
  • +
  • type:web AND method:POST - AND query
  • +
  • method:PUT OR method:POST - OR query
  • +
  • (method:PUT) AND (content:example OR content:test) AND NOT (content:foobar)
  • +
  • created_at:["2022-01-01 00:00:00" TO "2022-12-31 00:00:00"] - date range query
  • +
  • created_at:["2022-01-01 00:00:00" TO *] - date range query (from date until now)
  • +
  • created_at:[now-10m TO now] - date range query (10 minutes ago until now; reference for date expressions)
  • +
+

Full URL Example

+

If you're in doubt about where these parameters go in an API request, take a look below. This URL combines a search query via the query parameter (searching requests containing the word foobar), as well as the sorting and per_page parameters.

+

https://webhook.site/token/a94a7294-c4aa-4074-ab77-c4cf86fd53b1/requests?query=content:foobar&sorting=newest&per_page=10

+

Response

+
{
+  "data": [
+    {
+      "uuid": "a2a6a4ae-4130-4063-953a-84fa29d81d43",
+      "token_id": "a94a7294-c4aa-4074-ab77-c4cf86fd53b1",
+      "ip": "127.0.0.1",
+      "hostname": "webhook.site",
+      "method": "POST",
+      "user_agent": "Paw\/3.1.8 (Macintosh; OS X\/10.14.6) GCDHTTPRequest",
+      "content": "{\"first_name\":\"Arch\",\"last_name\":\"Weber\"}",
+      "query": {
+        "action": "create"
+      },
+      "request": {
+        "status": "example"
+      },
+      "files": {
+        "file": {
+           "id": "98bf4c25-58ab-4c5d-ba91-fb6f709ea78d",
+           "filename": "example.png",
+           "size": 420915,
+           "content_type": "image/png"
+        }
+      },
+      "headers": {
+        "content-length": [
+          "271"
+        ],
+        "user-agent": [
+          "Paw\/3.1.8 (Macintosh; OS X\/10.14.6) GCDHTTPRequest"
+        ],
+        "request-id": [
+          "37856131"
+        ]
+      },
+      "url": "https:\/\/webhook.site\/a94a7294-c4aa-4074-ab77-c4cf86fd53b1\/201?",
+      "created_at": "2019-10-03 19:06:35",
+      "updated_at": "2019-10-03 19:06:35",
+      "custom_action_output": []
+    }
+  ],
+  "total": 1,
+  "per_page": 50,
+  "current_page": 1,
+  "is_last_page": true,
+  "from": 1,
+  "to": 1
+}
+
+

Get single/latest request

+
    +
  • Can require authentication.
  • +
+

GET /token/:token_id/request/:request_id

+

GET /token/:token_id/request/latest - retrieves the latest request sent to the URL

+

Response

+
{
+  "uuid": "a2a6a4ae-4130-4063-953a-84fa29d81d43",
+  "token_id": "a94a7294-c4aa-4074-ab77-c4cf86fd53b1",
+  "ip": "127.0.0.1",
+  "hostname": "webhook.site",
+  "method": "POST",
+  "user_agent": "Paw\/3.1.8 (Macintosh; OS X\/10.14.6) GCDHTTPRequest",
+  "content": "{\"first_name\":\"Arch\",\"last_name\":\"Weber\"}",
+  "query": {
+    "action": "create"
+  },
+  "headers": {
+    "content-length": [
+      "271"
+    ],
+    "user-agent": [
+      "Paw\/3.1.8 (Macintosh; OS X\/10.14.6) GCDHTTPRequest"
+    ]
+  },
+  "files": {
+    "foo": {
+      "id": "65d6e0ce-a840-47bc-b6b6-ff1ff38c34ca",
+      "filename": "example.json",
+      "size": 5132873,
+      "content_type": "text/plain"
+    }
+  },
+  "url": "https:\/\/webhook.site\/a94a7294-c4aa-4074-ab77-c4cf86fd53b1\/201?",
+  "created_at": "2019-10-03 19:06:35",
+  "updated_at": "2019-10-03 19:06:35"
+}
+
+

Get raw request content

+
    +
  • Can require authentication.
  • +
+

GET /token/:token_id/request/:request_id/raw

+

GET /token/:token_id/request/latest/raw - retrieves the latest request sent to the URL

+

Returns the request as a response (body, content-type.)

+

Response

+

200 OK

+

Download request file

+
    +
  • Can require authentication.
  • +
+

GET /token/:tokenId/request/:requestId/download/:fileId

+

Files that are included in a request or as email attachments are available to download using this endpoint.

+

Response

+

304 Redirect

+

Delete request

+
    +
  • Can require authentication.
  • +
+

DELETE /token/:token_id/request/:request_id

+

Deletes a request.

+

Response

+

200 OK

+

Delete multiple requests

+
    +
  • Can require authentication.
  • +
  • Rate limit: 10 requests per minute.
  • +
+

DELETE /token/:token_id/request

+

Deletes all requests associated with the token, or if query, date_from and/or date_to is specified, only that subset of requests is deleted.

+

Query string parameters

+
    +
  • date_from, date_to - filter requests by date, format yyyy-MM-dd HH:mm:ss
  • +
  • query - filter requests by a query string search. See here for examples.
  • +
+

Response

+

200 OK

+ +
+
+ + + Last update: + April 6, 2024 10:34:57 + + + +
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/api/schedules.html b/api/schedules.html new file mode 100644 index 0000000..3f1a6d4 --- /dev/null +++ b/api/schedules.html @@ -0,0 +1,1559 @@ + + + + + + + + + + + + + + + + + + + + + + + + Schedules - Webhook.site Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + + + + + + +

API Endpoints: Schedules

+

More info about Schedules.

+

Create schedule

+
    +
  • Requires authentication.
  • +
+

Request

+

POST /schedules

+
    +
  • name The name of the schedule.
  • +
  • interval One of the following interval strings: monthly, weekly, daily, hourly, 10-minute, 5-minute, 1-minute, cron
  • +
  • cron When interval is cron, specify a cron-style interval, e.g. */5 * * * * for every 5 minutes. Otherwise can be left out.
  • +
  • request_url The request URL that the schedule should act on.
  • +
  • request_method HTTP Method (POST, GET, etc.)
  • +
  • request_body
  • +
  • request_headers HTTP headers, separated by \n
  • +
  • timeout Timeout in seconds (min 1, max 30)
  • +
  • require_body If specified, Webhook.site sends an error notification if response body doesn't contain this string.
  • +
  • require_status_min If specified, Webhook.site sends an error notification if response status doesn't fit within range.
  • +
  • require_status_max If specified, Webhook.site sends an error notification if response status doesn't fit within range.
  • +
+

Variables will be replaced in the fields request_url, request_method, request_headers and request_body. More info here.

+
{
+  "name": "My schedule",
+  "interval": "5-minute",
+  "request_url": "https://example.com",
+  "request_method": "POST",
+  "request_body": "{\"json\": \"message\"}",
+  "request_headers": "Authorization: Bearer mytoken\nContent-Type: application/json"
+}
+
+

Response

+
{
+  "name": "My schedule",
+  "interval": "5-minute",
+  "request_url": "https:\/\/example.com",
+  "request_method": "POST",
+  "request_body": "{\"json\": \"message\"}",
+  "request_headers": "Authorization: Bearer mytoken\nContent-Type: application\/json",
+  "require_body": null,
+  "require_status_min": null,
+  "require_status_max": null,
+  "user_id": 21,
+  "updated_at": "2021-05-01 13:27:25",
+  "created_at": "2021-05-01 13:27:25",
+  "id": 58
+}
+
+

Get all schedules

+

GET /schedules?page=1&per_page=15

+

Response

+
{
+  "current_page": 1,
+  "data": [
+    {
+      "id": 58,
+      "name": "My schedule",
+      "interval": "5-minute",
+      "cron": null,
+      "user_id": 21,
+      "request_method": "POST",
+      "request_url": "https:\/\/example.com",
+      "request_headers": "Authorization: Bearer mytoken\nContent-Type: application\/json",
+      "request_body": "{\"json\": \"message\"}",
+      "timeout": 5,
+      "require_body": null,
+      "require_status_min": null,
+      "require_status_max": null,
+      "last_run_at": null,
+      "last_status": null,
+      "created_at": "2021-05-01 13:27:25",
+      "updated_at": "2021-05-01 13:27:25"
+    }
+  ],
+  "first_page_url": "https:\/\/webhook.site\/schedules?page=1",
+  "from": 1,
+  "last_page": 1,
+  "last_page_url": "https:\/\/webhook.site\/schedules?page=1",
+  "next_page_url": null,
+  "path": "https:\/\/webhook.site\/schedules",
+  "per_page": 15,
+  "prev_page_url": null,
+  "to": 6,
+  "total": 6
+}
+
+

Get single schedule

+

Request

+

GET /schedules/:scheduleId

+

Response

+
{
+  "id": 58,
+  "name": "My schedule",
+  "interval": "5-minute",
+  "cron": null,
+  "user_id": 21,
+  "request_method": "POST",
+  "request_url": "https:\/\/example.com",
+  "request_headers": "Authorization: Bearer mytoken\nContent-Type: application\/json",
+  "request_body": "{\"json\": \"message\"}",
+  "timeout": 5,
+  "require_body": null,
+  "require_status_min": null,
+  "require_status_max": null,
+  "last_run_at": null,
+  "last_status": null,
+  "created_at": "2021-05-01 13:27:25",
+  "updated_at": "2021-05-01 13:27:25"
+}
+
+

Update schedule

+

Request

+

PUT /schedules/:scheduleId

+

(See Create schedule above for request.)

+

Response

+

(See Get single schedule for response.)

+

Delete schedule

+

Request

+

DELETE /schedules/:scheduleId

+

Response

+

204 No content

+

Run Schedule Now

+

Request

+

POST /schedules/:scheduleId/run-now

+

Get Schedule Logs

+

Request

+

GET /schedules/:scheduleId/logs

+

Set Accept header to application/json.

+

Rate limit: 60 requests per minute.

+

Response

+
{
+  "data": [
+    {
+      "id": 2,
+      "schedule_id": 1,
+      "response_status": 200,
+      "response_headers": {
+        "Age": [
+          "447707"
+        ],
+        "Cache-Control": [
+          "max-age=604800"
+        ],
+        "Content-Type": [
+          "text\/html; charset=UTF-8"
+        ]
+      },
+      "response_body": "<!doctype html>\n<html>\n<head>...",
+      "error": null,
+      "created_at": "2022-11-06 19:27:09",
+      "updated_at": "2022-11-06 19:27:09"
+    },
+    {
+      "id": 3,
+      "schedule_id": 1,
+      "response_status": 200,
+      "response_headers": {
+        "Age": [
+          "404973"
+        ],
+        "Cache-Control": [
+          "max-age=604800"
+        ],
+        "Content-Type": [
+          "text\/html; charset=UTF-8"
+        ]
+      },
+      "response_body": "<!doctype html>\n<html>\n<head>...",
+      "error": null,
+      "created_at": "2022-11-06 19:30:02",
+      "updated_at": "2022-11-06 19:30:02"
+    }
+  ],
+  "current_page": 1,
+  "first_page_url": "https:\/\/webhook.site\/control-panel\/schedules\/1\/logs?page=1",
+  "from": 1,
+  "last_page": 1,
+  "last_page_url": "https:\/\/webhook.site\/control-panel\/schedules\/1\/logs?page=1",
+  "next_page_url": null,
+  "path": "https:\/\/webhook.site\/control-panel\/schedules\/1\/logs",
+  "per_page": 15,
+  "prev_page_url": null,
+  "to": 2,
+  "total": 2
+}
+
+ +
+
+ + + Last update: + April 6, 2024 10:34:57 + + + +
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/api/templates.html b/api/templates.html new file mode 100644 index 0000000..9d5a42c --- /dev/null +++ b/api/templates.html @@ -0,0 +1,1500 @@ + + + + + + + + + + + + + + + + + + + + + + + + Templates - Webhook.site Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + + + + + + +

API Endpoints: Templates

+

Webhook.site Templates allows you to create templates of actions, and re-use these templates with the Include Template Custom Action.

+

Create Template

+
    +
  • Requires authentication.
  • +
+

Request

+

POST /template

+
    +
  • name The name of the template.
  • +
  • actions An array of objects containing Custom Actions. All parameters of actions except disabled can be used. More info here
  • +
  • variables An array of name-value objects containing predefined variables. These variables are defined before the action runs, and are available to any subsequent actions after the template is included.
  • +
+
{
+    "actions": [
+        {
+            "name": null,
+            "type": "conditions",
+            "queue": false,
+            "delay": 0,
+            "condition": null,
+            "parameters": {
+                "conditions": [
+                    {
+                        "input": "$date$",
+                        "operator": "eq",
+                        "value": "$post-news-last-date$"
+                    }
+                ],
+                "mode": "all",
+                "action": "stop"
+            },
+            "order": 2
+        },
+        {
+            "name": null,
+            "type": "twitter_tweet",
+            "queue": false,
+            "delay": 0,
+            "condition": null,
+            "parameters": {
+                "provider_id": "501133",
+                "tweet": "$tweet$"
+            },
+            "order": 3
+        },
+        {
+            "name": null,
+            "type": "store_global_variable",
+            "queue": false,
+            "delay": 0,
+            "condition": null,
+            "parameters": {
+                "name": "post-news-last-date",
+                "value": "$date$"
+            },
+            "order": 4
+        }
+    ],
+    "name": "My Template",
+    "variables": [
+        {
+            "name": "example",
+            "value": "hello world"
+        }
+    ],
+}
+
+

Response

+
{
+  "name": "My Template",
+  "variables": [
+    {
+      "name": "example",
+      "value": "hello world"
+    }
+  ],
+  "team_id": 1,
+  "updated_at": "2024-02-20T10:01:29.000000Z",
+  "created_at": "2024-02-20T10:01:29.000000Z",
+  "id": 21,
+  "actions": [
+    {
+      "condition": null,
+      "delay": 0,
+      "parameters": {
+        "mode": "all",
+        "conditions": [
+          {
+            "input": "$date$",
+            "operator": "eq",
+            "value": "$post-news-last-date$"
+          }
+        ],
+        "action": "stop"
+      },
+      "token_id": "f1bd342e-c98b-4ac4-bf3f-c35f1f338161",
+      "type": "conditions",
+      "order": 2,
+      "name": null,
+      "template_id": 21,
+      "uuid": "9b615454-3c64-4da2-a2f7-d524797a8925",
+      "updated_at": "2024-02-20T10:01:29.000000Z",
+      "created_at": "2024-02-20T10:01:29.000000Z"
+    },
+    {
+      "condition": null,
+      "delay": 0,
+      "parameters": {
+        "tweet": "$tweet$",
+        "provider_id": "501133"
+      },
+      "token_id": "f1bd342e-c98b-4ac4-bf3f-c35f1f338161",
+      "type": "twitter_tweet",
+      "order": 3,
+      "name": null,
+      "template_id": 21,
+      "uuid": "9b615454-3ce7-4c63-bc8b-3412694ae633",
+      "updated_at": "2024-02-20T10:01:29.000000Z",
+      "created_at": "2024-02-20T10:01:29.000000Z"
+    },
+    {
+      "condition": null,
+      "delay": 0,
+      "parameters": {
+        "name": "post-news-last-date",
+        "value": "$date$"
+      },
+      "token_id": "f1bd342e-c98b-4ac4-bf3f-c35f1f338161",
+      "type": "store_global_variable",
+      "order": 4,
+      "name": null,
+      "template_id": 21,
+      "uuid": "9b615454-3d5f-4cd6-bd4b-94b55e6f6f2f",
+      "updated_at": "2024-02-20T10:01:29.000000Z",
+      "created_at": "2024-02-20T10:01:29.000000Z"
+    }
+  ]
+}
+
+

Get all Templates

+
    +
  • Requires authentication.
  • +
+

Request

+

GET /templates

+

Response

+
{
+  "current_page": 1,
+  "data": [
+    {
+      "name": "My Template",
+      "variables": [
+        {
+          "name": "example",
+          "value": "hello world"
+        }
+      ],
+      "team_id": 1,
+      "updated_at": "2024-02-20T10:01:29.000000Z",
+      "created_at": "2024-02-20T10:01:29.000000Z",
+      "id": 21,
+      "actions": [
+        {
+          "condition": null,
+          "delay": 0,
+          "parameters": {
+            "mode": "all",
+            "conditions": [
+              {
+                "input": "$date$",
+                "operator": "eq",
+                "value": "$post-news-last-date$"
+              }
+            ],
+            "action": "stop"
+          },
+          "token_id": "f1bd342e-c98b-4ac4-bf3f-c35f1f338161",
+          "type": "conditions",
+          "order": 2,
+          "name": null,
+          "template_id": 21,
+          "uuid": "9b615454-3c64-4da2-a2f7-d524797a8925",
+          "updated_at": "2024-02-20T10:01:29.000000Z",
+          "created_at": "2024-02-20T10:01:29.000000Z"
+        },
+        {
+          "condition": null,
+          "delay": 0,
+          "parameters": {
+            "tweet": "$tweet$",
+            "provider_id": "501133"
+          },
+          "token_id": "f1bd342e-c98b-4ac4-bf3f-c35f1f338161",
+          "type": "twitter_tweet",
+          "order": 3,
+          "name": null,
+          "template_id": 21,
+          "uuid": "9b615454-3ce7-4c63-bc8b-3412694ae633",
+          "updated_at": "2024-02-20T10:01:29.000000Z",
+          "created_at": "2024-02-20T10:01:29.000000Z"
+        },
+        {
+          "condition": null,
+          "delay": 0,
+          "parameters": {
+            "name": "post-news-last-date",
+            "value": "$date$"
+          },
+          "token_id": "f1bd342e-c98b-4ac4-bf3f-c35f1f338161",
+          "type": "store_global_variable",
+          "order": 4,
+          "name": null,
+          "template_id": 21,
+          "uuid": "9b615454-3d5f-4cd6-bd4b-94b55e6f6f2f",
+          "updated_at": "2024-02-20T10:01:29.000000Z",
+          "created_at": "2024-02-20T10:01:29.000000Z"
+        }
+      ]
+    }
+  ],
+  "first_page_url": "https:\/\/webhook.site\/templates?page=1",
+  "from": 1,
+  "last_page": 1,
+  "last_page_url": "https:\/\/webhook.site\/templates?page=1",
+  "links": [
+    {
+      "url": null,
+      "label": "&laquo; Previous",
+      "active": false
+    },
+    {
+      "url": "https:\/\/webhook.site\/templates?page=1",
+      "label": "1",
+      "active": true
+    },
+    {
+      "url": null,
+      "label": "Next &raquo;",
+      "active": false
+    }
+  ],
+  "next_page_url": null,
+  "path": "https:\/\/webhook.site\/templates",
+  "per_page": 15,
+  "prev_page_url": null,
+  "to": 1,
+  "total": 1
+}
+
+

Update Template

+

Request

+

PUT /templates/:templateId

+

(See Create Template above for request.)

+

Response

+

(See Create Template above for response.)

+

Delete Template

+

Request

+

DELETE /templates/:templateId

+

Response

+

204 No content

+ +
+
+ + + Last update: + April 6, 2024 10:34:57 + + + +
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/api/tokens.html b/api/tokens.html new file mode 100644 index 0000000..2fbbea4 --- /dev/null +++ b/api/tokens.html @@ -0,0 +1,1664 @@ + + + + + + + + + + + + + + + + + + + + + + + + Tokens - Webhook.site Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + + + + + + +

API Endpoints:
Tokens (URLs & Email Addresses)

+

A token is a container for incoming requests and emails, and corresponds to a Webhook.site URL or Email. A token ID is a 36 character UUID consisting of hexadecimal characters and dashes.

+

Simply, the token ID is the part after https://webhook.site/ in the URL, or before @email.webhook.site in the email address.

+

Create token

+
    +
  • Can require authentication.
  • +
  • Rate limit: 10 per minute (free); 60 per minute (Pro and Enterprise)
  • +
+

POST /token

+

After creating a token, the URL at https://webhook.site/{token.uuid} becomes accessible, and emails can be sent to {token.uuid}@email.webhook.site.

+
    +
  • default_* parameters sets the response of the URL.
  • +
  • timeout (int) waits an amount of seconds before returning the response, max 30. Intended for testing timeouts, requests to tokens with timeouts are rate limited; a high timeout value will incur a lower rate limit.
  • +
  • expiry (int) amount of seconds until token auto-expiration. Max value (and default for non-upgraded URLs) is 604800 (one week). Intended for e.g. automated testing pipelines. Leave out or set to null to disable.
  • +
  • request_limit (int) - limits the request history amount from 1 to 10000 (default)
  • +
  • cors (bool) set to true will add CORS headers to the request so browsers will send cross-domain requests to the URL
  • +
  • alias (string) allows setting the alias of the token.
  • +
  • actions (bool) specifies if Custom Actions are enabled and executed on every request/email (true), or disabled (false.)
  • +
  • clone_from (uuid string) specifies a token UUID (or alias) that will act as a template for the new token. When specified, settingssuch as default content, timeout, password as well as Custom Actions are copied to the new token.
  • +
  • group_id (int) specifies which group ID the token should be added to.
  • +
+

Request

+
Example 1: JSON
+
{
+  "default_status": 200,
+  "default_content": "Hello world!",
+  "default_content_type": "text/html",
+  "timeout": 0,
+  "cors": false,
+  "expiry": 604800,
+  "alias": "my-webhook",
+  "actions": true
+}
+
+
Example 2: Creating with Python 3
+

Requires the requests module, which can be installed using pip install requests. You'll also need to replace the API key. Create an API key here.

+
import requests
+
+json = {
+  "default_status": 200,
+  "default_content": "Hello world!",
+  "default_content_type": "text/html",
+}
+
+headers = {
+    "api-key": "00000000-0000-0000-0000-000000000000"
+}
+
+r = requests.post('https://webhook.site/token', json=json, headers=headers)
+
+print('URL Created: https://webhook.site/' + r.json()['uuid'])
+
+

Response

+

200 OK

+
{
+  "redirect": false,
+  "alias": null,
+  "timeout": 0,
+  "premium": true,
+  "uuid": "9981f9f4-657a-4ebf-be7c-1915bedd4775",
+  "ip": "127.0.0.1",
+  "user_agent": "Paw\/3.1.8 (Macintosh; OS X\/10.14.6) GCDHTTPRequest",
+  "default_content": "Hello world!",
+  "default_status": 200,
+  "default_content_type": "text\/plain",
+  "premium_expires_at": "2019-10-22 10:52:20",
+  "created_at": "2019-09-22 10:52:20",
+  "updated_at": "2019-09-22 10:52:20"
+  "expires_at": "2019-09-29 10:52:20"
+}
+
+

Get token list

+
    +
  • Requires authentication.
  • +
+

Request

+

GET /token

+

Returns a list of all Tokens associated with an account.

+
Query string parameters
+
    +
  • per_page - amount of requests returned, defaults to 50 (max 100)
  • +
  • page - page number to retrieve (default 1)
  • +
  • order_by - which field to order tokens by (created_at (default) or token_id)
  • +
  • order_direction - order direction (asc (default) or desc)
  • +
+

Response

+
{
+  "current_page": 1,
+  "data": [
+    {
+      "uuid": "44fb1548-cd1f-4928-880c-cce094e5e179",
+      "redirect": false,
+      "alias": null,
+      "actions": true,
+      "cors": false,
+      "expiry": false,
+      "timeout": 0,
+      "premium": true,
+      "user_id": null,
+      "password": true,
+      "ip": "127.0.0.1",
+      "user_agent": "Mozilla\/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit\/605.1.15 (KHTML, like Gecko) Version\/14.0.3 Safari\/605.1.15",
+      "default_content": "",
+      "default_status": 200,
+      "default_content_type": "text\/plain",
+      "premium_expires_at": null,
+      "created_at": "2021-08-11 18:34:44",
+      "updated_at": "2021-08-11 18:34:44",
+      "latest_request_id": "ea5f5920-0398-465c-8f9c-8074f0d805a4",
+      "latest_request_at": "2021-08-12 19:56:50",
+      "group_id": null,
+      "requests": 1
+    },
+    ...
+  ],
+  "first_page_url": "https:\/\/webhook.site\/token?page=1",
+  "from": 1,
+  "last_page": 1,
+  "last_page_url": "https:\/\/webhook.site\/token?page=1",
+  "next_page_url": null,
+  "path": "https:\/\/webhook.site\/token",
+  "per_page": 50,
+  "prev_page_url": null,
+  "to": 2,
+  "total": 2
+}
+
+

Get token

+
    +
  • Can require authentication.
  • +
+

GET /token/:token_id

+

Response

+

See POST /token

+

Update token

+
    +
  • Can require authentication.
  • +
+

PUT /token/:token_id

+

Request

+

See POST /token

+

Response

+

See POST /token

+

Set password

+
    +
  • Can require authentication.
  • +
  • Requires user with active subscription.
  • +
+

PUT /token/:token_id/password

+

Sets a password to view the requests of a token.

+

Request

+
{"password": "hunter2", "old_password": "hunter1"}
+
+

Response

+

See POST /token

+

Set alias

+
    +
  • ⚠️ This endpoint is deprecated and may be removed.
  • +
  • Can require authentication.
  • +
  • Requires user with active subscription.
  • +
+

PUT /token/:token_id/alias

+

Sets the alias for the token, which makes the token available at https://webhook.site/<alias> or <alias>@email.webhook.site in addition to its 36 character UUID.

+

Rules for alias format: Length between 3-32 characters. Allowed characters: A-Z, a-z and - (dash.)

+

Request

+
{"alias": "my-webhook"}
+
+

Response

+

See POST /token

+

Toggle CORS

+
    +
  • ⚠️ This endpoint is deprecated and may be removed.
  • +
+

Attaches CORS headers to the response of the Token, allowing browsers to request it from all domains.

+

PUT /token/:token_id/cors/toggle

+

Response

+
{ "enabled": true}
+
+

Delete token

+
    +
  • Can require authentication.
  • +
+

DELETE /token/:token_id

+

Response

+

204 No Content

+ +
+
+ + + Last update: + April 6, 2024 10:34:57 + + + +
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/assets/images/favicon.png b/assets/images/favicon.png new file mode 100644 index 0000000..1cf13b9 Binary files /dev/null and b/assets/images/favicon.png differ diff --git a/assets/javascripts/bundle.51d95adb.min.js b/assets/javascripts/bundle.51d95adb.min.js new file mode 100644 index 0000000..b20ec68 --- /dev/null +++ b/assets/javascripts/bundle.51d95adb.min.js @@ -0,0 +1,29 @@ +"use strict";(()=>{var Hi=Object.create;var xr=Object.defineProperty;var Pi=Object.getOwnPropertyDescriptor;var $i=Object.getOwnPropertyNames,kt=Object.getOwnPropertySymbols,Ii=Object.getPrototypeOf,Er=Object.prototype.hasOwnProperty,an=Object.prototype.propertyIsEnumerable;var on=(e,t,r)=>t in e?xr(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,P=(e,t)=>{for(var r in t||(t={}))Er.call(t,r)&&on(e,r,t[r]);if(kt)for(var r of kt(t))an.call(t,r)&&on(e,r,t[r]);return e};var sn=(e,t)=>{var r={};for(var n in e)Er.call(e,n)&&t.indexOf(n)<0&&(r[n]=e[n]);if(e!=null&&kt)for(var n of kt(e))t.indexOf(n)<0&&an.call(e,n)&&(r[n]=e[n]);return r};var Ht=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var Fi=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of $i(t))!Er.call(e,o)&&o!==r&&xr(e,o,{get:()=>t[o],enumerable:!(n=Pi(t,o))||n.enumerable});return e};var yt=(e,t,r)=>(r=e!=null?Hi(Ii(e)):{},Fi(t||!e||!e.__esModule?xr(r,"default",{value:e,enumerable:!0}):r,e));var fn=Ht((wr,cn)=>{(function(e,t){typeof wr=="object"&&typeof cn!="undefined"?t():typeof define=="function"&&define.amd?define(t):t()})(wr,function(){"use strict";function e(r){var n=!0,o=!1,i=null,a={text:!0,search:!0,url:!0,tel:!0,email:!0,password:!0,number:!0,date:!0,month:!0,week:!0,time:!0,datetime:!0,"datetime-local":!0};function s(T){return!!(T&&T!==document&&T.nodeName!=="HTML"&&T.nodeName!=="BODY"&&"classList"in T&&"contains"in T.classList)}function f(T){var Ke=T.type,We=T.tagName;return!!(We==="INPUT"&&a[Ke]&&!T.readOnly||We==="TEXTAREA"&&!T.readOnly||T.isContentEditable)}function c(T){T.classList.contains("focus-visible")||(T.classList.add("focus-visible"),T.setAttribute("data-focus-visible-added",""))}function u(T){T.hasAttribute("data-focus-visible-added")&&(T.classList.remove("focus-visible"),T.removeAttribute("data-focus-visible-added"))}function p(T){T.metaKey||T.altKey||T.ctrlKey||(s(r.activeElement)&&c(r.activeElement),n=!0)}function m(T){n=!1}function d(T){s(T.target)&&(n||f(T.target))&&c(T.target)}function h(T){s(T.target)&&(T.target.classList.contains("focus-visible")||T.target.hasAttribute("data-focus-visible-added"))&&(o=!0,window.clearTimeout(i),i=window.setTimeout(function(){o=!1},100),u(T.target))}function v(T){document.visibilityState==="hidden"&&(o&&(n=!0),B())}function B(){document.addEventListener("mousemove",z),document.addEventListener("mousedown",z),document.addEventListener("mouseup",z),document.addEventListener("pointermove",z),document.addEventListener("pointerdown",z),document.addEventListener("pointerup",z),document.addEventListener("touchmove",z),document.addEventListener("touchstart",z),document.addEventListener("touchend",z)}function re(){document.removeEventListener("mousemove",z),document.removeEventListener("mousedown",z),document.removeEventListener("mouseup",z),document.removeEventListener("pointermove",z),document.removeEventListener("pointerdown",z),document.removeEventListener("pointerup",z),document.removeEventListener("touchmove",z),document.removeEventListener("touchstart",z),document.removeEventListener("touchend",z)}function z(T){T.target.nodeName&&T.target.nodeName.toLowerCase()==="html"||(n=!1,re())}document.addEventListener("keydown",p,!0),document.addEventListener("mousedown",m,!0),document.addEventListener("pointerdown",m,!0),document.addEventListener("touchstart",m,!0),document.addEventListener("visibilitychange",v,!0),B(),r.addEventListener("focus",d,!0),r.addEventListener("blur",h,!0),r.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&r.host?r.host.setAttribute("data-js-focus-visible",""):r.nodeType===Node.DOCUMENT_NODE&&(document.documentElement.classList.add("js-focus-visible"),document.documentElement.setAttribute("data-js-focus-visible",""))}if(typeof window!="undefined"&&typeof document!="undefined"){window.applyFocusVisiblePolyfill=e;var t;try{t=new CustomEvent("focus-visible-polyfill-ready")}catch(r){t=document.createEvent("CustomEvent"),t.initCustomEvent("focus-visible-polyfill-ready",!1,!1,{})}window.dispatchEvent(t)}typeof document!="undefined"&&e(document)})});var un=Ht(Sr=>{(function(e){var t=function(){try{return!!Symbol.iterator}catch(c){return!1}},r=t(),n=function(c){var u={next:function(){var p=c.shift();return{done:p===void 0,value:p}}};return r&&(u[Symbol.iterator]=function(){return u}),u},o=function(c){return encodeURIComponent(c).replace(/%20/g,"+")},i=function(c){return decodeURIComponent(String(c).replace(/\+/g," "))},a=function(){var c=function(p){Object.defineProperty(this,"_entries",{writable:!0,value:{}});var m=typeof p;if(m!=="undefined")if(m==="string")p!==""&&this._fromString(p);else if(p instanceof c){var d=this;p.forEach(function(re,z){d.append(z,re)})}else if(p!==null&&m==="object")if(Object.prototype.toString.call(p)==="[object Array]")for(var h=0;hd[0]?1:0}),c._entries&&(c._entries={});for(var p=0;p1?i(d[1]):"")}})})(typeof global!="undefined"?global:typeof window!="undefined"?window:typeof self!="undefined"?self:Sr);(function(e){var t=function(){try{var o=new e.URL("b","http://a");return o.pathname="c d",o.href==="http://a/c%20d"&&o.searchParams}catch(i){return!1}},r=function(){var o=e.URL,i=function(f,c){typeof f!="string"&&(f=String(f)),c&&typeof c!="string"&&(c=String(c));var u=document,p;if(c&&(e.location===void 0||c!==e.location.href)){c=c.toLowerCase(),u=document.implementation.createHTMLDocument(""),p=u.createElement("base"),p.href=c,u.head.appendChild(p);try{if(p.href.indexOf(c)!==0)throw new Error(p.href)}catch(T){throw new Error("URL unable to set base "+c+" due to "+T)}}var m=u.createElement("a");m.href=f,p&&(u.body.appendChild(m),m.href=m.href);var d=u.createElement("input");if(d.type="url",d.value=f,m.protocol===":"||!/:/.test(m.href)||!d.checkValidity()&&!c)throw new TypeError("Invalid URL");Object.defineProperty(this,"_anchorElement",{value:m});var h=new e.URLSearchParams(this.search),v=!0,B=!0,re=this;["append","delete","set"].forEach(function(T){var Ke=h[T];h[T]=function(){Ke.apply(h,arguments),v&&(B=!1,re.search=h.toString(),B=!0)}}),Object.defineProperty(this,"searchParams",{value:h,enumerable:!0});var z=void 0;Object.defineProperty(this,"_updateSearchParams",{enumerable:!1,configurable:!1,writable:!1,value:function(){this.search!==z&&(z=this.search,B&&(v=!1,this.searchParams._fromString(this.search),v=!0))}})},a=i.prototype,s=function(f){Object.defineProperty(a,f,{get:function(){return this._anchorElement[f]},set:function(c){this._anchorElement[f]=c},enumerable:!0})};["hash","host","hostname","port","protocol"].forEach(function(f){s(f)}),Object.defineProperty(a,"search",{get:function(){return this._anchorElement.search},set:function(f){this._anchorElement.search=f,this._updateSearchParams()},enumerable:!0}),Object.defineProperties(a,{toString:{get:function(){var f=this;return function(){return f.href}}},href:{get:function(){return this._anchorElement.href.replace(/\?$/,"")},set:function(f){this._anchorElement.href=f,this._updateSearchParams()},enumerable:!0},pathname:{get:function(){return this._anchorElement.pathname.replace(/(^\/?)/,"/")},set:function(f){this._anchorElement.pathname=f},enumerable:!0},origin:{get:function(){var f={"http:":80,"https:":443,"ftp:":21}[this._anchorElement.protocol],c=this._anchorElement.port!=f&&this._anchorElement.port!=="";return this._anchorElement.protocol+"//"+this._anchorElement.hostname+(c?":"+this._anchorElement.port:"")},enumerable:!0},password:{get:function(){return""},set:function(f){},enumerable:!0},username:{get:function(){return""},set:function(f){},enumerable:!0}}),i.createObjectURL=function(f){return o.createObjectURL.apply(o,arguments)},i.revokeObjectURL=function(f){return o.revokeObjectURL.apply(o,arguments)},e.URL=i};if(t()||r(),e.location!==void 0&&!("origin"in e.location)){var n=function(){return e.location.protocol+"//"+e.location.hostname+(e.location.port?":"+e.location.port:"")};try{Object.defineProperty(e.location,"origin",{get:n,enumerable:!0})}catch(o){setInterval(function(){e.location.origin=n()},100)}}})(typeof global!="undefined"?global:typeof window!="undefined"?window:typeof self!="undefined"?self:Sr)});var Qr=Ht((Lt,Kr)=>{/*! + * clipboard.js v2.0.11 + * https://clipboardjs.com/ + * + * Licensed MIT © Zeno Rocha + */(function(t,r){typeof Lt=="object"&&typeof Kr=="object"?Kr.exports=r():typeof define=="function"&&define.amd?define([],r):typeof Lt=="object"?Lt.ClipboardJS=r():t.ClipboardJS=r()})(Lt,function(){return function(){var e={686:function(n,o,i){"use strict";i.d(o,{default:function(){return ki}});var a=i(279),s=i.n(a),f=i(370),c=i.n(f),u=i(817),p=i.n(u);function m(j){try{return document.execCommand(j)}catch(O){return!1}}var d=function(O){var w=p()(O);return m("cut"),w},h=d;function v(j){var O=document.documentElement.getAttribute("dir")==="rtl",w=document.createElement("textarea");w.style.fontSize="12pt",w.style.border="0",w.style.padding="0",w.style.margin="0",w.style.position="absolute",w.style[O?"right":"left"]="-9999px";var k=window.pageYOffset||document.documentElement.scrollTop;return w.style.top="".concat(k,"px"),w.setAttribute("readonly",""),w.value=j,w}var B=function(O,w){var k=v(O);w.container.appendChild(k);var F=p()(k);return m("copy"),k.remove(),F},re=function(O){var w=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body},k="";return typeof O=="string"?k=B(O,w):O instanceof HTMLInputElement&&!["text","search","url","tel","password"].includes(O==null?void 0:O.type)?k=B(O.value,w):(k=p()(O),m("copy")),k},z=re;function T(j){return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?T=function(w){return typeof w}:T=function(w){return w&&typeof Symbol=="function"&&w.constructor===Symbol&&w!==Symbol.prototype?"symbol":typeof w},T(j)}var Ke=function(){var O=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},w=O.action,k=w===void 0?"copy":w,F=O.container,q=O.target,Le=O.text;if(k!=="copy"&&k!=="cut")throw new Error('Invalid "action" value, use either "copy" or "cut"');if(q!==void 0)if(q&&T(q)==="object"&&q.nodeType===1){if(k==="copy"&&q.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if(k==="cut"&&(q.hasAttribute("readonly")||q.hasAttribute("disabled")))throw new Error(`Invalid "target" attribute. You can't cut text from elements with "readonly" or "disabled" attributes`)}else throw new Error('Invalid "target" value, use a valid Element');if(Le)return z(Le,{container:F});if(q)return k==="cut"?h(q):z(q,{container:F})},We=Ke;function Ie(j){return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?Ie=function(w){return typeof w}:Ie=function(w){return w&&typeof Symbol=="function"&&w.constructor===Symbol&&w!==Symbol.prototype?"symbol":typeof w},Ie(j)}function Ti(j,O){if(!(j instanceof O))throw new TypeError("Cannot call a class as a function")}function nn(j,O){for(var w=0;w0&&arguments[0]!==void 0?arguments[0]:{};this.action=typeof F.action=="function"?F.action:this.defaultAction,this.target=typeof F.target=="function"?F.target:this.defaultTarget,this.text=typeof F.text=="function"?F.text:this.defaultText,this.container=Ie(F.container)==="object"?F.container:document.body}},{key:"listenClick",value:function(F){var q=this;this.listener=c()(F,"click",function(Le){return q.onClick(Le)})}},{key:"onClick",value:function(F){var q=F.delegateTarget||F.currentTarget,Le=this.action(q)||"copy",Rt=We({action:Le,container:this.container,target:this.target(q),text:this.text(q)});this.emit(Rt?"success":"error",{action:Le,text:Rt,trigger:q,clearSelection:function(){q&&q.focus(),window.getSelection().removeAllRanges()}})}},{key:"defaultAction",value:function(F){return yr("action",F)}},{key:"defaultTarget",value:function(F){var q=yr("target",F);if(q)return document.querySelector(q)}},{key:"defaultText",value:function(F){return yr("text",F)}},{key:"destroy",value:function(){this.listener.destroy()}}],[{key:"copy",value:function(F){var q=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body};return z(F,q)}},{key:"cut",value:function(F){return h(F)}},{key:"isSupported",value:function(){var F=arguments.length>0&&arguments[0]!==void 0?arguments[0]:["copy","cut"],q=typeof F=="string"?[F]:F,Le=!!document.queryCommandSupported;return q.forEach(function(Rt){Le=Le&&!!document.queryCommandSupported(Rt)}),Le}}]),w}(s()),ki=Ri},828:function(n){var o=9;if(typeof Element!="undefined"&&!Element.prototype.matches){var i=Element.prototype;i.matches=i.matchesSelector||i.mozMatchesSelector||i.msMatchesSelector||i.oMatchesSelector||i.webkitMatchesSelector}function a(s,f){for(;s&&s.nodeType!==o;){if(typeof s.matches=="function"&&s.matches(f))return s;s=s.parentNode}}n.exports=a},438:function(n,o,i){var a=i(828);function s(u,p,m,d,h){var v=c.apply(this,arguments);return u.addEventListener(m,v,h),{destroy:function(){u.removeEventListener(m,v,h)}}}function f(u,p,m,d,h){return typeof u.addEventListener=="function"?s.apply(null,arguments):typeof m=="function"?s.bind(null,document).apply(null,arguments):(typeof u=="string"&&(u=document.querySelectorAll(u)),Array.prototype.map.call(u,function(v){return s(v,p,m,d,h)}))}function c(u,p,m,d){return function(h){h.delegateTarget=a(h.target,p),h.delegateTarget&&d.call(u,h)}}n.exports=f},879:function(n,o){o.node=function(i){return i!==void 0&&i instanceof HTMLElement&&i.nodeType===1},o.nodeList=function(i){var a=Object.prototype.toString.call(i);return i!==void 0&&(a==="[object NodeList]"||a==="[object HTMLCollection]")&&"length"in i&&(i.length===0||o.node(i[0]))},o.string=function(i){return typeof i=="string"||i instanceof String},o.fn=function(i){var a=Object.prototype.toString.call(i);return a==="[object Function]"}},370:function(n,o,i){var a=i(879),s=i(438);function f(m,d,h){if(!m&&!d&&!h)throw new Error("Missing required arguments");if(!a.string(d))throw new TypeError("Second argument must be a String");if(!a.fn(h))throw new TypeError("Third argument must be a Function");if(a.node(m))return c(m,d,h);if(a.nodeList(m))return u(m,d,h);if(a.string(m))return p(m,d,h);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList")}function c(m,d,h){return m.addEventListener(d,h),{destroy:function(){m.removeEventListener(d,h)}}}function u(m,d,h){return Array.prototype.forEach.call(m,function(v){v.addEventListener(d,h)}),{destroy:function(){Array.prototype.forEach.call(m,function(v){v.removeEventListener(d,h)})}}}function p(m,d,h){return s(document.body,m,d,h)}n.exports=f},817:function(n){function o(i){var a;if(i.nodeName==="SELECT")i.focus(),a=i.value;else if(i.nodeName==="INPUT"||i.nodeName==="TEXTAREA"){var s=i.hasAttribute("readonly");s||i.setAttribute("readonly",""),i.select(),i.setSelectionRange(0,i.value.length),s||i.removeAttribute("readonly"),a=i.value}else{i.hasAttribute("contenteditable")&&i.focus();var f=window.getSelection(),c=document.createRange();c.selectNodeContents(i),f.removeAllRanges(),f.addRange(c),a=f.toString()}return a}n.exports=o},279:function(n){function o(){}o.prototype={on:function(i,a,s){var f=this.e||(this.e={});return(f[i]||(f[i]=[])).push({fn:a,ctx:s}),this},once:function(i,a,s){var f=this;function c(){f.off(i,c),a.apply(s,arguments)}return c._=a,this.on(i,c,s)},emit:function(i){var a=[].slice.call(arguments,1),s=((this.e||(this.e={}))[i]||[]).slice(),f=0,c=s.length;for(f;f{"use strict";/*! + * escape-html + * Copyright(c) 2012-2013 TJ Holowaychuk + * Copyright(c) 2015 Andreas Lubbe + * Copyright(c) 2015 Tiancheng "Timothy" Gu + * MIT Licensed + */var is=/["'&<>]/;Jo.exports=as;function as(e){var t=""+e,r=is.exec(t);if(!r)return t;var n,o="",i=0,a=0;for(i=r.index;i0&&i[i.length-1])&&(c[0]===6||c[0]===2)){r=0;continue}if(c[0]===3&&(!i||c[1]>i[0]&&c[1]=e.length&&(e=void 0),{value:e&&e[n++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")}function W(e,t){var r=typeof Symbol=="function"&&e[Symbol.iterator];if(!r)return e;var n=r.call(e),o,i=[],a;try{for(;(t===void 0||t-- >0)&&!(o=n.next()).done;)i.push(o.value)}catch(s){a={error:s}}finally{try{o&&!o.done&&(r=n.return)&&r.call(n)}finally{if(a)throw a.error}}return i}function D(e,t,r){if(r||arguments.length===2)for(var n=0,o=t.length,i;n1||s(m,d)})})}function s(m,d){try{f(n[m](d))}catch(h){p(i[0][3],h)}}function f(m){m.value instanceof Xe?Promise.resolve(m.value.v).then(c,u):p(i[0][2],m)}function c(m){s("next",m)}function u(m){s("throw",m)}function p(m,d){m(d),i.shift(),i.length&&s(i[0][0],i[0][1])}}function mn(e){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var t=e[Symbol.asyncIterator],r;return t?t.call(e):(e=typeof xe=="function"?xe(e):e[Symbol.iterator](),r={},n("next"),n("throw"),n("return"),r[Symbol.asyncIterator]=function(){return this},r);function n(i){r[i]=e[i]&&function(a){return new Promise(function(s,f){a=e[i](a),o(s,f,a.done,a.value)})}}function o(i,a,s,f){Promise.resolve(f).then(function(c){i({value:c,done:s})},a)}}function A(e){return typeof e=="function"}function at(e){var t=function(n){Error.call(n),n.stack=new Error().stack},r=e(t);return r.prototype=Object.create(Error.prototype),r.prototype.constructor=r,r}var $t=at(function(e){return function(r){e(this),this.message=r?r.length+` errors occurred during unsubscription: +`+r.map(function(n,o){return o+1+") "+n.toString()}).join(` + `):"",this.name="UnsubscriptionError",this.errors=r}});function De(e,t){if(e){var r=e.indexOf(t);0<=r&&e.splice(r,1)}}var Fe=function(){function e(t){this.initialTeardown=t,this.closed=!1,this._parentage=null,this._finalizers=null}return e.prototype.unsubscribe=function(){var t,r,n,o,i;if(!this.closed){this.closed=!0;var a=this._parentage;if(a)if(this._parentage=null,Array.isArray(a))try{for(var s=xe(a),f=s.next();!f.done;f=s.next()){var c=f.value;c.remove(this)}}catch(v){t={error:v}}finally{try{f&&!f.done&&(r=s.return)&&r.call(s)}finally{if(t)throw t.error}}else a.remove(this);var u=this.initialTeardown;if(A(u))try{u()}catch(v){i=v instanceof $t?v.errors:[v]}var p=this._finalizers;if(p){this._finalizers=null;try{for(var m=xe(p),d=m.next();!d.done;d=m.next()){var h=d.value;try{dn(h)}catch(v){i=i!=null?i:[],v instanceof $t?i=D(D([],W(i)),W(v.errors)):i.push(v)}}}catch(v){n={error:v}}finally{try{d&&!d.done&&(o=m.return)&&o.call(m)}finally{if(n)throw n.error}}}if(i)throw new $t(i)}},e.prototype.add=function(t){var r;if(t&&t!==this)if(this.closed)dn(t);else{if(t instanceof e){if(t.closed||t._hasParent(this))return;t._addParent(this)}(this._finalizers=(r=this._finalizers)!==null&&r!==void 0?r:[]).push(t)}},e.prototype._hasParent=function(t){var r=this._parentage;return r===t||Array.isArray(r)&&r.includes(t)},e.prototype._addParent=function(t){var r=this._parentage;this._parentage=Array.isArray(r)?(r.push(t),r):r?[r,t]:t},e.prototype._removeParent=function(t){var r=this._parentage;r===t?this._parentage=null:Array.isArray(r)&&De(r,t)},e.prototype.remove=function(t){var r=this._finalizers;r&&De(r,t),t instanceof e&&t._removeParent(this)},e.EMPTY=function(){var t=new e;return t.closed=!0,t}(),e}();var Or=Fe.EMPTY;function It(e){return e instanceof Fe||e&&"closed"in e&&A(e.remove)&&A(e.add)&&A(e.unsubscribe)}function dn(e){A(e)?e():e.unsubscribe()}var Ae={onUnhandledError:null,onStoppedNotification:null,Promise:void 0,useDeprecatedSynchronousErrorHandling:!1,useDeprecatedNextContext:!1};var st={setTimeout:function(e,t){for(var r=[],n=2;n0},enumerable:!1,configurable:!0}),t.prototype._trySubscribe=function(r){return this._throwIfClosed(),e.prototype._trySubscribe.call(this,r)},t.prototype._subscribe=function(r){return this._throwIfClosed(),this._checkFinalizedStatuses(r),this._innerSubscribe(r)},t.prototype._innerSubscribe=function(r){var n=this,o=this,i=o.hasError,a=o.isStopped,s=o.observers;return i||a?Or:(this.currentObservers=null,s.push(r),new Fe(function(){n.currentObservers=null,De(s,r)}))},t.prototype._checkFinalizedStatuses=function(r){var n=this,o=n.hasError,i=n.thrownError,a=n.isStopped;o?r.error(i):a&&r.complete()},t.prototype.asObservable=function(){var r=new U;return r.source=this,r},t.create=function(r,n){return new wn(r,n)},t}(U);var wn=function(e){ne(t,e);function t(r,n){var o=e.call(this)||this;return o.destination=r,o.source=n,o}return t.prototype.next=function(r){var n,o;(o=(n=this.destination)===null||n===void 0?void 0:n.next)===null||o===void 0||o.call(n,r)},t.prototype.error=function(r){var n,o;(o=(n=this.destination)===null||n===void 0?void 0:n.error)===null||o===void 0||o.call(n,r)},t.prototype.complete=function(){var r,n;(n=(r=this.destination)===null||r===void 0?void 0:r.complete)===null||n===void 0||n.call(r)},t.prototype._subscribe=function(r){var n,o;return(o=(n=this.source)===null||n===void 0?void 0:n.subscribe(r))!==null&&o!==void 0?o:Or},t}(E);var Et={now:function(){return(Et.delegate||Date).now()},delegate:void 0};var wt=function(e){ne(t,e);function t(r,n,o){r===void 0&&(r=1/0),n===void 0&&(n=1/0),o===void 0&&(o=Et);var i=e.call(this)||this;return i._bufferSize=r,i._windowTime=n,i._timestampProvider=o,i._buffer=[],i._infiniteTimeWindow=!0,i._infiniteTimeWindow=n===1/0,i._bufferSize=Math.max(1,r),i._windowTime=Math.max(1,n),i}return t.prototype.next=function(r){var n=this,o=n.isStopped,i=n._buffer,a=n._infiniteTimeWindow,s=n._timestampProvider,f=n._windowTime;o||(i.push(r),!a&&i.push(s.now()+f)),this._trimBuffer(),e.prototype.next.call(this,r)},t.prototype._subscribe=function(r){this._throwIfClosed(),this._trimBuffer();for(var n=this._innerSubscribe(r),o=this,i=o._infiniteTimeWindow,a=o._buffer,s=a.slice(),f=0;f0?e.prototype.requestAsyncId.call(this,r,n,o):(r.actions.push(this),r._scheduled||(r._scheduled=ut.requestAnimationFrame(function(){return r.flush(void 0)})))},t.prototype.recycleAsyncId=function(r,n,o){var i;if(o===void 0&&(o=0),o!=null?o>0:this.delay>0)return e.prototype.recycleAsyncId.call(this,r,n,o);var a=r.actions;n!=null&&((i=a[a.length-1])===null||i===void 0?void 0:i.id)!==n&&(ut.cancelAnimationFrame(n),r._scheduled=void 0)},t}(Ut);var On=function(e){ne(t,e);function t(){return e!==null&&e.apply(this,arguments)||this}return t.prototype.flush=function(r){this._active=!0;var n=this._scheduled;this._scheduled=void 0;var o=this.actions,i;r=r||o.shift();do if(i=r.execute(r.state,r.delay))break;while((r=o[0])&&r.id===n&&o.shift());if(this._active=!1,i){for(;(r=o[0])&&r.id===n&&o.shift();)r.unsubscribe();throw i}},t}(Wt);var we=new On(Tn);var R=new U(function(e){return e.complete()});function Dt(e){return e&&A(e.schedule)}function kr(e){return e[e.length-1]}function Qe(e){return A(kr(e))?e.pop():void 0}function Se(e){return Dt(kr(e))?e.pop():void 0}function Vt(e,t){return typeof kr(e)=="number"?e.pop():t}var pt=function(e){return e&&typeof e.length=="number"&&typeof e!="function"};function zt(e){return A(e==null?void 0:e.then)}function Nt(e){return A(e[ft])}function qt(e){return Symbol.asyncIterator&&A(e==null?void 0:e[Symbol.asyncIterator])}function Kt(e){return new TypeError("You provided "+(e!==null&&typeof e=="object"?"an invalid object":"'"+e+"'")+" where a stream was expected. You can provide an Observable, Promise, ReadableStream, Array, AsyncIterable, or Iterable.")}function Ki(){return typeof Symbol!="function"||!Symbol.iterator?"@@iterator":Symbol.iterator}var Qt=Ki();function Yt(e){return A(e==null?void 0:e[Qt])}function Gt(e){return ln(this,arguments,function(){var r,n,o,i;return Pt(this,function(a){switch(a.label){case 0:r=e.getReader(),a.label=1;case 1:a.trys.push([1,,9,10]),a.label=2;case 2:return[4,Xe(r.read())];case 3:return n=a.sent(),o=n.value,i=n.done,i?[4,Xe(void 0)]:[3,5];case 4:return[2,a.sent()];case 5:return[4,Xe(o)];case 6:return[4,a.sent()];case 7:return a.sent(),[3,2];case 8:return[3,10];case 9:return r.releaseLock(),[7];case 10:return[2]}})})}function Bt(e){return A(e==null?void 0:e.getReader)}function $(e){if(e instanceof U)return e;if(e!=null){if(Nt(e))return Qi(e);if(pt(e))return Yi(e);if(zt(e))return Gi(e);if(qt(e))return _n(e);if(Yt(e))return Bi(e);if(Bt(e))return Ji(e)}throw Kt(e)}function Qi(e){return new U(function(t){var r=e[ft]();if(A(r.subscribe))return r.subscribe(t);throw new TypeError("Provided object does not correctly implement Symbol.observable")})}function Yi(e){return new U(function(t){for(var r=0;r=2;return function(n){return n.pipe(e?_(function(o,i){return e(o,i,n)}):me,Oe(1),r?He(t):zn(function(){return new Xt}))}}function Nn(){for(var e=[],t=0;t=2,!0))}function fe(e){e===void 0&&(e={});var t=e.connector,r=t===void 0?function(){return new E}:t,n=e.resetOnError,o=n===void 0?!0:n,i=e.resetOnComplete,a=i===void 0?!0:i,s=e.resetOnRefCountZero,f=s===void 0?!0:s;return function(c){var u,p,m,d=0,h=!1,v=!1,B=function(){p==null||p.unsubscribe(),p=void 0},re=function(){B(),u=m=void 0,h=v=!1},z=function(){var T=u;re(),T==null||T.unsubscribe()};return g(function(T,Ke){d++,!v&&!h&&B();var We=m=m!=null?m:r();Ke.add(function(){d--,d===0&&!v&&!h&&(p=jr(z,f))}),We.subscribe(Ke),!u&&d>0&&(u=new et({next:function(Ie){return We.next(Ie)},error:function(Ie){v=!0,B(),p=jr(re,o,Ie),We.error(Ie)},complete:function(){h=!0,B(),p=jr(re,a),We.complete()}}),$(T).subscribe(u))})(c)}}function jr(e,t){for(var r=[],n=2;ne.next(document)),e}function K(e,t=document){return Array.from(t.querySelectorAll(e))}function V(e,t=document){let r=se(e,t);if(typeof r=="undefined")throw new ReferenceError(`Missing element: expected "${e}" to be present`);return r}function se(e,t=document){return t.querySelector(e)||void 0}function _e(){return document.activeElement instanceof HTMLElement&&document.activeElement||void 0}function tr(e){return L(b(document.body,"focusin"),b(document.body,"focusout")).pipe(ke(1),l(()=>{let t=_e();return typeof t!="undefined"?e.contains(t):!1}),N(e===_e()),Y())}function Be(e){return{x:e.offsetLeft,y:e.offsetTop}}function Yn(e){return L(b(window,"load"),b(window,"resize")).pipe(Ce(0,we),l(()=>Be(e)),N(Be(e)))}function rr(e){return{x:e.scrollLeft,y:e.scrollTop}}function dt(e){return L(b(e,"scroll"),b(window,"resize")).pipe(Ce(0,we),l(()=>rr(e)),N(rr(e)))}var Bn=function(){if(typeof Map!="undefined")return Map;function e(t,r){var n=-1;return t.some(function(o,i){return o[0]===r?(n=i,!0):!1}),n}return function(){function t(){this.__entries__=[]}return Object.defineProperty(t.prototype,"size",{get:function(){return this.__entries__.length},enumerable:!0,configurable:!0}),t.prototype.get=function(r){var n=e(this.__entries__,r),o=this.__entries__[n];return o&&o[1]},t.prototype.set=function(r,n){var o=e(this.__entries__,r);~o?this.__entries__[o][1]=n:this.__entries__.push([r,n])},t.prototype.delete=function(r){var n=this.__entries__,o=e(n,r);~o&&n.splice(o,1)},t.prototype.has=function(r){return!!~e(this.__entries__,r)},t.prototype.clear=function(){this.__entries__.splice(0)},t.prototype.forEach=function(r,n){n===void 0&&(n=null);for(var o=0,i=this.__entries__;o0},e.prototype.connect_=function(){!zr||this.connected_||(document.addEventListener("transitionend",this.onTransitionEnd_),window.addEventListener("resize",this.refresh),xa?(this.mutationsObserver_=new MutationObserver(this.refresh),this.mutationsObserver_.observe(document,{attributes:!0,childList:!0,characterData:!0,subtree:!0})):(document.addEventListener("DOMSubtreeModified",this.refresh),this.mutationEventsAdded_=!0),this.connected_=!0)},e.prototype.disconnect_=function(){!zr||!this.connected_||(document.removeEventListener("transitionend",this.onTransitionEnd_),window.removeEventListener("resize",this.refresh),this.mutationsObserver_&&this.mutationsObserver_.disconnect(),this.mutationEventsAdded_&&document.removeEventListener("DOMSubtreeModified",this.refresh),this.mutationsObserver_=null,this.mutationEventsAdded_=!1,this.connected_=!1)},e.prototype.onTransitionEnd_=function(t){var r=t.propertyName,n=r===void 0?"":r,o=ya.some(function(i){return!!~n.indexOf(i)});o&&this.refresh()},e.getInstance=function(){return this.instance_||(this.instance_=new e),this.instance_},e.instance_=null,e}(),Jn=function(e,t){for(var r=0,n=Object.keys(t);r0},e}(),Zn=typeof WeakMap!="undefined"?new WeakMap:new Bn,eo=function(){function e(t){if(!(this instanceof e))throw new TypeError("Cannot call a class as a function.");if(!arguments.length)throw new TypeError("1 argument required, but only 0 present.");var r=Ea.getInstance(),n=new Ra(t,r,this);Zn.set(this,n)}return e}();["observe","unobserve","disconnect"].forEach(function(e){eo.prototype[e]=function(){var t;return(t=Zn.get(this))[e].apply(t,arguments)}});var ka=function(){return typeof nr.ResizeObserver!="undefined"?nr.ResizeObserver:eo}(),to=ka;var ro=new E,Ha=I(()=>H(new to(e=>{for(let t of e)ro.next(t)}))).pipe(x(e=>L(Te,H(e)).pipe(C(()=>e.disconnect()))),J(1));function de(e){return{width:e.offsetWidth,height:e.offsetHeight}}function ge(e){return Ha.pipe(S(t=>t.observe(e)),x(t=>ro.pipe(_(({target:r})=>r===e),C(()=>t.unobserve(e)),l(()=>de(e)))),N(de(e)))}function bt(e){return{width:e.scrollWidth,height:e.scrollHeight}}function ar(e){let t=e.parentElement;for(;t&&(e.scrollWidth<=t.scrollWidth&&e.scrollHeight<=t.scrollHeight);)t=(e=t).parentElement;return t?e:void 0}var no=new E,Pa=I(()=>H(new IntersectionObserver(e=>{for(let t of e)no.next(t)},{threshold:0}))).pipe(x(e=>L(Te,H(e)).pipe(C(()=>e.disconnect()))),J(1));function sr(e){return Pa.pipe(S(t=>t.observe(e)),x(t=>no.pipe(_(({target:r})=>r===e),C(()=>t.unobserve(e)),l(({isIntersecting:r})=>r))))}function oo(e,t=16){return dt(e).pipe(l(({y:r})=>{let n=de(e),o=bt(e);return r>=o.height-n.height-t}),Y())}var cr={drawer:V("[data-md-toggle=drawer]"),search:V("[data-md-toggle=search]")};function io(e){return cr[e].checked}function qe(e,t){cr[e].checked!==t&&cr[e].click()}function je(e){let t=cr[e];return b(t,"change").pipe(l(()=>t.checked),N(t.checked))}function $a(e,t){switch(e.constructor){case HTMLInputElement:return e.type==="radio"?/^Arrow/.test(t):!0;case HTMLSelectElement:case HTMLTextAreaElement:return!0;default:return e.isContentEditable}}function Ia(){return L(b(window,"compositionstart").pipe(l(()=>!0)),b(window,"compositionend").pipe(l(()=>!1))).pipe(N(!1))}function ao(){let e=b(window,"keydown").pipe(_(t=>!(t.metaKey||t.ctrlKey)),l(t=>({mode:io("search")?"search":"global",type:t.key,claim(){t.preventDefault(),t.stopPropagation()}})),_(({mode:t,type:r})=>{if(t==="global"){let n=_e();if(typeof n!="undefined")return!$a(n,r)}return!0}),fe());return Ia().pipe(x(t=>t?R:e))}function Me(){return new URL(location.href)}function ot(e){location.href=e.href}function so(){return new E}function co(e,t){if(typeof t=="string"||typeof t=="number")e.innerHTML+=t.toString();else if(t instanceof Node)e.appendChild(t);else if(Array.isArray(t))for(let r of t)co(e,r)}function M(e,t,...r){let n=document.createElement(e);if(t)for(let o of Object.keys(t))typeof t[o]!="undefined"&&(typeof t[o]!="boolean"?n.setAttribute(o,t[o]):n.setAttribute(o,""));for(let o of r)co(n,o);return n}function fr(e){if(e>999){let t=+((e-950)%1e3>99);return`${((e+1e-6)/1e3).toFixed(t)}k`}else return e.toString()}function fo(){return location.hash.substring(1)}function uo(e){let t=M("a",{href:e});t.addEventListener("click",r=>r.stopPropagation()),t.click()}function Fa(){return b(window,"hashchange").pipe(l(fo),N(fo()),_(e=>e.length>0),J(1))}function po(){return Fa().pipe(l(e=>se(`[id="${e}"]`)),_(e=>typeof e!="undefined"))}function Nr(e){let t=matchMedia(e);return Zt(r=>t.addListener(()=>r(t.matches))).pipe(N(t.matches))}function lo(){let e=matchMedia("print");return L(b(window,"beforeprint").pipe(l(()=>!0)),b(window,"afterprint").pipe(l(()=>!1))).pipe(N(e.matches))}function qr(e,t){return e.pipe(x(r=>r?t():R))}function ur(e,t={credentials:"same-origin"}){return ve(fetch(`${e}`,t)).pipe(ce(()=>R),x(r=>r.status!==200?Tt(()=>new Error(r.statusText)):H(r)))}function Ue(e,t){return ur(e,t).pipe(x(r=>r.json()),J(1))}function mo(e,t){let r=new DOMParser;return ur(e,t).pipe(x(n=>n.text()),l(n=>r.parseFromString(n,"text/xml")),J(1))}function pr(e){let t=M("script",{src:e});return I(()=>(document.head.appendChild(t),L(b(t,"load"),b(t,"error").pipe(x(()=>Tt(()=>new ReferenceError(`Invalid script: ${e}`))))).pipe(l(()=>{}),C(()=>document.head.removeChild(t)),Oe(1))))}function ho(){return{x:Math.max(0,scrollX),y:Math.max(0,scrollY)}}function bo(){return L(b(window,"scroll",{passive:!0}),b(window,"resize",{passive:!0})).pipe(l(ho),N(ho()))}function vo(){return{width:innerWidth,height:innerHeight}}function go(){return b(window,"resize",{passive:!0}).pipe(l(vo),N(vo()))}function yo(){return Q([bo(),go()]).pipe(l(([e,t])=>({offset:e,size:t})),J(1))}function lr(e,{viewport$:t,header$:r}){let n=t.pipe(X("size")),o=Q([n,r]).pipe(l(()=>Be(e)));return Q([r,t,o]).pipe(l(([{height:i},{offset:a,size:s},{x:f,y:c}])=>({offset:{x:a.x-f,y:a.y-c+i},size:s})))}(()=>{function e(n,o){parent.postMessage(n,o||"*")}function t(...n){return n.reduce((o,i)=>o.then(()=>new Promise(a=>{let s=document.createElement("script");s.src=i,s.onload=a,document.body.appendChild(s)})),Promise.resolve())}var r=class{constructor(n){this.url=n,this.onerror=null,this.onmessage=null,this.onmessageerror=null,this.m=a=>{a.source===this.w&&(a.stopImmediatePropagation(),this.dispatchEvent(new MessageEvent("message",{data:a.data})),this.onmessage&&this.onmessage(a))},this.e=(a,s,f,c,u)=>{if(s===this.url.toString()){let p=new ErrorEvent("error",{message:a,filename:s,lineno:f,colno:c,error:u});this.dispatchEvent(p),this.onerror&&this.onerror(p)}};let o=new EventTarget;this.addEventListener=o.addEventListener.bind(o),this.removeEventListener=o.removeEventListener.bind(o),this.dispatchEvent=o.dispatchEvent.bind(o);let i=document.createElement("iframe");i.width=i.height=i.frameBorder="0",document.body.appendChild(this.iframe=i),this.w.document.open(),this.w.document.write(` + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + + + + + + +

Webhook.site CLI

+

The Webhook.site Command Line Interface listens for requests to a Webhook.site URL and forwards/redirects them to your local computer or server.

+ + + +

Star

+

Installation

+

Docker

+

After installing Docker, you can run Webhook.site CLI via docker run:

+

docker run -ti webhooksite/cli -- whcli help

+

Node.js

+

Node version 14 or greater required.

+

To install: npm install -g @webhooksite/cli

+

Then you can run e.g. whcli help

+

Environment variables

+

Some command arguments can be specified via environment variables:

+
    --token         WH_TOKEN
+    --api-key       WH_API_KEY
+    --target        WH_TARGET
+    --command       WH_COMMAND
+
+ +

General environment variables:

+

WH_LOG_LEVEL Sets log level (silent, trace, debug, info, warn, error, fatal.) Defaults to info.

+

Variable replacement

+

For some commands and arguments, runtime variables can be replaced with the standard Webhook.site Custom Actions syntax (e.g. $variable$). Global Variables are not replaced.

+

The variables that are available are the default base variables and any variables defined in a Custom Action that was run during the request.

+

Commands

+

help: List commands

+

Lists commands available to the CLI.

+

forward: Forward requests

+

The forward command listens for new incoming requests sent to your Webhook.site URL and immediately relays them to any URL you specify, or simply localhost (so it can be used as an ngrok alternative). This URL can be any URL that the machine running Webhook.site CLI can access.

+
    +
  • The token ID (--token) parameter must specify the Webhook.site URL ID (also called token ID). The token ID is the long 36-character ID at the end of your Webhook.site URL.
  • +
  • An API key (--api-key) must also be specified when the token belongs to a Webhook.site account, and can be generated from the Webhook.site Control Panel.
  • +
  • Finally, the target (--target) specifies where traffic should be redirected (defaults to https://localhost)
  • +
+

Example

+
whcli forward \
+  --token=1e25c1cb-e4d4-4399-a267-cd2cf1a6c864 \
+  --api-key=ef6ef2f8-3e48-4f77-a54c-3891dc11c05c \ 
+  --target=https://example.com
+
+

Custom Action variables are replaced in the --target argument.

+

The request method, headers and any additional path or query string parameters added to the Webhook.site URL is forwarded on to the target. For example, if the target URL is https://example.com, sending a POST request to https://webhook.site/c33f3c3e-6018-4634-b406-65338edee460/example?query=value, the target URL will also receive a POST request on https://example.com/example?query=value.

+

Docker and Localhost

+

When running Webhook.site CLI in Docker, to access the host machine, you can't use localhost or 127.0.0.1. Instead, use the special hostname host.docker.internal. More info here.

+

Self-signed certificates

+

If the target uses a self-signed certificate, you could get an error message about this. To allow self-signed certs, run whcli with the following environment variable and value:

+
NODE_TLS_REJECT_UNAUTHORIZED="0"
+
+

exec: Execute commands

+

Allows executing terminal commands for new incoming requests sent to your Webhook.site URL. Custom Action variables are replaced in the --command argument.

+

Example

+
whcli exec \
+  --token=1e25c1cb-e4d4-4399-a267-cd2cf1a6c864 \
+  --api-key=ef6ef2f8-3e48-4f77-a54c-3891dc11c05c \ 
+  --command='ping $request.ip$'
+
+ +
+
+ + + Last update: + April 15, 2024 11:25:37 + + + +
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/custom-actions.html b/custom-actions.html new file mode 100644 index 0000000..649e1d7 --- /dev/null +++ b/custom-actions.html @@ -0,0 +1,1184 @@ + + + + + + + + + + + + + + + + + + + + + + + + Custom Actions - Webhook.site Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + + + + + + +

Custom Actions

+

+ Custom Actions editor screenshot

+

With Custom Actions, it is possible to create a workflow out of a set of actions that are executed whenever a Webhook.site URL receives a request or email.

+

Using this functionality, you can connect APIs that aren't compatible, convert a HTTP request to an email or vice versa, build workflows that would otherwise require a developer, and much, much more.

+

Demos

+

JavaScript, X and Schedules

+

In this video I'm doing a quick demo of how I used Webhook.site to set up a workflow to post updates from my news page automatically to my X/Twitter account. I used the actions JavaScript, Conditions, X Post, and Store Global Variable.

+

+

JSONPath and Google Sheets

+

In the following demo, webshop order details are received in a webhook. We then use Extract JSONPath and Google Sheets actions to insert their name in a Google Sheet. It also shows how variables interact with downstream actions.

+

+

Templates

+

If you use the same set of Custom Actions often, you can create a Template that contains a copy of one or more Custom Actions, along with a set of Predefined Variables.

+

You can then use this template by creating an Import Template action.

+

Creating a Template

+

To create a Template, click the Create Template button at the bottom of the Custom Actions overlay. Then enter a name for the template and select which actions should be copied to the template. If your template actions e.g. depend on variables pre-existing, like configuration data, you can add one or more Predefined Variables. These are available to the actions in the Template, but also to any subsequent actions coming after the Import Template action.

+

Predefined Variables can be updated in the Control Panel.

+

Changes to the actions that the Template was created from do not automatically carry over to the template. Instead, Templates can be updated post-creation by overwriting them with a new set of actions.

+

Templates can also be managed using the Template API.

+

Repeating Actions

+

Webhook.site allows some action types to be repeating, which makes Webhook.site "loop over" one or more values without needing to use scripts.

+

+

Currently, repetition is only supported by the Extract JSONPath and Extract Regex action types.

+

Currently, the maximum amount of items that are supported is 100 to prevent abuse. This limit may be raised in the future. Items above that are ignored.

+

The repeating action should be ordered before the actions that are to be repeated. The actions that are repeated will run for each item that is extracted, using the same variable name.

+

Queued Actions

+

+ Custom Actions editor screenshot

+

By checking the Queued checkbox when creating a Custom Action, Webhook.site will run the action in an asynchronous background queue.

+

This is useful when you need your Webhook.site URL to respond quickly, but your Custom Actions are taking a long time to run. For example, if your Webhook.site URL should respond in 5 seconds, but you need to call an endpoint with a HTTP Request action that responds in 10 seconds, you can queue the HTTP Request action.

+

Additionally, you can specify an amount of seconds to wait until the action is executed. To do this, enter an amount of seconds in the Seconds textbox next to the Queue checkbox.

+

As the queued action will inherit the execution scope up until the action, there are a few things to be aware of when using Queued Actions:

+
    +
  • Variables defined in non-queued actions ordered before the queued action will be available to the action.
  • +
  • If several consecutive actions are marked as queued, and their delay is identical, they will pass variables and execute in order.
  • +
  • Variables defined by a queued action are not available to non-queued actions coming after it. You cannot, for example, mark a HTTP Request action as queued and use the response in a Modify Response action.
  • +
  • The amount of time until the queued actions are executed can vary by a few seconds.
  • +
+ +
+
+ + + Last update: + April 24, 2024 09:03:55 + + + +
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/custom-actions/action-types.html b/custom-actions/action-types.html new file mode 100644 index 0000000..07e6539 --- /dev/null +++ b/custom-actions/action-types.html @@ -0,0 +1,2728 @@ + + + + + + + + + + + + + + + + + + + + + + + + Action Types - Webhook.site Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + + + + + + +

Action Types

+ +

WebhookScript

+

"WebhookScript" Custom Action screenshot

+

Executes custom scripts using a scripting language that's very similar to JavaScript and PHP. More information here

+

Text

+

Extract JSONPath

+

This action runs a JSONPath query on the contents of a request. With it, you can extract any data from a JSON document and store it in a variable, which can then be used in a downstream action.

+

JSONPath is very similar to the jq commandline utility.

+
JSONPath Examples
+

Example data:

+
{
+  "store": {
+    "name": "Cool Books Ltd",
+    "books": [
+      {
+        "title": "12 Rules for Life",
+        "author": "Jordan B. Peterson",
+        "author.age": 60,
+        "price": 10,
+        "isbn": "13123123123"
+      },
+      {
+        "title": "How to Win Friends and Influence People",
+        "author": "Dale Carnegie",
+        "price": 9,
+        "isbn": "23482394"
+      }
+    ]
+  }
+}
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
JSONPathResult
.store.namename property of store object
.store.books[0]["author.age"]author age of first book (bracket syntax can be useful for e.g. keys containing periods)
$.store.books[*].authorthe authors of all books in the store
$..authorall authors
$.store..pricethe price of everything in the store.
$..books[2]the third book
$..books[(@.length-1)]the last book in order.
$..books[-1:]the last book in order.
$..books[0,1]the first two books
$..books[:2]the first two books
$..books[::2]every second book starting from first one
$..books[1:6:3]every third book starting from 1 till 6
$..books[?(@.isbn)]filter all books with isbn number property
$..books[?(@.isbn != '')]filter all books with isbn that isn't null or "" (empty string.) (Bracket syntax can also be used here, e.g. .values[?(@['my value'] != '')])
$..books[?(@.price<10)]filter all books cheaper than 10
$..*all elements in the data (recursively extracted)
+
JSONPath Syntax
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SymbolDescription
$The root object/element (not strictly necessary)
@The current object/element
. or []Child operator
..Recursive descent
*Wildcard. All child elements regardless their index.
[,]Array indices as a set
[start:end:step]Array slice operator borrowed from ES4/Python.
?()Filters a result set by a script expression
()Uses the result of a "script" expression as the index
+

For more details on what's possible with JSONPath, take a look at the docs.

+

As you start entering a JSONPath, the results are validated and shown next to the input field.

+

Auto JSON

+

This action automatically converts JSON data to Webhook.site Variables, and can be used as an alternative for Extract JSONPath when there's a large amount of variables that need to be extracted.

+

Per default, the action works on the JSON found in the $request.content$ variable, e.g. the request body data.

+

If the JSONPath parameter is specified, this can be used to limit the variable creation to only the subset of data specified by the JSONPath query.

+
Auto JSON Example
+

If the following data is specified in the Source parameter:

+
{
+  "Actors": [
+    {
+      "name": "Tom Cruise",
+      "age": 56,
+      "Born At": "Syracuse, NY",
+      "Birthdate": "July 3, 1962",
+      "photo": "https://jsonformatter.org/img/tom-cruise.jpg"
+    },
+    {
+      "name": "Robert Downey Jr.",
+      "age": 53,
+      "Born At": "New York City, NY",
+      "Birthdate": "April 4, 1965",
+      "photo": "https://jsonformatter.org/img/Robert-Downey-Jr.jpg"
+    }
+  ]
+}
+
+

If the JSONPath parameter is empty, the following 10 variables will be created:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Variable NameValue
$json.Actors.0.name$Tom Cruise
$json.Actors.0.age$56
$json.Actors.0.Born At$Syracuse, NY
$json.Actors.0.Birthdate$July 3, 1962
$json.Actors.0.photo$https://example.com/tom-cruise.jpg
$json.Actors.1.name$Robert Downey Jr.
$json.Actors.1.age$53
$json.Actors.1.Born At$New York City, NY
$json.Actors.1.Birthdate$April 4, 1965
$json.Actors.1.photo$https://example.com/Robert-Downey-Jr.jpg
+

If the JSONPath parameter is set to .Actors.0, only the following 5 variables are created:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Variable NameValue
$json.0.name$Tom Cruise
$json.0.age$56
$json.0.Born At$Syracuse, NY
$json.0.Birthdate$July 3, 1962
$json.0.photo$https://example.com/tom-cruise.jpg
+

Extract Regex

+

This action runs a Regex (regular expression) query on the contents of a request. With it, you can extract any data from a text document and store it in a variable, which can then be used in a downstream action.

+

As you start entering a Regex, the results are validated and shown next to the input field.

+

Extract XPath

+

Similar to the Extract JSONPath Custom Action, Extract XPath lets you extract values from an XML or HTML document and save the result as a variable.

+
XPath Examples
+

The following examples are based on this XML document:

+
<?xml version="1.0"?>
+<organization name="ExampleCo">
+  <employees>
+    <employee id="1">Jack</employee>
+    <employee id="2">Ann</employee>
+  </employees>
+</organization>
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Example XPathNotesResult
/organizationFinds all content within the organization elementJack
Ann
//employee[@id != 1]// traverses all <employee> elements in document, the @id query selects all except those with id=1Jack
/organization/@name@name to get the "name" property of the elementExampleCo
/organization/employees/employee[2][2] specifies 2nd elementAnn
/organization/employees/employee[2]/@idGet the "id" property of second employee element2
/organization/employees/employee[@id=1]Employee element with id property equal to "1"Jack
/organization/employees/employee[last()]Last employee elementAnn
//employee[contains(@id, "2")]Employee within any parent element where id contains "2"Ann
+

For more examples, see W3CSchools or XPath Cheatsheet

+

Replace Text

+

An action that allows replacing multiple inputs to a string with specified replacements. Additionally, Webhook.site will replace all variables in the source text as well as the text being replaced, and the replacement.

+

Split Text

+

Split text into multiple variables. Using hello,world as Source, and , as Delimiter, 2 variables will be created: $variable.1$ is "hello" and $variable.2$ is "world".

+

Map Text

+

Sets a variable depending on what maps to the source value and operator.

+

If we set Source to John, Operator to ends with, Variable Name to $user_id$, Default to unknown, and add a mapping of From: John -> To: 123, then the variable name $user_id$ would be set to 123.

+

If the Source had been Jack, $user_id$ would have been set to unknown.

+

Network

+

HTTP Request

+

This will send a HTTP/HTTPS request from the Webhook.site cloud.

+

The HTTP Request action has several modes:

+
    +
  • Text: In the default text mode, this allows sending plain-text content, but also data like JSON and XML.
  • +
  • Multipart: With Multipart selected, it is possble to build a form/multipart request and send form data and files. Note that the Filename and Content-Type fields are not required.
  • +
  • URL Encoded: In URL Encoded mode, the keys and values are sent using URL Encoding.
  • +
  • Forward: In forward mode, all data sent to the Webhook.site URL is forwarded here, including the HTTP method, query strings, headers and body data. It is possible to overwrite the method and append headers. To forward the HTTP method, set the Method dropdown to the blank option.
  • +
+

The response of the request is stored in a series of variable names prefixed with a value of your choosing. The following variables are set after the request has been fired:

+
    +
  • $your_prefix.content$ - response body content
  • +
  • $your_prefix.status$ - response status code
  • +
  • $your_prefix.headers$ - response headers
  • +
  • $your_prefix.url$ - the URL the request was sent to
  • +
  • $your_prefix.error$ - if the request resulted in an error, it's stored in this variable.
  • +
+

Send Email

+

This will send a email with variable contents from the Webhook.site cloud. Variables extracted previously can be used.

+

Send Email (SMTP)

+

This will send a email with variable contents from your own email provider. Variables extracted previously can be used.

+

Gmail and Google Workspace

+

For Gmail, the following specific setup is required:

+
    +
  • Hostname: smtp.gmail.com
  • +
  • Port:587
  • +
  • Username: youraccount@gmail.com or youraccount@example.com (replace with your Gmail address)
  • +
  • Password: You must create a Mail App Password
  • +
  • Encryption: TLS
  • +
+

Run SSH Command

+

Allows you to run one or more SSH command on a server. Webhook.site captures the output (stdout), stderr and the command exit code as Variables that can be used in downstream actions:

+
    +
  • $ssh.stdout$
  • +
  • $ssh.stderr$
  • +
  • $ssh.exit$
  • +
+

We recommend authenticating using a pre-generated keypair, which can be created under Control Panel -> Providers.

+

SFTP Upload

+

Allows uploading a file to a SFTP (SSH) server, specifying a hostname, port, username, password, relative path to the file. The file content can be specified, in which Variables are replaced.

+

We recommend authenticating using a pre-generated keypair, which can be created under Control Panel -> Providers.

+

FTP(S) Upload

+

Allows uploading a file to a FTP or FTPS (FTP with TLS/SSL) server, specifying a hostname, port, username, password, relative path to the file, whether to use SSL and whether to use passive mode. Finally, the file content can be specified, in which Variables are replaced.

+

We recommend storing the password as a Global Variable.

+

Database Query

+

Allows running a database query, with support for fetching out data in a series of variables. We recommend storing the password as a Global Variable.

+

Supported Database Servers

+

Currently supported are:

+
    +
  • PostgreSQL
  • +
  • MySQL
  • +
+

If your database server is not on the list, please contact support.

+

Using Parameters

+

When using e.g. INSERT or UPDATE statements, we strongly recommend using parameters for each column value. Doing this, you avoid SQL injection attacks and other issues when using user-submitted data (e.g. via Variables), or even just data containing special characters like quotes, that could otherwise break a query.

+

Each parameter name should start with a colon (:) and be a single word. You can then reference these parameters inside the query, like in the following example:

+

+

Fetching data

+

When fetching data using e.g. SELECT statements, Webhook.site automatically inserts data in a series of Custom Action Variables, which are then available to downstream actions.

+

For example, when fetching rows from the following table:

+

+

Using the following statement:

+
select * from employees
+
+

If the variable name prefix would be set to output, the following variables would be created containing specific values:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Variable NameValue
$output.0.id$1
$output.0.fname$Simon
$output.0.lname$Fredsted
$output.0.title$Founder
$output.1.id$2
$output.1.fname$Jack
$output.1.lname$Daniels
$output.1.title$Assistant
+

Additionally, a variable would be created with the name $output.json$ containing the data in JSON format:

+
[                              
+  {
+    "id": 1,
+    "fname": "Simon",
+    "lname": "Fredsted",
+    "title": "Founder"
+  },
+  {
+    "id": 2,
+    "fname": "Jack",
+    "lname": "Daniels",
+    "title": "Assistant"
+  }
+]
+
+

Behavior

+

Don't Save

+

Marks the request so it is not saved in Webhook.site, which is useful (especially in combination with Conditions) when receiving a large amount of requests.

+

Log

+

Adds a custom log entry to the Request's action output.

+

Modify Response

+

This action can be used to modify the response of the Webhook.site URL based on the input.

+

Rate Limit

+

This action can be used to allow a specific amount of requests in a specific amount of time per a given IP.

+

If the IP is rate limited, the URL will respond with a HTTP 429, action execution is stopped, and the request is not saved in Webhook.site.

+

Stop

+

Immediately stops Custom Action execution and returns the default response.

+

Logic

+

Conditions

+

"Condition" Custom Action screenshot

+

Useful if you need to validate that the request does or does not conform to certain criteria, the Condition action will either stop or continue based on a condition.

+

In both the input and the value fields, variables will be replaced (including Global Variables from the Control Panel), so you can compare e.g. JSONPath or Regex values - or even values from a previous HTTP request that was sent.

+

Currently, three actions are provided: use result, stop and continue. Use Result allows using the Condition result in further actions. Stop will stop further action execution of the condition is a match. Continue will only continue further execution if the condition is a match, and otherwise stop.

+

The following "operators" are available:

+
    +
  • is equal to
  • +
  • is not equal to
  • +
  • starts with
  • +
  • ends with
  • +
  • contains
  • +
  • does not contain
  • +
  • is greater than
  • +
  • is greater than or equal to
  • +
  • is less than
  • +
  • is less than or equal to
  • +
+

The "result" of the condition will be logged below the request details, so you can see what happened.

+

To use the result of the Condition, select it in the "only run when condition passes" checkbox:

+

+

Tip: To check if a Variable is set (or exists), you must enter the variable name in both input and value fields and use the "is not equal to" operator, since non-existing variables are not replaced.

+

JavaScript

+

With the JavaScript action, you can execute most kinds of JavaScript/Node.js code using a Node.js 20.10.0 sandbox.

+

+

Limitations

+

This feature is still in beta as of late 2023, and we expect to add more features in the coming months.

+

Currently identified limitations include:

+

General Functions

+

console.log(line) / echo(line) - log a string to Action output

+

set(variable_name, value) - sets a Webhook.site variable for use in downstream actions

+

The following code would set the variable $myvar$ to value:

+
set('myvar', 'value')
+
+

get(variable_name) - gets a Webhook.site variable (except Global Variables; use the global() function for that)

+

variables - global array variable containing Webhook.site variables

+

global(variable_name) - retrieves the value of a Webhook.site Global Variable. Must be used async. Returns null if variable doesn't exist.

+
echo(await global('my-variable'))
+
+

store(variable_name, value) - stores the value of a Webhook.site Global Variable. Must be used async.

+

stop() - stops action execution and return response

+

dont_save() - marks current requests as Don't Save, so it won't be stored or shown in the Webhook.site requests list

+

respond(content, status, headers) - stops action execution and return response

+
respond('OK', 200, ['Content-Type: text/plain'])
+
+

set_response(content, status, headers) - sets response, but doesn't stop action execution

+

Utility Modules

+

Code executed with the Webhook.site JavaScript action runs in a sandbox where the following utility libraries are available by using the require() function:

+
    +
  • axios - HTTP Client +
    axios = require('axios')
    +await axios.get('https://webhook.site')
    +   .then(response => {
    +     console.log(response.status)
    +   });
    +// 200
    +
  • +
  • lodash - General utility library +
    _ = require('lodash')
    +console.log(_.last([1, 2, 3]))
    +// 3
    +
  • +
  • dayjs - Date and time manipulation +
    dayjs = require('dayjs')
    +console.log(dayjs(1318781876406))
    +// "2011-10-16T16:17:56.406Z"
    +
  • +
  • cheerio - JQuery-like HTML selector library +
    cheerio = require('cheerio')
    +const $ = cheerio.load('<ul id="fruits">banana</ul>');
    +console.log($('#fruits').text());
    +// banana
    +
  • +
  • jsonpath - JSONPath query library +
    jsonpath = require('jsonpath')
    +var cities = [
    +  { name: "London", "population": 8615246 },
    +  { name: "Berlin", "population": 3517424 },
    +];
    +
    +var names = jsonpath.query(cities, '$..name');
    +
    +console.log(names)
    +// ["London","Berlin"]
    +
  • +
  • crypto – Node.js built-in crypto library +
    crypto = require('crypto');
    +
    +const secret = 'abcdefg';
    +const hash = crypto.createHmac('sha256', secret)
    +               .update('I love Webhook.site')
    +               .digest('hex');
    +
    +console.log(hash);
    +// 1745c764246c2782ebf97e25b89547a92571f19d41846b42880d3815480f098e
    +
  • +
  • faker - Seed data generator +
    faker = require('faker')
    +
    +console.log(faker.internet.email())
    +// Ila_Gutkowski9@yahoo.com
    +
  • +
+

Do you need a library that isn't listed here? Please contact support!

+

WebhookScript

+

For more information about WebhookScript, see the dedicated page.

+

Set Variable

+

Defines (or overwrites) a variable that's available to downstream actions. The variable is not saved permanently as a Global Variable.

+

There are three modes:

+
    +
  • Text: Using the default "Text" mode, the variable is simply set to what's entered in the Text field.
  • +
  • Random: When using the "Random" mode, you can generate a random string for e.g. one-time identifiers and passwords.
  • +
  • Date: Generate date strings specifying a custom input date and an output format - defaults to ISO-8601 format.
  • +
+

Store Global Variable

+

Saves (or overwrites) a Global Variable that's saved permanently and available to all URLs in your account. If you don't need to save the variable permanently, you should use the Set Runtime Variable instead.

+

Image Handling

+

Resize Image

+

Takes an image from either a URL or raw image data from e.g. a file upload, email attachment, request response or another action such as Dropbox.

+

You can enter both width and height to contrain the image in both dimensions, or enter a single dimension.

+

Check "Keep Aspect Ratio" so that the image keeps the aspect ratio, but doesn't exceed the height and width constraints.

+

Google Sheets

+
+

Note

+

Google Sheets should not be used as a database, and have low usage limits. If you need to import on the order of thousands +of rows or make thousands of calls a day, Google Sheets cannot be used. We recommend using a database like Postgres in conjunction with the Database Query action.

+
+

Google Sheets Custom Actions lets you manipulate and retrieve values from a Google Sheet.

+

The following Google Sheets Custom Actions are available:

+
    +
  • Add Row - appends one or more new rows to an existing spreadsheet
  • +
  • Update Row - updates one or more cells in an existing spreadsheet
  • +
  • Get Values - retrieves one or more cell values from an existing spreadsheet
  • +
+

To start, you need to make sure that you have connected a Google account in the Control Panel, available here.

+

After that, you can select the account in the dropdown when creating the Custom Action.

+

Usage Limits

+

It is important to note that Google will block Write requests (i.e. adding or updating rows) at 60 requests per minute. After that, the action will temporarily fail with the following error message:

+
Quota exceeded for quota metric 'Write requests' and limit 'Write requests per minute per user' of service 'sheets.googleapis.com' for consumer
+
+

Therefore, for importing mass amounts of data in a short timespan, Google Sheets is not recommended. Instead, we recommend using the Database Query action.

+

Additionally, Webhook.site will automatically disable Google Sheets actions that continously fail due to e.g. quota errors.

+

Specifying the spreadsheet

+

When specifying the spreadsheet, you can either just copy/paste the spreadsheet URL or enter the spreadsheet ID. Variables can be used to specify the spreadsheet.

+

Ranges

+

All actions must specify a range, which behaves similar in all actions. For the Add Row action, Google Sheets will automatically find a "table" (e.g. a homogenous mass of data) and add the values at the bottom.

+

A range is the same query as in Google Sheets, e.g. to select A1-C3 in Worksheet "Example", enter 'Example'!A1:C3.

+

Values

+

When inserting or updating values, you can either enter a value in the text field, or supply multiple cells and/or rows using JSON. To insert two rows, the JSON would be ["cell 1", "cell 2"].

+

Variables

+

The Get Values Action allows you to define variables based on the output. Since this action can return multiple pieces of data, multiple variables are created.

+

For example, if you select two columns and two rows, e.g. A1:B2, four variables would be defined:

+
    +
  1. variable_name.0.0 = value of A1
  2. +
  3. variable_name.0.1 = value of A2
  4. +
  5. variable_name.1.0 = value of B1
  6. +
  7. variable_name.1.1 = value of B2
  8. +
+

Additionally, the data is available in JSON, with the variable_name.json variable being defined, and continuing with the example above, would contain the following JSON:

+
[
+  ["A1","A2"],
+  ["B1","B2"]
+]
+
+

Microsoft

+

OneDrive

+

With Webhook.site, you can now use your Microsoft account to upload and download files in your OneDrive account using the Upload and Download Custom Actions.

+

Excel

+

Using the Add Rows and Get Values actions, Webhook.site now allows using your Microsoft account to append and retrieve data from Excel worksheets in your OneDrive account.

+

Amazon Web Services (AWS)

+

S3

+

The following actions are available for AWS S3:

+
    +
  • Create Bucket
  • +
  • Create Object
  • +
  • Delete Object
  • +
  • Get Object (retrieves object contents to a Variable)
  • +
+

In addition to the "official" Amazon endpoints, Webhook.site also supports S3-compatible storages like DigitalOcean, MinIO, Wasabi and more. The endpoint can be specified when setting up the account in Control Panel.

+

CloudFront

+

The "Create Invalidation" action allows you to dynamically create a CloudFront cache invalidation as a Custom Action. Both the Distribution ID and the paths to be invalidated are replaced with Webhook.site Variables.

+

Discord

+

With the Discord Custom Action, you can send messages to a specified channel (Each bot account uses a specific channel, so you can connect more accounts to send to different channels or servers.) In addition, you can choose a custom username and avatar image for the bot user.

+

"Discord" Custom Action screenshot

+

Slack

+

With the Slack Custom Action, you can easily use Slack's Webhook URLs to send messages to a channel.

+

Dropbox

+

The Dropbox integration has access to the entire contents of your dropbox, and currently the following actions are available:

+
    +
  • Create Folder
  • +
  • Download File
  • +
  • Upload File
  • +
  • Delete File
  • +
  • Delete Folder
  • +
  • Get Link - creates a temporary download link for any file in your Dropbox, and saves it in a variable.
  • +
+

X (formerly known as Twitter)

+

The X Integration supports the following actions using X's API:

+
    +
  • Post Tweet
  • +
+

RabbitMQ

+

The RabbitMQ Integration allows you to publish and consume messages from a RabbitMQ queue by specifying the server connection details.

+

Pushed

+

With the Send Push Notification action, you can easily send push notifications to your mobile devices using your Pushed.co account.

+

"Pushed" Custom Action screenshot

+

With a free Pushed.co account, you can send up to 1000 push notifications a month.

+

ntfy.sh

+

Allows you to easily send push notifications to your browser, phone, watch, etc. Simply download the ntfy.sh app, subscribe to your topic name and send a message to the topic name via this Custom Action. No account required.

+

App download links:

+ + +
+
+ + + Last update: + April 15, 2024 12:58:43 + + + +
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/custom-actions/examples.html b/custom-actions/examples.html new file mode 100644 index 0000000..d8dcde0 --- /dev/null +++ b/custom-actions/examples.html @@ -0,0 +1,1045 @@ + + + + + + + + + + + + + + + + + + + + + + + + Examples - Webhook.site Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + + + + + + +

Examples

+ +

Adding rows to an Airtable Base

+

While Webhook.site doesn't have a native integration with Airtable, due to the simple API, it's exceedingly easy to add rows to a so-called Airtable Base.

+

First, create an API key on your Account page: https://airtable.com/account.

+

Next, go to Airtable's API documentation and select the Base you want to interact with: https://airtable.com/api. In the upper right corner, make sure show API key is checked.

+

Creating an Airtable row using the API documentation

+

If you then scroll down to the Create records section, you can essentially copy everything over to a Send Request action.

+

Things to note:

+
    +
  • The Request Method should be POST
  • +
  • Make sure you copy everything between --data ' and the final ' (quote) character
  • +
  • Also make sure that quotes aren't included in the two header lines
  • +
+ +
+
+ + + Last update: + April 6, 2024 10:34:57 + + + +
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/custom-actions/variables.html b/custom-actions/variables.html new file mode 100644 index 0000000..3333fa7 --- /dev/null +++ b/custom-actions/variables.html @@ -0,0 +1,1292 @@ + + + + + + + + + + + + + + + + + + + + + + + + Variables - Webhook.site Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + + + + + + +

Variables

+ +

Variables are the most important part of Custom Actions, and are characterized by a name surrounded by two dollar signs: $example$. Variables can be used in any field that has a ⓥ icon in the editor. They act as placeholders that are replaced by dynamic content as the request or email is received.

+

Each request or email has a set of Base Variables (see below) that contain information like the request IP, method, headers, query string values, form values and the request content. To see a list of variables, click the Variables button in the editor. Clicking on a variable copies it to the clipboard.

+

Variables Menu

+

Many of the the available Custom Actions can register a variable during the runtime of the actions, so for example you can register the result of a JSONPath query and use it in a "Modify Response" action to make the response dynamic, or even use it to send a request to another HTTP address, and then use the response of that. Files can referred to and be used through Variables.

+

This works since Custom Actions are executed synchronously in a chain, sharing data as they're being executed.

+

The format of variables are dollar signs surrounded by a word, for example: $example$.

+

Global Variables

+

In Webhook.site Control Panel, you can define Global Variables which can be accessed between all URLs and used in Schedules. Global Variables are permanent.

+

Global Variables can also be created, modified or deleted using Custom Actions, including in WebhookScript and JavaScript actions.

+

Additionally, Global Variables can be managed using the Webhook.site API.

+

Variable Modifiers

+

Adding specific suffixes to variable names will let you process the value in the following ways:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
VariableExample InputExample OutputDescription
$example${"json": "value"}{"json": "value"}no modifier
$example.json${"json": "value"}{\"json\": \"value\"}Escapes all special JSON characters, allowing to use any string in a JSON object. Escaped characters include \b, \f, \n, \r, \t, ", \
$example.html_encode$<p>some html</p>&lt;p&gt;some html&lt;/p&gt;Escapes all special HTML characters
$example.html_decode$&lt;p&gt;some html&lt;/p&gt;<p>some html</p>Replaces all escaped HTML escapes with normal characters
$example.html_strip$<p>some html</p>some htmlRemoves all HTML tags from input string
$example.base64_encode${"json": "<b>value</b>"}eyJqc29uIjogIjxiPnZhbHVlPC9iPiJ9Cg==Encodes the variable to base64
$example.base64_decode$eyJqc29uIjogIjxiPnZhbHVlPC9iPiJ9Cg=={"json": "<b>value</b>"}Decodes a base64 encoded string
$example.url_encode${"json": "value"}%7B%22json%22%3A+%22value%22%7DEscapes all special HTTP URL characters
$example.url_decode$%7B%22json%22%3A+%22value%22%7D{"json": "value"}Replaces all special HTTP URL escapes with normal characters
+

Base Variables

+

These variables are automatically available for each request or email. Different variables are available depending on the type.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Variable NameAvailable ForDescription
request.uuidAllThe UUID of the request
request.token_idAllThe Token UUID (URL ID) of the request
request.contentAllThe body content of the request
request.dateAllCreation date in Y-m-d H:m:s format
request.dateAllCreation date in UNIX timestamp format
request.hostnameAllHostname of the request (usually webhook.site)
request.header.[name]AllCreated for each HTTP header
request.sizeAllRequest body size in bytes
request.typeAllRequest type (email or web)
request.file.[name].filenameAllCreated for each file upload, with name being the input name property. Contains the client file name
request.file.[name].sizeAllContains the file size in bytes
request.file.[name].contentAllContains the file content
request.file.[name].content_typeAllContains the file content type (e.g. image/png)
request.file.[name].idAllContains the Webhook.site file ID
request.file.[name].linkAllContains the direct download link to the file from Webhook.site's server.
request.query.[name]WebCreated for each query string (e.g. ?name=value)
request.form.[name]WebCreated for each form field
request.ipWebIP of the host making the request
request.user_agentWebUser agent header
request.urlWebFull URL of the request (e.g. https://webhook.site/xxx-xxx...)
request.pathWebSub-path of URL, after the token ID. Defaults to /
request.queryWebFull query string of the URL
request.methodWebHTTP method (GET, POST, etc.)
request.senderEmailSender address
request.message_idEmailEmail message ID
request.text_contentEmailParsed plaintext content
request.destinationsEmailComma separated list of recipients.
request.checks.[name]EmailTrue or false for email checks (DKIM, SPF, etc.)
+ +
+
+ + + Last update: + April 15, 2024 11:25:37 + + + +
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/dnshook.html b/dnshook.html new file mode 100644 index 0000000..2064350 --- /dev/null +++ b/dnshook.html @@ -0,0 +1,1118 @@ + + + + + + + + + + + + + + + + + + + + + + DNSHook - Webhook.site Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + + + + + + +

DNSHook by Webhook.site

+

What is DNSHook?

+

Webhook.site DNSHook is a type of hook, like webhooks and emailhooks, that on Webhook.site will automatically show all DNS requests to a unique DNS name and all its subdomains.

+

DNSHooks can be used to send data solely via DNS. DNSHooks can also be used as a canary token as DNS can be useful in cases where it can bypass firewalls, for example.

+

+

Create DNS workflows with Custom Actions

+

You can even create workflows from DNSHook requests with Custom Actions.

+

For example, you can send a notification to your phone whenever a specific subdomain has had its DNS looked up via the Ntfy action.

+

Receive data via DNS

+

As all subdomains are also logged and shown on Webhook.site, you can send data in DNSHooks by e.g. base64-encoding a subdomain. For example, the string hello world can be encoded in a DNS lookup as the following.

+
aGVsbG8gd29ybGQ.47bb8761-e40b-42c2-8c98-a448f492df70.dnshook.site
+
+

(In this case, aGVsbG8gd29ybGQ base64-decodes to hello world and 47bb8761-e40b-42c2-8c98-a448f492df70 is the ID of the Webhook.site token/URL.)

+

Indeed, you can even use different record types, like CNAME and MX, as flags to transfer information to Webhook.site.

+

Send DNS Response

+

You can also set the DNS response dynamically by using the URL response in the following format. You can return one or more responses.

+
[
+    {
+        "type": "a",
+        "value": "127.0.0.1"
+    },
+    {
+        "type": "cname",
+        "value": "example.com."
+    },
+    {
+        "type": "txt",
+        "value": "hello world"
+    }
+]
+
+

To set the response, either enter the JSON in EditContent, or use the Modify Response Custom Action and setting the Response Body field.

+

+

type can be one of the following:

+
    +
  • a
  • +
  • cname
  • +
  • txt
  • +
+

Note: If the response isn't valid (e.g. invalid JSON, using a domain name in an A record), no response is returned. It is currently not possible to be notified of DNS parsing errors, so make sure to test this well.

+

For txt responses, multiple lines can be sent by separating with \n (newline).

+ +
+
+ + + Last update: + April 9, 2024 08:30:15 + + + +
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/faq.html b/faq.html new file mode 100644 index 0000000..784fff9 --- /dev/null +++ b/faq.html @@ -0,0 +1,1544 @@ + + + + + + + + + + + + + + + + + + + + + + + + FAQ - Webhook.site Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + + + + + + +

Webhook.site Frequently Asked Questions

+

What's a webhook?

+

The term 'webhook' refers to the general technology of Web-based systems communication.

+

In short, many systems (e.g. a payment platform and a customer management system) communicate with each other by sending Web requests back and forth, e.g. from https://paymentsys.example to https://customersys.example/register-payment.

+

We don't offer support or help with general questions or issues with webhooks. More about webhooks.

+

What's Webhook.site?

+

Webhook.site is a tool for building software that use webhooks, either by allowing developers to inspect the data that's being sent via a webhook, but also helps users create workflows that respond to and interact with webhooks from various systems.

+

With Webhook.site, users instantly get a unique, random URL and e-mail address. Everything that's sent to these addresses are shown instantly. With this, users can test and debug Webhooks and HTTP requests, as well as create workflows using the Custom Actions graphical builder or WebhookScript, a simple scripting language, to transform, validate and process HTTP requests in a variety of ways – without setting up and maintaining your own infrastructure.

+

Webhook.site company stats as of March 2024:

+
    +
  • Registered corporation since August 2020
  • +
  • 250.000+ monthly unique users
  • +
  • 1600+ subscribed customers
  • +
  • Handles more than 250 million requests per day
  • +
+

Is my data private?

+

Yes. Per default, all URLs associated with a paid Webhook.site subscription are protected with login. Additionally, users can decide exactly how much (or little) data Webhook.site stores, either by amount of requests/emails or

+

For free users, data is accessible to anyone who knows the ID of the URL.

+

Can I use Webhook.site for production workloads?

+

Yes. Thousands of our customers use Webhook.site to build workflows that help their business, without needing to hire a programmer or pay for and setup servers. We take care of the infrastructure so you can build what you need.

+

How much data does Webhook.site store?

+

For each URL associated with a Webhook.site Pro account, Webhook.site makes the latest 10.000 requests or emails available. Old requests are automatically rotated/purged periodically.

+

For free users, the amount is 100 and old requests are not automatically rotated. Instead, the URL stops accepting new requests after the limit has been met.

+

How long is data stored on Webhook.site?

+

For Free users, the URL – and its data – is automatically removed after 7 days with no activity.

+

For Pro and Enterprise URLs, URLs never automatically expire, but data is removed after 365 days.

+

How do I transfer my Webhook.site account and data?

+

To hand over your account to a different business or individual you essentially only need to change the email address, as it is the only piece of identification we store. However, be aware of the following:

+
    +
  1. +

    If billing details need to change, make sure to cancel the subscription first. The subscription will continue to work until the expiry date.

    +
  2. +
  3. +

    If 2-Factor Authentication is enabled, disable 2-Factor.

    +
  4. +
  5. +

    For Enterprise users, make sure you delete any extraneous users.

    +
  6. +
  7. +

    Delete any extraneous API keys that you should no longer have access to.

    +
  8. +
  9. +

    Change the account email address to the receiver's email address.

    +
  10. +
  11. +

    You, or the account receiver, can then issue a Password Reset email so they can set their own password.

    +
  12. +
  13. +

    The account receiver can then create a new subscription on the account.

    +
  14. +
+

After this, you will no longer have access to your account and it is fully handed over.

+

I want to whitelist Webhook.site in our firewall, which IP do you use?

+

You'll need to whitelist the IPs 46.4.105.116 and 88.99.82.58.

+

Both inbound and outbound originate and destinate at this IP address.

+

Note that this may change in the future, so sign up for the newsletter to be notified of changes.

+

How do I add authentication to my URL?

+

You can use the Conditions Custom Action to add a quick header based authentication mechanism to your URL. You can also add the Don't Save action as a condition if you don't wish to save the unauthenticated request.

+

Quick Conditions Based Authentication

+

We also have an example WebhookScript for adding basic auth:

+
username = 'john'
+password = '1234'
+
+if (var('request.header.php-auth-user', '') != username and var('request.header.php-auth-pw', '') != password) {
+    respond('', 401, ['WWW-Authenticate: Basic realm="Authentication required"']);
+    dont_save()
+}
+
+respond('Login OK!');
+
+

Can I get a push notification on my phone when my URL receives a request?

+

Via Custom Actions, Webhook.site supports the service Pushed, which has a free tier. More info here.

+

Alternatively, at least on iPhones, you can use the Send Email custom action and mark the sender address as VIP. This will trigger a push notification when the email is received.

+

Can I pay via invoice?

+

After you've paid for and created a subscription, you will receive an invoice via email.

+

If you are an enterprise customer that wishes to buy a subscription via bank transfer, please contact Support.

+

How do I add my company name to my invoice?

+

Go to Control Panel -> Billing, then click View next to an invoice and finally click the "Add Address & VAT Number" link.

+

How can I see the pricing in my currency?

+

Once you start the checkout process, you will see the amount in your local currency, including any applicable VAT.

+

The JSON data is in a weird format/can't be parsed by Extract JSONPath

+

The JSON data might have been attached to the request as form data rather than as request body data, which is usually how JSON is sent.

+

The data might look like this on Webhook.site:

+

JSON Form Data

+

To remediate this in Extract JSONPath, you'll need to set the source field to the form field variable, which is automatically set by Webhook.site. In the screenshot above, the variable name would be $request.form.my_json_data$, which works with Extract JSONPath:

+

JSON Form Data in JSONPath

+

JSON data is invalid when using the HTTP Request action

+

If you use any variables in the JSON that could contain e.g. new lines or quote characters, these characters need to be "escaped" properly so that the JSON remains valid.

+

Webhook.site provides an easy way to do this with the .json Variable Modifier, which will automatically escape any special JSON characters. More info here.

+

Before:

+
{
+  "message": "$request.query.message$"
+}
+
+

After, with the JSON Escape Variable Modifier:

+
{
+  "message": "$request.query.message.json$"
+}
+
+

How do I export the data stored on Webhook.site?

+

With Webhook.site Pro, there's a variety of different ways to export data sent to your URL or email address.

+
    +
  1. +

    Custom Actions can be used in a variety of ways to export data. Below are listed a few examples of actions that could be used. More info here.

    + +
  2. +
  3. +

    Webhook.site provides a CSV Export functionality, simply click the button in the menu to download all data as a CSV file.

    +

    CSV Export

    +
  4. +
  5. +

    Data can be retrieved and saved using the Webhook.site API using any programming language.

    +
  6. +
  7. +

    With the Webhook.site CLI (Command-Line Interface), requests can be forwarded directly from Webhook.site to a local workstation or server. More info here

    +
  8. +
+

How do I send data to my computer/localhost?

+

There's several ways to accomplish this depending on your needs.

+
    +
  1. +

    You can periodically fetch the data using the Webhook.site API

    +
  2. +
  3. +

    Requests can also be streamed to a local URL using the Webhook.site CLI, in a similar fashion to e.g. ngrok.

    +
  4. +
  5. +

    Webhook.site also supports the XHR Redirect feature, which uses your browser in order to forward the requests. The endpoint will need to respond with CORS headers in all requests so that the browser will be able to send requests to it. The forwarding will only work as long as the browser window is open.

    +
  6. +
+

The following CORS headers should allow Webhook.site to forward requests to your local endpoint via XHR Redirect:

+
Access-Control-Allow-Origin: *
+Access-Control-Allow-Methods: *
+Access-Control-Allow-Headers: *
+Access-Control-Expose-Headers: Content-Length,Content-Range
+
+

How can I test an IPv6-only request?

+

If you access Webhook.site with the hostname https://ipv6.webhook.site, your URL will only work with IPv6.

+

To use it with a URL, simply replace the webhook.site hostname with ipv6.webhook.site.

+

I'm getting a 404 Not Found, what's wrong? / When does Webhook.site URLs expire?

+

Using the free version of Webhook.site, URLs automatically expire in 7 days. After that, the URL is no longer available and data is deleted.

+

With the paid version, Webhook.site Pro, URLs never expire automatically.

+

I'm getting a 405 Method Not Allowed, what's wrong?

+

You might be copying the URL for the Webhook.site application (by copying the link from your browsers' address bar), and not the actual URL.

+

Webhook.site app (⛔️ wrong):
https://webhook.site/#!/view/6dbb3859-4ad5-4e85-acae-e44d6e37ea4a

+

Webhook.site url (✅ correct):
https://webhook.site/6dbb3859-4ad5-4e85-acae-e44d6e37ea4a

+

I'm getting a 429 Too Many Requests, what's wrong?

+

First, make sure that you have copied the correct URL, see here.

+

For free users: The URL has met the limit of the amount of requests it can receive. To unlock more requests, the URL must be associated with a Webhook.site Pro or Enterprise account. To associate a URL to your account, click Upgrade in the upper-right corner when logged in.

+

For Webhook.site Pro or Enterprise users: If you're getting this error with a Webhook.site URL, the URL may have been automatically blocked due to an extraordinarly large amount of requests, as per the Fair Use guidelines in our Terms of Service. This is done to prevent a decrease in service level for our other customers. For more info, or to request a whitelisting, please contact Support. If you're getting this error with a Webhook.site API endpoint, you have exceeded the API endpoint quota, and should implement e.g. a backoff strategy.

+

I'm getting a 413 Payload Too Large, what's wrong? / What's the request size limit?

+

The HTTP body data (e.g. files or JSON data) submitted to Webhook.site must be below 10 megabytes. More than that will cause a HTTP 413 response.

+

I'm getting an "Access Control Check error"

+

If you're requesting the Webhook.site endpoint from another domain via JavaScript, you'll need to enable CORS so the browser allows the request.

+

To do this, click Edit in the upper-right corner, check the Add CORS headers checkbox, and click Save.

+

I'm getting a "Certificate Expired" error

+

Our SSL certificate is fully working; the issue lies with your system. In september 2021, our SSL provider, LetsEncrypt, updated their root certificate. This can mean that if your locally installed trusted root certificates are of an old version, you'll be seeing a certificate error as Webhook.site now runs a certificate that is based on the new root certificate chain.

+

To remediate this problem, you'll need to update your local certificate trust store:

+ +

Some systems and packages, like Python certifi/urllib3, also come with static certificates. We cannot support updating these.

+

What is a DNSHook?

+

For more information about DNSHook, please see here.

+ +
+
+ + + Last update: + April 6, 2024 10:34:57 + + + +
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/images/EQeP6s783LK1y5hnj6u7ObvO.png b/images/EQeP6s783LK1y5hnj6u7ObvO.png new file mode 100644 index 0000000..fe021f3 Binary files /dev/null and b/images/EQeP6s783LK1y5hnj6u7ObvO.png differ diff --git a/images/airtable-example.png b/images/airtable-example.png new file mode 100644 index 0000000..8cd6509 Binary files /dev/null and b/images/airtable-example.png differ diff --git a/images/auth.png b/images/auth.png new file mode 100644 index 0000000..4a07d1b Binary files /dev/null and b/images/auth.png differ diff --git a/images/condition-action.png b/images/condition-action.png new file mode 100644 index 0000000..2378901 Binary files /dev/null and b/images/condition-action.png differ diff --git a/images/corsenable.png b/images/corsenable.png new file mode 100644 index 0000000..1d1f471 Binary files /dev/null and b/images/corsenable.png differ diff --git a/images/csv-export.png b/images/csv-export.png new file mode 100644 index 0000000..d5e976b Binary files /dev/null and b/images/csv-export.png differ diff --git a/images/custom-actions.png b/images/custom-actions.png new file mode 100644 index 0000000..26f5da0 Binary files /dev/null and b/images/custom-actions.png differ diff --git a/images/database-example-table.png b/images/database-example-table.png new file mode 100644 index 0000000..306fc20 Binary files /dev/null and b/images/database-example-table.png differ diff --git a/images/database.png b/images/database.png new file mode 100644 index 0000000..d71d405 Binary files /dev/null and b/images/database.png differ diff --git a/images/discord.png b/images/discord.png new file mode 100644 index 0000000..5385e64 Binary files /dev/null and b/images/discord.png differ diff --git a/images/dnshook.png b/images/dnshook.png new file mode 100644 index 0000000..1b33976 Binary files /dev/null and b/images/dnshook.png differ diff --git a/images/example-telegram-bot-script.png b/images/example-telegram-bot-script.png new file mode 100644 index 0000000..3f80dcb Binary files /dev/null and b/images/example-telegram-bot-script.png differ diff --git a/images/example-telegram-bot.png b/images/example-telegram-bot.png new file mode 100644 index 0000000..ad1e767 Binary files /dev/null and b/images/example-telegram-bot.png differ diff --git a/images/favicon.ico b/images/favicon.ico new file mode 100644 index 0000000..c3ff54d Binary files /dev/null and b/images/favicon.ico differ diff --git a/images/icon.png b/images/icon.png new file mode 100644 index 0000000..6360bb9 Binary files /dev/null and b/images/icon.png differ diff --git a/images/javascript.png b/images/javascript.png new file mode 100644 index 0000000..4f6ddd9 Binary files /dev/null and b/images/javascript.png differ diff --git a/images/json-form-data-jsonpath.png b/images/json-form-data-jsonpath.png new file mode 100644 index 0000000..856782a Binary files /dev/null and b/images/json-form-data-jsonpath.png differ diff --git a/images/json-form-data.png b/images/json-form-data.png new file mode 100644 index 0000000..1dd6888 Binary files /dev/null and b/images/json-form-data.png differ diff --git a/images/logo.png b/images/logo.png new file mode 100644 index 0000000..a485bd1 Binary files /dev/null and b/images/logo.png differ diff --git a/images/pushed.png b/images/pushed.png new file mode 100644 index 0000000..6afeca2 Binary files /dev/null and b/images/pushed.png differ diff --git a/images/queue-and-delay.png b/images/queue-and-delay.png new file mode 100644 index 0000000..8a66004 Binary files /dev/null and b/images/queue-and-delay.png differ diff --git a/images/schedules-editor.png b/images/schedules-editor.png new file mode 100644 index 0000000..e5d2ea6 Binary files /dev/null and b/images/schedules-editor.png differ diff --git a/images/variables.png b/images/variables.png new file mode 100644 index 0000000..9fb40bf Binary files /dev/null and b/images/variables.png differ diff --git a/images/webhookscript-action.png b/images/webhookscript-action.png new file mode 100644 index 0000000..a9a7a3f Binary files /dev/null and b/images/webhookscript-action.png differ diff --git a/images/webhookscript-in-action.png b/images/webhookscript-in-action.png new file mode 100644 index 0000000..0cd7426 Binary files /dev/null and b/images/webhookscript-in-action.png differ diff --git a/index.html b/index.html new file mode 100644 index 0000000..4882900 --- /dev/null +++ b/index.html @@ -0,0 +1,1078 @@ + + + + + + + + + + + + + + + + + + + + + + About - Webhook.site Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + + + + + + +

About Webhook.site

+

With Webhook.site, you instantly get a unique, random URL and e-mail address. Everything that's sent to these addresses are shown instantly. With this, you can test and debug Webhooks and HTTP requests, as well as create your own workflows using the Custom Actions graphical editor or WebhookScript, a simple scripting language, to transform, validate and process HTTP requests in a variety of ways – without setting up and maintaining your own infrastructure.

+

What are customers using Webhook.site for?

+
    +
  • Receive Webhooks without needing an internet-facing Web server
  • +
  • Use Webhook.site as an intermediary, proxying requests and being able to see what was sent in the past
  • +
  • Send Webhooks to a server that's behind a firewall or private subnet
  • +
  • Transforming Webhooks into other formats, and re-sending them to different systems
  • +
  • Connect different APIs that aren't compatible
  • +
  • Building contact forms that send emails
  • +
  • Instantly build APIs without needing infrastructure
  • +
+

The following video is a quick demo of Webhook.site Custom Actions is used to set up a workflow to post updates from a news page to an X/Twitter account automatically.

+

+

Company information

+

Webhook.site is operated by Webhook ApS (VAT ID: DK41561718).

+

Address: Damhusvej 95, 3 tv, 5000 Odense, Denmark.

+

Founded and built by Simon Fredsted (@fredsted).

+

Contact information.

+

Acknowledgements

+
    +
  • The app was built with Laravel for the API.
  • +
  • Angular.js is used for the frontend SPA.
  • +
  • WebhookScript is based on Primi Copyright (c) Přemysl Karbula.
  • +
  • The WebhookScript editor is using the Ace editor plugin.
  • +
  • JSONPath extraction provided by FlowCommunications.
  • +
  • This documentation site uses MkDocs with the Material theme.
  • +
  • Docs hosted by Github. Pull requests are appreciated!
  • +
+ +
+
+ + + Last update: + April 9, 2024 10:35:29 + + + +
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/jobs.html b/jobs.html new file mode 100644 index 0000000..7014d7f --- /dev/null +++ b/jobs.html @@ -0,0 +1,1212 @@ + + + + + + + + + + + + + + + + + + + + + + + + Webhook.site Jobs - Webhook.site Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + + + + + + +

Webhook.site Jobs

+

Webhook.site is a small startup that's fully remote. We believe in absolute trust in our employees. What's important to us is your work output and communication, not how many hours you spend. You'll be working at a company with a lot of dedicated and passionate customers that use the product to solve real problems in their work.

+

Support Engineer (part time)

+

Job Roles

+
    +
  • Work on and resolve customer support tickets.
  • +
  • Respond within 24 hours.
  • +
  • Solve problems for customers.
  • +
  • Help setting up Custom Actions.
  • +
  • Handle billing issues.
  • +
  • Identify and track bugs and feature requests.
  • +
+

Requirements

+
    +
  • Excellent English language skills
  • +
  • Experience with writing JavaScript or similar
  • +
  • Experience with Web technologies: HTTP, FTP
  • +
+

Description

+

Customers use Webhook.site to solve a wide variety of problems, and it's your job to help them use Webhook.site to complete their goals.

+

Users can be at the beginner to intermediate stage in terms of their understanding of Internet technology, scripting etc., and often you’ll need to sense what the actual problem is–which can be wildly different from what the support ticket is about.

+

100% remote. Around 10 hours per week.

+

To apply, send an email to jobs@webhook.site. We expect you to send us a CV along with a short email describing yourself, and then we'll do a half-hour video call to talk about the job and any questions you may have. If we decide to hire you, you'll be able to start as soon as you like.

+

Full-Stack Developer (part time/full time)

+

Job Roles

+
    +
  • Reorganize Webhook.site code
  • +
  • Upgrade PHP version / frameworks / dependencies
  • +
  • Optimize request times and performance
  • +
  • Fix bugs
  • +
  • Implement new features
  • +
  • Write documentation (here!) for work done
  • +
+

Requirements

+
    +
  • Excellent English language skills
  • +
  • Professional experience with at lease one of:
      +
    • PHP
    • +
    • Angular.js
    • +
    +
  • +
  • Professional experience with:
      +
    • Git
    • +
    • Linux
    • +
    • Docker
    • +
    +
  • +
+

Description

+

Webhook.site is a complex Laravel and Angular.js based system with more than 100.000 monthly unique users which use it for everything from Webhook API development to workflow automation using Webhook.site’s Custom Actions feature. Much of the site is a REST API with an Angular.js client in addition to some Blade pages.

+

Your job is to continuously improve on the codebase, whether it’s code organisation, framework and dependency updates, implementing new features and fixing bug tickets.

+

The job is paid hourly, and you’ll be 100% free to schedule your work as you see fit and work as may or as few hours as you like.

+

To apply, send an email to jobs@webhook.site. We expect you to send us a CV along with a short email describing yourself, and then we'll do a half-hour video call to talk about the job and any questions you may have. If we decide to hire you, you'll be able to start as soon as you like.

+ +
+
+ + + Last update: + April 6, 2024 10:34:57 + + + +
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/news.html b/news.html new file mode 100644 index 0000000..9ef3dec --- /dev/null +++ b/news.html @@ -0,0 +1,4250 @@ + + + + + + + + + + + + + + + + + + + + + + + + News & Changelog - Webhook.site Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + + + + + + +

News

+

Subscribe below to receive updates about improvements and new features on Webhook.site as well as infrastructure changes like new IP addresses for e.g. firewall whitelisting. Expect a newsletter a few times a year at most.

+

+ +
+
+
+ + + +
+
+
+
+ +

22 April 2024

+
    +
  • If a default Custom Domain is specified and is validated for email, it's now used as the sender address in the Send Email action (applies to new URLs only.)
  • +
  • Improved display of text content of incoming emails - links are now clickable and quotes are indented.
  • +
  • Fixed "401 Missing Password" error when saving configuration of Tokens that have a password set.
  • +
+

15 April 2024

+
    +
  • Webhook.site now uses the domain emailhook.site for email receiving and sending. The old domain, email.webhook.site, continues to work.
  • +
  • JavaScript action now supports Global Variables via the built-in store() and global() functions. More info and examples here
  • +
  • JavaScript action no longer considered in beta.
  • +
  • New API: Global Variables. More info here
  • +
  • Webhook.site CLI forward command now defaults to https://localhost for the --target parameter.
  • +
+

9 April 2024

+
    +
  • Action Editor improvements: drag and drop to change order of actions is now supported, improved renaming of actions, textboxes have been set to proper sizes
  • +
+

18 March 2024

+
    +
  • New Feature: DNSHooks, which will automatically show all DNS requests to your unique DNS name, and all its subdomains. It can be used to send data solely via DNS, or as a canary token. More info here
  • +
+

13 March 2024

+
    +
  • HTTP headers with underscores are no longer ignored. However, underscores are converted to dashes due to a technical limitation.
  • +
  • When a search query is set, Webhook.site will now only show incoming requests and emails that match the search query.
  • +
  • Search queries are now stored in the browser's local storage, so it will be saved even after closing the browser.
  • +
+

1 March 2024

+
    +
  • Fixed a bug where the $request.query$ Base Variable not being generated.
  • +
+

29 Feburary 2024

+
    +
  • Webhook.site now automatically decompresses gzip encoded request bodies.
  • +
+

26 Feburary 2024

+
    +
  • New features for "Set Variable" action: The Set Variable action can now generate random strings, date strings and timestamps. More info here
  • +
+

20 Feburary 2024

+
    +
  • New Feature: Templates, which are created out of existing Custom Actions, and can be reused via the Import Template Custom Action. More info here Template API
  • +
  • Webhook.site CLI: Better logging and can now be used for free users without API key.
  • +
+

7 Feburary 2024

+
    +
  • faker library added to the JavaScript Custom Action. More info here
  • +
+

6 Feburary 2024

+
    +
  • Tokens now support timeouts up to 30 seconds, from 10 before, which allows more flexibility when testing application timeouts.
  • +
  • Tokens with timeouts are now have a dynamic rate limit. More info here
  • +
  • Updates to our Terms of Service and Privacy Policy. Summary:
      +
    • Adding language specifically prohibiting submitting illegal content to Webhook.site
    • +
    • Fair Use policy has been updated to a "requests per minute" metric (from 10000 requests per day), and a guideline for 100 Tokens created per day when the "expiry" option is used
    • +
    • Added language about intellectual property rights, disclaimer of warranties, limitation of liability, indemnification, modification of terms, termination and governing law and jurisdiction.
    • +
    +
  • +
+

29 January 2024

+
    +
  • Split Text action now supports repeating. More info here
  • +
  • Split Text action now recognizes the string \n as a newline, allowing splitting strings by line.
  • +
+

15 January 2024

+
    +
  • Dynamic Request Limits: Webhook.site URLs/Tokens can now have custom request limits, from 1 to 10000, which is great when you're concerned about the data stored on Webhook.site. With this, you can limit the request history to the amount you choose.
  • +
+

11 January 2024

+
    +
  • New $request.path$ (contains any subpath after the Webhook.site URL ID) and $request.query$ (contains the query string) variables added. More info here
  • +
  • Don't Save, Rate Limit and Modify Response actions can no longer be marked as Queued.
  • +
+

10 January 2024

+
    +
  • Requests API: It's now possible to delete a subset of requests using the date_from, date_to, and query parameters. More info here.
  • +
+

9 January 2024

+
    +
  • HTTP Request action: Fixed an issue where headers wouldn't be forwarded when using the Forward mode.
  • +
+

3 January 2024

+
    +
  • Happy New Year :-)
  • +
  • Webhook.site now supports 2-factor authentication via TOTP. To enable, go to Control Panel -> User Profile.
  • +
+

27 December 2023

+
    +
  • New WebhookScript function: http(), which replaces the request() function and allows for more flexibility as well as sending e.g. form/multipart requests as the new HTTP Request Custom Action also allows. More info here
  • +
+

22 December 2023

+
    +
  • The new Custom Action HTTP Request has replaced Send Request, which has several benefits:
      +
    • HTTP Request has different modes: text, multipart, etc., which lets you build more forms of HTTP requests that couldn't be done using Send Request.
    • +
    • The Forward mode is now able to forward Multipart requests.
    • +
    • Both the request and response are now saved so you can see exactly what was sent to the URL in HTTP Request.
    • +
    • The HTTP Request has a handy Format JSON button.
    • +
    +
  • +
  • It is still possible to make changes to existing Send Request actions, but it is no longer possible to create new Send Request actions.
  • +
+

7 December 2023

+
    +
  • Image files are now previewed in the file list, e.g. for email attachments
  • +
  • Binary requests with content-types including image/*, video/* and application/pdf are now shown as linked files in the file list, not binary data.
  • +
+

6 December 2023

+
    +
  • Token (URL) expiry is now configurable with an amount of seconds. More info here
  • +
+

28 November 2023

+
    +
  • New Custom Action: JavaScript. It is now possible to run JavaScript/Node.js code in your Custom Actions. This action is marked as beta as some limitations apply. More info and examples here
  • +
+

7 November 2023

+
    +
  • New Custom Actions: Microsoft Excel. Webhook.site now allows using your Microsoft account to append and retrieve data from Excel worksheets in your OneDrive account.
  • +
  • New Custom Actions: Microsoft OneDrive. With Webhook.site, you can now use your Microsoft account to upload and download files in your OneDrive account.
  • +
  • It's now possible to test IPv6-only traffic using the ipv6.webhook.site hostname. More info here
  • +
+

31 October 2023

+
    +
  • New feature when testing actions: Test Until Here, which allows testing only the actions up until and including the currently selected action. This is useful when, for example, testing a flow that extracts data and sends an email, but you just want to test how data is extracted, and not sending the email (which is usually the last action.)
  • +
+

25 October 2023

+
    +
  • Schedules now have support for requirements which will send an error notification emails when they don't pass, making it an easy option for e.g. uptime monitoring. Currently supported requirements are "Response body must contain" and "Response status code must be in range". More info here
  • +
  • Webhook.site will now highlight the last viewed URL after logging in.
  • +
+

19 October 2023

+
    +
  • Queued Custom Actions that share the same delay are now run in groups, so they can share data and variables. This makes it possible to create more advanced workflows that run in the future.
  • +
+

12 October 2023

+
    +
  • New Custom Action: Auto JSON. Automatically converts JSON data into Webhook.site Variables. More info here
  • +
+

11 October 2023

+
    +
  • Custom Actions editor modal dialog has been changed to an overlay, which allows for more space to edit actions.
  • +
  • Moved Delete Action button to avoid accidentally deleting actions.
  • +
  • WebhookScript editor and action output panel can now be resized.
  • +
+

22 September 2023

+
    +
  • New update for Webhook.site CLI, a tool for interacting with the Webhook.site API and allows forwarding requests from your Webhook.site URL to your local network. More info here
  • +
+

21 September 2023

+
    +
  • New Custom Action: Split Text. Takes a source, delimiter and variable name prefix and splits text into X amount of variables.
  • +
  • New Custom Action: Map Text. Takes a source, an operator (like the Conditions action) and a series of mappings and sets the resulting variable name to whether one of the mappings are a match to the source text.
  • +
+

15 September 2023

+
    +
  • It's now possible to name individual Custom Actions, so you can keep track of which action does what. To change the name of an action, click the dashed name at the top of the action editor when creating or editing an action.
  • +
  • The Variables dropdown shows all available variables after clicking the Test button.
  • +
  • Variables section of the Custom Actions editor now allows copying each variable name.
  • +
+

14 September 2023

+
    +
  • New Custom Action: SFTP Upload
  • +
  • The Run SSH Command action now supports regular password authentication in addition to standard keypair authentication.
  • +
+

30 August 2023

+
    +
  • Send Email action: It's now possible to add attachments to the email being sent.
  • +
  • Send Email (SMTP) action: It's now possible to add attachments to the email being sent.
  • +
  • WebhookScript: The json_encode function now allows disabling JSON formatting.
  • +
+

11 August 2023

+
    +
  • WebhookScript: New delete() function added for deleting Global Variables.
  • +
+

4 August 2023

+
    +
  • Improvements to Dark Mode.
  • +
+

29 July 2023

+
    +
  • Custom Actions: Maintenance was carried out on the underlying database system storing Custom Actions, and this may have resulted in 500 errors for around a minute starting 14:10 UTC.
  • +
+

20 July 2023

+
    +
  • New WebhookScript function: multipart(), for sending HTTP multipart requests. More info here.
  • +
  • Webhook.site can now send browser notifications to alert you of new emails or requests.
  • +
  • Added "Mark all as read" button.
  • +
+

29 June 2023

+
    +
  • For teams using Custom Domains, it's now possible to specify a default domain in Control Panel that will be shown anywhere the Webhook.site URL can be copied, for example.
  • +
+

16 June 2023

+
    +
  • Dark Mode has been added to the user interface for Webhook.site.
  • +
+

7 June 2023

+
    +
  • New Custom Action: Send Push Notification via ntfy.sh. Allows you to easily send push notifications to your browser, phone, watch, etc. Simply download the ntfy.sh app, subscribe to your topic name and send a message to the topic name via this Custom Action. No account required.
  • +
+

22 May 2023

+
    +
  • Webhook.site was down from approximately 10:45 to 11:30 UTC. The cause was a customer abusing the Delay Action feature which caused a buildup of data. As a result, we've had to reset the "delayed action" queue, meaning that any delayed actions not executed at 10:00 UTC today have been lost. Any newly created delayed actions will still be run as of 12:00 UTC. We apologize for the inconvenience.
  • +
+

21 May 2023

+
    +
  • We've carried out an upgrade of some of the underlying software powering Webhook.site. As a result, Webhook.site should generally perform faster.
    Beginning 10:45 UTC, there may have been instances of increased error rates. As of 12:00 UTC, these issues have been resolved. We apologize for the inconvenience. As always, if you experience issues with your Webhook.site URLs, Custom Actions, etc., please let us know at support.webhook.site.
  • +
+

20 May 2023

+
    +
  • Custom Domains now show the exact error reason in Control Panel.
  • +
+

18 May 2023

+
    +
  • Fixed an issue where the Custom Domain setup email wouldn't show the correct DNS entries.
  • +
+

28 April 2023

+
    +
  • Free URLs now accept a maximum of 500 requests in total. Deleting requests won't allow the URL to accept more requests. We encourage upgrading to Webhook.site Pro or Enterprise to avoid these limitations.
  • +
+

26 April 2023

+
    +
  • New API for Groups. More info here.
  • +
  • It's now possible to use Unicode characters like emojis in user names, group names, etc.
  • +
  • WebhookScript: xml2array() logs more helpful errors.
  • +
+

16 April 2023

+
    +
  • New WebhookScript function: xml2array(). More info here.
  • +
  • Conditions action: It's now possible to delete individual conditions.
  • +
+

21 March 2023

+
    +
  • Repeat: Fixed a bug where only the last output of a repeated action would be shown in the action's output.
  • +
  • Fixed link to Extract JSONPath examples.
  • +
  • Added example for making queries using fields that contain spaces.
  • +
+

14 March 2023

+
    +
  • WebhookScript: Fixed issue where floats would be parsed as strings (and not numbers, as they're supposed to), in some instances.
  • +
+

3 March 2023

+
    +
  • New WebhookScript string functions: string_random(), uuid(). More info here.
  • +
+

23 Febuary 2023

+
    +
  • For WebhookScript actions, the first line of the script is now shown in the action list. It allows easily adding a title to the script by making the first line a comment.
  • +
+

6 Feburary 2023

+ +

1 Feburary 2023

+
    +
  • New Custom Action: Send Email (SMTP) - send an email using your own email provider.
  • +
+

20 January 2023

+
    +
  • XPath: Improvements to the XPath action have been made so that it's now able to parse both XML and HTML-style documents.
  • +
  • WebhookScript: Fixed a bug in the set_response() function where it wasn't possible to set the response headers.
  • +
  • WebhookScript: Fixed a bug where internal errors would be returned when using array functions on arrays containing specific strings.
  • +
  • CSV Export: When exporting to CSV, the search query is now used so you get the same items in the CSV as you see in the request list.
  • +
  • WebhookScript: Added array_splice and array_range functions. More info here
  • +
+

14 December 2022

+
    +
  • Fixed a bug where Extract XPath and WebhookScript xpath functions would not match correctly in all cases.
  • +
+

30 November 2022

+
    +
  • WebhookScript: stop() function now stops entire Custom Action flow and returns respond rather than simply exiting the current script.
  • +
+

28 November 2022

+
    +
  • Discord: Added an Embed URL action to Discord Custom Action for attaching videos, images, articles, etc. to a chat message.
  • +
+

10 November 2022

+
    +
  • Schedules: Control Panel now shows Schedule IDs.
  • +
  • Removed "Amount of requests to keep for Auto Cleanup" (configuring this didn't actually do anything.) As an alternative, you could use the Don't Save Custom Action.
  • +
  • Send Request: Header Names are replaced with Variables.
  • +
  • Global Variables: It's now possible to search for Global Variables.
  • +
+

6 November 2022

+
    +
  • Schedules/API: It's now possible to fetch Schedule Logs. More info here
  • +
  • Schedules: Added "Run Now" button to all Schedules.
  • +
+

31 October 2022

+
    +
  • Control Panel: Category selector dropdown now sorted by name.
  • +
+

26 October 2022

+
    +
  • Improvements to Schedules
  • +
  • Ability to rename Groups
  • +
  • Group selection is now automatically remembered
  • +
+

30 September 2022

+
    +
  • New WebhookScript function: is_empty() More info here
  • +
  • New WebhookScript function: is_null() - handy for checking if a value is null without type checking issues. More info here
  • +
+

21 September 2022

+
    +
  • API: It's now possible to sort tokens returned by the Get Tokens endpoint. More info here: More info here
  • +
+

8 September 2022

+
    +
  • Fixed a bug in Webhook.site CLI ("TypeError: Echo is not a constructor" error.) - please upgrade the NPM package to 0.1.5.
  • +
  • Please do not use async-http-client (User-Agent AHC/2.1.) It is abandoned and contains bugs that creates too many HTTP requests. We may block users of this package in the future.
  • +
+

17 August 2022

+
    +
  • As a result of customer abuse, we have decided to introduce rate limits on creation of URLs. The rate limit will be initially set to 10 per minute. After reaching this limit, the POST /token endpoint will return a 429 Too Many Requests response.
  • +
+

28 June 2022

+
    +
  • New Custom Action Type: Send push messages with Pushed.co. More info here.
  • +
+

24 June 2022

+
    +
  • New WebhookScript function: preg_match() - allows matching regex with custom regex options More info here
  • +
  • New WebhookScript function: html_to_text() - converts html to text. A more aggressive version of html_strip_tags() More info here
  • +
  • WebhookScript: regex_extract_first() now has a default parameter that is returned when there's no matches. The function still returns false by default when this third parameter is not set. More info here
  • +
+

21 May 2022

+
    +
  • New Custom Actions feature: It is now possible to delay queued actions by a specified amount of seconds. More info here
  • +
+

20 May 2022

+
    +
  • New WebhookScript function: is_numeric(). More info here
  • +
  • Rate Limit Custom Action: It is now possible to specify a key to let you rate limit on a custom parameter. The request IP address ($request.ip$) is still the default key.
  • +
  • Action and Schedule error reports now specify the name, ID or alias of the Schedule or URL in question.
  • +
  • Fixed a bug with Webhook.site Enterprise Custom Domain email validation.
  • +
+

19 April 2022

+
    +
  • Fixed a bug that prevented action error notifications from being sent to the users.
  • +
+

14 April 2022

+
    +
  • It is now possible to search requests and emails, using either the frontend or the API. The data can be filtered by a wide range of fields, queries. More info here.
  • +
+

30 March 2022

+ +

20 March 2022

+
    +
  • New Variables for Files: $request.file.[name].id$ and $request.file.[name].link$ (which returns direct link to download the file.)
  • +
+

14 March 2022

+
    +
  • Added num2hex, hex2num and hex2bin functions.
  • +
+

19 January 2022

+
    +
  • New Custom Actions: RabbitMQ Get & Publish, allows consuming and publishing to RabbitMQ Queues via Webhook.site Custom Actions.
  • +
+

21 December 2021

+
    +
  • Improved handling of binary data received from Send Request actions.
  • +
  • Added a group_id parameter when creating or updating Tokens.
  • +
  • Fixed an issue with the Twitter Custom Action.
  • +
  • Requests to /token/:tokenId/requests are now throttled at 60 requests/minute.
  • +
+

24 November 2021

+
    +
  • WebhookScript: Fixed an issue that would cause strings to be interpreted as integers when encoding JSON.
  • +
+

30 October 2021

+
    +
  • Webhook.site's requests to itself, e.g. via Send Request action or Schedules by Webhook.site, now shows more clearly as coming from Webhook.site in the request list. Outgoing requests are now sent with a User-Agent header of Webhook.site/1.0, which can be overwrited if specifying a User-Agent header manually.
  • +
  • Error deleting Global Variables fixed.
  • +
  • It is now possible for Webhook.site Enterprise customers to manage their Custom Domains from the control panel.
  • +
+

15 October 2021

+
    +
  • Fix invalid charset configurations causing issues saving requests.
  • +
+

4 October 2021

+
    +
  • Webhook.site now supports multiple sub-users on an account, with different access permissions, available to Webhook.site Enterprise users. For more information, please contact us.
  • +
+

29 September 2021

+
    +
  • Webhook.site CLI: New minor version, fixes a bug causing Invalid namespace errors.
  • +
+

17 September 2021

+
    +
  • New Custom Action Variable Modifiers: .html_decode, .url_encode, and .url_decode. More info here
  • +
+

12 September 2021

+
    +
  • New WebhookScript function: array_merge(), that merges two arrays into one. More info here
  • +
  • New WebhookScript function: array_chunk(), that splits an array into chunks. More info here
  • +
  • Functions dd(), dump() and echo() can now take a variable amount of arguments. More info here
  • +
  • New WebhookScript date function: now(), which returns the current date in ISO format. More info here
  • +
  • The date_interval() and date_interval_human() functions now defaults to "now" if the second parameter isn't specified.
  • +
  • Script editor now has more space for outputs in full screen mode.
  • +
+

18 August 2021

+
    +
  • New API Endpoint: Get tokens, which returns a list of all tokens belonging to the account. More info here
  • +
  • Fixed a bug that caused logins to be slow on especially older accounts.
  • +
  • Fixed a bug that caused the FTP Upload action to error when the Port field was missing.
  • +
+

12 August 2021

+
    +
  • Google Sheet actions that consistently cause errors are now disabled automatically. Users are sent an email when this occurs.
  • +
+

30 July 2021

+
    +
  • New WebhookScript function: hmac(), which allows easily verifying strings using the HMAC method. More info here
  • +
+

14 July 2021

+
    +
  • New Custom Action: Replace Text, which allows easily making text replacements from variable input, and either overwrites an existing variable or creates a new one with the replaced content.
  • +
+

4 July 2021

+
    +
  • Fixed bug causing the "Use Request Content" checkbox in the Send Email action to not work.
  • +
+

15 June 2021

+
    +
  • New Custom Action: Twitter, so you can easily send tweets using Webhook.site.
  • +
  • New WebhookScript functions: convert_kana(), string_slice(), string_upper(), string_lower(), string_title() More info here.
  • +
+

10 June 2021

+
    +
  • Individual Custom Actions can now be set as queued, which causes them to be run in the background, or asynchronously. More info here
  • +
+

7 June 2021

+
    +
  • Raised the limit for the amount of items processed by repeating actions to 100.
  • +
  • Fixed a bug that would cause an error when updating notification settings in Control Panel.
  • +
  • Fixed a bug where emails containing attachments would be stored.
  • +
+

23 May 2021

+ +

13 May 2021

+
    +
  • Documented clone_from option when using the API to create Tokens (URLs)
  • +
  • WebhookScript: json_decode / json_encode now output error messages if they fail due to e.g. bad data.
  • +
+

1 May 2021

+
    +
  • Webhook.site Schedules now has an API. More info here
  • +
  • Fixed a bug where URLs could be in two groups at the same time.
  • +
+

20 April 2021

+
    +
  • Added base64 encoding and decoding variable modifiers. More info here
  • +
+

11 April 2021

+
    +
  • New Custom Action and WebhookScript function: Don't Save, which marks the request so it is not saved in Webhook.site. The request can still be seen when it comes in, but will not be available through through the app later, or through the API.
  • +
  • New Custom Action: Stop, which immediately stops Custom Action execution and returns the default response.
  • +
  • The Extract Regex now supports the Repeat function. More info here.
  • +
+

7 April 2021

+
    +
  • New powerful feature: Repeating actions. Currently supported by the Extract JSONPath action, it is now possible to "loop over" items in a JSON array. More info here
  • +
+

2 April 2021

+
    +
  • It is now possible to enable or disable Custom Actions on a specific Token with the API. More info here or here.
  • +
  • When exporting CSVs, the sorting selected in the application is now used automatically.
  • +
+

28 March 2021

+
    +
  • Today we've released the first version of the Webhook.site Command-line Interface (CLI), which allows you to forward requests from your Webhook.site URL to your local machine. More info here
  • +
+

24 March 2021

+
    +
  • WebhookScript: Added array_sort, array_join and json_escape functions.
  • +
  • Added modifiers for variables. More info here
  • +
+

23 March 2021

+
    +
  • Control Panel: It's now possible to clone URLs, including their Custom Actions and other configuration.
  • +
  • Control Panel: URLs with a password can be deleted more easily.
  • +
+

13 March 2021

+
    +
  • Control Panel: It's now possible to set a password for a Webhook.site URL in the Control Panel. Additionally, it's now possible to easily select and delete multiple URLs at once.
  • +
+

11 March 2021

+
    +
  • API: It's now possible to specify an alias when creating a URL via the API. More info here
  • +
+

6 March 2021

+
    +
  • New Action: Database Query - allows running database queries on PostgreSQL and MySQL servers, inserting, changing and fetching data in specific variables or JSON format. More info here
  • +
+

3 March 2021

+
    +
  • Webhook.site Premium has changed name to Webhook.site Pro. Functionality, pricing and everything else remains the same; it's a cosmetic change.
  • +
  • More currencies are now supported for Webhook.site Pro subscriptions: GBP and EUR. To change the currency of an existing subscription, please contact Webhook.site Support.
  • +
  • Custom Action output is now included in CSV Exports.
  • +
+

17 Feburary 2021

+
    +
  • New Action: FTP(S) Upload - allows easy file upload to FTP servers.
  • +
+

5 Feburary 2021

+
    +
  • New WebhookScript functions: html_strip_tags, html_decode, html_encode, markdown_to_html. For more information, see here.
  • +
+

1 Feburary 2021

+
    +
  • Webhook.site has had intermittent downtime today due abuse from a user. We've identified them and blocked them from our systems. We're very sorry for the inconvenience.
  • +
+

31 January 2021

+
    +
  • We have discontinued support for subscriptions via Patreon, who will need to create a new subscription. For more information please contact support.
  • +
+

19 January 2021

+
    +
  • Happy new year!
  • +
  • New Action Type: Conditions 2.0. Now supports adding multiple conditions in a single action.
  • +
  • New Action Type: Set Variable. Working similarly to the Store Global Variable action, this action sets a runtime variable that is not persisted.
  • +
  • Actions can now individually be executed depending on a previous set of conditions.
  • +
  • The Debug Output section in the Custom Actions builder now shows the action number and type from where it came.
  • +
  • The Modify Response action now supports returning the response immediately.
  • +
+

5 December 2020

+
    +
  • Added new Custom Action: Store Global Variable, which does what it says on the tin.
  • +
  • Bug fix: In Control Panel, the update date for each Global Variable now actually updates when a Global Variable is updated.
  • +
+

26 November 2020

+
    +
  • Webhook.site had downtime during the night. The problem has been fixed.
  • +
+

25 November 2020

+
    +
  • WebhookScript: It's now possible to store non-string values in set(). If the value is an array, however, it is JSON encoded first.
  • +
  • WebhookScript: Added more examples for the date functions.
  • +
+

1 November 2020

+
    +
  • Added new Custom Action: Rate Limit, which lets you specify the maximum amount of requests in a given duration per IP to allow to request the Webhook.URL.
  • +
  • Dates shown in the application now include seconds.
  • +
+

29 October 2020

+
    +
  • Added new Custom Action: Run SSH Command, which allows you to run SSH commands on your server.
  • +
+

22 October 2020

+
    +
  • WebhookScript: Added array_keys and array_values functions. For more information, see here.
  • +
+

19 October 2020

+
    +
  • It's now possible to set a timeout for the Send Request action. A new timeout parameter can also be given to the request() function in WebhookScript. Both places accept a value in seconds, with decimals.
  • +
  • When exporting Custom Actions, if the URL has an alias, this is now used for the resulting filename.
  • +
+

11 October 2020

+
    +
  • It's now possible to export and import Custom Actions to a file using the new Import/Export buttons in the Custom Actions builder.
  • +
+

7 October 2020

+
    +
  • Added documentation for managing Custom Actions via the API. For more information, see here.
  • +
  • Fixed a bug causing the Operator of an action to be reset to "is equal to" when testing.
  • +
+

6 October 2020

+
    +
  • Action output is no longer displayed twice when testing Condition actions.
  • +
+

24 September 2020

+
    +
  • New feature: Customize Auto-Cleanup threshold. This lets you specify how many requests or emails to keep for your URLs, if you want to keep fewer than the default amount of 10.000 for e.g. data protection reasons. Available from the brand new Settings page in Control Panel. The setting applies to all URLs that have the Auto Cleanup feature enabled - click Edit on a URL to enable it.
  • +
  • New feature: URL groups, which lets you categorize your URLs into groups. Available from the URLs page in Control Panel. Click Edit on a URL to change its group.
  • +
  • The URLs page in Control Panel has a new design which is less cluttered and allows you to more quickly change certain settings, URL aliases, and the description of a URL.
  • +
+

23 September 2020

+
    +
  • Regrettably, we saw a long period of downtime again from approx 20:00 to 05.40 UTC. The cause of the downtime was a user flooding their Webhook.site URLs with many gigabytes of data, causing the system to be overloaded. The same user was responsible for the downtime at 15 September 2020 and we've now terminated their license to use Webhook.site. We are also going prioritize changes that will automatically limit this kind of abuse, as well as move to another database system that will be more resilient.
  • +
+

15 September 2020

+
    +
  • We've seen spurious instances of downtime in the last 24 hours, the longest one lasting from approx. 14:00 to 14:50 UTC. We apologize for the inconvenience.
  • +
+

13 September 2020

+
    +
  • WebhookScript: Added override parameter to request(), which prevents content from the source request from being included.
  • +
+

3 September 2020

+
    +
  • WebhookScript: It is now possible to set a default for the var() function.
  • +
+

29 August 2020

+
    +
  • A bug in the Extract JSONPath action has been fixed so that it is now also possible to filter for keys containing punctuation, e.g. .data[?(@.Employee.FirstName)].
  • +
+

18 August 2020

+
    +
  • WebhookScript: The to_date and date_format functions have been improved with timezone handling capabilities.
  • +
+

15 August 2020

+
    +
  • It's now possible to set a custom timeout for Schedules, up to 30 seconds.
  • +
+

8 August 2020

+
    +
  • You can now specify a custom Cron expression for your Webhook.site Schedule, in addition to the predefined intervals. This lets you decide exactly the hour, day and minute, etc., of when the schedule runs (based on UTC time.)
  • +
  • It's now possible to enable email notifications for whenever a Schedule run fails to execute. To enable this, simply check the checkbox in Notification Settings..
  • +
+

7 August 2020

+
    +
  • It's now possible to change the name of your Provider accounts to e.g. something that's easier to remember.
  • +
+

5 August 2020

+
    +
  • Webhook.site had an unplanned outage starting at 03.30 UTC. The site was down for around an hour.
  • +
+

2 August 2020

+
    +
  • It is now possible to specify a default value in the Extract JSONPath, Extract Regex and Extract XPath actions, so that if the extraction could not find the item, the variable is set to the default value that is defined. This field also takes variables.
  • +
  • Request list is now sorted by Newest First per default.
  • +
  • Custom Action number and type is now shown next to the output in the request details. If the Action was deleted, the UUID is shown instead.
  • +
+

1 August 2020

+
    +
  • It is now possible to enable email notifications for whenever a Custom Action encountered an error. To enable this, simply check the checkbox in Notification Settings..
  • +
+

29 July 2020

+
    +
  • New WebhookScript function: trim(string), which removes space, newline and tab characters from the beginning and end of a string, similar to PHP's own trim() function.
  • +
  • New Schedule intervals: weekly (every monday), monthly (every 1st day of month)
  • +
+

25 July 2020

+
    +
  • New WebhookScript function: action(action_type, parameters), to run Custom Actions inside a WebhookScript. More info here.
  • +
  • It's now possible to download email attachments or uploaded files directly from the Webhook.site app.
  • +
  • When sending a request using either the Send Request Custom Action or the request() function, the response is now truncated if the response content is over 20KiB. This means the whole contents is not visible in the app, but is still available to Actions.
  • +
+

16 July 2020

+
    +
  • Better file handling for emails: attached files are now also extracted as variables
  • +
  • New file management functions for WebhookScript: files() retrieves a an array of all files, file_content(fileId) returns the content of a specific file. More info here.
  • +
+

5 July 2020

+
    +
  • New "Resize Image" action added for resizing images from either a file upload, email attachment or other Action.
  • +
  • Better handling of downloaded files: the contents won't be shown in the debug overlay to prevent very large files from crashing the browser.
  • +
  • Fixed a bug in the Dropbox provider returning creating an empty variable when downloading large files.
  • +
+

3 July 2020

+
    +
  • Webhook.site was down for about 30 minutes starting 07:20 UTC due to a memory upgrade.
  • +
  • Max request size has been increased to 10 MB from 2 MB.
  • +
+

23 June 2020

+
    +
  • Added new Dropbox Custom Actions: Create Folder, Download, Upload, Delete, Get Link.
  • +
+

14 June 2020

+
    +
  • WebhookScript editor syntax highlighting improved with regards to multiline strings, escape characters and more
  • +
  • New WebhookScript editor keyboard shortcut for saving (Mac: Cmd-S, Windows: Ctrl-S.)
  • +
  • Fix WebhookScript fullscreen mode not being disengaged when saving
  • +
  • URLs can now accept file uploads via multipart. File contents are available via variables: request.file.<formname>.content, request.file.<formname>.size, request.file.<formname>.filename
  • +
  • New WebhookScript function: csv_to_array(), which converts a CSV file from a string to an array that can easily be parsed.
  • +
  • Added an example script demoing file uploads and CSV parsing
  • +
+

7 June 2020

+
    +
  • Added new Slack Send Message Custom Action, which lets you send Slack messages via a Slack Webhook URL.
  • +
+

5 June 2020

+
    +
  • Added "Formula Mode" checkbox for Add and Update Row Google Sheets actions, which parses values like entered in a cell, and allows inserting formulas.
  • +
+

4 June 2020

+
    +
  • Added new endpoints to fetch the content and information about the latest request on a URL. See here and here.
  • +
+

2 June 2020

+
    +
  • Added Amazon Web Services CloudFront Cache Invalidation Custom Action.
  • +
  • Added ability to toggle Auto Cleanup, which automatically cleans up requests/emails.
  • +
+

30 May 2020

+ +

29 May 2020

+
    +
  • New set of date functions added to WebhookScript, namely: to_date(), date_format(), date_to_array(), date_interval(), date_interval_human(). Read more in the docs
  • +
+

25 May 2020

+
    +
  • New set of Amazon Web Services S3 actions: Create Bucket, Put Object, Delete Object and Get Object (which retrieves object contents to a Variable.)
  • +
+

22 May 2020

+
    +
  • New Schedule intervals: every 1 minute and every 10 minutes, in addition to the already existing ones.
  • +
+

17 May 2020

+
    +
  • New WebhookScript function: delay(), which lets you delay and execute WebhookScript code a set amount of seconds in the future.
  • +
  • New WebhookScript function: exec(), which lets you dynamically execute code in a string.
  • +
  • New WebhookScript function: import(), which downloads and executes code from a URL - great if you want to reuse your code, just put it on Github and import it with the URL!
  • +
+

16 May 2020

+
    +
  • It's now possible to set a Token (URL or email address) to expire automatically, even for Premium users. This is useful for creating tokens for automated testing.
  • +
+

3 May 2020

+
    +
  • New Google Sheets Custom Actions (Beta). 3 initial actions are available: Append Row, Update Row and Get Values, which allow you to manipulate or retrieve the values of a Google Sheet without writing any code.
  • +
+

24 April 2020

+
    +
  • New fullscreen mode in WebhookScript editor
  • +
  • Ability to edit your user profile
  • +
  • New WebhookScript functions: base64_encode(), base64_decode().
  • +
+

21 April 2020

+
    +
  • New WebhookScript function: store() - creates or updates an existing Global Variable
  • +
+

20 April 2020

+
    +
  • New Global Variables section in Control Panel.
  • +
+

19 April 2020

+
    +
  • New WebhookScript math functions: max(), min(), mod(), pi(), rand() - for more, see the Reference
  • +
+

28 March 2020

+
    +
  • New feature: Webhook.site Schedules lets you request any URL – including Webhook.site URLs – automatically on an interval, so you can for example run Custom Actions every 5 minutes, or make a health check for your Web site.
  • +
  • Send Request action request timeout has been raised from 5 to 10 seconds. Applies to both the Custom Action and the WebhookScript request() function.
  • +
+

24 March 2020

+
    +
  • New feature: API Keys can now be created so you can use the API with URLs that have the "Require Authentication" or "Password" options set.
  • +
  • Fix: It's now possible to test Send Email actions before creating them. Prior to this, the Test button would not do anything for the Send Email action.
  • +
+

6 March 2020

+
    +
  • New feature: Extract XPath Custom Action with accompanying xpath() WebhookScript function. Read more.
  • +
+

29 Feburary 2020

+
    +
  • Values are no longer required for Condition actions, so it's possible to compare an empty string or missing value.
  • +
  • Fixed an issue where a tooltip in the Custom Actions modal would not disappear.
  • +
  • Removed Beta label from WebhookScript.
  • +
+

27 Feburary 2020

+
    +
  • Fixed a bug where slashes at the end of Webhook.site Single Page App URLs didn't work.
  • +
  • Fixed a bug where Copy To CURL sometimes wouldn't return a valid CURL command.
  • +
+

26 Feburary 2020

+
    +
  • It's no longer a requirement to specify a variable for the Send Request action.
  • +
+

25 Feburary 2020

+
    +
  • New feature: It's now possible to receive emails, which are treated like Webhooks – so you can automate emails with Custom Actions on Webhook.site. You can also test email deliverability using DKIM, DMARC and SPF validation.
  • +
  • JSON formatting is now always enabled per default.
  • +
  • The requests view is cleared after deleting the last request, and the tutorial text is shown.
  • +
+

16 Feburary 2020

+
    +
  • WebhookScript: Added regex_extract and regex_extract_first functions.
  • +
+

15 Feburary 2020

+
    +
  • WebhookScript: Added hash function.
  • +
+

14 Feburary 2020

+
    +
  • New feature: Export to CSV lets you export all requests on a given URL to a CSV file.
  • +
  • Fixed a bug where duplicate in-app notifications would appear on new requests.
  • +
+

12 Feburary 2020

+
    +
  • WebhookScript: Added url_encode, url_decode, and query functions.
  • +
+

8 Febuary 2020

+
    +
  • New Custom Action type: Condition, which lets you conditionally stop a set of actions based on comparisons.
  • +
+

28 January 2020

+
    +
  • WebhookScript now supports newline literals (\\n) in strings, escaped by 2 backslashes.
  • +
+

25 January 2020

+
    +
  • +

    Global Variables are now available in the Control Panel, which lets you keep configuration like API keys in a separate place from your Custom Actions and scripts while managing them at a central place.

    +
  • +
  • +

    Changed the font of the WebhookScript editor, which resulted in uneven selection of text.

    +
  • +
+

23 January 2020

+
    +
  • You can now specify a source variable for JSONPath and Regex actions, so you can extract text from not only the request content.
  • +
+

12 January 2020

+
    +
  • Switched to using Ace as editor for WebhookScript.
  • +
+ +
+
+ + + Last update: + April 22, 2024 12:35:53 + + + +
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/open-source.html b/open-source.html new file mode 100644 index 0000000..dc2401d --- /dev/null +++ b/open-source.html @@ -0,0 +1,1264 @@ + + + + + + + + + + + + + + + + + + + + + + + + Install - Webhook.site Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + + + + + + +

Webhook.site Open Source

+

About the Open Source version

+

There are two separate editions of Webhook.site:

+
    +
  • +

    The code for the completely open-source, MIT-licensed version described on this page is available on https://github.com/webhooksite/webhook.site, and can be self-hosted using e.g. Docker, is great for testing Webhooks, but doesn't include Webhook.site Pro features like Custom Actions.

    +
  • +
  • +

    The cloud version of Webhook.site at https://webhook.site which has more features, some of them requiring a paid subscription.

    +
  • +
+

You can choose to run the Open Source version of Webhook.site either via Docker, or install it on any Web server with PHP7 support.

+

Realtime updates

+

laravel-echo-server or Pusher can be used to enable realtime updates. Take a look at the .env.example to see the environment variables required to configure it.

+

For laravel-echo-server, the app expects socket.io to be available at the /socket.io path relative to the index page. This can be done with nginx like so:

+
    location /socket.io {
+        proxy_pass http://127.0.0.1:6001;
+        proxy_http_version 1.1;
+        proxy_set_header Upgrade $http_upgrade;
+        proxy_set_header Connection 'upgrade';
+        proxy_set_header Host $host;
+        proxy_cache_bypass $http_upgrade;
+    }
+
+

Installation

+ +

The provided Docker Compose file sets up a complete environment that runs the Webhook.site image and all dependencies (Redis, Laravel Echo Server, etc.). Note that if running this in production, you should probably run a Redis server that persists data to disk. The Docker image is also not tuned for large amounts of traffic.

+

Installation Guide

+
    +
  1. Run docker-compose up
  2. +
  3. The app will be available on http://127.0.0.1:8084.
  4. +
+

Kubernetes

+

A set of Kubernetes configuration files can be found in the kubernetes subfolder.

+

Installation Guide

+

Configure the resources, and apply with kubectl apply -f ./.

+

Web Server

+

Requirements

+
    +
  • PHP 7
  • +
  • Redis
  • +
  • Composer
  • +
  • Web server – e.g. nginx, apache2
  • +
+

DigitalOcean has a guide on how to configure nginx.

+

Installation Guide

+
    +
  1. Run the following commands:
  2. +
  3. composer install
  4. +
  5. cp .env.example .env - adjust settings as needed
  6. +
  7. php artisan key:generate
  8. +
  9. Setup virtual host pointing to the /public folder.
  10. +
+ +
+
+ + + Last update: + April 6, 2024 10:34:57 + + + +
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/premium.html b/premium.html new file mode 100644 index 0000000..9b47fac --- /dev/null +++ b/premium.html @@ -0,0 +1,979 @@ + + + + + + + + + + + + + + + + + + + + Premium - Webhook.site Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + + + + + + +

Webhook.site Premium

+

Webhook.site Pro was formerly known as Premium. For more information, see here.

+ +
+
+ + + Last update: + April 6, 2024 10:34:57 + + + +
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/pro.html b/pro.html new file mode 100644 index 0000000..783a7f8 --- /dev/null +++ b/pro.html @@ -0,0 +1,1423 @@ + + + + + + + + + + + + + + + + + + + + + + + + Webhook.site Pro and Enterprise - Webhook.site Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + + + + + +
+
+ + + + + + + + + + + + + +

Webhook.site Basic, Pro and Enterprise

+

With Webhook.site Basic, Pro and Webhook.site Enterprise subscriptions, you get more features that allows you to do more with your URL, as well as keep the data contained private and secure.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FreeBasicProEnterprise
URLsn/a1UnlimitedUnlimited
Schedulesn/a1UnlimitedUnlimited
Custom Actions
Schedules
Custom Addresses
Secure Data
Permanent URLs
CSV Export
Free Email Support
Custom Domain
Multi-User Support
Request History100 (hard limit)10.000210.000210.0002
URL/Email Address expiry7 days1Never expiresNever expiresNever expires
Data storage duration7 days1365 days365 days365 days
Pricing3$9/month $90/year (save 20%)$18/month $180/year (save 20%)$49/month $499/year (save 20%)
+ + +
    +
  1. Free URLs and email addresses automatically expire and are permanently deleted after 7 days.
  2. +
  3. Pro and Enterprise URLs accept an unlimited amount of requests or emails, but only the latest 10.000 are available. Older requests are removed periodically.
  4. +
  5. All pricing in USD and excluding VAT. Local currency can be used at checkout.
  6. +
+

Pro features

+

Create workflows with Custom Actions

+

Extract data, send emails and HTTP requests, upload files, run scripts and much more with Custom Actions that are run on each incoming request or email, with the Webhook.site Custom Actions builder.

+

Native integrations for AWS, Google Sheets, Slack, Dropbox, MySQL and others.

+

Read more

+

Schedules

+

Use Schedules by Webhook.site to send requests any URL or run your Custom Actions automatically on an interval. Use it for monitoring your Web site, clearing caches, and much more. Supports cron syntax, in addition to predefined intervals.

+

Read more

+

Custom URLs and Emails

+

Get an address that's easy to remember:

+

webhook.site/my-alias

+

my-alias@email.webhook.site

+

(With Webhook.site Enterprise, you can even use your own domain name.)

+

Security

+

Your data is secured in your account, and can be accessed by API Key or login. With the free version of Webhook.site, others can freely view the requests sent to your URL.

+

Permanent URLs

+

The URLs stay in your account forever, the 7-day auto expiration of the free version is removed.

+

Store more than 500 requests or emails

+

With the free version, URLs stop taking in new requests or emails after the 500 request limit is reached. With Pro, the limit of max 500 requests or emails per URL is removed and raised to 10.000 requests or emails, which are then rotated automatically.

+

Unlimited URLs

+

Create as many upgraded URLs or email addresses as you need at no extra cost.

+

CSV Export

+

Export all requests and emails to a CSV file.

+

Localhost Forwarding

+

Forward requests to your Webhook.site URL to your local network via Webhook.site CLI.

+

Email Support

+

We’ll help you troubleshoot and set up your Custom Actions and workflows.

+

Enterprise features

+

In addition to all Pro features, Enterprise also contains the following features:

+

Custom Domain

+

Use a your own (sub)domain for URLs and emails:

+

mydomain.com/my-alias

+

my-alias@email.mydomain.com

+

Additionally, Webhook.site provides an SSL certificate which is included free of charge with your Enterprise subscription.

+

Multi-User Support

+

Ideal for larger organizations, share URLs, schedules, and other data with the rest of the organization. Configure individual users' access with User Types like Administrator and Viewer, so some users may only view the content.

+ +
+
+ + + Last update: + April 6, 2024 10:34:57 + + + +
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/schedules.html b/schedules.html new file mode 100644 index 0000000..4d930d7 --- /dev/null +++ b/schedules.html @@ -0,0 +1,1074 @@ + + + + + + + + + + + + + + + + + + + + + + + + Schedules - Webhook.site Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + + + + + + +

Webhook.site Schedules

+

Included in your Webhook.site subscription is Webhook.site Schedules, a feature that enables you to periodically send requests to specified URLs (including your Webhook.site URLs, so your Custom Actions can be executed periodially) with a custom method, headers, and interval.

+

Schedules can be used for a variety of purposes, including cache warming, uptime monitoring, automatic data transfer, etc.

+

After creating the Schedule, you can view the logs for the last 100 scheduled requests.

+

Per default, the timeout for the Schedule requests is 5 seconds, but can range from 1 to 30 seconds.

+

A timeout or server error will trigger a Schedule error notification email, if enabled in Control Panel -> Settings.

+

Schedules can also be managed using the Schedules API.

+

Schedules editor

+

Uptime monitoring & Requirements

+

If you create a Schedule and enable the When an error happens during a Schedule run setting, Webhook.site will automatically send an email notification when a URL has a timeout longer than the one specified, or when one of the requirements aren't met. It is possible to specify requirements for the response body containing a string, and the response status code being within a certain range.

+

Schedule Intervals

+

In addition to be able to use a custom cron-style expression string, Schedules can be executed at the following preset intervals:

+
    +
  • 1 minute
  • +
  • 5 minutes
  • +
  • 10 minutes
  • +
  • 1 hour
  • +
  • 24 hours (at 00:00)
  • +
  • Every week (mondays at 00:00)
  • +
  • Every month (1st day at 00:00)
  • +
+

Schedule intervals are based on UTC time.

+

For building cron-style expressions, we recommend https://crontab.guru.

+ +
+
+ + + Last update: + April 22, 2024 10:09:27 + + + +
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/search/search_index.json b/search/search_index.json new file mode 100644 index 0000000..c235cfa --- /dev/null +++ b/search/search_index.json @@ -0,0 +1 @@ +{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"index.html","title":"About Webhook.site","text":"

With Webhook.site, you instantly get a unique, random URL and e-mail address. Everything that's sent to these addresses are shown instantly. With this, you can test and debug Webhooks and HTTP requests, as well as create your own workflows using the Custom Actions graphical editor or WebhookScript, a simple scripting language, to transform, validate and process HTTP requests in a variety of ways \u2013 without setting up and maintaining your own infrastructure.

What are customers using Webhook.site for?

  • Receive Webhooks without needing an internet-facing Web server
  • Use Webhook.site as an intermediary, proxying requests and being able to see what was sent in the past
  • Send Webhooks to a server that's behind a firewall or private subnet
  • Transforming Webhooks into other formats, and re-sending them to different systems
  • Connect different APIs that aren't compatible
  • Building contact forms that send emails
  • Instantly build APIs without needing infrastructure

The following video is a quick demo of Webhook.site Custom Actions is used to set up a workflow to post updates from a news page to an X/Twitter account automatically.

"},{"location":"index.html#company-information","title":"Company information","text":"

Webhook.site is operated by Webhook ApS (VAT ID: DK41561718).

Address: Damhusvej 95, 3 tv, 5000 Odense, Denmark.

Founded and built by Simon Fredsted (@fredsted).

Contact information.

"},{"location":"index.html#acknowledgements","title":"Acknowledgements","text":"
  • The app was built with Laravel for the API.
  • Angular.js is used for the frontend SPA.
  • WebhookScript is based on Primi Copyright (c) P\u0159emysl Karbula.
  • The WebhookScript editor is using the Ace editor plugin.
  • JSONPath extraction provided by FlowCommunications.
  • This documentation site uses MkDocs with the Material theme.
  • Docs hosted by Github. Pull requests are appreciated!
"},{"location":"cli.html","title":"Webhook.site CLI","text":"

The Webhook.site Command Line Interface listens for requests to a Webhook.site URL and forwards/redirects them to your local computer or server.

Star

"},{"location":"cli.html#installation","title":"Installation","text":""},{"location":"cli.html#docker","title":"Docker","text":"

After installing Docker, you can run Webhook.site CLI via docker run:

docker run -ti webhooksite/cli -- whcli help

"},{"location":"cli.html#nodejs","title":"Node.js","text":"

Node version 14 or greater required.

To install: npm install -g @webhooksite/cli

Then you can run e.g. whcli help

"},{"location":"cli.html#environment-variables","title":"Environment variables","text":"

Some command arguments can be specified via environment variables:

    --token         WH_TOKEN\n    --api-key       WH_API_KEY\n    --target        WH_TARGET\n    --command       WH_COMMAND\n

General environment variables:

WH_LOG_LEVEL Sets log level (silent, trace, debug, info, warn, error, fatal.) Defaults to info.

"},{"location":"cli.html#variable-replacement","title":"Variable replacement","text":"

For some commands and arguments, runtime variables can be replaced with the standard Webhook.site Custom Actions syntax (e.g. $variable$). Global Variables are not replaced.

The variables that are available are the default base variables and any variables defined in a Custom Action that was run during the request.

"},{"location":"cli.html#commands","title":"Commands","text":""},{"location":"cli.html#help-list-commands","title":"help: List commands","text":"

Lists commands available to the CLI.

"},{"location":"cli.html#forward-forward-requests","title":"forward: Forward requests","text":"

The forward command listens for new incoming requests sent to your Webhook.site URL and immediately relays them to any URL you specify, or simply localhost (so it can be used as an ngrok alternative). This URL can be any URL that the machine running Webhook.site CLI can access.

  • The token ID (--token) parameter must specify the Webhook.site URL ID (also called token ID). The token ID is the long 36-character ID at the end of your Webhook.site URL.
  • An API key (--api-key) must also be specified when the token belongs to a Webhook.site account, and can be generated from the Webhook.site Control Panel.
  • Finally, the target (--target) specifies where traffic should be redirected (defaults to https://localhost)
"},{"location":"cli.html#example","title":"Example","text":"
whcli forward \\\n--token=1e25c1cb-e4d4-4399-a267-cd2cf1a6c864 \\\n--api-key=ef6ef2f8-3e48-4f77-a54c-3891dc11c05c \\ \n--target=https://example.com\n

Custom Action variables are replaced in the --target argument.

The request method, headers and any additional path or query string parameters added to the Webhook.site URL is forwarded on to the target. For example, if the target URL is https://example.com, sending a POST request to https://webhook.site/c33f3c3e-6018-4634-b406-65338edee460/example?query=value, the target URL will also receive a POST request on https://example.com/example?query=value.

"},{"location":"cli.html#docker-and-localhost","title":"Docker and Localhost","text":"

When running Webhook.site CLI in Docker, to access the host machine, you can't use localhost or 127.0.0.1. Instead, use the special hostname host.docker.internal. More info here.

"},{"location":"cli.html#self-signed-certificates","title":"Self-signed certificates","text":"

If the target uses a self-signed certificate, you could get an error message about this. To allow self-signed certs, run whcli with the following environment variable and value:

NODE_TLS_REJECT_UNAUTHORIZED=\"0\"\n
"},{"location":"cli.html#exec-execute-commands","title":"exec: Execute commands","text":"

Allows executing terminal commands for new incoming requests sent to your Webhook.site URL. Custom Action variables are replaced in the --command argument.

"},{"location":"cli.html#example_1","title":"Example","text":"
whcli exec \\\n--token=1e25c1cb-e4d4-4399-a267-cd2cf1a6c864 \\\n--api-key=ef6ef2f8-3e48-4f77-a54c-3891dc11c05c \\ \n--command='ping $request.ip$'\n
"},{"location":"custom-actions.html","title":"Custom Actions","text":"

With Custom Actions, it is possible to create a workflow out of a set of actions that are executed whenever a Webhook.site URL receives a request or email.

Using this functionality, you can connect APIs that aren't compatible, convert a HTTP request to an email or vice versa, build workflows that would otherwise require a developer, and much, much more.

"},{"location":"custom-actions.html#demos","title":"Demos","text":""},{"location":"custom-actions.html#javascript-x-and-schedules","title":"JavaScript, X and Schedules","text":"

In this video I'm doing a quick demo of how I used Webhook.site to set up a workflow to post updates from my news page automatically to my X/Twitter account. I used the actions JavaScript, Conditions, X Post, and Store Global Variable.

"},{"location":"custom-actions.html#jsonpath-and-google-sheets","title":"JSONPath and Google Sheets","text":"

In the following demo, webshop order details are received in a webhook. We then use Extract JSONPath and Google Sheets actions to insert their name in a Google Sheet. It also shows how variables interact with downstream actions.

"},{"location":"custom-actions.html#templates","title":"Templates","text":"

If you use the same set of Custom Actions often, you can create a Template that contains a copy of one or more Custom Actions, along with a set of Predefined Variables.

You can then use this template by creating an Import Template action.

"},{"location":"custom-actions.html#creating-a-template","title":"Creating a Template","text":"

To create a Template, click the Create Template button at the bottom of the Custom Actions overlay. Then enter a name for the template and select which actions should be copied to the template. If your template actions e.g. depend on variables pre-existing, like configuration data, you can add one or more Predefined Variables. These are available to the actions in the Template, but also to any subsequent actions coming after the Import Template action.

Predefined Variables can be updated in the Control Panel.

Changes to the actions that the Template was created from do not automatically carry over to the template. Instead, Templates can be updated post-creation by overwriting them with a new set of actions.

Templates can also be managed using the Template API.

"},{"location":"custom-actions.html#repeating-actions","title":"Repeating Actions","text":"

Webhook.site allows some action types to be repeating, which makes Webhook.site \"loop over\" one or more values without needing to use scripts.

Currently, repetition is only supported by the Extract JSONPath and Extract Regex action types.

Currently, the maximum amount of items that are supported is 100 to prevent abuse. This limit may be raised in the future. Items above that are ignored.

The repeating action should be ordered before the actions that are to be repeated. The actions that are repeated will run for each item that is extracted, using the same variable name.

"},{"location":"custom-actions.html#queued-actions","title":"Queued Actions","text":"

By checking the Queued checkbox when creating a Custom Action, Webhook.site will run the action in an asynchronous background queue.

This is useful when you need your Webhook.site URL to respond quickly, but your Custom Actions are taking a long time to run. For example, if your Webhook.site URL should respond in 5 seconds, but you need to call an endpoint with a HTTP Request action that responds in 10 seconds, you can queue the HTTP Request action.

Additionally, you can specify an amount of seconds to wait until the action is executed. To do this, enter an amount of seconds in the Seconds textbox next to the Queue checkbox.

As the queued action will inherit the execution scope up until the action, there are a few things to be aware of when using Queued Actions:

  • Variables defined in non-queued actions ordered before the queued action will be available to the action.
  • If several consecutive actions are marked as queued, and their delay is identical, they will pass variables and execute in order.
  • Variables defined by a queued action are not available to non-queued actions coming after it. You cannot, for example, mark a HTTP Request action as queued and use the response in a Modify Response action.
  • The amount of time until the queued actions are executed can vary by a few seconds.
"},{"location":"dnshook.html","title":"DNSHook by Webhook.site","text":""},{"location":"dnshook.html#what-is-dnshook","title":"What is DNSHook?","text":"

Webhook.site DNSHook is a type of hook, like webhooks and emailhooks, that on Webhook.site will automatically show all DNS requests to a unique DNS name and all its subdomains.

DNSHooks can be used to send data solely via DNS. DNSHooks can also be used as a canary token as DNS can be useful in cases where it can bypass firewalls, for example.

"},{"location":"dnshook.html#create-dns-workflows-with-custom-actions","title":"Create DNS workflows with Custom Actions","text":"

You can even create workflows from DNSHook requests with Custom Actions.

For example, you can send a notification to your phone whenever a specific subdomain has had its DNS looked up via the Ntfy action.

"},{"location":"dnshook.html#receive-data-via-dns","title":"Receive data via DNS","text":"

As all subdomains are also logged and shown on Webhook.site, you can send data in DNSHooks by e.g. base64-encoding a subdomain. For example, the string hello world can be encoded in a DNS lookup as the following.

aGVsbG8gd29ybGQ.47bb8761-e40b-42c2-8c98-a448f492df70.dnshook.site\n

(In this case, aGVsbG8gd29ybGQ base64-decodes to hello world and 47bb8761-e40b-42c2-8c98-a448f492df70 is the ID of the Webhook.site token/URL.)

Indeed, you can even use different record types, like CNAME and MX, as flags to transfer information to Webhook.site.

"},{"location":"dnshook.html#send-dns-response","title":"Send DNS Response","text":"

You can also set the DNS response dynamically by using the URL response in the following format. You can return one or more responses.

[\n{\n\"type\": \"a\",\n\"value\": \"127.0.0.1\"\n},\n{\n\"type\": \"cname\",\n\"value\": \"example.com.\"\n},\n{\n\"type\": \"txt\",\n\"value\": \"hello world\"\n}\n]\n

To set the response, either enter the JSON in Edit \u2192 Content, or use the Modify Response Custom Action and setting the Response Body field.

type can be one of the following:

  • a
  • cname
  • txt

Note: If the response isn't valid (e.g. invalid JSON, using a domain name in an A record), no response is returned. It is currently not possible to be notified of DNS parsing errors, so make sure to test this well.

For txt responses, multiple lines can be sent by separating with \\n (newline).

"},{"location":"faq.html","title":"Webhook.site Frequently Asked Questions","text":""},{"location":"faq.html#whats-a-webhook","title":"What's a webhook?","text":"

The term 'webhook' refers to the general technology of Web-based systems communication.

In short, many systems (e.g. a payment platform and a customer management system) communicate with each other by sending Web requests back and forth, e.g. from https://paymentsys.example to https://customersys.example/register-payment.

We don't offer support or help with general questions or issues with webhooks. More about webhooks.

"},{"location":"faq.html#whats-webhooksite","title":"What's Webhook.site?","text":"

Webhook.site is a tool for building software that use webhooks, either by allowing developers to inspect the data that's being sent via a webhook, but also helps users create workflows that respond to and interact with webhooks from various systems.

With Webhook.site, users instantly get a unique, random URL and e-mail address. Everything that's sent to these addresses are shown instantly. With this, users can test and debug Webhooks and HTTP requests, as well as create workflows using the Custom Actions graphical builder or WebhookScript, a simple scripting language, to transform, validate and process HTTP requests in a variety of ways \u2013 without setting up and maintaining your own infrastructure.

Webhook.site company stats as of March 2024:

  • Registered corporation since August 2020
  • 250.000+ monthly unique users
  • 1600+ subscribed customers
  • Handles more than 250 million requests per day
"},{"location":"faq.html#is-my-data-private","title":"Is my data private?","text":"

Yes. Per default, all URLs associated with a paid Webhook.site subscription are protected with login. Additionally, users can decide exactly how much (or little) data Webhook.site stores, either by amount of requests/emails or

For free users, data is accessible to anyone who knows the ID of the URL.

"},{"location":"faq.html#can-i-use-webhooksite-for-production-workloads","title":"Can I use Webhook.site for production workloads?","text":"

Yes. Thousands of our customers use Webhook.site to build workflows that help their business, without needing to hire a programmer or pay for and setup servers. We take care of the infrastructure so you can build what you need.

"},{"location":"faq.html#how-much-data-does-webhooksite-store","title":"How much data does Webhook.site store?","text":"

For each URL associated with a Webhook.site Pro account, Webhook.site makes the latest 10.000 requests or emails available. Old requests are automatically rotated/purged periodically.

For free users, the amount is 100 and old requests are not automatically rotated. Instead, the URL stops accepting new requests after the limit has been met.

"},{"location":"faq.html#how-long-is-data-stored-on-webhooksite","title":"How long is data stored on Webhook.site?","text":"

For Free users, the URL \u2013 and its data \u2013 is automatically removed after 7 days with no activity.

For Pro and Enterprise URLs, URLs never automatically expire, but data is removed after 365 days.

"},{"location":"faq.html#how-do-i-transfer-my-webhooksite-account-and-data","title":"How do I transfer my Webhook.site account and data?","text":"

To hand over your account to a different business or individual you essentially only need to change the email address, as it is the only piece of identification we store. However, be aware of the following:

  1. If billing details need to change, make sure to cancel the subscription first. The subscription will continue to work until the expiry date.

  2. If 2-Factor Authentication is enabled, disable 2-Factor.

  3. For Enterprise users, make sure you delete any extraneous users.

  4. Delete any extraneous API keys that you should no longer have access to.

  5. Change the account email address to the receiver's email address.

  6. You, or the account receiver, can then issue a Password Reset email so they can set their own password.

  7. The account receiver can then create a new subscription on the account.

After this, you will no longer have access to your account and it is fully handed over.

"},{"location":"faq.html#i-want-to-whitelist-webhooksite-in-our-firewall-which-ip-do-you-use","title":"I want to whitelist Webhook.site in our firewall, which IP do you use?","text":"

You'll need to whitelist the IPs 46.4.105.116 and 88.99.82.58.

Both inbound and outbound originate and destinate at this IP address.

Note that this may change in the future, so sign up for the newsletter to be notified of changes.

"},{"location":"faq.html#how-do-i-add-authentication-to-my-url","title":"How do I add authentication to my URL?","text":"

You can use the Conditions Custom Action to add a quick header based authentication mechanism to your URL. You can also add the Don't Save action as a condition if you don't wish to save the unauthenticated request.

We also have an example WebhookScript for adding basic auth:

username = 'john'\npassword = '1234'\nif (var('request.header.php-auth-user', '') != username and var('request.header.php-auth-pw', '') != password) {\nrespond('', 401, ['WWW-Authenticate: Basic realm=\"Authentication required\"']);\ndont_save()\n}\nrespond('Login OK!');\n
"},{"location":"faq.html#can-i-get-a-push-notification-on-my-phone-when-my-url-receives-a-request","title":"Can I get a push notification on my phone when my URL receives a request?","text":"

Via Custom Actions, Webhook.site supports the service Pushed, which has a free tier. More info here.

Alternatively, at least on iPhones, you can use the Send Email custom action and mark the sender address as VIP. This will trigger a push notification when the email is received.

"},{"location":"faq.html#can-i-pay-via-invoice","title":"Can I pay via invoice?","text":"

After you've paid for and created a subscription, you will receive an invoice via email.

If you are an enterprise customer that wishes to buy a subscription via bank transfer, please contact Support.

"},{"location":"faq.html#how-do-i-add-my-company-name-to-my-invoice","title":"How do I add my company name to my invoice?","text":"

Go to Control Panel -> Billing, then click View next to an invoice and finally click the \"Add Address & VAT Number\" link.

"},{"location":"faq.html#how-can-i-see-the-pricing-in-my-currency","title":"How can I see the pricing in my currency?","text":"

Once you start the checkout process, you will see the amount in your local currency, including any applicable VAT.

"},{"location":"faq.html#the-json-data-is-in-a-weird-formatcant-be-parsed-by-extract-jsonpath","title":"The JSON data is in a weird format/can't be parsed by Extract JSONPath","text":"

The JSON data might have been attached to the request as form data rather than as request body data, which is usually how JSON is sent.

The data might look like this on Webhook.site:

To remediate this in Extract JSONPath, you'll need to set the source field to the form field variable, which is automatically set by Webhook.site. In the screenshot above, the variable name would be $request.form.my_json_data$, which works with Extract JSONPath:

"},{"location":"faq.html#json-data-is-invalid-when-using-the-http-request-action","title":"JSON data is invalid when using the HTTP Request action","text":"

If you use any variables in the JSON that could contain e.g. new lines or quote characters, these characters need to be \"escaped\" properly so that the JSON remains valid.

Webhook.site provides an easy way to do this with the .json Variable Modifier, which will automatically escape any special JSON characters. More info here.

Before:

{\n\"message\": \"$request.query.message$\"\n}\n

After, with the JSON Escape Variable Modifier:

{\n\"message\": \"$request.query.message.json$\"\n}\n
"},{"location":"faq.html#how-do-i-export-the-data-stored-on-webhooksite","title":"How do I export the data stored on Webhook.site?","text":"

With Webhook.site Pro, there's a variety of different ways to export data sent to your URL or email address.

  1. Custom Actions can be used in a variety of ways to export data. Below are listed a few examples of actions that could be used. More info here.

    • Database Query
    • HTTP Request
    • Run SSH Command
    • Amazon Web Services S3
    • Dropbox
  2. Webhook.site provides a CSV Export functionality, simply click the button in the menu to download all data as a CSV file.

  3. Data can be retrieved and saved using the Webhook.site API using any programming language.

  4. With the Webhook.site CLI (Command-Line Interface), requests can be forwarded directly from Webhook.site to a local workstation or server. More info here

"},{"location":"faq.html#how-do-i-send-data-to-my-computerlocalhost","title":"How do I send data to my computer/localhost?","text":"

There's several ways to accomplish this depending on your needs.

  1. You can periodically fetch the data using the Webhook.site API

  2. Requests can also be streamed to a local URL using the Webhook.site CLI, in a similar fashion to e.g. ngrok.

  3. Webhook.site also supports the XHR Redirect feature, which uses your browser in order to forward the requests. The endpoint will need to respond with CORS headers in all requests so that the browser will be able to send requests to it. The forwarding will only work as long as the browser window is open.

The following CORS headers should allow Webhook.site to forward requests to your local endpoint via XHR Redirect:

Access-Control-Allow-Origin: *\nAccess-Control-Allow-Methods: *\nAccess-Control-Allow-Headers: *\nAccess-Control-Expose-Headers: Content-Length,Content-Range\n
"},{"location":"faq.html#how-can-i-test-an-ipv6-only-request","title":"How can I test an IPv6-only request?","text":"

If you access Webhook.site with the hostname https://ipv6.webhook.site, your URL will only work with IPv6.

To use it with a URL, simply replace the webhook.site hostname with ipv6.webhook.site.

"},{"location":"faq.html#im-getting-a-404-not-found-whats-wrong-when-does-webhooksite-urls-expire","title":"I'm getting a 404 Not Found, what's wrong? / When does Webhook.site URLs expire?","text":"

Using the free version of Webhook.site, URLs automatically expire in 7 days. After that, the URL is no longer available and data is deleted.

With the paid version, Webhook.site Pro, URLs never expire automatically.

"},{"location":"faq.html#im-getting-a-405-method-not-allowed-whats-wrong","title":"I'm getting a 405 Method Not Allowed, what's wrong?","text":"

You might be copying the URL for the Webhook.site application (by copying the link from your browsers' address bar), and not the actual URL.

Webhook.site app (\u26d4\ufe0f wrong):https://webhook.site/#!/view/6dbb3859-4ad5-4e85-acae-e44d6e37ea4a

Webhook.site url (\u2705 correct):https://webhook.site/6dbb3859-4ad5-4e85-acae-e44d6e37ea4a

"},{"location":"faq.html#im-getting-a-429-too-many-requests-whats-wrong","title":"I'm getting a 429 Too Many Requests, what's wrong?","text":"

First, make sure that you have copied the correct URL, see here.

For free users: The URL has met the limit of the amount of requests it can receive. To unlock more requests, the URL must be associated with a Webhook.site Pro or Enterprise account. To associate a URL to your account, click Upgrade in the upper-right corner when logged in.

For Webhook.site Pro or Enterprise users: If you're getting this error with a Webhook.site URL, the URL may have been automatically blocked due to an extraordinarly large amount of requests, as per the Fair Use guidelines in our Terms of Service. This is done to prevent a decrease in service level for our other customers. For more info, or to request a whitelisting, please contact Support. If you're getting this error with a Webhook.site API endpoint, you have exceeded the API endpoint quota, and should implement e.g. a backoff strategy.

"},{"location":"faq.html#im-getting-a-413-payload-too-large-whats-wrong-whats-the-request-size-limit","title":"I'm getting a 413 Payload Too Large, what's wrong? / What's the request size limit?","text":"

The HTTP body data (e.g. files or JSON data) submitted to Webhook.site must be below 10 megabytes. More than that will cause a HTTP 413 response.

"},{"location":"faq.html#im-getting-an-access-control-check-error","title":"I'm getting an \"Access Control Check error\"","text":"

If you're requesting the Webhook.site endpoint from another domain via JavaScript, you'll need to enable CORS so the browser allows the request.

To do this, click Edit in the upper-right corner, check the Add CORS headers checkbox, and click Save.

"},{"location":"faq.html#im-getting-a-certificate-expired-error","title":"I'm getting a \"Certificate Expired\" error","text":"

Our SSL certificate is fully working; the issue lies with your system. In september 2021, our SSL provider, LetsEncrypt, updated their root certificate. This can mean that if your locally installed trusted root certificates are of an old version, you'll be seeing a certificate error as Webhook.site now runs a certificate that is based on the new root certificate chain.

To remediate this problem, you'll need to update your local certificate trust store:

  • Debian-based systems: Use update-ca-certificates; more info here.
  • Red Hat based systems: yum update ca-certificates; more info here

Some systems and packages, like Python certifi/urllib3, also come with static certificates. We cannot support updating these.

"},{"location":"faq.html#what-is-a-dnshook","title":"What is a DNSHook?","text":"

For more information about DNSHook, please see here.

"},{"location":"jobs.html","title":"Webhook.site Jobs","text":"

Webhook.site is a small startup that's fully remote. We believe in absolute trust in our employees. What's important to us is your work output and communication, not how many hours you spend. You'll be working at a company with a lot of dedicated and passionate customers that use the product to solve real problems in their work.

"},{"location":"jobs.html#support-engineer-part-time","title":"Support Engineer (part time)","text":""},{"location":"jobs.html#job-roles","title":"Job Roles","text":"
  • Work on and resolve customer support tickets.
  • Respond within 24 hours.
  • Solve problems for customers.
  • Help setting up Custom Actions.
  • Handle billing issues.
  • Identify and track bugs and feature requests.
"},{"location":"jobs.html#requirements","title":"Requirements","text":"
  • Excellent English language skills
  • Experience with writing JavaScript or similar
  • Experience with Web technologies: HTTP, FTP
"},{"location":"jobs.html#description","title":"Description","text":"

Customers use Webhook.site to solve a wide variety of problems, and it's your job to help them use Webhook.site to complete their goals.

Users can be at the beginner to intermediate stage in terms of their understanding of Internet technology, scripting etc., and often you\u2019ll need to sense what the actual problem is\u2013which can be wildly different from what the support ticket is about.

100% remote. Around 10 hours per week.

To apply, send an email to jobs@webhook.site. We expect you to send us a CV along with a short email describing yourself, and then we'll do a half-hour video call to talk about the job and any questions you may have. If we decide to hire you, you'll be able to start as soon as you like.

"},{"location":"jobs.html#full-stack-developer-part-timefull-time","title":"Full-Stack Developer (part time/full time)","text":""},{"location":"jobs.html#job-roles_1","title":"Job Roles","text":"
  • Reorganize Webhook.site code
  • Upgrade PHP version / frameworks / dependencies
  • Optimize request times and performance
  • Fix bugs
  • Implement new features
  • Write documentation (here!) for work done
"},{"location":"jobs.html#requirements_1","title":"Requirements","text":"
  • Excellent English language skills
  • Professional experience with at lease one of:
    • PHP
    • Angular.js
  • Professional experience with:
    • Git
    • Linux
    • Docker
"},{"location":"jobs.html#description_1","title":"Description","text":"

Webhook.site is a complex Laravel and Angular.js based system with more than 100.000 monthly unique users which use it for everything from Webhook API development to workflow automation using Webhook.site\u2019s Custom Actions feature. Much of the site is a REST API with an Angular.js client in addition to some Blade pages.

Your job is to continuously improve on the codebase, whether it\u2019s code organisation, framework and dependency updates, implementing new features and fixing bug tickets.

The job is paid hourly, and you\u2019ll be 100% free to schedule your work as you see fit and work as may or as few hours as you like.

To apply, send an email to jobs@webhook.site. We expect you to send us a CV along with a short email describing yourself, and then we'll do a half-hour video call to talk about the job and any questions you may have. If we decide to hire you, you'll be able to start as soon as you like.

"},{"location":"news.html","title":"News","text":"

Subscribe below to receive updates about improvements and new features on Webhook.site as well as infrastructure changes like new IP addresses for e.g. firewall whitelisting. Expect a newsletter a few times a year at most.

"},{"location":"news.html#22-april-2024","title":"22 April 2024","text":"
  • If a default Custom Domain is specified and is validated for email, it's now used as the sender address in the Send Email action (applies to new URLs only.)
  • Improved display of text content of incoming emails - links are now clickable and quotes are indented.
  • Fixed \"401 Missing Password\" error when saving configuration of Tokens that have a password set.
"},{"location":"news.html#15-april-2024","title":"15 April 2024","text":"
  • Webhook.site now uses the domain emailhook.site for email receiving and sending. The old domain, email.webhook.site, continues to work.
  • JavaScript action now supports Global Variables via the built-in store() and global() functions. More info and examples here
  • JavaScript action no longer considered in beta.
  • New API: Global Variables. More info here
  • Webhook.site CLI forward command now defaults to https://localhost for the --target parameter.
"},{"location":"news.html#9-april-2024","title":"9 April 2024","text":"
  • Action Editor improvements: drag and drop to change order of actions is now supported, improved renaming of actions, textboxes have been set to proper sizes
"},{"location":"news.html#18-march-2024","title":"18 March 2024","text":"
  • New Feature: DNSHooks, which will automatically show all DNS requests to your unique DNS name, and all its subdomains. It can be used to send data solely via DNS, or as a canary token. More info here
"},{"location":"news.html#13-march-2024","title":"13 March 2024","text":"
  • HTTP headers with underscores are no longer ignored. However, underscores are converted to dashes due to a technical limitation.
  • When a search query is set, Webhook.site will now only show incoming requests and emails that match the search query.
  • Search queries are now stored in the browser's local storage, so it will be saved even after closing the browser.
"},{"location":"news.html#1-march-2024","title":"1 March 2024","text":"
  • Fixed a bug where the $request.query$ Base Variable not being generated.
"},{"location":"news.html#29-feburary-2024","title":"29 Feburary 2024","text":"
  • Webhook.site now automatically decompresses gzip encoded request bodies.
"},{"location":"news.html#26-feburary-2024","title":"26 Feburary 2024","text":"
  • New features for \"Set Variable\" action: The Set Variable action can now generate random strings, date strings and timestamps. More info here
"},{"location":"news.html#20-feburary-2024","title":"20 Feburary 2024","text":"
  • New Feature: Templates, which are created out of existing Custom Actions, and can be reused via the Import Template Custom Action. More info here Template API
  • Webhook.site CLI: Better logging and can now be used for free users without API key.
"},{"location":"news.html#7-feburary-2024","title":"7 Feburary 2024","text":"
  • faker library added to the JavaScript Custom Action. More info here
"},{"location":"news.html#6-feburary-2024","title":"6 Feburary 2024","text":"
  • Tokens now support timeouts up to 30 seconds, from 10 before, which allows more flexibility when testing application timeouts.
  • Tokens with timeouts are now have a dynamic rate limit. More info here
  • Updates to our Terms of Service and Privacy Policy. Summary:
    • Adding language specifically prohibiting submitting illegal content to Webhook.site
    • Fair Use policy has been updated to a \"requests per minute\" metric (from 10000 requests per day), and a guideline for 100 Tokens created per day when the \"expiry\" option is used
    • Added language about intellectual property rights, disclaimer of warranties, limitation of liability, indemnification, modification of terms, termination and governing law and jurisdiction.
"},{"location":"news.html#29-january-2024","title":"29 January 2024","text":"
  • Split Text action now supports repeating. More info here
  • Split Text action now recognizes the string \\n as a newline, allowing splitting strings by line.
"},{"location":"news.html#15-january-2024","title":"15 January 2024","text":"
  • Dynamic Request Limits: Webhook.site URLs/Tokens can now have custom request limits, from 1 to 10000, which is great when you're concerned about the data stored on Webhook.site. With this, you can limit the request history to the amount you choose.
"},{"location":"news.html#11-january-2024","title":"11 January 2024","text":"
  • New $request.path$ (contains any subpath after the Webhook.site URL ID) and $request.query$ (contains the query string) variables added. More info here
  • Don't Save, Rate Limit and Modify Response actions can no longer be marked as Queued.
"},{"location":"news.html#10-january-2024","title":"10 January 2024","text":"
  • Requests API: It's now possible to delete a subset of requests using the date_from, date_to, and query parameters. More info here.
"},{"location":"news.html#9-january-2024","title":"9 January 2024","text":"
  • HTTP Request action: Fixed an issue where headers wouldn't be forwarded when using the Forward mode.
"},{"location":"news.html#3-january-2024","title":"3 January 2024","text":"
  • Happy New Year :-)
  • Webhook.site now supports 2-factor authentication via TOTP. To enable, go to Control Panel -> User Profile.
"},{"location":"news.html#27-december-2023","title":"27 December 2023","text":"
  • New WebhookScript function: http(), which replaces the request() function and allows for more flexibility as well as sending e.g. form/multipart requests as the new HTTP Request Custom Action also allows. More info here
"},{"location":"news.html#22-december-2023","title":"22 December 2023","text":"
  • The new Custom Action HTTP Request has replaced Send Request, which has several benefits:
    • HTTP Request has different modes: text, multipart, etc., which lets you build more forms of HTTP requests that couldn't be done using Send Request.
    • The Forward mode is now able to forward Multipart requests.
    • Both the request and response are now saved so you can see exactly what was sent to the URL in HTTP Request.
    • The HTTP Request has a handy Format JSON button.
  • It is still possible to make changes to existing Send Request actions, but it is no longer possible to create new Send Request actions.
"},{"location":"news.html#7-december-2023","title":"7 December 2023","text":"
  • Image files are now previewed in the file list, e.g. for email attachments
  • Binary requests with content-types including image/*, video/* and application/pdf are now shown as linked files in the file list, not binary data.
"},{"location":"news.html#6-december-2023","title":"6 December 2023","text":"
  • Token (URL) expiry is now configurable with an amount of seconds. More info here
"},{"location":"news.html#28-november-2023","title":"28 November 2023","text":"
  • New Custom Action: JavaScript. It is now possible to run JavaScript/Node.js code in your Custom Actions. This action is marked as beta as some limitations apply. More info and examples here
"},{"location":"news.html#7-november-2023","title":"7 November 2023","text":"
  • New Custom Actions: Microsoft Excel. Webhook.site now allows using your Microsoft account to append and retrieve data from Excel worksheets in your OneDrive account.
  • New Custom Actions: Microsoft OneDrive. With Webhook.site, you can now use your Microsoft account to upload and download files in your OneDrive account.
  • It's now possible to test IPv6-only traffic using the ipv6.webhook.site hostname. More info here
"},{"location":"news.html#31-october-2023","title":"31 October 2023","text":"
  • New feature when testing actions: Test Until Here, which allows testing only the actions up until and including the currently selected action. This is useful when, for example, testing a flow that extracts data and sends an email, but you just want to test how data is extracted, and not sending the email (which is usually the last action.)
"},{"location":"news.html#25-october-2023","title":"25 October 2023","text":"
  • Schedules now have support for requirements which will send an error notification emails when they don't pass, making it an easy option for e.g. uptime monitoring. Currently supported requirements are \"Response body must contain\" and \"Response status code must be in range\". More info here
  • Webhook.site will now highlight the last viewed URL after logging in.
"},{"location":"news.html#19-october-2023","title":"19 October 2023","text":"
  • Queued Custom Actions that share the same delay are now run in groups, so they can share data and variables. This makes it possible to create more advanced workflows that run in the future.
"},{"location":"news.html#12-october-2023","title":"12 October 2023","text":"
  • New Custom Action: Auto JSON. Automatically converts JSON data into Webhook.site Variables. More info here
"},{"location":"news.html#11-october-2023","title":"11 October 2023","text":"
  • Custom Actions editor modal dialog has been changed to an overlay, which allows for more space to edit actions.
  • Moved Delete Action button to avoid accidentally deleting actions.
  • WebhookScript editor and action output panel can now be resized.
"},{"location":"news.html#22-september-2023","title":"22 September 2023","text":"
  • New update for Webhook.site CLI, a tool for interacting with the Webhook.site API and allows forwarding requests from your Webhook.site URL to your local network. More info here
"},{"location":"news.html#21-september-2023","title":"21 September 2023","text":"
  • New Custom Action: Split Text. Takes a source, delimiter and variable name prefix and splits text into X amount of variables.
  • New Custom Action: Map Text. Takes a source, an operator (like the Conditions action) and a series of mappings and sets the resulting variable name to whether one of the mappings are a match to the source text.
"},{"location":"news.html#15-september-2023","title":"15 September 2023","text":"
  • It's now possible to name individual Custom Actions, so you can keep track of which action does what. To change the name of an action, click the dashed name at the top of the action editor when creating or editing an action.
  • The Variables dropdown shows all available variables after clicking the Test button.
  • Variables section of the Custom Actions editor now allows copying each variable name.
"},{"location":"news.html#14-september-2023","title":"14 September 2023","text":"
  • New Custom Action: SFTP Upload
  • The Run SSH Command action now supports regular password authentication in addition to standard keypair authentication.
"},{"location":"news.html#30-august-2023","title":"30 August 2023","text":"
  • Send Email action: It's now possible to add attachments to the email being sent.
  • Send Email (SMTP) action: It's now possible to add attachments to the email being sent.
  • WebhookScript: The json_encode function now allows disabling JSON formatting.
"},{"location":"news.html#11-august-2023","title":"11 August 2023","text":"
  • WebhookScript: New delete() function added for deleting Global Variables.
"},{"location":"news.html#4-august-2023","title":"4 August 2023","text":"
  • Improvements to Dark Mode.
"},{"location":"news.html#29-july-2023","title":"29 July 2023","text":"
  • Custom Actions: Maintenance was carried out on the underlying database system storing Custom Actions, and this may have resulted in 500 errors for around a minute starting 14:10 UTC.
"},{"location":"news.html#20-july-2023","title":"20 July 2023","text":"
  • New WebhookScript function: multipart(), for sending HTTP multipart requests. More info here.
  • Webhook.site can now send browser notifications to alert you of new emails or requests.
  • Added \"Mark all as read\" button.
"},{"location":"news.html#29-june-2023","title":"29 June 2023","text":"
  • For teams using Custom Domains, it's now possible to specify a default domain in Control Panel that will be shown anywhere the Webhook.site URL can be copied, for example.
"},{"location":"news.html#16-june-2023","title":"16 June 2023","text":"
  • Dark Mode has been added to the user interface for Webhook.site.
"},{"location":"news.html#7-june-2023","title":"7 June 2023","text":"
  • New Custom Action: Send Push Notification via ntfy.sh. Allows you to easily send push notifications to your browser, phone, watch, etc. Simply download the ntfy.sh app, subscribe to your topic name and send a message to the topic name via this Custom Action. No account required.
"},{"location":"news.html#22-may-2023","title":"22 May 2023","text":"
  • Webhook.site was down from approximately 10:45 to 11:30 UTC. The cause was a customer abusing the Delay Action feature which caused a buildup of data. As a result, we've had to reset the \"delayed action\" queue, meaning that any delayed actions not executed at 10:00 UTC today have been lost. Any newly created delayed actions will still be run as of 12:00 UTC. We apologize for the inconvenience.
"},{"location":"news.html#21-may-2023","title":"21 May 2023","text":"
  • We've carried out an upgrade of some of the underlying software powering Webhook.site. As a result, Webhook.site should generally perform faster.Beginning 10:45 UTC, there may have been instances of increased error rates. As of 12:00 UTC, these issues have been resolved. We apologize for the inconvenience. As always, if you experience issues with your Webhook.site URLs, Custom Actions, etc., please let us know at support.webhook.site.
"},{"location":"news.html#20-may-2023","title":"20 May 2023","text":"
  • Custom Domains now show the exact error reason in Control Panel.
"},{"location":"news.html#18-may-2023","title":"18 May 2023","text":"
  • Fixed an issue where the Custom Domain setup email wouldn't show the correct DNS entries.
"},{"location":"news.html#28-april-2023","title":"28 April 2023","text":"
  • Free URLs now accept a maximum of 500 requests in total. Deleting requests won't allow the URL to accept more requests. We encourage upgrading to Webhook.site Pro or Enterprise to avoid these limitations.
"},{"location":"news.html#26-april-2023","title":"26 April 2023","text":"
  • New API for Groups. More info here.
  • It's now possible to use Unicode characters like emojis in user names, group names, etc.
  • WebhookScript: xml2array() logs more helpful errors.
"},{"location":"news.html#16-april-2023","title":"16 April 2023","text":"
  • New WebhookScript function: xml2array(). More info here.
  • Conditions action: It's now possible to delete individual conditions.
"},{"location":"news.html#21-march-2023","title":"21 March 2023","text":"
  • Repeat: Fixed a bug where only the last output of a repeated action would be shown in the action's output.
  • Fixed link to Extract JSONPath examples.
  • Added example for making queries using fields that contain spaces.
"},{"location":"news.html#14-march-2023","title":"14 March 2023","text":"
  • WebhookScript: Fixed issue where floats would be parsed as strings (and not numbers, as they're supposed to), in some instances.
"},{"location":"news.html#3-march-2023","title":"3 March 2023","text":"
  • New WebhookScript string functions: string_random(), uuid(). More info here.
"},{"location":"news.html#23-febuary-2023","title":"23 Febuary 2023","text":"
  • For WebhookScript actions, the first line of the script is now shown in the action list. It allows easily adding a title to the script by making the first line a comment.
"},{"location":"news.html#6-feburary-2023","title":"6 Feburary 2023","text":"
  • New WebhookScript cryptography functions: sign(), digest(), verify(). More info here. JWT example here.
  • New WebhookScript base64 functions: base64url_encode(), base64url_decode(). More info here.
"},{"location":"news.html#1-feburary-2023","title":"1 Feburary 2023","text":"
  • New Custom Action: Send Email (SMTP) - send an email using your own email provider.
"},{"location":"news.html#20-january-2023","title":"20 January 2023","text":"
  • XPath: Improvements to the XPath action have been made so that it's now able to parse both XML and HTML-style documents.
  • WebhookScript: Fixed a bug in the set_response() function where it wasn't possible to set the response headers.
  • WebhookScript: Fixed a bug where internal errors would be returned when using array functions on arrays containing specific strings.
  • CSV Export: When exporting to CSV, the search query is now used so you get the same items in the CSV as you see in the request list.
  • WebhookScript: Added array_splice and array_range functions. More info here
"},{"location":"news.html#14-december-2022","title":"14 December 2022","text":"
  • Fixed a bug where Extract XPath and WebhookScript xpath functions would not match correctly in all cases.
"},{"location":"news.html#30-november-2022","title":"30 November 2022","text":"
  • WebhookScript: stop() function now stops entire Custom Action flow and returns respond rather than simply exiting the current script.
"},{"location":"news.html#28-november-2022","title":"28 November 2022","text":"
  • Discord: Added an Embed URL action to Discord Custom Action for attaching videos, images, articles, etc. to a chat message.
"},{"location":"news.html#10-november-2022","title":"10 November 2022","text":"
  • Schedules: Control Panel now shows Schedule IDs.
  • Removed \"Amount of requests to keep for Auto Cleanup\" (configuring this didn't actually do anything.) As an alternative, you could use the Don't Save Custom Action.
  • Send Request: Header Names are replaced with Variables.
  • Global Variables: It's now possible to search for Global Variables.
"},{"location":"news.html#6-november-2022","title":"6 November 2022","text":"
  • Schedules/API: It's now possible to fetch Schedule Logs. More info here
  • Schedules: Added \"Run Now\" button to all Schedules.
"},{"location":"news.html#31-october-2022","title":"31 October 2022","text":"
  • Control Panel: Category selector dropdown now sorted by name.
"},{"location":"news.html#26-october-2022","title":"26 October 2022","text":"
  • Improvements to Schedules
  • Ability to rename Groups
  • Group selection is now automatically remembered
"},{"location":"news.html#30-september-2022","title":"30 September 2022","text":"
  • New WebhookScript function: is_empty() More info here
  • New WebhookScript function: is_null() - handy for checking if a value is null without type checking issues. More info here
"},{"location":"news.html#21-september-2022","title":"21 September 2022","text":"
  • API: It's now possible to sort tokens returned by the Get Tokens endpoint. More info here: More info here
"},{"location":"news.html#8-september-2022","title":"8 September 2022","text":"
  • Fixed a bug in Webhook.site CLI (\"TypeError: Echo is not a constructor\" error.) - please upgrade the NPM package to 0.1.5.
  • Please do not use async-http-client (User-Agent AHC/2.1.) It is abandoned and contains bugs that creates too many HTTP requests. We may block users of this package in the future.
"},{"location":"news.html#17-august-2022","title":"17 August 2022","text":"
  • As a result of customer abuse, we have decided to introduce rate limits on creation of URLs. The rate limit will be initially set to 10 per minute. After reaching this limit, the POST /token endpoint will return a 429 Too Many Requests response.
"},{"location":"news.html#28-june-2022","title":"28 June 2022","text":"
  • New Custom Action Type: Send push messages with Pushed.co. More info here.
"},{"location":"news.html#24-june-2022","title":"24 June 2022","text":"
  • New WebhookScript function: preg_match() - allows matching regex with custom regex options More info here
  • New WebhookScript function: html_to_text() - converts html to text. A more aggressive version of html_strip_tags() More info here
  • WebhookScript: regex_extract_first() now has a default parameter that is returned when there's no matches. The function still returns false by default when this third parameter is not set. More info here
"},{"location":"news.html#21-may-2022","title":"21 May 2022","text":"
  • New Custom Actions feature: It is now possible to delay queued actions by a specified amount of seconds. More info here
"},{"location":"news.html#20-may-2022","title":"20 May 2022","text":"
  • New WebhookScript function: is_numeric(). More info here
  • Rate Limit Custom Action: It is now possible to specify a key to let you rate limit on a custom parameter. The request IP address ($request.ip$) is still the default key.
  • Action and Schedule error reports now specify the name, ID or alias of the Schedule or URL in question.
  • Fixed a bug with Webhook.site Enterprise Custom Domain email validation.
"},{"location":"news.html#19-april-2022","title":"19 April 2022","text":"
  • Fixed a bug that prevented action error notifications from being sent to the users.
"},{"location":"news.html#14-april-2022","title":"14 April 2022","text":"
  • It is now possible to search requests and emails, using either the frontend or the API. The data can be filtered by a wide range of fields, queries. More info here.
"},{"location":"news.html#30-march-2022","title":"30 March 2022","text":"
  • Added documentation for the Test Action endpoint.
"},{"location":"news.html#20-march-2022","title":"20 March 2022","text":"
  • New Variables for Files: $request.file.[name].id$ and $request.file.[name].link$ (which returns direct link to download the file.)
"},{"location":"news.html#14-march-2022","title":"14 March 2022","text":"
  • Added num2hex, hex2num and hex2bin functions.
"},{"location":"news.html#19-january-2022","title":"19 January 2022","text":"
  • New Custom Actions: RabbitMQ Get & Publish, allows consuming and publishing to RabbitMQ Queues via Webhook.site Custom Actions.
"},{"location":"news.html#21-december-2021","title":"21 December 2021","text":"
  • Improved handling of binary data received from Send Request actions.
  • Added a group_id parameter when creating or updating Tokens.
  • Fixed an issue with the Twitter Custom Action.
  • Requests to /token/:tokenId/requests are now throttled at 60 requests/minute.
"},{"location":"news.html#24-november-2021","title":"24 November 2021","text":"
  • WebhookScript: Fixed an issue that would cause strings to be interpreted as integers when encoding JSON.
"},{"location":"news.html#30-october-2021","title":"30 October 2021","text":"
  • Webhook.site's requests to itself, e.g. via Send Request action or Schedules by Webhook.site, now shows more clearly as coming from Webhook.site in the request list. Outgoing requests are now sent with a User-Agent header of Webhook.site/1.0, which can be overwrited if specifying a User-Agent header manually.
  • Error deleting Global Variables fixed.
  • It is now possible for Webhook.site Enterprise customers to manage their Custom Domains from the control panel.
"},{"location":"news.html#15-october-2021","title":"15 October 2021","text":"
  • Fix invalid charset configurations causing issues saving requests.
"},{"location":"news.html#4-october-2021","title":"4 October 2021","text":"
  • Webhook.site now supports multiple sub-users on an account, with different access permissions, available to Webhook.site Enterprise users. For more information, please contact us.
"},{"location":"news.html#29-september-2021","title":"29 September 2021","text":"
  • Webhook.site CLI: New minor version, fixes a bug causing Invalid namespace errors.
"},{"location":"news.html#17-september-2021","title":"17 September 2021","text":"
  • New Custom Action Variable Modifiers: .html_decode, .url_encode, and .url_decode. More info here
"},{"location":"news.html#12-september-2021","title":"12 September 2021","text":"
  • New WebhookScript function: array_merge(), that merges two arrays into one. More info here
  • New WebhookScript function: array_chunk(), that splits an array into chunks. More info here
  • Functions dd(), dump() and echo() can now take a variable amount of arguments. More info here
  • New WebhookScript date function: now(), which returns the current date in ISO format. More info here
  • The date_interval() and date_interval_human() functions now defaults to \"now\" if the second parameter isn't specified.
  • Script editor now has more space for outputs in full screen mode.
"},{"location":"news.html#18-august-2021","title":"18 August 2021","text":"
  • New API Endpoint: Get tokens, which returns a list of all tokens belonging to the account. More info here
  • Fixed a bug that caused logins to be slow on especially older accounts.
  • Fixed a bug that caused the FTP Upload action to error when the Port field was missing.
"},{"location":"news.html#12-august-2021","title":"12 August 2021","text":"
  • Google Sheet actions that consistently cause errors are now disabled automatically. Users are sent an email when this occurs.
"},{"location":"news.html#30-july-2021","title":"30 July 2021","text":"
  • New WebhookScript function: hmac(), which allows easily verifying strings using the HMAC method. More info here
"},{"location":"news.html#14-july-2021","title":"14 July 2021","text":"
  • New Custom Action: Replace Text, which allows easily making text replacements from variable input, and either overwrites an existing variable or creates a new one with the replaced content.
"},{"location":"news.html#4-july-2021","title":"4 July 2021","text":"
  • Fixed bug causing the \"Use Request Content\" checkbox in the Send Email action to not work.
"},{"location":"news.html#15-june-2021","title":"15 June 2021","text":"
  • New Custom Action: Twitter, so you can easily send tweets using Webhook.site.
  • New WebhookScript functions: convert_kana(), string_slice(), string_upper(), string_lower(), string_title() More info here.
"},{"location":"news.html#10-june-2021","title":"10 June 2021","text":"
  • Individual Custom Actions can now be set as queued, which causes them to be run in the background, or asynchronously. More info here
"},{"location":"news.html#7-june-2021","title":"7 June 2021","text":"
  • Raised the limit for the amount of items processed by repeating actions to 100.
  • Fixed a bug that would cause an error when updating notification settings in Control Panel.
  • Fixed a bug where emails containing attachments would be stored.
"},{"location":"news.html#23-may-2021","title":"23 May 2021","text":"
  • API: It's now possible to filter requests by date. More info here
"},{"location":"news.html#13-may-2021","title":"13 May 2021","text":"
  • Documented clone_from option when using the API to create Tokens (URLs)
  • WebhookScript: json_decode / json_encode now output error messages if they fail due to e.g. bad data.
"},{"location":"news.html#1-may-2021","title":"1 May 2021","text":"
  • Webhook.site Schedules now has an API. More info here
  • Fixed a bug where URLs could be in two groups at the same time.
"},{"location":"news.html#20-april-2021","title":"20 April 2021","text":"
  • Added base64 encoding and decoding variable modifiers. More info here
"},{"location":"news.html#11-april-2021","title":"11 April 2021","text":"
  • New Custom Action and WebhookScript function: Don't Save, which marks the request so it is not saved in Webhook.site. The request can still be seen when it comes in, but will not be available through through the app later, or through the API.
  • New Custom Action: Stop, which immediately stops Custom Action execution and returns the default response.
  • The Extract Regex now supports the Repeat function. More info here.
"},{"location":"news.html#7-april-2021","title":"7 April 2021","text":"
  • New powerful feature: Repeating actions. Currently supported by the Extract JSONPath action, it is now possible to \"loop over\" items in a JSON array. More info here
"},{"location":"news.html#2-april-2021","title":"2 April 2021","text":"
  • It is now possible to enable or disable Custom Actions on a specific Token with the API. More info here or here.
  • When exporting CSVs, the sorting selected in the application is now used automatically.
"},{"location":"news.html#28-march-2021","title":"28 March 2021","text":"
  • Today we've released the first version of the Webhook.site Command-line Interface (CLI), which allows you to forward requests from your Webhook.site URL to your local machine. More info here
"},{"location":"news.html#24-march-2021","title":"24 March 2021","text":"
  • WebhookScript: Added array_sort, array_join and json_escape functions.
  • Added modifiers for variables. More info here
"},{"location":"news.html#23-march-2021","title":"23 March 2021","text":"
  • Control Panel: It's now possible to clone URLs, including their Custom Actions and other configuration.
  • Control Panel: URLs with a password can be deleted more easily.
"},{"location":"news.html#13-march-2021","title":"13 March 2021","text":"
  • Control Panel: It's now possible to set a password for a Webhook.site URL in the Control Panel. Additionally, it's now possible to easily select and delete multiple URLs at once.
"},{"location":"news.html#11-march-2021","title":"11 March 2021","text":"
  • API: It's now possible to specify an alias when creating a URL via the API. More info here
"},{"location":"news.html#6-march-2021","title":"6 March 2021","text":"
  • New Action: Database Query - allows running database queries on PostgreSQL and MySQL servers, inserting, changing and fetching data in specific variables or JSON format. More info here
"},{"location":"news.html#3-march-2021","title":"3 March 2021","text":"
  • Webhook.site Premium has changed name to Webhook.site Pro. Functionality, pricing and everything else remains the same; it's a cosmetic change.
  • More currencies are now supported for Webhook.site Pro subscriptions: GBP and EUR. To change the currency of an existing subscription, please contact Webhook.site Support.
  • Custom Action output is now included in CSV Exports.
"},{"location":"news.html#17-feburary-2021","title":"17 Feburary 2021","text":"
  • New Action: FTP(S) Upload - allows easy file upload to FTP servers.
"},{"location":"news.html#5-feburary-2021","title":"5 Feburary 2021","text":"
  • New WebhookScript functions: html_strip_tags, html_decode, html_encode, markdown_to_html. For more information, see here.
"},{"location":"news.html#1-feburary-2021","title":"1 Feburary 2021","text":"
  • Webhook.site has had intermittent downtime today due abuse from a user. We've identified them and blocked them from our systems. We're very sorry for the inconvenience.
"},{"location":"news.html#31-january-2021","title":"31 January 2021","text":"
  • We have discontinued support for subscriptions via Patreon, who will need to create a new subscription. For more information please contact support.
"},{"location":"news.html#19-january-2021","title":"19 January 2021","text":"
  • Happy new year!
  • New Action Type: Conditions 2.0. Now supports adding multiple conditions in a single action.
  • New Action Type: Set Variable. Working similarly to the Store Global Variable action, this action sets a runtime variable that is not persisted.
  • Actions can now individually be executed depending on a previous set of conditions.
  • The Debug Output section in the Custom Actions builder now shows the action number and type from where it came.
  • The Modify Response action now supports returning the response immediately.
"},{"location":"news.html#5-december-2020","title":"5 December 2020","text":"
  • Added new Custom Action: Store Global Variable, which does what it says on the tin.
  • Bug fix: In Control Panel, the update date for each Global Variable now actually updates when a Global Variable is updated.
"},{"location":"news.html#26-november-2020","title":"26 November 2020","text":"
  • Webhook.site had downtime during the night. The problem has been fixed.
"},{"location":"news.html#25-november-2020","title":"25 November 2020","text":"
  • WebhookScript: It's now possible to store non-string values in set(). If the value is an array, however, it is JSON encoded first.
  • WebhookScript: Added more examples for the date functions.
"},{"location":"news.html#1-november-2020","title":"1 November 2020","text":"
  • Added new Custom Action: Rate Limit, which lets you specify the maximum amount of requests in a given duration per IP to allow to request the Webhook.URL.
  • Dates shown in the application now include seconds.
"},{"location":"news.html#29-october-2020","title":"29 October 2020","text":"
  • Added new Custom Action: Run SSH Command, which allows you to run SSH commands on your server.
"},{"location":"news.html#22-october-2020","title":"22 October 2020","text":"
  • WebhookScript: Added array_keys and array_values functions. For more information, see here.
"},{"location":"news.html#19-october-2020","title":"19 October 2020","text":"
  • It's now possible to set a timeout for the Send Request action. A new timeout parameter can also be given to the request() function in WebhookScript. Both places accept a value in seconds, with decimals.
  • When exporting Custom Actions, if the URL has an alias, this is now used for the resulting filename.
"},{"location":"news.html#11-october-2020","title":"11 October 2020","text":"
  • It's now possible to export and import Custom Actions to a file using the new Import/Export buttons in the Custom Actions builder.
"},{"location":"news.html#7-october-2020","title":"7 October 2020","text":"
  • Added documentation for managing Custom Actions via the API. For more information, see here.
  • Fixed a bug causing the Operator of an action to be reset to \"is equal to\" when testing.
"},{"location":"news.html#6-october-2020","title":"6 October 2020","text":"
  • Action output is no longer displayed twice when testing Condition actions.
"},{"location":"news.html#24-september-2020","title":"24 September 2020","text":"
  • New feature: Customize Auto-Cleanup threshold. This lets you specify how many requests or emails to keep for your URLs, if you want to keep fewer than the default amount of 10.000 for e.g. data protection reasons. Available from the brand new Settings page in Control Panel. The setting applies to all URLs that have the Auto Cleanup feature enabled - click Edit on a URL to enable it.
  • New feature: URL groups, which lets you categorize your URLs into groups. Available from the URLs page in Control Panel. Click Edit on a URL to change its group.
  • The URLs page in Control Panel has a new design which is less cluttered and allows you to more quickly change certain settings, URL aliases, and the description of a URL.
"},{"location":"news.html#23-september-2020","title":"23 September 2020","text":"
  • Regrettably, we saw a long period of downtime again from approx 20:00 to 05.40 UTC. The cause of the downtime was a user flooding their Webhook.site URLs with many gigabytes of data, causing the system to be overloaded. The same user was responsible for the downtime at 15 September 2020 and we've now terminated their license to use Webhook.site. We are also going prioritize changes that will automatically limit this kind of abuse, as well as move to another database system that will be more resilient.
"},{"location":"news.html#15-september-2020","title":"15 September 2020","text":"
  • We've seen spurious instances of downtime in the last 24 hours, the longest one lasting from approx. 14:00 to 14:50 UTC. We apologize for the inconvenience.
"},{"location":"news.html#13-september-2020","title":"13 September 2020","text":"
  • WebhookScript: Added override parameter to request(), which prevents content from the source request from being included.
"},{"location":"news.html#3-september-2020","title":"3 September 2020","text":"
  • WebhookScript: It is now possible to set a default for the var() function.
"},{"location":"news.html#29-august-2020","title":"29 August 2020","text":"
  • A bug in the Extract JSONPath action has been fixed so that it is now also possible to filter for keys containing punctuation, e.g. .data[?(@.Employee.FirstName)].
"},{"location":"news.html#18-august-2020","title":"18 August 2020","text":"
  • WebhookScript: The to_date and date_format functions have been improved with timezone handling capabilities.
"},{"location":"news.html#15-august-2020","title":"15 August 2020","text":"
  • It's now possible to set a custom timeout for Schedules, up to 30 seconds.
"},{"location":"news.html#8-august-2020","title":"8 August 2020","text":"
  • You can now specify a custom Cron expression for your Webhook.site Schedule, in addition to the predefined intervals. This lets you decide exactly the hour, day and minute, etc., of when the schedule runs (based on UTC time.)
  • It's now possible to enable email notifications for whenever a Schedule run fails to execute. To enable this, simply check the checkbox in Notification Settings..
"},{"location":"news.html#7-august-2020","title":"7 August 2020","text":"
  • It's now possible to change the name of your Provider accounts to e.g. something that's easier to remember.
"},{"location":"news.html#5-august-2020","title":"5 August 2020","text":"
  • Webhook.site had an unplanned outage starting at 03.30 UTC. The site was down for around an hour.
"},{"location":"news.html#2-august-2020","title":"2 August 2020","text":"
  • It is now possible to specify a default value in the Extract JSONPath, Extract Regex and Extract XPath actions, so that if the extraction could not find the item, the variable is set to the default value that is defined. This field also takes variables.
  • Request list is now sorted by Newest First per default.
  • Custom Action number and type is now shown next to the output in the request details. If the Action was deleted, the UUID is shown instead.
"},{"location":"news.html#1-august-2020","title":"1 August 2020","text":"
  • It is now possible to enable email notifications for whenever a Custom Action encountered an error. To enable this, simply check the checkbox in Notification Settings..
"},{"location":"news.html#29-july-2020","title":"29 July 2020","text":"
  • New WebhookScript function: trim(string), which removes space, newline and tab characters from the beginning and end of a string, similar to PHP's own trim() function.
  • New Schedule intervals: weekly (every monday), monthly (every 1st day of month)
"},{"location":"news.html#25-july-2020","title":"25 July 2020","text":"
  • New WebhookScript function: action(action_type, parameters), to run Custom Actions inside a WebhookScript. More info here.
  • It's now possible to download email attachments or uploaded files directly from the Webhook.site app.
  • When sending a request using either the Send Request Custom Action or the request() function, the response is now truncated if the response content is over 20KiB. This means the whole contents is not visible in the app, but is still available to Actions.
"},{"location":"news.html#16-july-2020","title":"16 July 2020","text":"
  • Better file handling for emails: attached files are now also extracted as variables
  • New file management functions for WebhookScript: files() retrieves a an array of all files, file_content(fileId) returns the content of a specific file. More info here.
"},{"location":"news.html#5-july-2020","title":"5 July 2020","text":"
  • New \"Resize Image\" action added for resizing images from either a file upload, email attachment or other Action.
  • Better handling of downloaded files: the contents won't be shown in the debug overlay to prevent very large files from crashing the browser.
  • Fixed a bug in the Dropbox provider returning creating an empty variable when downloading large files.
"},{"location":"news.html#3-july-2020","title":"3 July 2020","text":"
  • Webhook.site was down for about 30 minutes starting 07:20 UTC due to a memory upgrade.
  • Max request size has been increased to 10 MB from 2 MB.
"},{"location":"news.html#23-june-2020","title":"23 June 2020","text":"
  • Added new Dropbox Custom Actions: Create Folder, Download, Upload, Delete, Get Link.
"},{"location":"news.html#14-june-2020","title":"14 June 2020","text":"
  • WebhookScript editor syntax highlighting improved with regards to multiline strings, escape characters and more
  • New WebhookScript editor keyboard shortcut for saving (Mac: Cmd-S, Windows: Ctrl-S.)
  • Fix WebhookScript fullscreen mode not being disengaged when saving
  • URLs can now accept file uploads via multipart. File contents are available via variables: request.file.<formname>.content, request.file.<formname>.size, request.file.<formname>.filename
  • New WebhookScript function: csv_to_array(), which converts a CSV file from a string to an array that can easily be parsed.
  • Added an example script demoing file uploads and CSV parsing
"},{"location":"news.html#7-june-2020","title":"7 June 2020","text":"
  • Added new Slack Send Message Custom Action, which lets you send Slack messages via a Slack Webhook URL.
"},{"location":"news.html#5-june-2020","title":"5 June 2020","text":"
  • Added \"Formula Mode\" checkbox for Add and Update Row Google Sheets actions, which parses values like entered in a cell, and allows inserting formulas.
"},{"location":"news.html#4-june-2020","title":"4 June 2020","text":"
  • Added new endpoints to fetch the content and information about the latest request on a URL. See here and here.
"},{"location":"news.html#2-june-2020","title":"2 June 2020","text":"
  • Added Amazon Web Services CloudFront Cache Invalidation Custom Action.
  • Added ability to toggle Auto Cleanup, which automatically cleans up requests/emails.
"},{"location":"news.html#30-may-2020","title":"30 May 2020","text":"
  • Added Discord Custom Action for sending messages. Read more in the docs
"},{"location":"news.html#29-may-2020","title":"29 May 2020","text":"
  • New set of date functions added to WebhookScript, namely: to_date(), date_format(), date_to_array(), date_interval(), date_interval_human(). Read more in the docs
"},{"location":"news.html#25-may-2020","title":"25 May 2020","text":"
  • New set of Amazon Web Services S3 actions: Create Bucket, Put Object, Delete Object and Get Object (which retrieves object contents to a Variable.)
"},{"location":"news.html#22-may-2020","title":"22 May 2020","text":"
  • New Schedule intervals: every 1 minute and every 10 minutes, in addition to the already existing ones.
"},{"location":"news.html#17-may-2020","title":"17 May 2020","text":"
  • New WebhookScript function: delay(), which lets you delay and execute WebhookScript code a set amount of seconds in the future.
  • New WebhookScript function: exec(), which lets you dynamically execute code in a string.
  • New WebhookScript function: import(), which downloads and executes code from a URL - great if you want to reuse your code, just put it on Github and import it with the URL!
"},{"location":"news.html#16-may-2020","title":"16 May 2020","text":"
  • It's now possible to set a Token (URL or email address) to expire automatically, even for Premium users. This is useful for creating tokens for automated testing.
"},{"location":"news.html#3-may-2020","title":"3 May 2020","text":"
  • New Google Sheets Custom Actions (Beta). 3 initial actions are available: Append Row, Update Row and Get Values, which allow you to manipulate or retrieve the values of a Google Sheet without writing any code.
"},{"location":"news.html#24-april-2020","title":"24 April 2020","text":"
  • New fullscreen mode in WebhookScript editor
  • Ability to edit your user profile
  • New WebhookScript functions: base64_encode(), base64_decode().
"},{"location":"news.html#21-april-2020","title":"21 April 2020","text":"
  • New WebhookScript function: store() - creates or updates an existing Global Variable
"},{"location":"news.html#20-april-2020","title":"20 April 2020","text":"
  • New Global Variables section in Control Panel.
"},{"location":"news.html#19-april-2020","title":"19 April 2020","text":"
  • New WebhookScript math functions: max(), min(), mod(), pi(), rand() - for more, see the Reference
"},{"location":"news.html#28-march-2020","title":"28 March 2020","text":"
  • New feature: Webhook.site Schedules lets you request any URL \u2013 including Webhook.site URLs \u2013 automatically on an interval, so you can for example run Custom Actions every 5 minutes, or make a health check for your Web site.
  • Send Request action request timeout has been raised from 5 to 10 seconds. Applies to both the Custom Action and the WebhookScript request() function.
"},{"location":"news.html#24-march-2020","title":"24 March 2020","text":"
  • New feature: API Keys can now be created so you can use the API with URLs that have the \"Require Authentication\" or \"Password\" options set.
  • Fix: It's now possible to test Send Email actions before creating them. Prior to this, the Test button would not do anything for the Send Email action.
"},{"location":"news.html#6-march-2020","title":"6 March 2020","text":"
  • New feature: Extract XPath Custom Action with accompanying xpath() WebhookScript function. Read more.
"},{"location":"news.html#29-feburary-2020","title":"29 Feburary 2020","text":"
  • Values are no longer required for Condition actions, so it's possible to compare an empty string or missing value.
  • Fixed an issue where a tooltip in the Custom Actions modal would not disappear.
  • Removed Beta label from WebhookScript.
"},{"location":"news.html#27-feburary-2020","title":"27 Feburary 2020","text":"
  • Fixed a bug where slashes at the end of Webhook.site Single Page App URLs didn't work.
  • Fixed a bug where Copy To CURL sometimes wouldn't return a valid CURL command.
"},{"location":"news.html#26-feburary-2020","title":"26 Feburary 2020","text":"
  • It's no longer a requirement to specify a variable for the Send Request action.
"},{"location":"news.html#25-feburary-2020","title":"25 Feburary 2020","text":"
  • New feature: It's now possible to receive emails, which are treated like Webhooks \u2013 so you can automate emails with Custom Actions on Webhook.site. You can also test email deliverability using DKIM, DMARC and SPF validation.
  • JSON formatting is now always enabled per default.
  • The requests view is cleared after deleting the last request, and the tutorial text is shown.
"},{"location":"news.html#16-feburary-2020","title":"16 Feburary 2020","text":"
  • WebhookScript: Added regex_extract and regex_extract_first functions.
"},{"location":"news.html#15-feburary-2020","title":"15 Feburary 2020","text":"
  • WebhookScript: Added hash function.
"},{"location":"news.html#14-feburary-2020","title":"14 Feburary 2020","text":"
  • New feature: Export to CSV lets you export all requests on a given URL to a CSV file.
  • Fixed a bug where duplicate in-app notifications would appear on new requests.
"},{"location":"news.html#12-feburary-2020","title":"12 Feburary 2020","text":"
  • WebhookScript: Added url_encode, url_decode, and query functions.
"},{"location":"news.html#8-febuary-2020","title":"8 Febuary 2020","text":"
  • New Custom Action type: Condition, which lets you conditionally stop a set of actions based on comparisons.
"},{"location":"news.html#28-january-2020","title":"28 January 2020","text":"
  • WebhookScript now supports newline literals (\\\\n) in strings, escaped by 2 backslashes.
"},{"location":"news.html#25-january-2020","title":"25 January 2020","text":"
  • Global Variables are now available in the Control Panel, which lets you keep configuration like API keys in a separate place from your Custom Actions and scripts while managing them at a central place.

  • Changed the font of the WebhookScript editor, which resulted in uneven selection of text.

"},{"location":"news.html#23-january-2020","title":"23 January 2020","text":"
  • You can now specify a source variable for JSONPath and Regex actions, so you can extract text from not only the request content.
"},{"location":"news.html#12-january-2020","title":"12 January 2020","text":"
  • Switched to using Ace as editor for WebhookScript.
"},{"location":"open-source.html","title":"Webhook.site Open Source","text":""},{"location":"open-source.html#about-the-open-source-version","title":"About the Open Source version","text":"

There are two separate editions of Webhook.site:

  • The code for the completely open-source, MIT-licensed version described on this page is available on https://github.com/webhooksite/webhook.site, and can be self-hosted using e.g. Docker, is great for testing Webhooks, but doesn't include Webhook.site Pro features like Custom Actions.

  • The cloud version of Webhook.site at https://webhook.site which has more features, some of them requiring a paid subscription.

You can choose to run the Open Source version of Webhook.site either via Docker, or install it on any Web server with PHP7 support.

"},{"location":"open-source.html#realtime-updates","title":"Realtime updates","text":"

laravel-echo-server or Pusher can be used to enable realtime updates. Take a look at the .env.example to see the environment variables required to configure it.

For laravel-echo-server, the app expects socket.io to be available at the /socket.io path relative to the index page. This can be done with nginx like so:

    location /socket.io {\n        proxy_pass http://127.0.0.1:6001;\n        proxy_http_version 1.1;\n        proxy_set_header Upgrade $http_upgrade;\n        proxy_set_header Connection 'upgrade';\n        proxy_set_header Host $host;\n        proxy_cache_bypass $http_upgrade;\n    }\n
"},{"location":"open-source.html#installation","title":"Installation","text":""},{"location":"open-source.html#docker-recommended","title":"Docker (Recommended)","text":"

The provided Docker Compose file sets up a complete environment that runs the Webhook.site image and all dependencies (Redis, Laravel Echo Server, etc.). Note that if running this in production, you should probably run a Redis server that persists data to disk. The Docker image is also not tuned for large amounts of traffic.

"},{"location":"open-source.html#installation-guide","title":"Installation Guide","text":"
  1. Run docker-compose up
  2. The app will be available on http://127.0.0.1:8084.
"},{"location":"open-source.html#kubernetes","title":"Kubernetes","text":"

A set of Kubernetes configuration files can be found in the kubernetes subfolder.

"},{"location":"open-source.html#installation-guide_1","title":"Installation Guide","text":"

Configure the resources, and apply with kubectl apply -f ./.

"},{"location":"open-source.html#web-server","title":"Web Server","text":""},{"location":"open-source.html#requirements","title":"Requirements","text":"
  • PHP 7
  • Redis
  • Composer
  • Web server \u2013 e.g. nginx, apache2

DigitalOcean has a guide on how to configure nginx.

"},{"location":"open-source.html#installation-guide_2","title":"Installation Guide","text":"
  1. Run the following commands:
  2. composer install
  3. cp .env.example .env - adjust settings as needed
  4. php artisan key:generate
  5. Setup virtual host pointing to the /public folder.
"},{"location":"premium.html","title":"Webhook.site Premium","text":"

Webhook.site Pro was formerly known as Premium. For more information, see here.

"},{"location":"pro.html","title":"Webhook.site Basic, Pro and Enterprise","text":"

With Webhook.site Basic, Pro and Webhook.site Enterprise subscriptions, you get more features that allows you to do more with your URL, as well as keep the data contained private and secure.

Free Basic Pro Enterprise URLs n/a 1 Unlimited Unlimited Schedules n/a 1 Unlimited Unlimited Custom Actions \u274c \u2705 \u2705 \u2705 Schedules \u274c \u2705 \u2705 \u2705 Custom Addresses \u274c \u2705 \u2705 \u2705 Secure Data \u274c \u2705 \u2705 \u2705 Permanent URLs \u274c \u2705 \u2705 \u2705 CSV Export \u274c \u2705 \u2705 \u2705 Free Email Support \u274c \u2705 \u2705 \u2705 Custom Domain \u274c \u274c \u274c \u2705 Multi-User Support \u274c \u274c \u274c \u2705 Request History 100 (hard limit) 10.0002 10.0002 10.0002 URL/Email Address expiry 7 days1 Never expires Never expires Never expires Data storage duration 7 days1 365 days 365 days 365 days Pricing3 $9/month $90/year (save 20%) $18/month $180/year (save 20%) $49/month $499/year (save 20%) Subscribe Now
  1. Free URLs and email addresses automatically expire and are permanently deleted after 7 days.
  2. Pro and Enterprise URLs accept an unlimited amount of requests or emails, but only the latest 10.000 are available. Older requests are removed periodically.
  3. All pricing in USD and excluding VAT. Local currency can be used at checkout.
"},{"location":"pro.html#pro-features","title":"Pro features","text":""},{"location":"pro.html#create-workflows-with-custom-actions","title":"Create workflows with Custom Actions","text":"

Extract data, send emails and HTTP requests, upload files, run scripts and much more with Custom Actions that are run on each incoming request or email, with the Webhook.site Custom Actions builder.

Native integrations for AWS, Google Sheets, Slack, Dropbox, MySQL and others.

Read more

"},{"location":"pro.html#schedules","title":"Schedules","text":"

Use Schedules by Webhook.site to send requests any URL or run your Custom Actions automatically on an interval. Use it for monitoring your Web site, clearing caches, and much more. Supports cron syntax, in addition to predefined intervals.

Read more

"},{"location":"pro.html#custom-urls-and-emails","title":"Custom URLs and Emails","text":"

Get an address that's easy to remember:

webhook.site/my-alias

my-alias@email.webhook.site

(With Webhook.site Enterprise, you can even use your own domain name.)

"},{"location":"pro.html#security","title":"Security","text":"

Your data is secured in your account, and can be accessed by API Key or login. With the free version of Webhook.site, others can freely view the requests sent to your URL.

"},{"location":"pro.html#permanent-urls","title":"Permanent URLs","text":"

The URLs stay in your account forever, the 7-day auto expiration of the free version is removed.

"},{"location":"pro.html#store-more-than-500-requests-or-emails","title":"Store more than 500 requests or emails","text":"

With the free version, URLs stop taking in new requests or emails after the 500 request limit is reached. With Pro, the limit of max 500 requests or emails per URL is removed and raised to 10.000 requests or emails, which are then rotated automatically.

"},{"location":"pro.html#unlimited-urls","title":"Unlimited URLs","text":"

Create as many upgraded URLs or email addresses as you need at no extra cost.

"},{"location":"pro.html#csv-export","title":"CSV Export","text":"

Export all requests and emails to a CSV file.

"},{"location":"pro.html#localhost-forwarding","title":"Localhost Forwarding","text":"

Forward requests to your Webhook.site URL to your local network via Webhook.site CLI.

"},{"location":"pro.html#email-support","title":"Email Support","text":"

We\u2019ll help you troubleshoot and set up your Custom Actions and workflows.

"},{"location":"pro.html#enterprise-features","title":"Enterprise features","text":"

In addition to all Pro features, Enterprise also contains the following features:

"},{"location":"pro.html#custom-domain","title":"Custom Domain","text":"

Use a your own (sub)domain for URLs and emails:

mydomain.com/my-alias

my-alias@email.mydomain.com

Additionally, Webhook.site provides an SSL certificate which is included free of charge with your Enterprise subscription.

"},{"location":"pro.html#multi-user-support","title":"Multi-User Support","text":"

Ideal for larger organizations, share URLs, schedules, and other data with the rest of the organization. Configure individual users' access with User Types like Administrator and Viewer, so some users may only view the content.

"},{"location":"schedules.html","title":"Webhook.site Schedules","text":"

Included in your Webhook.site subscription is Webhook.site Schedules, a feature that enables you to periodically send requests to specified URLs (including your Webhook.site URLs, so your Custom Actions can be executed periodially) with a custom method, headers, and interval.

Schedules can be used for a variety of purposes, including cache warming, uptime monitoring, automatic data transfer, etc.

After creating the Schedule, you can view the logs for the last 100 scheduled requests.

Per default, the timeout for the Schedule requests is 5 seconds, but can range from 1 to 30 seconds.

A timeout or server error will trigger a Schedule error notification email, if enabled in Control Panel -> Settings.

Schedules can also be managed using the Schedules API.

"},{"location":"schedules.html#uptime-monitoring-requirements","title":"Uptime monitoring & Requirements","text":"

If you create a Schedule and enable the When an error happens during a Schedule run setting, Webhook.site will automatically send an email notification when a URL has a timeout longer than the one specified, or when one of the requirements aren't met. It is possible to specify requirements for the response body containing a string, and the response status code being within a certain range.

"},{"location":"schedules.html#schedule-intervals","title":"Schedule Intervals","text":"

In addition to be able to use a custom cron-style expression string, Schedules can be executed at the following preset intervals:

  • 1 minute
  • 5 minutes
  • 10 minutes
  • 1 hour
  • 24 hours (at 00:00)
  • Every week (mondays at 00:00)
  • Every month (1st day at 00:00)

Schedule intervals are based on UTC time.

For building cron-style expressions, we recommend https://crontab.guru.

"},{"location":"api/about.html","title":"Webhook.site API","text":"

The Webhook.site API is public, free to use, doesn't require authentication and is relatively easy to use.

"},{"location":"api/about.html#general-usage","title":"General Usage","text":"

Base URL: https://webhook.site.

You must set the Accept and Content-Type headers to application/json.

"},{"location":"api/about.html#things-to-note","title":"Things to Note","text":"
  • In all examples in this API documentation, URL parameters are prefixed with : (colon) to show which parameters must be changed by the user. You must not include this character in the URL.
  • A Token ID refers to the ID of the Webhook.site URL/e-mail address, i.e., when your Webhook.site URL is https://webhook.site/00000000-0000-0000-0000-000000000000, the Token ID is then 00000000-0000-0000-0000-000000000000.
  • In API URLs, you cannot use Token Aliases in place of the Token ID.
  • Webhook.site API Keys must be specified using the Api-Key HTTP header.
  • Fair use guidelines, rate limits, and other limitations apply as described by the Terms of Service.
"},{"location":"api/about.html#authentication","title":"Authentication","text":"

While many endpoints of the Webhook.site API are public and work without any authentication, some endpoints do require authentication, or will return a 401 Unauthorized status code.

"},{"location":"api/about.html#api-key","title":"API Key","text":"

An API Key can be generated in the Control Panel, and provides access to Tokens that are either a) password protected or b) require login.

API Keys must be specified in the Api-Key HTTP header.

Create API Key"},{"location":"api/about.html#password","title":"Password","text":"

If you have set a password on a Webhook.site URL/token, to access the API resources for that token, you can use either of the following methods:

  1. Specify the password using the password query string: ?password=[your password]
  2. Set the password using HTTP Basic Auth, using the Authorization header. More info
"},{"location":"api/about.html#common-usages","title":"Common Usages","text":""},{"location":"api/about.html#get-data-sent-to-url","title":"Get data sent to URL","text":"

To retrieve the data that's sent to a Webhook.site URL or Email, you'll want to use the Get Requests endpoint.

"},{"location":"api/about.html#create-new-urlemail-address","title":"Create new URL/email address","text":"

To create a new token programmatically, you can use the API like this:

$ curl -X POST https://webhook.site/token\n

This will return information about the token in JSON format, including its UUID. Your URL will be available at the endpoint https://webhook.site/[token uuid].

If you are a Webhook.site Pro or Enterprise customer, you should provide an API key in order to associate the created token with your account automatically:

$ curl -X POST -H 'Api-Key: 00000000-0000-0000-0000-000000000000' https://webhook.site/token\n

More info here.

"},{"location":"api/action-types.html","title":"Action types","text":"

The following is a list of the API names for Action Types, along with a list of parameters, and their validation requirements.

"},{"location":"api/action-types.html#auto_json","title":"auto_json","text":"
  • source: string
  • jsonpath: string
  • variable_name: required, string
"},{"location":"api/action-types.html#aws_cf_invalidate","title":"aws_cf_invalidate","text":"
  • provider_id: required, int
  • distribution_id: required, string
  • paths: required, string
"},{"location":"api/action-types.html#aws_s3_create_bucket","title":"aws_s3_create_bucket","text":"
  • provider_id: string, required
  • region: string, required
  • bucket_name: string, required
  • canned_acl: string, in:private,public-read,public-read-write,authenticated-read
"},{"location":"api/action-types.html#aws_s3_delete_object","title":"aws_s3_delete_object","text":"
  • provider_id: string, required
  • region: string
  • bucket_name: string, required
  • object_key: string, required
"},{"location":"api/action-types.html#aws_s3_get_object","title":"aws_s3_get_object","text":"
  • provider_id: string, required
  • region: string
  • bucket_name: string, required
  • object_key: string, required
  • variable_name: string, required, min:1
"},{"location":"api/action-types.html#aws_s3_put_object","title":"aws_s3_put_object","text":"
  • provider_id: string, required
  • region: string, required
  • bucket_name: string
  • object_key: string, required
  • body: string, required
  • canned_acl: string, in:private,public-read,public-read-write,authenticated-read
"},{"location":"api/action-types.html#condition","title":"condition","text":"
  • input: string
  • operator: required, string, in:eq,neq,sw,ew,ct,nct,gt,gte,lt,lte
  • value: string
  • action: required, string, in:stop,continue,noop
"},{"location":"api/action-types.html#conditions","title":"conditions","text":"
  • conditions: required, array
  • mode: required, string, in:one,all,none
  • action: required, string, in:stop,continue,noop
"},{"location":"api/action-types.html#database","title":"database","text":"
  • type: required, in:mysql,pgsql
  • host: required, string
  • port: number, min:1, max:65535
  • database: required, string
  • password: string
  • username: required, string
  • statement: required, string
  • params: array
  • variable_name: string
  • charset: string
"},{"location":"api/action-types.html#discord_send_message","title":"discord_send_message","text":"
  • provider_id: required, string
  • content: required, string
  • username: string
  • avatar_url: url
  • embed_type: string, in:link,image,video
  • embed_url: url
"},{"location":"api/action-types.html#dont_save","title":"dont_save","text":"

No parameters for dont_save.

"},{"location":"api/action-types.html#dropbox_create_folder","title":"dropbox_create_folder","text":"
  • provider_id: string, required
  • path: string, required
"},{"location":"api/action-types.html#dropbox_delete","title":"dropbox_delete","text":"
  • provider_id: string, required
  • path: string, required
"},{"location":"api/action-types.html#dropbox_download_file","title":"dropbox_download_file","text":"
  • provider_id: string, required
  • path: string, required
  • variable_name: string, required
"},{"location":"api/action-types.html#dropbox_get_link","title":"dropbox_get_link","text":"
  • provider_id: string, required
  • path: string, required
  • variable_name: string, required
"},{"location":"api/action-types.html#dropbox_upload_file","title":"dropbox_upload_file","text":"
  • provider_id: string, required
  • path: string, required
  • body: string, required
  • mode: string, required, in:add,overwrite,update
"},{"location":"api/action-types.html#extract_jsonpath","title":"extract_jsonpath","text":"
  • jsonpath: required, string
  • variable_name: required, string
  • source: string
  • default: string
  • repeat: boolean
"},{"location":"api/action-types.html#extract_regex","title":"extract_regex","text":"
  • regex: required, string
  • variable_name: required, string
  • source: string
  • default: string
  • repeat: boolean
"},{"location":"api/action-types.html#extract_xpath","title":"extract_xpath","text":"
  • xpath: required, string
  • variable_name: required, string
  • source: string
  • default: string
"},{"location":"api/action-types.html#ftp_upload","title":"ftp_upload","text":"
  • host: required, string
  • port: number, min:1, max:65535
  • password: required, string
  • username: required, string
  • path: required, string
  • content: required, string
  • ssl: bool
  • passive: bool
"},{"location":"api/action-types.html#google_sheets_add_row","title":"google_sheets_add_row","text":"
  • provider_id: string, required
  • spreadsheet_id: string, required
  • range: string, required
  • values: string, required
  • formula_mode: bool
"},{"location":"api/action-types.html#google_sheets_get_values","title":"google_sheets_get_values","text":"
  • provider_id: string, required
  • spreadsheet_id: string, required
  • range: string, required
  • variable_name: required, string
"},{"location":"api/action-types.html#google_sheets_update_row","title":"google_sheets_update_row","text":"
  • provider_id: string, required
  • spreadsheet_id: string, required
  • range: string, required
  • values: string, required
  • formula_mode: bool
"},{"location":"api/action-types.html#http","title":"http","text":"
  • url: required, string
  • content: nullable, string
  • method: nullable, in:POST,GET,OPTIONS,PUT,DELETE,PATCH,TRACE
  • mode: nullable, in:text,json,multipart,urlencoded,forward
  • auth: nullable, object
  • auth.mode: string, in:basic,digest,ntlm
  • auth.username: string
  • auth.password: string
  • multipart: array, required_if:mode,multipart
  • multipart.*.name: string
  • multipart.*.filename: string
  • multipart.*.content-type: string
  • multipart.*.content: string
  • urlencoded: array
  • urlencoded.*.name: string, required_if:mode,urlencoded
  • urlencoded.*.value: string, required_if:mode,urlencoded
  • headers: nullable, string
  • skip_ssl_verification: nullable, bool
  • variable_name: string
  • timeout: nullable, numeric, max:15
"},{"location":"api/action-types.html#image_resize","title":"image_resize","text":"
  • source: string, required
  • width: string, required_without:height
  • height: string, required_without:width
  • aspect_ratio: bool, required
  • variable_name: string, required
"},{"location":"api/action-types.html#javascript","title":"javascript","text":"
  • script: required, string
"},{"location":"api/action-types.html#log","title":"log","text":"
  • text: required, string
"},{"location":"api/action-types.html#microsoft_drive_download","title":"microsoft_drive_download","text":"
  • provider_id: required, string
  • path: required, string
  • variable_name: string
"},{"location":"api/action-types.html#microsoft_drive_upload","title":"microsoft_drive_upload","text":"
  • provider_id: required, string
  • path: required, string
  • content_type: string
  • content: string
  • variable_name: string
"},{"location":"api/action-types.html#microsoft_excel_add_rows","title":"microsoft_excel_add_rows","text":"
  • provider_id: required, string
  • path: string
  • table: string
  • index: int
  • values: required, array
"},{"location":"api/action-types.html#microsoft_excel_get_values","title":"microsoft_excel_get_values","text":"
  • provider_id: required, string
  • path: required, string
  • worksheet: required, string
  • range: required, string
  • variable_name: required, string
"},{"location":"api/action-types.html#modify_response","title":"modify_response","text":"
  • content: string
  • status: string
  • headers: string
  • stop: bool
"},{"location":"api/action-types.html#ntfy","title":"ntfy","text":"
  • topic: string, required
  • title: string
  • message: string, required
"},{"location":"api/action-types.html#pushed_send","title":"pushed_send","text":"
  • app_key: string, required
  • app_secret: string, required
  • target_type: string, required
  • target: string, required
  • message: string, required
"},{"location":"api/action-types.html#rabbitmq_get","title":"rabbitmq_get","text":"
  • host: string, required
  • port: int
  • username: string, required
  • password: string, required
  • vhost: string
  • queue: string, required
  • ssl: boolean
  • variable_name: string
"},{"location":"api/action-types.html#rabbitmq_publish","title":"rabbitmq_publish","text":"
  • host: string, required
  • port: int
  • username: string, required
  • password: string, required
  • vhost: string
  • queue: string, required
  • ssl: boolean
  • message: string, required
"},{"location":"api/action-types.html#rate_limit","title":"rate_limit","text":"
  • period: required, int
  • count: required, int
  • key: string
"},{"location":"api/action-types.html#script","title":"script","text":"
  • script: required, string
"},{"location":"api/action-types.html#send_email","title":"send_email","text":"
  • sender: string
  • recipient: required, string
  • content: string
  • is_html: boolean
  • subject: required, string
  • attachments: array
"},{"location":"api/action-types.html#send_email_smtp","title":"send_email_smtp","text":"
  • sender_name: string
  • sender_email: string
  • recipient: required, string
  • content: string
  • is_html: boolean
  • subject: required, string
  • encryption: string, in:none,ssl,tls
  • port: int
  • username: string, required
  • password: string, required
  • host: string_required
  • attachments: array
"},{"location":"api/action-types.html#send_request","title":"send_request","text":"
  • url: required, string
  • content: nullable, string
  • method: nullable, in:POST,GET,OPTIONS,PUT,DELETE
  • headers: nullable, string
  • skip_ssl_verification: nullable, bool
  • variable_name: string
  • timeout: nullable, numeric, max:30
"},{"location":"api/action-types.html#set_variable","title":"set_variable","text":"
  • name: required, string
  • value: nullable, string
"},{"location":"api/action-types.html#sftp_upload","title":"sftp_upload","text":"
  • provider_id: string
  • host: required, string
  • port: number, min:1, max:65535
  • username: required, string
  • password: string
  • path: required, string
  • content: required, string
"},{"location":"api/action-types.html#slack_send_message","title":"slack_send_message","text":"
  • webhook_url: required, url
  • raw: bool
  • content: required, string
"},{"location":"api/action-types.html#ssh_run_command","title":"ssh_run_command","text":"
  • provider_id: string
  • host: required, string
  • port: number, min:1, max:65535
  • username: required, string
  • password: string
  • command: required, string
  • variable_name: string
"},{"location":"api/action-types.html#stop","title":"stop","text":"

No parameters for stop.

"},{"location":"api/action-types.html#store_global_variable","title":"store_global_variable","text":"
  • name: required, string
  • value: nullable, string
"},{"location":"api/action-types.html#template","title":"template","text":"
  • template_id: required, int
  • variables: array
"},{"location":"api/action-types.html#text_map","title":"text_map","text":"
  • source: required, string
  • operator: required, string
  • variable_name: required, string
  • default: required, string
  • mappings: required, array
"},{"location":"api/action-types.html#text_replace","title":"text_replace","text":"
  • source: required, string
  • variable_name: required, string
  • replacements: required, array
"},{"location":"api/action-types.html#text_split","title":"text_split","text":"
  • delimiter: required, string
  • source: required, string
  • variable_name: required, string
  • repeat: boolean
"},{"location":"api/action-types.html#twitter_tweet","title":"twitter_tweet","text":"
  • provider_id: required, string
  • tweet: required, string
"},{"location":"api/custom-actions.html","title":"API Endpoints: Custom Actions","text":"

The Custom Actions API allows you to manage the Custom Actions associated with a given Token. More info about Custom Actions.

List of the API names and parameters for Action Types.

"},{"location":"api/custom-actions.html#actions","title":"Actions","text":""},{"location":"api/custom-actions.html#create-custom-action","title":"Create Custom Action","text":"
  • Can require authentication.

POST /token/:token_id/actions

  • type (string) is the name of an Action Type.
  • order (int) specified which order the action is executed in.
  • parameters (object) can vary depending on the Action Type.
  • disabled (bool) if set to true, the action is skipped upon execution.
  • queue (bool) If set to true, the action is run asynchronously. More info here
  • delay (int, max 86400) If set (along with queue to true), Webhook.site waits the specified amount of seconds to run the action.
  • condition (uuid) If set to an ID of a Conditions action, the action will only run if the condition passes, and is otherwise skipped.
"},{"location":"api/custom-actions.html#request","title":"Request","text":""},{"location":"api/custom-actions.html#example-1-condition-action","title":"Example 1: Condition action","text":"
{\n\"type\": \"condition\",\n\"order\": 3,\n\"disabled\": false,\n\"parameters\": {\n\"input\": \"$request.content$\",\n\"operator\": \"eq\",\n\"value\": \"\",\n\"action\": \"stop\"\n}\n}\n
"},{"location":"api/custom-actions.html#example-2-webhookscript-action","title":"Example 2: WebhookScript action","text":"
{\n\"type\": \"script\",\n\"order\": 1,\n\"parameters\": {\n\"script\": \"expiry = '2021-08-01T00:00:00.000000Z'\\nnow = to_date('now')\\n\\nif (date_interval(now, expiry) < 0) {\\n    // Respond with 410 Gone\\n    respond('This content is no longer available.', 410)\\n}\\n\"\n}\n}\n
"},{"location":"api/custom-actions.html#example-3-creating-webhookscript-action-with-python-3","title":"Example 3: Creating WebhookScript action with Python 3","text":"

Same script as Example 2. Requires the requests module, which can be installed using pip install requests.

import requests\nscript = \"\"\"\nexpiry = '2021-08-01T00:00:00.000000Z'\nnow = to_date('now')\nif (date_interval(now, expiry) < 0) {\n    // Respond with 410 Gone\n    respond('This content is no longer available.', 410)\n}\n\"\"\"\ndata = {\n\"type\": \"script\",\n\"order\": 1,\n\"parameters\": {\n\"script\": script\n}\n}\nr = requests.post('https://webhook.site/token/7d63959e-4fec-49bd-90dc-a4615722825e/actions', json=data)\n
"},{"location":"api/custom-actions.html#response","title":"Response","text":"
{\n\"uuid\": \"7ae324d6-c65b-416b-8f83-18fb89e0c740\",\n\"token_id\": \"fe18d303-631d-4620-acb3-5c0b1b0b876d\",\n\"type\": \"condition\",\n\"order\": 3,\n\"disabled\": null,\n\"parameters\": {\n\"input\": \"$request.content$\",\n\"operator\": \"eq\",\n\"value\": \"\",\n\"action\": \"stop\"\n}\n}\n
"},{"location":"api/custom-actions.html#get-custom-actions","title":"Get Custom Actions","text":"
  • Can require authentication.

GET /token/:token_id/actions

"},{"location":"api/custom-actions.html#response_1","title":"Response","text":"

200 OK

{\n\"data\": [\n{\n\"uuid\": \"52055928-099a-44dc-ba31-e8d808b98ea1\",\n\"token_id\": \"fe18d303-631d-4620-acb3-5c0b1b0b876d\",\n\"type\": \"condition\",\n\"order\": 1,\n\"disabled\": false,\n\"parameters\": {\n\"input\": \"$request.header.content-type$\",\n\"operator\": \"nct\",\n\"value\": \"application/json\",\n\"action\": \"stop\"\n}\n},\n{\n\"uuid\": \"27b07ca7-ea83-48f5-b376-2372cf25d3a1\",\n\"token_id\": \"fe18d303-631d-4620-acb3-5c0b1b0b876d\",\n\"type\": \"condition\",\n\"order\": 2,\n\"disabled\": null,\n\"parameters\": {\n\"input\": \"$request.content$\",\n\"operator\": \"eq\",\n\"value\": \"\",\n\"action\": \"stop\"\n}\n}\n]\n}\n
"},{"location":"api/custom-actions.html#update-custom-action","title":"Update Custom Action","text":"
  • Can require authentication.

PUT /token/:token_id/actions/:action_id

"},{"location":"api/custom-actions.html#request_1","title":"Request","text":"

See Create Custom Action endpoint.

"},{"location":"api/custom-actions.html#response_2","title":"Response","text":"

See Create Custom Action endpoint.

"},{"location":"api/custom-actions.html#test-custom-action","title":"Test Custom Action","text":"
  • Can require authentication.
"},{"location":"api/custom-actions.html#request_2","title":"Request","text":"

POST /token/:token_id/test-action

"},{"location":"api/custom-actions.html#query-string-parameters","title":"Query string parameters","text":"
  • request_id: A request ID to base the test run on. If not set, uses default request variables.
  • action_id: When set, overwrites the parameters of an existing action. If not, tests a temporary new, empty action with ID 00000000-0000-4000-0000-000000000000.
{\n\"type\": \"script\",\n\"order\": 2,\n\"parameters\": {\n\"script\": \"echo('hello world')\"\n}\n}\n
"},{"location":"api/custom-actions.html#response_3","title":"Response","text":"

200 OK

{\n\"success\": true,\n\"result\": {\n\"output\": {\n\"08529a4f-ad84-450b-977a-1d126d6ca6b7\": [\n\"Set runtime variable $aaa$ to \\\"example\\\"\"\n],\n\"00000000-0000-4000-0000-000000000000\": [\n\"hello world\"\n]\n},\n\"response\": {\n\"content\": null,\n\"status\": null,\n\"headers\": null\n},\n\"variables\": {\n\"request.header.content-length\": \"57362\",\n\"request.header.user-agent\": \"Paw/3.3.5 (Macintosh; OS X/11.6.2) GCDHTTPRequest\",\n\"request.header.connection\": \"close\",\n\"request.header.host\": \"webhook.site\",\n\"request.header.content-type\": \"application/json\",\n\"request.uuid\": \"87240a26-1426-45dd-9b4c-961a323652a9\",\n\"request.token_id\": \"7fc77812-9efe-41b6-9365-e2c1fb5feb62\",\n\"request.content\": \"\",\n\"request.date\": \"2022-03-20 10:18:58\",\n\"request.timestamp\": 1647771538,\n\"request.hostname\": \"webhook.site\",\n\"request.size\": 0,\n\"request.type\": \"web\",\n\"request.ip\": \"86.52.35.76\",\n\"request.user_agent\": \"Paw/3.3.5 (Macintosh; OS X/11.6.2) GCDHTTPRequest\",\n\"request.url\": \"https://webhook.site/7fc77812-9efe-41b6-9365-e2c1fb5feb62\",\n\"request.method\": \"POST\",\n\"aaa\": \"example\"\n}\n}\n}\n
"},{"location":"api/custom-actions.html#delete-custom-action","title":"Delete Custom Action","text":"
  • Can require authentication.

DELETE /token/:token_id/actions/:action_id

"},{"location":"api/custom-actions.html#toggle-custom-actions","title":"Toggle Custom Actions","text":"
  • Can require authentication.

PUT /token/:token_id/actions/toggle

This endpoint toggles whether actions are enabled on a specific token.

"},{"location":"api/custom-actions.html#response_4","title":"Response","text":"

200 OK

{\n\"enabled\": true\n}\n
"},{"location":"api/date-expressions.html","title":"API Endpoints: Query string date expressions","text":"

Date expressions can be used in the query parameter when retreiving and filtering Requests from the API.

The expression starts with an anchor date, which can either be now (or *), or a date string ending with || (two pipe characters).

This anchor date can optionally be followed by one or more maths expressions:

  • +1h \u2013 Add one hour
  • -1d \u2013 Subtract one day
  • /d \u2013 Round down to the nearest day

The supported time units differ from those supported by time units for durations. The supported units are:

Symbol Meaning y Years M Months w Weeks d Days h Hours H Hours m Minutes s Seconds

Assuming now is 2001-01-01 12:00:00, some examples are:

Example Resolves to now+1h now in milliseconds plus one hour. Resolves to: 2001-01-01 13:00:00 now-1h now in milliseconds minus one hour. Resolves to: 2001-01-01 11:00:00 now-1h/d now in milliseconds minus one hour, rounded down to UTC 00:00. Resolves to: 2001-01-01 00:00:00 2001.02.01||+1M/d 2001-02-01 in milliseconds plus one month. Resolves to: 2001-03-01 00:00:00"},{"location":"api/examples.html","title":"API Examples","text":"

If you have a Webhook.site account, before using the API, please first create an API key here. The examples below can also be used without an account, but in that case you should remove the API key header.

Don't have an account yet? Sign up here.

"},{"location":"api/examples.html#curl","title":"cURL","text":""},{"location":"api/examples.html#send-json-data-to-url","title":"Send JSON data to URL","text":"
curl -X POST 'https://webhook.site/00000000-0000-0000-0000-000000000000' \\\n-H 'content-type: application/json' \\\n-d $'{\"id\": 7, \"name\": \"Jack Daniels\", \"position\": \"Assistant\"}'\n
"},{"location":"api/examples.html#get-data-of-last-request-sent-to-url","title":"Get data of last request sent to URL","text":"
curl 'https://webhook.site/token/00000000-0000-0000-0000-000000000000/request/latest/raw' \\\n-H 'accept: application/json' \\\n-H 'api-key: 00000000-0000-0000-0000-000000000000'\n

Output:

{\"id\": 7, \"name\": \"Jack Daniels\", \"position\": \"Assistant\"}\n
"},{"location":"api/examples.html#send-file-to-url","title":"Send file to URL","text":"

Uploads the file example.png from the current directory.

curl -F 'file=@example.png' https://webhook.site/00000000-0000-0000-0000-000000000000\n

To download the file, click the Download link in the Webhook.site interface, or via the API, use the download endpoint.

"},{"location":"api/examples.html#python","title":"Python","text":""},{"location":"api/examples.html#fetch-latest-data","title":"Fetch latest data","text":"

Requires the requests module, which can be installed using pip install requests.

Prints the 50 latest requests sent to a given URL to console.

import requests\ntoken_id = \"00000000-0000-0000-0000-000000000000\"\nheaders = {\"api-key\": \"00000000-0000-0000-0000-000000000000\"}\nr = requests.get('https://webhook.site/token/'+ token_id +'/requests?sorting=newest', headers=headers)\nfor request in r.json()['data']:\nprint(request)\n
"},{"location":"api/examples.html#create-urlemail-address","title":"Create URL/Email address","text":"

Requires the requests module, which can be installed using pip install requests.

You'll also need to replace the API key.

import requests\njson = {\n\"default_status\": 200,\n\"default_content\": \"Hello world!\",\n\"default_content_type\": \"text/html\",\n}\nheaders = {\n\"api-key\": \"00000000-0000-0000-0000-000000000000\"\n}\nr = requests.post('https://webhook.site/token', json=json, headers=headers)\nprint('URL Created: https://webhook.site/' + r.json()['uuid'])\n
"},{"location":"api/examples.html#php","title":"PHP","text":""},{"location":"api/examples.html#create-token-urlemail-address","title":"Create Token (URL/Email address)","text":"

Creates a Webhook.site Token and outputs its Web URL. You'll need to replace the API key.

<?php\n$apiKey = '00000000-0000-0000-0000-000000000000';\n// Create a stream context\n$context = stream_context_create(['http' => [\n'method' => 'POST',\n'header' => \"Api-Key: $apiKey\\r\\n\"\n]]);\n// Send API request\n$response = json_decode(file_get_contents('https://webhook.site/token', false, $context), true);\necho \"URL Created: https://webhook.site/{$response['uuid']}\";\n
"},{"location":"api/examples.html#fetch-latest-data_1","title":"Fetch latest data","text":"

Simple example of how to loop through the latest requests or emails sent to a Webhook.site URL or email and display in a friendly manner.

You'll need to replace the API key (if you have a Webhook.site account, otherwise leave it out) and token ID.

<?php\n$apiKey = '00000000-0000-0000-0000-000000000000';\n$tokenId = '00000000-0000-0000-0000-000000000000';\n$url = \"https://webhook.site/token/$tokenId/requests?sorting=newest\";\n$context = stream_context_create(['http' => ['header' => \"Api-Key: $apiKey\\r\\n\"]]);\n$response = json_decode(file_get_contents($url, false, $context), true);\nforeach ($response['data'] as $req) {\necho \"\\n\";\necho json_encode([\n'method' => $req['method'],\n'body' => $req['content'],\n'date' => $req['created_at'],\n], \\JSON_PRETTY_PRINT);\n}\n

Example output when running the script after running e.g. curl -X POST https://webhook.site/00000000-0000-0000-0000-000000000000 -d \"Hello world\":

{\n    \"method\": \"POST\",\n    \"body\": \"Hello world\",\n    \"date\": \"2023-06-08 13:04:33\"\n}\n{\n    \"method\": \"POST\",\n    \"body\": \"just testing\",\n    \"date\": \"2023-06-08 13:03:57\"\n}\n
"},{"location":"api/examples.html#download-all-request-data-as-files","title":"Download all request data as files","text":"

Per default, this script saves the body content of all requests or emails sent to a URL as .json files in the /requests directory relative to the script file location.

<?php\n$directory = __DIR__ . '/requests';\n//$apiKey = '00000000-0000-0000-0000-000000000000';\n$tokenId = '00000000-0000-0000-0000-000000000000';\nif (!is_dir($directory) || !is_writable($directory)) {\nthrow new Exception(sprintf('%s not writable, directory missing or rights issue.', $directory));\n}\n$context = stream_context_create(['http' =>\nisset($apiKey) ? ['header' => \"Api-Key: $apiKey\\r\\n\"] : [],\n]);\n$page = 1;\ndo {\n$url = sprintf('https://webhook.site/token/%s/requests?sorting=newest&page=%d', $tokenId, $page);\n$response = json_decode(file_get_contents($url, false, $context), true);\nforeach ($response['data'] as $req) {\nfile_put_contents(\nsprintf('/%s/%s.json', $directory, $req['uuid']),\n$req['content']\n);\necho(sprintf(\n\"[Page %3d] Downloaded request %s sent at %s (%d bytes)\\n\",\n$page, $req['uuid'], $req['created_at'], $req['size']\n));\n}\n$page++;\nsleep(1);\n} while (!$response['is_last_page'] && isset($response['data']));\n
"},{"location":"api/examples.html#nodejs","title":"Node.js","text":""},{"location":"api/examples.html#fetch-latest-data_2","title":"Fetch latest data","text":"

This script outputs the data sent to a Webhook.site URL in the last 2 hours.

To do this, the script uses the query parameter (more info here) in conjunction with a created_at filter.

Before running the script, you should install dependencies by running npm install axios moment.

import axios from 'axios';\nimport moment from 'moment';\n// Change these!\nconst apiKey = '00000000-0000-0000-0000-000000000000';\nconst tokenId = '00000000-0000-0000-0000-000000000000';\nasync function getData(apiKey, tokenId) {\nlet date = moment.utc().subtract(2, 'hours').format('YYYY-MM-DD hh:mm:ss');  let dateQuery = `created_at:[\"${date}\" TO \"*\"]`\ntry {\nconst response = await axios.get(`https://webhook.site/token/${tokenId}/requests`, {\nparams: {\nquery: dateQuery,\n},\nheaders: {\n'Api-Key': apiKey,\n'Accept': 'application/json',\n}\n});\nreturn response.data;\n} catch (error) {\nconsole.error(error);\n}\n}\nconst requests = await getData(apiKey, tokenId);\nconsole.log(`${requests.total} requests found:`);\nfor (const request of requests.data) {\nconsole.log({\nmethod: request.method, body: request.content,\ndate: request.created_at,\n});\n}\n
"},{"location":"api/global-variables.html","title":"API Endpoints: Global Variables","text":"

With Global Variables, you can store data permanently that can be shared between your URLs. Global Variables can be used when creating Custom Actions and in Schedules. More about Global Variables

"},{"location":"api/global-variables.html#create-global-variable","title":"Create Global Variable","text":"
  • Requires authentication.

After creating, the variable $name$ will be available in Custom Actions.

"},{"location":"api/global-variables.html#request","title":"Request","text":"

POST /global-variables

  • name (string) The name of the variable.
  • value (string) The value of the variable.
{\n\"name\": \"content_type\",\n\"value\": \"application/json\"\n}\n
"},{"location":"api/global-variables.html#response","title":"Response","text":"
{\n\"id\": 598297,\n\"name\": \"content_type\",\n\"team_id\": 1,\n\"value\": \"application\\/json\",\n\"updated_at\": \"2024-04-15T11:20:02.000000Z\",\n\"created_at\": \"2024-04-15T11:20:02.000000Z\"\n}\n
"},{"location":"api/global-variables.html#get-all-global-variables","title":"Get all Global Variables","text":"
  • Requires authentication.
"},{"location":"api/global-variables.html#request_1","title":"Request","text":"

GET /global-variables

"},{"location":"api/global-variables.html#query-string-parameters","title":"Query string parameters","text":"
  • per_page (int) - amount of requests returned, defaults to 50 (max 100)
  • page (int) - page number to retrieve (default 1)
  • search (string) - filter variables by name
"},{"location":"api/global-variables.html#response_1","title":"Response","text":"
{\n\"current_page\": 1,\n\"data\": [\n{\n\"id\": 598297,\n\"user_id\": 0,\n\"team_id\": 1,\n\"name\": \"content_type\",\n\"value\": \"application\\/json\",\n\"created_at\": \"2024-04-15T11:20:02.000000Z\",\n\"updated_at\": \"2024-04-15T11:20:02.000000Z\"\n},\n{\n\"id\": 598294,\n\"user_id\": 0,\n\"team_id\": 1,\n\"name\": \"test\",\n\"value\": \"\\ud83e\\udd72\",\n\"created_at\": \"2024-04-14T13:21:24.000000Z\",\n\"updated_at\": \"2024-04-14T13:21:24.000000Z\"\n}\n],\n\"first_page_url\": \"https:\\/\\/webhook.test\\/global-variables?page=1\",\n\"from\": 1,\n\"last_page\": 21992,\n\"last_page_url\": \"https:\\/\\/webhook.test\\/global-variables?page=21992\",\n\"links\": [\n{\n\"url\": null,\n\"label\": \"&laquo; Previous\",\n\"active\": false\n},\n{\n\"url\": \"https:\\/\\/webhook.test\\/global-variables?page=1\",\n\"label\": \"1\",\n\"active\": true\n},\n{\n\"url\": null,\n\"label\": \"...\",\n\"active\": false\n},\n{\n\"url\": \"https:\\/\\/webhook.test\\/global-variables?page=21991\",\n\"label\": \"21991\",\n\"active\": false\n},\n{\n\"url\": \"https:\\/\\/webhook.test\\/global-variables?page=2\",\n\"label\": \"Next &raquo;\",\n\"active\": false\n}\n],\n\"next_page_url\": \"https:\\/\\/webhook.test\\/global-variables?page=2\",\n\"path\": \"https:\\/\\/webhook.test\\/global-variables\",\n\"per_page\": 15,\n\"prev_page_url\": null,\n\"to\": 15,\n\"total\": 329870\n}\n
"},{"location":"api/global-variables.html#update-global-variable","title":"Update Global Variable","text":""},{"location":"api/global-variables.html#request_2","title":"Request","text":"

PUT /global-variables/:globalVariableId

(See Create Global Variable above for request.)

"},{"location":"api/global-variables.html#response_2","title":"Response","text":"

(See Create Global Variable above for response.)

"},{"location":"api/global-variables.html#delete-global-variable","title":"Delete Global Variable","text":""},{"location":"api/global-variables.html#request_3","title":"Request","text":"

DELETE /global-variables/:globalVariableId

"},{"location":"api/global-variables.html#response_3","title":"Response","text":"

204 No content

"},{"location":"api/groups.html","title":"API Endpoints: Groups","text":"

Webhook.site Groups allows you to organize your Tokens. Each Group is a container for multiple Tokens.

"},{"location":"api/groups.html#create-group","title":"Create Group","text":"
  • Requires authentication.
"},{"location":"api/groups.html#request","title":"Request","text":"

POST /groups

  • name (string) The name of the group.
{\n\"name\": \"My Group\"\n}\n
"},{"location":"api/groups.html#response","title":"Response","text":"
{\n\"id\": 3498,\n\"team_id\": 12098,\n\"name\": \"My Group\",\n\"updated_at\": \"2023-04-26 18:43:46\",\n\"created_at\": \"2023-04-26 18:43:46\"\n}\n
"},{"location":"api/groups.html#get-all-groups","title":"Get all Groups","text":"
  • Requires authentication.
"},{"location":"api/groups.html#request_1","title":"Request","text":"

GET /groups

"},{"location":"api/groups.html#response_1","title":"Response","text":"
{\n\"current_page\": 1,\n\"data\": [\n{\n\"id\": 3498,\n\"team_id\": 12098,\n\"name\": \"My Group\",\n\"created_at\": \"2022-10-26 14:25:11\",\n\"updated_at\": \"2022-10-26 14:25:11\"\n},\n{\n\"id\": 3499,\n\"team_id\": 12098,\n\"name\": \"My nice group\",\n\"created_at\": \"2023-04-26 09:57:40\",\n\"updated_at\": \"2023-04-26 09:57:40\"\n}\n],\n\"first_page_url\": \"https:\\/\\/webhook.site\\/groups?page=1\",\n\"from\": 1,\n\"last_page\": 1,\n\"last_page_url\": \"https:\\/\\/webhook.site\\/groups?page=1\",\n\"next_page_url\": null,\n\"path\": \"https:\\/\\/webhook.site\\/groups\",\n\"per_page\": \"2\",\n\"prev_page_url\": null,\n\"to\": 2,\n\"total\": 2\n}\n
"},{"location":"api/groups.html#update-group","title":"Update Group","text":""},{"location":"api/groups.html#request_2","title":"Request","text":"

PUT /groups/:groupId

(See Create Group above for request.)

"},{"location":"api/groups.html#response_2","title":"Response","text":"

(See Create Group above for response.)

"},{"location":"api/groups.html#delete-group","title":"Delete Group","text":""},{"location":"api/groups.html#request_3","title":"Request","text":"

DELETE /groups/:groupId

"},{"location":"api/groups.html#response_3","title":"Response","text":"

204 No content

"},{"location":"api/requests.html","title":"API Endpoints: Requests","text":"

The Requests API is used to retrieve, manipulate and delete data sent to a given Webhook.site token (URL, E-mail Address or DNSHook.)

"},{"location":"api/requests.html#capture-request","title":"Capture request","text":"

any method /:tokenId any method /:tokenId/:statusCode any method /:tokenId/(anything)

If statusCode is valid, that HTTP status will be used in the response (instead of the default.)

Instead of tokenId, an the alias of the token can also be supplied. Multiple subpaths, e.g. /:tokenId/api/v1/users, will also be captured.

If the Token has a timeout value, there is a dynamic rate limit of 100 \u00f7 timeout requests per minute, e.g. a timeout of 30 allows for 3 requests per minute, and 1 second allows for 100 requests per minute.

"},{"location":"api/requests.html#response","title":"Response","text":"

The default response (or a response set with e.g. the Modify Response Custom Action) of the Token will be returned.

"},{"location":"api/requests.html#get-requests","title":"Get requests","text":"
  • Can require authentication.
  • Rate limit: 120 requests per minute.

GET /token/:token_id/requests

Lists all request sent to a token.

"},{"location":"api/requests.html#query-string-parameters","title":"Query string parameters","text":"
  • sorting (string) - either newest or oldest (default)
  • per_page (int) - amount of requests returned, defaults to 50 (max 100)
  • page (int) - page number to retrieve (default 1)
  • date_from, date_to (date string) - filter requests by date, format yyyy-MM-dd HH:mm:ss
  • query (string) - filter requests by a query string search (see below for examples)
"},{"location":"api/requests.html#search-query-examples","title":"Search query examples","text":"

The following fields can be used to filter via the query parameter:

  • uuid
  • token_id
  • team_id
  • type
  • hostname
  • size
  • content
  • time
  • created_at
  • updated_at
  • custom_action_output
  • files.[id]
  • headers.[header]
  • method - type web only
  • user_agent - type web only
  • url - type web only
  • ip - type web only
  • query.[field] - type web only
  • request.[field] - type webonly (form fields)
  • sender - type email only
  • text_content - type email only
  • message_id - type email only
  • checks.[type] - type email only
  • destinations] - type email only

You can filter requests by the following syntax:

  • foobar - returns requests or emails with body contents containing the word foobar
  • content:foobar - returns requests or emails with body contents containing the word foobar
  • method:GET - returns all requests with method GET
  • headers.user-agent:\"Paw/3.3.5 (Macintosh; OS X/11.6.2) GCDHTTPRequest\" - search value of user-agent header
  • query.action:create - returns requests that have the query string action set to create.
  • _exists_:query.action - returns requests where the action query parameter exists
  • type:web / type:email - returns either Web requests or emails
  • type:web AND method:POST - AND query
  • method:PUT OR method:POST - OR query
  • (method:PUT) AND (content:example OR content:test) AND NOT (content:foobar)
  • created_at:[\"2022-01-01 00:00:00\" TO \"2022-12-31 00:00:00\"] - date range query
  • created_at:[\"2022-01-01 00:00:00\" TO *] - date range query (from date until now)
  • created_at:[now-10m TO now] - date range query (10 minutes ago until now; reference for date expressions)
"},{"location":"api/requests.html#full-url-example","title":"Full URL Example","text":"

If you're in doubt about where these parameters go in an API request, take a look below. This URL combines a search query via the query parameter (searching requests containing the word foobar), as well as the sorting and per_page parameters.

https://webhook.site/token/a94a7294-c4aa-4074-ab77-c4cf86fd53b1/requests?query=content:foobar&sorting=newest&per_page=10

"},{"location":"api/requests.html#response_1","title":"Response","text":"
{\n\"data\": [\n{\n\"uuid\": \"a2a6a4ae-4130-4063-953a-84fa29d81d43\",\n\"token_id\": \"a94a7294-c4aa-4074-ab77-c4cf86fd53b1\",\n\"ip\": \"127.0.0.1\",\n\"hostname\": \"webhook.site\",\n\"method\": \"POST\",\n\"user_agent\": \"Paw\\/3.1.8 (Macintosh; OS X\\/10.14.6) GCDHTTPRequest\",\n\"content\": \"{\\\"first_name\\\":\\\"Arch\\\",\\\"last_name\\\":\\\"Weber\\\"}\",\n\"query\": {\n\"action\": \"create\"\n},\n\"request\": {\n\"status\": \"example\"\n},\n\"files\": {\n\"file\": {\n\"id\": \"98bf4c25-58ab-4c5d-ba91-fb6f709ea78d\",\n\"filename\": \"example.png\",\n\"size\": 420915,\n\"content_type\": \"image/png\"\n}\n},\n\"headers\": {\n\"content-length\": [\n\"271\"\n],\n\"user-agent\": [\n\"Paw\\/3.1.8 (Macintosh; OS X\\/10.14.6) GCDHTTPRequest\"\n],\n\"request-id\": [\n\"37856131\"\n]\n},\n\"url\": \"https:\\/\\/webhook.site\\/a94a7294-c4aa-4074-ab77-c4cf86fd53b1\\/201?\",\n\"created_at\": \"2019-10-03 19:06:35\",\n\"updated_at\": \"2019-10-03 19:06:35\",\n\"custom_action_output\": []\n}\n],\n\"total\": 1,\n\"per_page\": 50,\n\"current_page\": 1,\n\"is_last_page\": true,\n\"from\": 1,\n\"to\": 1\n}\n
"},{"location":"api/requests.html#get-singlelatest-request","title":"Get single/latest request","text":"
  • Can require authentication.

GET /token/:token_id/request/:request_id

GET /token/:token_id/request/latest - retrieves the latest request sent to the URL

"},{"location":"api/requests.html#response_2","title":"Response","text":"
{\n\"uuid\": \"a2a6a4ae-4130-4063-953a-84fa29d81d43\",\n\"token_id\": \"a94a7294-c4aa-4074-ab77-c4cf86fd53b1\",\n\"ip\": \"127.0.0.1\",\n\"hostname\": \"webhook.site\",\n\"method\": \"POST\",\n\"user_agent\": \"Paw\\/3.1.8 (Macintosh; OS X\\/10.14.6) GCDHTTPRequest\",\n\"content\": \"{\\\"first_name\\\":\\\"Arch\\\",\\\"last_name\\\":\\\"Weber\\\"}\",\n\"query\": {\n\"action\": \"create\"\n},\n\"headers\": {\n\"content-length\": [\n\"271\"\n],\n\"user-agent\": [\n\"Paw\\/3.1.8 (Macintosh; OS X\\/10.14.6) GCDHTTPRequest\"\n]\n},\n\"files\": {\n\"foo\": {\n\"id\": \"65d6e0ce-a840-47bc-b6b6-ff1ff38c34ca\",\n\"filename\": \"example.json\",\n\"size\": 5132873,\n\"content_type\": \"text/plain\"\n}\n},\n\"url\": \"https:\\/\\/webhook.site\\/a94a7294-c4aa-4074-ab77-c4cf86fd53b1\\/201?\",\n\"created_at\": \"2019-10-03 19:06:35\",\n\"updated_at\": \"2019-10-03 19:06:35\"\n}\n
"},{"location":"api/requests.html#get-raw-request-content","title":"Get raw request content","text":"
  • Can require authentication.

GET /token/:token_id/request/:request_id/raw

GET /token/:token_id/request/latest/raw - retrieves the latest request sent to the URL

Returns the request as a response (body, content-type.)

"},{"location":"api/requests.html#response_3","title":"Response","text":"

200 OK

"},{"location":"api/requests.html#download-request-file","title":"Download request file","text":"
  • Can require authentication.

GET /token/:tokenId/request/:requestId/download/:fileId

Files that are included in a request or as email attachments are available to download using this endpoint.

"},{"location":"api/requests.html#response_4","title":"Response","text":"

304 Redirect

"},{"location":"api/requests.html#delete-request","title":"Delete request","text":"
  • Can require authentication.

DELETE /token/:token_id/request/:request_id

Deletes a request.

"},{"location":"api/requests.html#response_5","title":"Response","text":"

200 OK

"},{"location":"api/requests.html#delete-multiple-requests","title":"Delete multiple requests","text":"
  • Can require authentication.
  • Rate limit: 10 requests per minute.

DELETE /token/:token_id/request

Deletes all requests associated with the token, or if query, date_from and/or date_to is specified, only that subset of requests is deleted.

"},{"location":"api/requests.html#query-string-parameters_1","title":"Query string parameters","text":"
  • date_from, date_to - filter requests by date, format yyyy-MM-dd HH:mm:ss
  • query - filter requests by a query string search. See here for examples.
"},{"location":"api/requests.html#response_6","title":"Response","text":"

200 OK

"},{"location":"api/schedules.html","title":"API Endpoints: Schedules","text":"

More info about Schedules.

"},{"location":"api/schedules.html#create-schedule","title":"Create schedule","text":"
  • Requires authentication.
"},{"location":"api/schedules.html#request","title":"Request","text":"

POST /schedules

  • name The name of the schedule.
  • interval One of the following interval strings: monthly, weekly, daily, hourly, 10-minute, 5-minute, 1-minute, cron
  • cron When interval is cron, specify a cron-style interval, e.g. */5 * * * * for every 5 minutes. Otherwise can be left out.
  • request_url The request URL that the schedule should act on.
  • request_method HTTP Method (POST, GET, etc.)
  • request_body
  • request_headers HTTP headers, separated by \\n
  • timeout Timeout in seconds (min 1, max 30)
  • require_body If specified, Webhook.site sends an error notification if response body doesn't contain this string.
  • require_status_min If specified, Webhook.site sends an error notification if response status doesn't fit within range.
  • require_status_max If specified, Webhook.site sends an error notification if response status doesn't fit within range.

Variables will be replaced in the fields request_url, request_method, request_headers and request_body. More info here.

{\n\"name\": \"My schedule\",\n\"interval\": \"5-minute\",\n\"request_url\": \"https://example.com\",\n\"request_method\": \"POST\",\n\"request_body\": \"{\\\"json\\\": \\\"message\\\"}\",\n\"request_headers\": \"Authorization: Bearer mytoken\\nContent-Type: application/json\"\n}\n
"},{"location":"api/schedules.html#response","title":"Response","text":"
{\n\"name\": \"My schedule\",\n\"interval\": \"5-minute\",\n\"request_url\": \"https:\\/\\/example.com\",\n\"request_method\": \"POST\",\n\"request_body\": \"{\\\"json\\\": \\\"message\\\"}\",\n\"request_headers\": \"Authorization: Bearer mytoken\\nContent-Type: application\\/json\",\n\"require_body\": null,\n\"require_status_min\": null,\n\"require_status_max\": null,\n\"user_id\": 21,\n\"updated_at\": \"2021-05-01 13:27:25\",\n\"created_at\": \"2021-05-01 13:27:25\",\n\"id\": 58\n}\n
"},{"location":"api/schedules.html#get-all-schedules","title":"Get all schedules","text":"

GET /schedules?page=1&per_page=15

"},{"location":"api/schedules.html#response_1","title":"Response","text":"
{\n\"current_page\": 1,\n\"data\": [\n{\n\"id\": 58,\n\"name\": \"My schedule\",\n\"interval\": \"5-minute\",\n\"cron\": null,\n\"user_id\": 21,\n\"request_method\": \"POST\",\n\"request_url\": \"https:\\/\\/example.com\",\n\"request_headers\": \"Authorization: Bearer mytoken\\nContent-Type: application\\/json\",\n\"request_body\": \"{\\\"json\\\": \\\"message\\\"}\",\n\"timeout\": 5,\n\"require_body\": null,\n\"require_status_min\": null,\n\"require_status_max\": null,\n\"last_run_at\": null,\n\"last_status\": null,\n\"created_at\": \"2021-05-01 13:27:25\",\n\"updated_at\": \"2021-05-01 13:27:25\"\n}\n],\n\"first_page_url\": \"https:\\/\\/webhook.site\\/schedules?page=1\",\n\"from\": 1,\n\"last_page\": 1,\n\"last_page_url\": \"https:\\/\\/webhook.site\\/schedules?page=1\",\n\"next_page_url\": null,\n\"path\": \"https:\\/\\/webhook.site\\/schedules\",\n\"per_page\": 15,\n\"prev_page_url\": null,\n\"to\": 6,\n\"total\": 6\n}\n
"},{"location":"api/schedules.html#get-single-schedule","title":"Get single schedule","text":""},{"location":"api/schedules.html#request_1","title":"Request","text":"

GET /schedules/:scheduleId

"},{"location":"api/schedules.html#response_2","title":"Response","text":"
{\n\"id\": 58,\n\"name\": \"My schedule\",\n\"interval\": \"5-minute\",\n\"cron\": null,\n\"user_id\": 21,\n\"request_method\": \"POST\",\n\"request_url\": \"https:\\/\\/example.com\",\n\"request_headers\": \"Authorization: Bearer mytoken\\nContent-Type: application\\/json\",\n\"request_body\": \"{\\\"json\\\": \\\"message\\\"}\",\n\"timeout\": 5,\n\"require_body\": null,\n\"require_status_min\": null,\n\"require_status_max\": null,\n\"last_run_at\": null,\n\"last_status\": null,\n\"created_at\": \"2021-05-01 13:27:25\",\n\"updated_at\": \"2021-05-01 13:27:25\"\n}\n
"},{"location":"api/schedules.html#update-schedule","title":"Update schedule","text":""},{"location":"api/schedules.html#request_2","title":"Request","text":"

PUT /schedules/:scheduleId

(See Create schedule above for request.)

"},{"location":"api/schedules.html#response_3","title":"Response","text":"

(See Get single schedule for response.)

"},{"location":"api/schedules.html#delete-schedule","title":"Delete schedule","text":""},{"location":"api/schedules.html#request_3","title":"Request","text":"

DELETE /schedules/:scheduleId

"},{"location":"api/schedules.html#response_4","title":"Response","text":"

204 No content

"},{"location":"api/schedules.html#run-schedule-now","title":"Run Schedule Now","text":""},{"location":"api/schedules.html#request_4","title":"Request","text":"

POST /schedules/:scheduleId/run-now

"},{"location":"api/schedules.html#get-schedule-logs","title":"Get Schedule Logs","text":""},{"location":"api/schedules.html#request_5","title":"Request","text":"

GET /schedules/:scheduleId/logs

Set Accept header to application/json.

Rate limit: 60 requests per minute.

"},{"location":"api/schedules.html#response_5","title":"Response","text":"
{\n\"data\": [\n{\n\"id\": 2,\n\"schedule_id\": 1,\n\"response_status\": 200,\n\"response_headers\": {\n\"Age\": [\n\"447707\"\n],\n\"Cache-Control\": [\n\"max-age=604800\"\n],\n\"Content-Type\": [\n\"text\\/html; charset=UTF-8\"\n]\n},\n\"response_body\": \"<!doctype html>\\n<html>\\n<head>...\",\n\"error\": null,\n\"created_at\": \"2022-11-06 19:27:09\",\n\"updated_at\": \"2022-11-06 19:27:09\"\n},\n{\n\"id\": 3,\n\"schedule_id\": 1,\n\"response_status\": 200,\n\"response_headers\": {\n\"Age\": [\n\"404973\"\n],\n\"Cache-Control\": [\n\"max-age=604800\"\n],\n\"Content-Type\": [\n\"text\\/html; charset=UTF-8\"\n]\n},\n\"response_body\": \"<!doctype html>\\n<html>\\n<head>...\",\n\"error\": null,\n\"created_at\": \"2022-11-06 19:30:02\",\n\"updated_at\": \"2022-11-06 19:30:02\"\n}\n],\n\"current_page\": 1,\n\"first_page_url\": \"https:\\/\\/webhook.site\\/control-panel\\/schedules\\/1\\/logs?page=1\",\n\"from\": 1,\n\"last_page\": 1,\n\"last_page_url\": \"https:\\/\\/webhook.site\\/control-panel\\/schedules\\/1\\/logs?page=1\",\n\"next_page_url\": null,\n\"path\": \"https:\\/\\/webhook.site\\/control-panel\\/schedules\\/1\\/logs\",\n\"per_page\": 15,\n\"prev_page_url\": null,\n\"to\": 2,\n\"total\": 2\n}\n
"},{"location":"api/templates.html","title":"API Endpoints: Templates","text":"

Webhook.site Templates allows you to create templates of actions, and re-use these templates with the Include Template Custom Action.

"},{"location":"api/templates.html#create-template","title":"Create Template","text":"
  • Requires authentication.
"},{"location":"api/templates.html#request","title":"Request","text":"

POST /template

  • name The name of the template.
  • actions An array of objects containing Custom Actions. All parameters of actions except disabled can be used. More info here
  • variables An array of name-value objects containing predefined variables. These variables are defined before the action runs, and are available to any subsequent actions after the template is included.
{\n\"actions\": [\n{\n\"name\": null,\n\"type\": \"conditions\",\n\"queue\": false,\n\"delay\": 0,\n\"condition\": null,\n\"parameters\": {\n\"conditions\": [\n{\n\"input\": \"$date$\",\n\"operator\": \"eq\",\n\"value\": \"$post-news-last-date$\"\n}\n],\n\"mode\": \"all\",\n\"action\": \"stop\"\n},\n\"order\": 2\n},\n{\n\"name\": null,\n\"type\": \"twitter_tweet\",\n\"queue\": false,\n\"delay\": 0,\n\"condition\": null,\n\"parameters\": {\n\"provider_id\": \"501133\",\n\"tweet\": \"$tweet$\"\n},\n\"order\": 3\n},\n{\n\"name\": null,\n\"type\": \"store_global_variable\",\n\"queue\": false,\n\"delay\": 0,\n\"condition\": null,\n\"parameters\": {\n\"name\": \"post-news-last-date\",\n\"value\": \"$date$\"\n},\n\"order\": 4\n}\n],\n\"name\": \"My Template\",\n\"variables\": [\n{\n\"name\": \"example\",\n\"value\": \"hello world\"\n}\n],\n}\n
"},{"location":"api/templates.html#response","title":"Response","text":"
{\n\"name\": \"My Template\",\n\"variables\": [\n{\n\"name\": \"example\",\n\"value\": \"hello world\"\n}\n],\n\"team_id\": 1,\n\"updated_at\": \"2024-02-20T10:01:29.000000Z\",\n\"created_at\": \"2024-02-20T10:01:29.000000Z\",\n\"id\": 21,\n\"actions\": [\n{\n\"condition\": null,\n\"delay\": 0,\n\"parameters\": {\n\"mode\": \"all\",\n\"conditions\": [\n{\n\"input\": \"$date$\",\n\"operator\": \"eq\",\n\"value\": \"$post-news-last-date$\"\n}\n],\n\"action\": \"stop\"\n},\n\"token_id\": \"f1bd342e-c98b-4ac4-bf3f-c35f1f338161\",\n\"type\": \"conditions\",\n\"order\": 2,\n\"name\": null,\n\"template_id\": 21,\n\"uuid\": \"9b615454-3c64-4da2-a2f7-d524797a8925\",\n\"updated_at\": \"2024-02-20T10:01:29.000000Z\",\n\"created_at\": \"2024-02-20T10:01:29.000000Z\"\n},\n{\n\"condition\": null,\n\"delay\": 0,\n\"parameters\": {\n\"tweet\": \"$tweet$\",\n\"provider_id\": \"501133\"\n},\n\"token_id\": \"f1bd342e-c98b-4ac4-bf3f-c35f1f338161\",\n\"type\": \"twitter_tweet\",\n\"order\": 3,\n\"name\": null,\n\"template_id\": 21,\n\"uuid\": \"9b615454-3ce7-4c63-bc8b-3412694ae633\",\n\"updated_at\": \"2024-02-20T10:01:29.000000Z\",\n\"created_at\": \"2024-02-20T10:01:29.000000Z\"\n},\n{\n\"condition\": null,\n\"delay\": 0,\n\"parameters\": {\n\"name\": \"post-news-last-date\",\n\"value\": \"$date$\"\n},\n\"token_id\": \"f1bd342e-c98b-4ac4-bf3f-c35f1f338161\",\n\"type\": \"store_global_variable\",\n\"order\": 4,\n\"name\": null,\n\"template_id\": 21,\n\"uuid\": \"9b615454-3d5f-4cd6-bd4b-94b55e6f6f2f\",\n\"updated_at\": \"2024-02-20T10:01:29.000000Z\",\n\"created_at\": \"2024-02-20T10:01:29.000000Z\"\n}\n]\n}\n
"},{"location":"api/templates.html#get-all-templates","title":"Get all Templates","text":"
  • Requires authentication.
"},{"location":"api/templates.html#request_1","title":"Request","text":"

GET /templates

"},{"location":"api/templates.html#response_1","title":"Response","text":"
{\n\"current_page\": 1,\n\"data\": [\n{\n\"name\": \"My Template\",\n\"variables\": [\n{\n\"name\": \"example\",\n\"value\": \"hello world\"\n}\n],\n\"team_id\": 1,\n\"updated_at\": \"2024-02-20T10:01:29.000000Z\",\n\"created_at\": \"2024-02-20T10:01:29.000000Z\",\n\"id\": 21,\n\"actions\": [\n{\n\"condition\": null,\n\"delay\": 0,\n\"parameters\": {\n\"mode\": \"all\",\n\"conditions\": [\n{\n\"input\": \"$date$\",\n\"operator\": \"eq\",\n\"value\": \"$post-news-last-date$\"\n}\n],\n\"action\": \"stop\"\n},\n\"token_id\": \"f1bd342e-c98b-4ac4-bf3f-c35f1f338161\",\n\"type\": \"conditions\",\n\"order\": 2,\n\"name\": null,\n\"template_id\": 21,\n\"uuid\": \"9b615454-3c64-4da2-a2f7-d524797a8925\",\n\"updated_at\": \"2024-02-20T10:01:29.000000Z\",\n\"created_at\": \"2024-02-20T10:01:29.000000Z\"\n},\n{\n\"condition\": null,\n\"delay\": 0,\n\"parameters\": {\n\"tweet\": \"$tweet$\",\n\"provider_id\": \"501133\"\n},\n\"token_id\": \"f1bd342e-c98b-4ac4-bf3f-c35f1f338161\",\n\"type\": \"twitter_tweet\",\n\"order\": 3,\n\"name\": null,\n\"template_id\": 21,\n\"uuid\": \"9b615454-3ce7-4c63-bc8b-3412694ae633\",\n\"updated_at\": \"2024-02-20T10:01:29.000000Z\",\n\"created_at\": \"2024-02-20T10:01:29.000000Z\"\n},\n{\n\"condition\": null,\n\"delay\": 0,\n\"parameters\": {\n\"name\": \"post-news-last-date\",\n\"value\": \"$date$\"\n},\n\"token_id\": \"f1bd342e-c98b-4ac4-bf3f-c35f1f338161\",\n\"type\": \"store_global_variable\",\n\"order\": 4,\n\"name\": null,\n\"template_id\": 21,\n\"uuid\": \"9b615454-3d5f-4cd6-bd4b-94b55e6f6f2f\",\n\"updated_at\": \"2024-02-20T10:01:29.000000Z\",\n\"created_at\": \"2024-02-20T10:01:29.000000Z\"\n}\n]\n}\n],\n\"first_page_url\": \"https:\\/\\/webhook.site\\/templates?page=1\",\n\"from\": 1,\n\"last_page\": 1,\n\"last_page_url\": \"https:\\/\\/webhook.site\\/templates?page=1\",\n\"links\": [\n{\n\"url\": null,\n\"label\": \"&laquo; Previous\",\n\"active\": false\n},\n{\n\"url\": \"https:\\/\\/webhook.site\\/templates?page=1\",\n\"label\": \"1\",\n\"active\": true\n},\n{\n\"url\": null,\n\"label\": \"Next &raquo;\",\n\"active\": false\n}\n],\n\"next_page_url\": null,\n\"path\": \"https:\\/\\/webhook.site\\/templates\",\n\"per_page\": 15,\n\"prev_page_url\": null,\n\"to\": 1,\n\"total\": 1\n}\n
"},{"location":"api/templates.html#update-template","title":"Update Template","text":""},{"location":"api/templates.html#request_2","title":"Request","text":"

PUT /templates/:templateId

(See Create Template above for request.)

"},{"location":"api/templates.html#response_2","title":"Response","text":"

(See Create Template above for response.)

"},{"location":"api/templates.html#delete-template","title":"Delete Template","text":""},{"location":"api/templates.html#request_3","title":"Request","text":"

DELETE /templates/:templateId

"},{"location":"api/templates.html#response_3","title":"Response","text":"

204 No content

"},{"location":"api/tokens.html","title":"API Endpoints:Tokens (URLs & Email Addresses)","text":"

A token is a container for incoming requests and emails, and corresponds to a Webhook.site URL or Email. A token ID is a 36 character UUID consisting of hexadecimal characters and dashes.

Simply, the token ID is the part after https://webhook.site/ in the URL, or before @email.webhook.site in the email address.

"},{"location":"api/tokens.html#create-token","title":"Create token","text":"
  • Can require authentication.
  • Rate limit: 10 per minute (free); 60 per minute (Pro and Enterprise)

POST /token

After creating a token, the URL at https://webhook.site/{token.uuid} becomes accessible, and emails can be sent to {token.uuid}@email.webhook.site.

  • default_* parameters sets the response of the URL.
  • timeout (int) waits an amount of seconds before returning the response, max 30. Intended for testing timeouts, requests to tokens with timeouts are rate limited; a high timeout value will incur a lower rate limit.
  • expiry (int) amount of seconds until token auto-expiration. Max value (and default for non-upgraded URLs) is 604800 (one week). Intended for e.g. automated testing pipelines. Leave out or set to null to disable.
  • request_limit (int) - limits the request history amount from 1 to 10000 (default)
  • cors (bool) set to true will add CORS headers to the request so browsers will send cross-domain requests to the URL
  • alias (string) allows setting the alias of the token.
  • actions (bool) specifies if Custom Actions are enabled and executed on every request/email (true), or disabled (false.)
  • clone_from (uuid string) specifies a token UUID (or alias) that will act as a template for the new token. When specified, settingssuch as default content, timeout, password as well as Custom Actions are copied to the new token.
  • group_id (int) specifies which group ID the token should be added to.
"},{"location":"api/tokens.html#request","title":"Request","text":""},{"location":"api/tokens.html#example-1-json","title":"Example 1: JSON","text":"
{\n\"default_status\": 200,\n\"default_content\": \"Hello world!\",\n\"default_content_type\": \"text/html\",\n\"timeout\": 0,\n\"cors\": false,\n\"expiry\": 604800,\n\"alias\": \"my-webhook\",\n\"actions\": true\n}\n
"},{"location":"api/tokens.html#example-2-creating-with-python-3","title":"Example 2: Creating with Python 3","text":"

Requires the requests module, which can be installed using pip install requests. You'll also need to replace the API key. Create an API key here.

import requests\njson = {\n\"default_status\": 200,\n\"default_content\": \"Hello world!\",\n\"default_content_type\": \"text/html\",\n}\nheaders = {\n\"api-key\": \"00000000-0000-0000-0000-000000000000\"\n}\nr = requests.post('https://webhook.site/token', json=json, headers=headers)\nprint('URL Created: https://webhook.site/' + r.json()['uuid'])\n
"},{"location":"api/tokens.html#response","title":"Response","text":"

200 OK

{\n\"redirect\": false,\n\"alias\": null,\n\"timeout\": 0,\n\"premium\": true,\n\"uuid\": \"9981f9f4-657a-4ebf-be7c-1915bedd4775\",\n\"ip\": \"127.0.0.1\",\n\"user_agent\": \"Paw\\/3.1.8 (Macintosh; OS X\\/10.14.6) GCDHTTPRequest\",\n\"default_content\": \"Hello world!\",\n\"default_status\": 200,\n\"default_content_type\": \"text\\/plain\",\n\"premium_expires_at\": \"2019-10-22 10:52:20\",\n\"created_at\": \"2019-09-22 10:52:20\",\n\"updated_at\": \"2019-09-22 10:52:20\"\n\"expires_at\": \"2019-09-29 10:52:20\"\n}\n
"},{"location":"api/tokens.html#get-token-list","title":"Get token list","text":"
  • Requires authentication.
"},{"location":"api/tokens.html#request_1","title":"Request","text":"

GET /token

Returns a list of all Tokens associated with an account.

"},{"location":"api/tokens.html#query-string-parameters","title":"Query string parameters","text":"
  • per_page - amount of requests returned, defaults to 50 (max 100)
  • page - page number to retrieve (default 1)
  • order_by - which field to order tokens by (created_at (default) or token_id)
  • order_direction - order direction (asc (default) or desc)
"},{"location":"api/tokens.html#response_1","title":"Response","text":"
{\n\"current_page\": 1,\n\"data\": [\n{\n\"uuid\": \"44fb1548-cd1f-4928-880c-cce094e5e179\",\n\"redirect\": false,\n\"alias\": null,\n\"actions\": true,\n\"cors\": false,\n\"expiry\": false,\n\"timeout\": 0,\n\"premium\": true,\n\"user_id\": null,\n\"password\": true,\n\"ip\": \"127.0.0.1\",\n\"user_agent\": \"Mozilla\\/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit\\/605.1.15 (KHTML, like Gecko) Version\\/14.0.3 Safari\\/605.1.15\",\n\"default_content\": \"\",\n\"default_status\": 200,\n\"default_content_type\": \"text\\/plain\",\n\"premium_expires_at\": null,\n\"created_at\": \"2021-08-11 18:34:44\",\n\"updated_at\": \"2021-08-11 18:34:44\",\n\"latest_request_id\": \"ea5f5920-0398-465c-8f9c-8074f0d805a4\",\n\"latest_request_at\": \"2021-08-12 19:56:50\",\n\"group_id\": null,\n\"requests\": 1\n},\n...\n],\n\"first_page_url\": \"https:\\/\\/webhook.site\\/token?page=1\",\n\"from\": 1,\n\"last_page\": 1,\n\"last_page_url\": \"https:\\/\\/webhook.site\\/token?page=1\",\n\"next_page_url\": null,\n\"path\": \"https:\\/\\/webhook.site\\/token\",\n\"per_page\": 50,\n\"prev_page_url\": null,\n\"to\": 2,\n\"total\": 2\n}\n
"},{"location":"api/tokens.html#get-token","title":"Get token","text":"
  • Can require authentication.

GET /token/:token_id

"},{"location":"api/tokens.html#response_2","title":"Response","text":"

See POST /token

"},{"location":"api/tokens.html#update-token","title":"Update token","text":"
  • Can require authentication.

PUT /token/:token_id

"},{"location":"api/tokens.html#request_2","title":"Request","text":"

See POST /token

"},{"location":"api/tokens.html#response_3","title":"Response","text":"

See POST /token

"},{"location":"api/tokens.html#set-password","title":"Set password","text":"
  • Can require authentication.
  • Requires user with active subscription.

PUT /token/:token_id/password

Sets a password to view the requests of a token.

"},{"location":"api/tokens.html#request_3","title":"Request","text":"
{\"password\": \"hunter2\", \"old_password\": \"hunter1\"}\n
"},{"location":"api/tokens.html#response_4","title":"Response","text":"

See POST /token

"},{"location":"api/tokens.html#set-alias","title":"Set alias","text":"
  • \u26a0\ufe0f This endpoint is deprecated and may be removed.
  • Can require authentication.
  • Requires user with active subscription.

PUT /token/:token_id/alias

Sets the alias for the token, which makes the token available at https://webhook.site/<alias> or <alias>@email.webhook.site in addition to its 36 character UUID.

Rules for alias format: Length between 3-32 characters. Allowed characters: A-Z, a-z and - (dash.)

"},{"location":"api/tokens.html#request_4","title":"Request","text":"
{\"alias\": \"my-webhook\"}\n
"},{"location":"api/tokens.html#response_5","title":"Response","text":"

See POST /token

"},{"location":"api/tokens.html#toggle-cors","title":"Toggle CORS","text":"
  • \u26a0\ufe0f This endpoint is deprecated and may be removed.

Attaches CORS headers to the response of the Token, allowing browsers to request it from all domains.

PUT /token/:token_id/cors/toggle

"},{"location":"api/tokens.html#response_6","title":"Response","text":"
{ \"enabled\": true}\n
"},{"location":"api/tokens.html#delete-token","title":"Delete token","text":"
  • Can require authentication.

DELETE /token/:token_id

"},{"location":"api/tokens.html#response_7","title":"Response","text":"

204 No Content

"},{"location":"custom-actions/action-types.html","title":"Action Types","text":""},{"location":"custom-actions/action-types.html#webhookscript","title":"WebhookScript","text":"

Executes custom scripts using a scripting language that's very similar to JavaScript and PHP. More information here

"},{"location":"custom-actions/action-types.html#text","title":"Text","text":""},{"location":"custom-actions/action-types.html#extract-jsonpath","title":"Extract JSONPath","text":"

This action runs a JSONPath query on the contents of a request. With it, you can extract any data from a JSON document and store it in a variable, which can then be used in a downstream action.

JSONPath is very similar to the jq commandline utility.

"},{"location":"custom-actions/action-types.html#jsonpath-examples","title":"JSONPath Examples","text":"

Example data:

{\n\"store\": {\n\"name\": \"Cool Books Ltd\",\n\"books\": [\n{\n\"title\": \"12 Rules for Life\",\n\"author\": \"Jordan B. Peterson\",\n\"author.age\": 60,\n\"price\": 10,\n\"isbn\": \"13123123123\"\n},\n{\n\"title\": \"How to Win Friends and Influence People\",\n\"author\": \"Dale Carnegie\",\n\"price\": 9,\n\"isbn\": \"23482394\"\n}\n]\n}\n}\n
JSONPath Result .store.name name property of store object .store.books[0][\"author.age\"] author age of first book (bracket syntax can be useful for e.g. keys containing periods) $.store.books[*].author the authors of all books in the store $..author all authors $.store..price the price of everything in the store. $..books[2] the third book $..books[(@.length-1)] the last book in order. $..books[-1:] the last book in order. $..books[0,1] the first two books $..books[:2] the first two books $..books[::2] every second book starting from first one $..books[1:6:3] every third book starting from 1 till 6 $..books[?(@.isbn)] filter all books with isbn number property $..books[?(@.isbn != '')] filter all books with isbn that isn't null or \"\" (empty string.) (Bracket syntax can also be used here, e.g. .values[?(@['my value'] != '')]) $..books[?(@.price<10)] filter all books cheaper than 10 $..* all elements in the data (recursively extracted)"},{"location":"custom-actions/action-types.html#jsonpath-syntax","title":"JSONPath Syntax","text":"Symbol Description $ The root object/element (not strictly necessary) @ The current object/element . or [] Child operator .. Recursive descent * Wildcard. All child elements regardless their index. [,] Array indices as a set [start:end:step] Array slice operator borrowed from ES4/Python. ?() Filters a result set by a script expression () Uses the result of a \"script\" expression as the index

For more details on what's possible with JSONPath, take a look at the docs.

As you start entering a JSONPath, the results are validated and shown next to the input field.

"},{"location":"custom-actions/action-types.html#auto-json","title":"Auto JSON","text":"

This action automatically converts JSON data to Webhook.site Variables, and can be used as an alternative for Extract JSONPath when there's a large amount of variables that need to be extracted.

Per default, the action works on the JSON found in the $request.content$ variable, e.g. the request body data.

If the JSONPath parameter is specified, this can be used to limit the variable creation to only the subset of data specified by the JSONPath query.

"},{"location":"custom-actions/action-types.html#auto-json-example","title":"Auto JSON Example","text":"

If the following data is specified in the Source parameter:

{\n\"Actors\": [\n{\n\"name\": \"Tom Cruise\",\n\"age\": 56,\n\"Born At\": \"Syracuse, NY\",\n\"Birthdate\": \"July 3, 1962\",\n\"photo\": \"https://jsonformatter.org/img/tom-cruise.jpg\"\n},\n{\n\"name\": \"Robert Downey Jr.\",\n\"age\": 53,\n\"Born At\": \"New York City, NY\",\n\"Birthdate\": \"April 4, 1965\",\n\"photo\": \"https://jsonformatter.org/img/Robert-Downey-Jr.jpg\"\n}\n]\n}\n

If the JSONPath parameter is empty, the following 10 variables will be created:

Variable Name Value $json.Actors.0.name$ Tom Cruise $json.Actors.0.age$ 56 $json.Actors.0.Born At$ Syracuse, NY $json.Actors.0.Birthdate$ July 3, 1962 $json.Actors.0.photo$ https://example.com/tom-cruise.jpg $json.Actors.1.name$ Robert Downey Jr. $json.Actors.1.age$ 53 $json.Actors.1.Born At$ New York City, NY $json.Actors.1.Birthdate$ April 4, 1965 $json.Actors.1.photo$ https://example.com/Robert-Downey-Jr.jpg

If the JSONPath parameter is set to .Actors.0, only the following 5 variables are created:

Variable Name Value $json.0.name$ Tom Cruise $json.0.age$ 56 $json.0.Born At$ Syracuse, NY $json.0.Birthdate$ July 3, 1962 $json.0.photo$ https://example.com/tom-cruise.jpg"},{"location":"custom-actions/action-types.html#extract-regex","title":"Extract Regex","text":"

This action runs a Regex (regular expression) query on the contents of a request. With it, you can extract any data from a text document and store it in a variable, which can then be used in a downstream action.

As you start entering a Regex, the results are validated and shown next to the input field.

"},{"location":"custom-actions/action-types.html#extract-xpath","title":"Extract XPath","text":"

Similar to the Extract JSONPath Custom Action, Extract XPath lets you extract values from an XML or HTML document and save the result as a variable.

"},{"location":"custom-actions/action-types.html#xpath-examples","title":"XPath Examples","text":"

The following examples are based on this XML document:

<?xml version=\"1.0\"?>\n<organization name=\"ExampleCo\">\n<employees>\n<employee id=\"1\">Jack</employee>\n<employee id=\"2\">Ann</employee>\n</employees>\n</organization>\n
Example XPath Notes Result /organization Finds all content within the organization element JackAnn //employee[@id != 1] // traverses all <employee> elements in document, the @id query selects all except those with id=1 Jack /organization/@name @name to get the \"name\" property of the element ExampleCo /organization/employees/employee[2] [2] specifies 2nd element Ann /organization/employees/employee[2]/@id Get the \"id\" property of second employee element 2 /organization/employees/employee[@id=1] Employee element with id property equal to \"1\" Jack /organization/employees/employee[last()] Last employee element Ann //employee[contains(@id, \"2\")] Employee within any parent element where id contains \"2\" Ann

For more examples, see W3CSchools or XPath Cheatsheet

"},{"location":"custom-actions/action-types.html#replace-text","title":"Replace Text","text":"

An action that allows replacing multiple inputs to a string with specified replacements. Additionally, Webhook.site will replace all variables in the source text as well as the text being replaced, and the replacement.

"},{"location":"custom-actions/action-types.html#split-text","title":"Split Text","text":"

Split text into multiple variables. Using hello,world as Source, and , as Delimiter, 2 variables will be created: $variable.1$ is \"hello\" and $variable.2$ is \"world\".

"},{"location":"custom-actions/action-types.html#map-text","title":"Map Text","text":"

Sets a variable depending on what maps to the source value and operator.

If we set Source to John, Operator to ends with, Variable Name to $user_id$, Default to unknown, and add a mapping of From: John -> To: 123, then the variable name $user_id$ would be set to 123.

If the Source had been Jack, $user_id$ would have been set to unknown.

"},{"location":"custom-actions/action-types.html#network","title":"Network","text":""},{"location":"custom-actions/action-types.html#http-request","title":"HTTP Request","text":"

This will send a HTTP/HTTPS request from the Webhook.site cloud.

The HTTP Request action has several modes:

  • Text: In the default text mode, this allows sending plain-text content, but also data like JSON and XML.
  • Multipart: With Multipart selected, it is possble to build a form/multipart request and send form data and files. Note that the Filename and Content-Type fields are not required.
  • URL Encoded: In URL Encoded mode, the keys and values are sent using URL Encoding.
  • Forward: In forward mode, all data sent to the Webhook.site URL is forwarded here, including the HTTP method, query strings, headers and body data. It is possible to overwrite the method and append headers. To forward the HTTP method, set the Method dropdown to the blank option.

The response of the request is stored in a series of variable names prefixed with a value of your choosing. The following variables are set after the request has been fired:

  • $your_prefix.content$ - response body content
  • $your_prefix.status$ - response status code
  • $your_prefix.headers$ - response headers
  • $your_prefix.url$ - the URL the request was sent to
  • $your_prefix.error$ - if the request resulted in an error, it's stored in this variable.
"},{"location":"custom-actions/action-types.html#send-email","title":"Send Email","text":"

This will send a email with variable contents from the Webhook.site cloud. Variables extracted previously can be used.

"},{"location":"custom-actions/action-types.html#send-email-smtp","title":"Send Email (SMTP)","text":"

This will send a email with variable contents from your own email provider. Variables extracted previously can be used.

"},{"location":"custom-actions/action-types.html#gmail-and-google-workspace","title":"Gmail and Google Workspace","text":"

For Gmail, the following specific setup is required:

  • Hostname: smtp.gmail.com
  • Port:587
  • Username: youraccount@gmail.com or youraccount@example.com (replace with your Gmail address)
  • Password: You must create a Mail App Password
  • Encryption: TLS
"},{"location":"custom-actions/action-types.html#run-ssh-command","title":"Run SSH Command","text":"

Allows you to run one or more SSH command on a server. Webhook.site captures the output (stdout), stderr and the command exit code as Variables that can be used in downstream actions:

  • $ssh.stdout$
  • $ssh.stderr$
  • $ssh.exit$

We recommend authenticating using a pre-generated keypair, which can be created under Control Panel -> Providers.

"},{"location":"custom-actions/action-types.html#sftp-upload","title":"SFTP Upload","text":"

Allows uploading a file to a SFTP (SSH) server, specifying a hostname, port, username, password, relative path to the file. The file content can be specified, in which Variables are replaced.

We recommend authenticating using a pre-generated keypair, which can be created under Control Panel -> Providers.

"},{"location":"custom-actions/action-types.html#ftps-upload","title":"FTP(S) Upload","text":"

Allows uploading a file to a FTP or FTPS (FTP with TLS/SSL) server, specifying a hostname, port, username, password, relative path to the file, whether to use SSL and whether to use passive mode. Finally, the file content can be specified, in which Variables are replaced.

We recommend storing the password as a Global Variable.

"},{"location":"custom-actions/action-types.html#database-query","title":"Database Query","text":"

Allows running a database query, with support for fetching out data in a series of variables. We recommend storing the password as a Global Variable.

"},{"location":"custom-actions/action-types.html#supported-database-servers","title":"Supported Database Servers","text":"

Currently supported are:

  • PostgreSQL
  • MySQL

If your database server is not on the list, please contact support.

"},{"location":"custom-actions/action-types.html#using-parameters","title":"Using Parameters","text":"

When using e.g. INSERT or UPDATE statements, we strongly recommend using parameters for each column value. Doing this, you avoid SQL injection attacks and other issues when using user-submitted data (e.g. via Variables), or even just data containing special characters like quotes, that could otherwise break a query.

Each parameter name should start with a colon (:) and be a single word. You can then reference these parameters inside the query, like in the following example:

"},{"location":"custom-actions/action-types.html#fetching-data","title":"Fetching data","text":"

When fetching data using e.g. SELECT statements, Webhook.site automatically inserts data in a series of Custom Action Variables, which are then available to downstream actions.

For example, when fetching rows from the following table:

Using the following statement:

select * from employees\n

If the variable name prefix would be set to output, the following variables would be created containing specific values:

Variable Name Value $output.0.id$ 1 $output.0.fname$ Simon $output.0.lname$ Fredsted $output.0.title$ Founder $output.1.id$ 2 $output.1.fname$ Jack $output.1.lname$ Daniels $output.1.title$ Assistant

Additionally, a variable would be created with the name $output.json$ containing the data in JSON format:

[                              {\n\"id\": 1,\n\"fname\": \"Simon\",\n\"lname\": \"Fredsted\",\n\"title\": \"Founder\"\n},\n{\n\"id\": 2,\n\"fname\": \"Jack\",\n\"lname\": \"Daniels\",\n\"title\": \"Assistant\"\n}\n]\n
"},{"location":"custom-actions/action-types.html#behavior","title":"Behavior","text":""},{"location":"custom-actions/action-types.html#dont-save","title":"Don't Save","text":"

Marks the request so it is not saved in Webhook.site, which is useful (especially in combination with Conditions) when receiving a large amount of requests.

"},{"location":"custom-actions/action-types.html#log","title":"Log","text":"

Adds a custom log entry to the Request's action output.

"},{"location":"custom-actions/action-types.html#modify-response","title":"Modify Response","text":"

This action can be used to modify the response of the Webhook.site URL based on the input.

"},{"location":"custom-actions/action-types.html#rate-limit","title":"Rate Limit","text":"

This action can be used to allow a specific amount of requests in a specific amount of time per a given IP.

If the IP is rate limited, the URL will respond with a HTTP 429, action execution is stopped, and the request is not saved in Webhook.site.

"},{"location":"custom-actions/action-types.html#stop","title":"Stop","text":"

Immediately stops Custom Action execution and returns the default response.

"},{"location":"custom-actions/action-types.html#logic","title":"Logic","text":""},{"location":"custom-actions/action-types.html#conditions","title":"Conditions","text":"

Useful if you need to validate that the request does or does not conform to certain criteria, the Condition action will either stop or continue based on a condition.

In both the input and the value fields, variables will be replaced (including Global Variables from the Control Panel), so you can compare e.g. JSONPath or Regex values - or even values from a previous HTTP request that was sent.

Currently, three actions are provided: use result, stop and continue. Use Result allows using the Condition result in further actions. Stop will stop further action execution of the condition is a match. Continue will only continue further execution if the condition is a match, and otherwise stop.

The following \"operators\" are available:

  • is equal to
  • is not equal to
  • starts with
  • ends with
  • contains
  • does not contain
  • is greater than
  • is greater than or equal to
  • is less than
  • is less than or equal to

The \"result\" of the condition will be logged below the request details, so you can see what happened.

To use the result of the Condition, select it in the \"only run when condition passes\" checkbox:

Tip: To check if a Variable is set (or exists), you must enter the variable name in both input and value fields and use the \"is not equal to\" operator, since non-existing variables are not replaced.

"},{"location":"custom-actions/action-types.html#javascript","title":"JavaScript","text":"

With the JavaScript action, you can execute most kinds of JavaScript/Node.js code using a Node.js 20.10.0 sandbox.

"},{"location":"custom-actions/action-types.html#limitations","title":"Limitations","text":"

This feature is still in beta as of late 2023, and we expect to add more features in the coming months.

Currently identified limitations include:

"},{"location":"custom-actions/action-types.html#general-functions","title":"General Functions","text":"

console.log(line) / echo(line) - log a string to Action output

set(variable_name, value) - sets a Webhook.site variable for use in downstream actions

The following code would set the variable $myvar$ to value:

set('myvar', 'value')\n

get(variable_name) - gets a Webhook.site variable (except Global Variables; use the global() function for that)

variables - global array variable containing Webhook.site variables

global(variable_name) - retrieves the value of a Webhook.site Global Variable. Must be used async. Returns null if variable doesn't exist.

echo(await global('my-variable'))\n

store(variable_name, value) - stores the value of a Webhook.site Global Variable. Must be used async.

stop() - stops action execution and return response

dont_save() - marks current requests as Don't Save, so it won't be stored or shown in the Webhook.site requests list

respond(content, status, headers) - stops action execution and return response

respond('OK', 200, ['Content-Type: text/plain'])\n

set_response(content, status, headers) - sets response, but doesn't stop action execution

"},{"location":"custom-actions/action-types.html#utility-modules","title":"Utility Modules","text":"

Code executed with the Webhook.site JavaScript action runs in a sandbox where the following utility libraries are available by using the require() function:

  • axios - HTTP Client
    axios = require('axios')\nawait axios.get('https://webhook.site')\n.then(response => {\nconsole.log(response.status)\n});\n// 200\n
  • lodash - General utility library
    _ = require('lodash')\nconsole.log(_.last([1, 2, 3]))\n// 3\n
  • dayjs - Date and time manipulation
    dayjs = require('dayjs')\nconsole.log(dayjs(1318781876406))\n// \"2011-10-16T16:17:56.406Z\"\n
  • cheerio - JQuery-like HTML selector library
    cheerio = require('cheerio')\nconst $ = cheerio.load('<ul id=\"fruits\">banana</ul>');\nconsole.log($('#fruits').text());\n// banana\n
  • jsonpath - JSONPath query library
    jsonpath = require('jsonpath')\nvar cities = [\n{ name: \"London\", \"population\": 8615246 },\n{ name: \"Berlin\", \"population\": 3517424 },\n];\nvar names = jsonpath.query(cities, '$..name');\nconsole.log(names)\n// [\"London\",\"Berlin\"]\n
  • crypto \u2013 Node.js built-in crypto library
    crypto = require('crypto');\nconst secret = 'abcdefg';\nconst hash = crypto.createHmac('sha256', secret)\n.update('I love Webhook.site')\n.digest('hex');\nconsole.log(hash);\n// 1745c764246c2782ebf97e25b89547a92571f19d41846b42880d3815480f098e\n
  • faker - Seed data generator
    faker = require('faker')\nconsole.log(faker.internet.email())\n// Ila_Gutkowski9@yahoo.com\n

Do you need a library that isn't listed here? Please contact support!

"},{"location":"custom-actions/action-types.html#webhookscript_1","title":"WebhookScript","text":"

For more information about WebhookScript, see the dedicated page.

"},{"location":"custom-actions/action-types.html#set-variable","title":"Set Variable","text":"

Defines (or overwrites) a variable that's available to downstream actions. The variable is not saved permanently as a Global Variable.

There are three modes:

  • Text: Using the default \"Text\" mode, the variable is simply set to what's entered in the Text field.
  • Random: When using the \"Random\" mode, you can generate a random string for e.g. one-time identifiers and passwords.
  • Date: Generate date strings specifying a custom input date and an output format - defaults to ISO-8601 format.
"},{"location":"custom-actions/action-types.html#store-global-variable","title":"Store Global Variable","text":"

Saves (or overwrites) a Global Variable that's saved permanently and available to all URLs in your account. If you don't need to save the variable permanently, you should use the Set Runtime Variable instead.

"},{"location":"custom-actions/action-types.html#image-handling","title":"Image Handling","text":""},{"location":"custom-actions/action-types.html#resize-image","title":"Resize Image","text":"

Takes an image from either a URL or raw image data from e.g. a file upload, email attachment, request response or another action such as Dropbox.

You can enter both width and height to contrain the image in both dimensions, or enter a single dimension.

Check \"Keep Aspect Ratio\" so that the image keeps the aspect ratio, but doesn't exceed the height and width constraints.

"},{"location":"custom-actions/action-types.html#google-sheets","title":"Google Sheets","text":"

Note

Google Sheets should not be used as a database, and have low usage limits. If you need to import on the order of thousands of rows or make thousands of calls a day, Google Sheets cannot be used. We recommend using a database like Postgres in conjunction with the Database Query action.

Google Sheets Custom Actions lets you manipulate and retrieve values from a Google Sheet.

The following Google Sheets Custom Actions are available:

  • Add Row - appends one or more new rows to an existing spreadsheet
  • Update Row - updates one or more cells in an existing spreadsheet
  • Get Values - retrieves one or more cell values from an existing spreadsheet

To start, you need to make sure that you have connected a Google account in the Control Panel, available here.

After that, you can select the account in the dropdown when creating the Custom Action.

"},{"location":"custom-actions/action-types.html#usage-limits","title":"Usage Limits","text":"

It is important to note that Google will block Write requests (i.e. adding or updating rows) at 60 requests per minute. After that, the action will temporarily fail with the following error message:

Quota exceeded for quota metric 'Write requests' and limit 'Write requests per minute per user' of service 'sheets.googleapis.com' for consumer\n

Therefore, for importing mass amounts of data in a short timespan, Google Sheets is not recommended. Instead, we recommend using the Database Query action.

Additionally, Webhook.site will automatically disable Google Sheets actions that continously fail due to e.g. quota errors.

"},{"location":"custom-actions/action-types.html#specifying-the-spreadsheet","title":"Specifying the spreadsheet","text":"

When specifying the spreadsheet, you can either just copy/paste the spreadsheet URL or enter the spreadsheet ID. Variables can be used to specify the spreadsheet.

"},{"location":"custom-actions/action-types.html#ranges","title":"Ranges","text":"

All actions must specify a range, which behaves similar in all actions. For the Add Row action, Google Sheets will automatically find a \"table\" (e.g. a homogenous mass of data) and add the values at the bottom.

A range is the same query as in Google Sheets, e.g. to select A1-C3 in Worksheet \"Example\", enter 'Example'!A1:C3.

"},{"location":"custom-actions/action-types.html#values","title":"Values","text":"

When inserting or updating values, you can either enter a value in the text field, or supply multiple cells and/or rows using JSON. To insert two rows, the JSON would be [\"cell 1\", \"cell 2\"].

"},{"location":"custom-actions/action-types.html#variables","title":"Variables","text":"

The Get Values Action allows you to define variables based on the output. Since this action can return multiple pieces of data, multiple variables are created.

For example, if you select two columns and two rows, e.g. A1:B2, four variables would be defined:

  1. variable_name.0.0 = value of A1
  2. variable_name.0.1 = value of A2
  3. variable_name.1.0 = value of B1
  4. variable_name.1.1 = value of B2

Additionally, the data is available in JSON, with the variable_name.json variable being defined, and continuing with the example above, would contain the following JSON:

[\n[\"A1\",\"A2\"],\n[\"B1\",\"B2\"]\n]\n
"},{"location":"custom-actions/action-types.html#microsoft","title":"Microsoft","text":""},{"location":"custom-actions/action-types.html#onedrive","title":"OneDrive","text":"

With Webhook.site, you can now use your Microsoft account to upload and download files in your OneDrive account using the Upload and Download Custom Actions.

"},{"location":"custom-actions/action-types.html#excel","title":"Excel","text":"

Using the Add Rows and Get Values actions, Webhook.site now allows using your Microsoft account to append and retrieve data from Excel worksheets in your OneDrive account.

"},{"location":"custom-actions/action-types.html#amazon-web-services-aws","title":"Amazon Web Services (AWS)","text":""},{"location":"custom-actions/action-types.html#s3","title":"S3","text":"

The following actions are available for AWS S3:

  • Create Bucket
  • Create Object
  • Delete Object
  • Get Object (retrieves object contents to a Variable)

In addition to the \"official\" Amazon endpoints, Webhook.site also supports S3-compatible storages like DigitalOcean, MinIO, Wasabi and more. The endpoint can be specified when setting up the account in Control Panel.

"},{"location":"custom-actions/action-types.html#cloudfront","title":"CloudFront","text":"

The \"Create Invalidation\" action allows you to dynamically create a CloudFront cache invalidation as a Custom Action. Both the Distribution ID and the paths to be invalidated are replaced with Webhook.site Variables.

"},{"location":"custom-actions/action-types.html#discord","title":"Discord","text":"

With the Discord Custom Action, you can send messages to a specified channel (Each bot account uses a specific channel, so you can connect more accounts to send to different channels or servers.) In addition, you can choose a custom username and avatar image for the bot user.

"},{"location":"custom-actions/action-types.html#slack","title":"Slack","text":"

With the Slack Custom Action, you can easily use Slack's Webhook URLs to send messages to a channel.

"},{"location":"custom-actions/action-types.html#dropbox","title":"Dropbox","text":"

The Dropbox integration has access to the entire contents of your dropbox, and currently the following actions are available:

  • Create Folder
  • Download File
  • Upload File
  • Delete File
  • Delete Folder
  • Get Link - creates a temporary download link for any file in your Dropbox, and saves it in a variable.
"},{"location":"custom-actions/action-types.html#x-formerly-known-as-twitter","title":"X (formerly known as Twitter)","text":"

The X Integration supports the following actions using X's API:

  • Post Tweet
"},{"location":"custom-actions/action-types.html#rabbitmq","title":"RabbitMQ","text":"

The RabbitMQ Integration allows you to publish and consume messages from a RabbitMQ queue by specifying the server connection details.

"},{"location":"custom-actions/action-types.html#pushed","title":"Pushed","text":"

With the Send Push Notification action, you can easily send push notifications to your mobile devices using your Pushed.co account.

With a free Pushed.co account, you can send up to 1000 push notifications a month.

"},{"location":"custom-actions/action-types.html#ntfysh","title":"ntfy.sh","text":"

Allows you to easily send push notifications to your browser, phone, watch, etc. Simply download the ntfy.sh app, subscribe to your topic name and send a message to the topic name via this Custom Action. No account required.

App download links:

  • App Store
  • Google Play
  • Browser
"},{"location":"custom-actions/examples.html","title":"Examples","text":""},{"location":"custom-actions/examples.html#adding-rows-to-an-airtable-base","title":"Adding rows to an Airtable Base","text":"

While Webhook.site doesn't have a native integration with Airtable, due to the simple API, it's exceedingly easy to add rows to a so-called Airtable Base.

First, create an API key on your Account page: https://airtable.com/account.

Next, go to Airtable's API documentation and select the Base you want to interact with: https://airtable.com/api. In the upper right corner, make sure show API key is checked.

If you then scroll down to the Create records section, you can essentially copy everything over to a Send Request action.

Things to note:

  • The Request Method should be POST
  • Make sure you copy everything between --data ' and the final ' (quote) character
  • Also make sure that quotes aren't included in the two header lines
"},{"location":"custom-actions/variables.html","title":"Variables","text":"

Variables are the most important part of Custom Actions, and are characterized by a name surrounded by two dollar signs: $example$. Variables can be used in any field that has a \u24e5 icon in the editor. They act as placeholders that are replaced by dynamic content as the request or email is received.

Each request or email has a set of Base Variables (see below) that contain information like the request IP, method, headers, query string values, form values and the request content. To see a list of variables, click the Variables button in the editor. Clicking on a variable copies it to the clipboard.

Many of the the available Custom Actions can register a variable during the runtime of the actions, so for example you can register the result of a JSONPath query and use it in a \"Modify Response\" action to make the response dynamic, or even use it to send a request to another HTTP address, and then use the response of that. Files can referred to and be used through Variables.

This works since Custom Actions are executed synchronously in a chain, sharing data as they're being executed.

The format of variables are dollar signs surrounded by a word, for example: $example$.

"},{"location":"custom-actions/variables.html#global-variables","title":"Global Variables","text":"

In Webhook.site Control Panel, you can define Global Variables which can be accessed between all URLs and used in Schedules. Global Variables are permanent.

Global Variables can also be created, modified or deleted using Custom Actions, including in WebhookScript and JavaScript actions.

Additionally, Global Variables can be managed using the Webhook.site API.

"},{"location":"custom-actions/variables.html#variable-modifiers","title":"Variable Modifiers","text":"

Adding specific suffixes to variable names will let you process the value in the following ways:

Variable Example Input Example Output Description $example$ {\"json\": \"value\"} {\"json\": \"value\"} no modifier $example.json$ {\"json\": \"value\"} {\\\"json\\\": \\\"value\\\"} Escapes all special JSON characters, allowing to use any string in a JSON object. Escaped characters include \\b, \\f, \\n, \\r, \\t, \", \\ $example.html_encode$ <p>some html</p> &lt;p&gt;some html&lt;/p&gt; Escapes all special HTML characters $example.html_decode$ &lt;p&gt;some html&lt;/p&gt; <p>some html</p> Replaces all escaped HTML escapes with normal characters $example.html_strip$ <p>some html</p> some html Removes all HTML tags from input string $example.base64_encode$ {\"json\": \"<b>value</b>\"} eyJqc29uIjogIjxiPnZhbHVlPC9iPiJ9Cg== Encodes the variable to base64 $example.base64_decode$ eyJqc29uIjogIjxiPnZhbHVlPC9iPiJ9Cg== {\"json\": \"<b>value</b>\"} Decodes a base64 encoded string $example.url_encode$ {\"json\": \"value\"} %7B%22json%22%3A+%22value%22%7D Escapes all special HTTP URL characters $example.url_decode$ %7B%22json%22%3A+%22value%22%7D {\"json\": \"value\"} Replaces all special HTTP URL escapes with normal characters"},{"location":"custom-actions/variables.html#base-variables","title":"Base Variables","text":"

These variables are automatically available for each request or email. Different variables are available depending on the type.

Variable Name Available For Description request.uuid All The UUID of the request request.token_id All The Token UUID (URL ID) of the request request.content All The body content of the request request.date All Creation date in Y-m-d H:m:s format request.date All Creation date in UNIX timestamp format request.hostname All Hostname of the request (usually webhook.site) request.header.[name] All Created for each HTTP header request.size All Request body size in bytes request.type All Request type (email or web) request.file.[name].filename All Created for each file upload, with name being the input name property. Contains the client file name request.file.[name].size All Contains the file size in bytes request.file.[name].content All Contains the file content request.file.[name].content_type All Contains the file content type (e.g. image/png) request.file.[name].id All Contains the Webhook.site file ID request.file.[name].link All Contains the direct download link to the file from Webhook.site's server. request.query.[name] Web Created for each query string (e.g. ?name=value) request.form.[name] Web Created for each form field request.ip Web IP of the host making the request request.user_agent Web User agent header request.url Web Full URL of the request (e.g. https://webhook.site/xxx-xxx...) request.path Web Sub-path of URL, after the token ID. Defaults to / request.query Web Full query string of the URL request.method Web HTTP method (GET, POST, etc.) request.sender Email Sender address request.message_id Email Email message ID request.text_content Email Parsed plaintext content request.destinations Email Comma separated list of recipients. request.checks.[name] Email True or false for email checks (DKIM, SPF, etc.)"},{"location":"webhookscript/index.html","title":"About WebhookScript","text":"

WebhookScript is an easy to use scripting language designed for executing Web-related actions on incoming requests.

While the other actions like Extract Regex and Send Email allows you to create flows in a visual editor, WebhookScript makes it quicker to create more advanced logic.

WebhookScript can be combined with other Custom Actions as data can be shared between them using Variables.

"},{"location":"webhookscript/index.html#syntax","title":"Syntax","text":"

The syntax is very similar to PHP and JavaScript. See also the full language specification.

products = [\n'apple':     ['price': 10],\n'blueberry': ['price': 1],\n'cake':      ['price': 550]\n]\nshouldAddVat = var('request.query.vat');\nselectedProduct = var('request.query.product');\nif (!selectedProduct) {\nrespond('Please select a product!', 500)\n}\nprice = products[selectedProduct]['price'];\nif (shouldAddVat == 1) {\nprice = price * 1.25;\n}\nrespond(\n'Your price is {}'.format(price),\n200\n);\n
"},{"location":"webhookscript/index.html#variables-in-webhookscript","title":"Variables in WebhookScript","text":"

Custom Action Variables in WebhookScript behave a little differently than other action types: in the code, they will not be replaced automatically like in other action types.

Instead, to interface with Custom Action Variables (created in previous actions, or default variables provided for each request or email), the function var() can be used.

The dollar-sign syntax (e.g. $request.content$) is optional when using the var() function, and the following two statements are equivalent: var('$request.content$') / var('request.content').

In addition, set() can be used to export a variable from your script to further downstream actions. store() is used to permanently set a Global Variable.

"},{"location":"webhookscript/index.html#about-the-editor","title":"About the Editor","text":""},{"location":"webhookscript/index.html#shortcuts","title":"Shortcuts","text":"

The shortcuts are available when the editor is focused.

Windows Mac Shortcut Alt-R Alt-R Test code (update Debug Panel) Ctrl-S Cmd-S Save action without exiting"},{"location":"webhookscript/index.html#debug-panel","title":"Debug Panel","text":"

Below the editor is the \"debug panel\" containing data relating to the current and previous actions:

  • Debug outputs shows the outputs of all the actions, with the current action being edited or created marked in blue.

  • Response shows details of the response of the URL formatted in JSON.

  • Variables is a table of all current available variables for use in the script with the var() function or variables array.

"},{"location":"webhookscript/index.html#fullscreen-mode","title":"Fullscreen Mode","text":"

To enable fullscreen mode, click the Expand button in the upper right corner to make the editor take up more screen space. Click again to disengage fullscreen mode.

"},{"location":"webhookscript/date-format.html","title":"Date format characters","text":"

WebhookScript uses the ISO format for converting and formatting dates, and the format is compatible with the Moment.js format method.

The following examples are based on the date 2017-01-05 17:04:05.084512.

Code Example Description OD 5 Day number with alternative numbers such as \u4e09 for 3 if locale is ja_JP OM 1 Month number with alternative numbers such as \u1040\u1042 for 2 if locale is my_MM OY 2017 Year number with alternative numbers such as \u06f1\u06f9\u06f9\u06f8 for 1998 if locale is fa OH 17 24-hours number with alternative numbers such as \u1091\u1093 for 13 if locale is shn_MM Oh 5 12-hours number with alternative numbers such as \u5341\u4e00 for 11 if locale is lzh_TW Om 4 Minute number with alternative numbers such as \u0b6b\u0b6d for 57 if locale is or Os 5 Second number with alternative numbers such as \u5341\u4e94 for 15 if locale is ja_JP D 5 Day of month number (from 1 to 31) DD 05 Day of month number with trailing zero (from 01 to 31) Do 5th Day of month with ordinal suffix (from 1st to 31th), translatable d 4 Day of week number (from 0 (Sunday) to 6 (Saturday)) dd Th Minified day name (from Su to Sa), transatable ddd Thu Short day name (from Sun to Sat), transatable dddd Thursday Day name (from Sunday to Saturday), transatable DDD 5 Day of year number (from 1 to 366) DDDD 005 Day of year number with trailing zeros (3 digits, from 001 to 366) DDDo 5th Day of year number with ordinal suffix (from 1st to 366th), translatable e 4 Day of week number (from 0 (Sunday) to 6 (Saturday)), similar to \"d\" but this one is translatable (takes first day of week of the current locale) E 4 Day of week number (from 1 (Monday) to 7 (Sunday)) H 17 Hour from 0 to 23 HH 17 Hour with trailing zero from 00 to 23 h 5 Hour from 0 to 12 hh 05 Hour with trailing zero from 00 to 12 k 17 Hour from 1 to 24 kk 17 Hour with trailing zero from 01 to 24 L 04/09/1986 Date (in local format) LL September 4 1986 Month name, day of month, year LLL September 4 1986 8:30 PM Month name, day of month, year, time LLLL Thursday, September 4 1986 8:30 PM Day of week, month name, day of month, year, time LT 8:30 PM Time (without seconds) LTS 8:30:00 PM Time (with seconds) m 4 Minute from 0 to 59 mm 04 Minute with trailing zero from 00 to 59 a pm Meridiem am/pm A PM Meridiem AM/PM s 5 Second from 0 to 59 ss 05 Second with trailing zero from 00 to 59 S 0 Second tenth SS 08 Second hundredth (on 2 digits with trailing zero) SSS 084 Millisecond (on 3 digits with trailing zeros) SSSS 0845 Second ten thousandth (on 4 digits with trailing zeros) SSSSS 08451 Second hundred thousandth (on 5 digits with trailing zeros) SSSSSS 084512 Microsecond (on 6 digits with trailing zeros) SSSSSSS 0845120 Second ten millionth (on 7 digits with trailing zeros) SSSSSSSS 08451200 Second hundred millionth (on 8 digits with trailing zeros) SSSSSSSSS 084512000 Nanosecond (on 9 digits with trailing zeros) M 1 Month from 1 to 12 MM 01 Month with trailing zero from 01 to 12 MMM Jan Short month name, translatable MMMM January Month name, translatable Mo 1st Month with ordinal suffix from 1st to 12th, translatable Q 1 Quarter from 1 to 4 Qo 1st Quarter with ordinal suffix from 1st to 4th, translatable G 2017 ISO week year (see ISO week date) GG 2017 ISO week year (on 2 digits with trailing zero) GGG 2017 ISO week year (on 3 digits with trailing zeros) GGGG 2017 ISO week year (on 4 digits with trailing zeros) GGGGG 02017 ISO week year (on 5 digits with trailing zeros) g 2017 Week year according to locale settings, translatable gg 2017 Week year according to locale settings (on 2 digits with trailing zero), translatable ggg 2017 Week year according to locale settings (on 3 digits with trailing zeros), translatable gggg 2017 Week year according to locale settings (on 4 digits with trailing zeros), translatable ggggg 02017 Week year according to locale settings (on 5 digits with trailing zeros), translatable W 1 ISO week number in the year (see ISO week date) WW 01 ISO week number in the year (on 2 digits with trailing zero) Wo 1st ISO week number in the year with ordinal suffix, translatable w 1 Week number in the year according to locale settings, translatable ww 01 Week number in the year according to locale settings (on 2 digits with trailing zero) wo 1st Week number in the year according to locale settings with ordinal suffix, translatable x 1483635845085 Millisecond-precision timestamp (same as date.getTime() in JavaScript) X 1483635845 Timestamp (number of seconds since 1970-01-01) Y 2017 Full year from -9999 to 9999 YY 17 Year on 2 digits from 00 to 99 YYYY 2017 Year on 4 digits from 0000 to 9999 YYYYY 02017 Year on 5 digits from 00000 to 09999 YYYYYY +002017 Year on 5 digits with sign from -09999 to +09999 z UTC Abbreviated time zone name zz UTC Time zone name Z +00:00 Time zone offset HH:mm ZZ +0000 Time zone offset HHmm

Source: Carbon Docs

"},{"location":"webhookscript/date-format.html#timezone-list","title":"Timezone List","text":"
  • Africa/Abidjan
  • Africa/Accra
  • Africa/Addis_Ababa
  • Africa/Algiers
  • Africa/Asmara
  • Africa/Bamako
  • Africa/Bangui
  • Africa/Banjul
  • Africa/Bissau
  • Africa/Blantyre
  • Africa/Brazzaville
  • Africa/Bujumbura
  • Africa/Cairo
  • Africa/Casablanca
  • Africa/Ceuta
  • Africa/Conakry
  • Africa/Dakar
  • Africa/Dar_es_Salaam
  • Africa/Djibouti
  • Africa/Douala
  • Africa/El_Aaiun
  • Africa/Freetown
  • Africa/Gaborone
  • Africa/Harare
  • Africa/Johannesburg
  • Africa/Juba
  • Africa/Kampala
  • Africa/Khartoum
  • Africa/Kigali
  • Africa/Kinshasa
  • Africa/Lagos
  • Africa/Libreville
  • Africa/Lome
  • Africa/Luanda
  • Africa/Lubumbashi
  • Africa/Lusaka
  • Africa/Malabo
  • Africa/Maputo
  • Africa/Maseru
  • Africa/Mbabane
  • Africa/Mogadishu
  • Africa/Monrovia
  • Africa/Nairobi
  • Africa/Ndjamena
  • Africa/Niamey
  • Africa/Nouakchott
  • Africa/Ouagadougou
  • Africa/Porto-Novo
  • Africa/Sao_Tome
  • Africa/Tripoli
  • Africa/Tunis
  • Africa/Windhoek
  • America/Adak
  • America/Anchorage
  • America/Anguilla
  • America/Antigua
  • America/Araguaina
  • America/Argentina/Buenos_Aires
  • America/Argentina/Catamarca
  • America/Argentina/Cordoba
  • America/Argentina/Jujuy
  • America/Argentina/La_Rioja
  • America/Argentina/Mendoza
  • America/Argentina/Rio_Gallegos
  • America/Argentina/Salta
  • America/Argentina/San_Juan
  • America/Argentina/San_Luis
  • America/Argentina/Tucuman
  • America/Argentina/Ushuaia
  • America/Aruba
  • America/Asuncion
  • America/Atikokan
  • America/Bahia
  • America/Bahia_Banderas
  • America/Barbados
  • America/Belem
  • America/Belize
  • America/Blanc-Sablon
  • America/Boa_Vista
  • America/Bogota
  • America/Boise
  • America/Cambridge_Bay
  • America/Campo_Grande
  • America/Cancun
  • America/Caracas
  • America/Cayenne
  • America/Cayman
  • America/Chicago
  • America/Chihuahua
  • America/Costa_Rica
  • America/Creston
  • America/Cuiaba
  • America/Curacao
  • America/Danmarkshavn
  • America/Dawson
  • America/Dawson_Creek
  • America/Denver
  • America/Detroit
  • America/Dominica
  • America/Edmonton
  • America/Eirunepe
  • America/El_Salvador
  • America/Fort_Nelson
  • America/Fortaleza
  • America/Glace_Bay
  • America/Goose_Bay
  • America/Grand_Turk
  • America/Grenada
  • America/Guadeloupe
  • America/Guatemala
  • America/Guayaquil
  • America/Guyana
  • America/Halifax
  • America/Havana
  • America/Hermosillo
  • America/Indiana/Indianapolis
  • America/Indiana/Knox
  • America/Indiana/Marengo
  • America/Indiana/Petersburg
  • America/Indiana/Tell_City
  • America/Indiana/Vevay
  • America/Indiana/Vincennes
  • America/Indiana/Winamac
  • America/Inuvik
  • America/Iqaluit
  • America/Jamaica
  • America/Juneau
  • America/Kentucky/Louisville
  • America/Kentucky/Monticello
  • America/Kralendijk
  • America/La_Paz
  • America/Lima
  • America/Los_Angeles
  • America/Lower_Princes
  • America/Maceio
  • America/Managua
  • America/Manaus
  • America/Marigot
  • America/Martinique
  • America/Matamoros
  • America/Mazatlan
  • America/Menominee
  • America/Merida
  • America/Metlakatla
  • America/Mexico_City
  • America/Miquelon
  • America/Moncton
  • America/Monterrey
  • America/Montevideo
  • America/Montserrat
  • America/Nassau
  • America/New_York
  • America/Nipigon
  • America/Nome
  • America/Noronha
  • America/North_Dakota/Beulah
  • America/North_Dakota/Center
  • America/North_Dakota/New_Salem
  • America/Nuuk
  • America/Ojinaga
  • America/Panama
  • America/Pangnirtung
  • America/Paramaribo
  • America/Phoenix
  • America/Port-au-Prince
  • America/Port_of_Spain
  • America/Porto_Velho
  • America/Puerto_Rico
  • America/Punta_Arenas
  • America/Rainy_River
  • America/Rankin_Inlet
  • America/Recife
  • America/Regina
  • America/Resolute
  • America/Rio_Branco
  • America/Santarem
  • America/Santiago
  • America/Santo_Domingo
  • America/Sao_Paulo
  • America/Scoresbysund
  • America/Sitka
  • America/St_Barthelemy
  • America/St_Johns
  • America/St_Kitts
  • America/St_Lucia
  • America/St_Thomas
  • America/St_Vincent
  • America/Swift_Current
  • America/Tegucigalpa
  • America/Thule
  • America/Thunder_Bay
  • America/Tijuana
  • America/Toronto
  • America/Tortola
  • America/Vancouver
  • America/Whitehorse
  • America/Winnipeg
  • America/Yakutat
  • America/Yellowknife
  • Antarctica/Casey
  • Antarctica/Davis
  • Antarctica/DumontDUrville
  • Antarctica/Macquarie
  • Antarctica/Mawson
  • Antarctica/McMurdo
  • Antarctica/Palmer
  • Antarctica/Rothera
  • Antarctica/Syowa
  • Antarctica/Troll
  • Antarctica/Vostok
  • Arctic/Longyearbyen
  • Asia/Aden
  • Asia/Almaty
  • Asia/Amman
  • Asia/Anadyr
  • Asia/Aqtau
  • Asia/Aqtobe
  • Asia/Ashgabat
  • Asia/Atyrau
  • Asia/Baghdad
  • Asia/Bahrain
  • Asia/Baku
  • Asia/Bangkok
  • Asia/Barnaul
  • Asia/Beirut
  • Asia/Bishkek
  • Asia/Brunei
  • Asia/Chita
  • Asia/Choibalsan
  • Asia/Colombo
  • Asia/Damascus
  • Asia/Dhaka
  • Asia/Dili
  • Asia/Dubai
  • Asia/Dushanbe
  • Asia/Famagusta
  • Asia/Gaza
  • Asia/Hebron
  • Asia/Ho_Chi_Minh
  • Asia/Hong_Kong
  • Asia/Hovd
  • Asia/Irkutsk
  • Asia/Jakarta
  • Asia/Jayapura
  • Asia/Jerusalem
  • Asia/Kabul
  • Asia/Kamchatka
  • Asia/Karachi
  • Asia/Kathmandu
  • Asia/Khandyga
  • Asia/Kolkata
  • Asia/Krasnoyarsk
  • Asia/Kuala_Lumpur
  • Asia/Kuching
  • Asia/Kuwait
  • Asia/Macau
  • Asia/Magadan
  • Asia/Makassar
  • Asia/Manila
  • Asia/Muscat
  • Asia/Nicosia
  • Asia/Novokuznetsk
  • Asia/Novosibirsk
  • Asia/Omsk
  • Asia/Oral
  • Asia/Phnom_Penh
  • Asia/Pontianak
  • Asia/Pyongyang
  • Asia/Qatar
  • Asia/Qostanay
  • Asia/Qyzylorda
  • Asia/Riyadh
  • Asia/Sakhalin
  • Asia/Samarkand
  • Asia/Seoul
  • Asia/Shanghai
  • Asia/Singapore
  • Asia/Srednekolymsk
  • Asia/Taipei
  • Asia/Tashkent
  • Asia/Tbilisi
  • Asia/Tehran
  • Asia/Thimphu
  • Asia/Tokyo
  • Asia/Tomsk
  • Asia/Ulaanbaatar
  • Asia/Urumqi
  • Asia/Ust-Nera
  • Asia/Vientiane
  • Asia/Vladivostok
  • Asia/Yakutsk
  • Asia/Yangon
  • Asia/Yekaterinburg
  • Asia/Yerevan
  • Atlantic/Azores
  • Atlantic/Bermuda
  • Atlantic/Canary
  • Atlantic/Cape_Verde
  • Atlantic/Faroe
  • Atlantic/Madeira
  • Atlantic/Reykjavik
  • Atlantic/South_Georgia
  • Atlantic/St_Helena
  • Atlantic/Stanley
  • Australia/Adelaide
  • Australia/Brisbane
  • Australia/Broken_Hill
  • Australia/Darwin
  • Australia/Eucla
  • Australia/Hobart
  • Australia/Lindeman
  • Australia/Lord_Howe
  • Australia/Melbourne
  • Australia/Perth
  • Australia/Sydney
  • Europe/Amsterdam
  • Europe/Andorra
  • Europe/Astrakhan
  • Europe/Athens
  • Europe/Belgrade
  • Europe/Berlin
  • Europe/Bratislava
  • Europe/Brussels
  • Europe/Bucharest
  • Europe/Budapest
  • Europe/Busingen
  • Europe/Chisinau
  • Europe/Copenhagen
  • Europe/Dublin
  • Europe/Gibraltar
  • Europe/Guernsey
  • Europe/Helsinki
  • Europe/Isle_of_Man
  • Europe/Istanbul
  • Europe/Jersey
  • Europe/Kaliningrad
  • Europe/Kiev
  • Europe/Kirov
  • Europe/Lisbon
  • Europe/Ljubljana
  • Europe/London
  • Europe/Luxembourg
  • Europe/Madrid
  • Europe/Malta
  • Europe/Mariehamn
  • Europe/Minsk
  • Europe/Monaco
  • Europe/Moscow
  • Europe/Oslo
  • Europe/Paris
  • Europe/Podgorica
  • Europe/Prague
  • Europe/Riga
  • Europe/Rome
  • Europe/Samara
  • Europe/San_Marino
  • Europe/Sarajevo
  • Europe/Saratov
  • Europe/Simferopol
  • Europe/Skopje
  • Europe/Sofia
  • Europe/Stockholm
  • Europe/Tallinn
  • Europe/Tirane
  • Europe/Ulyanovsk
  • Europe/Uzhgorod
  • Europe/Vaduz
  • Europe/Vatican
  • Europe/Vienna
  • Europe/Vilnius
  • Europe/Volgograd
  • Europe/Warsaw
  • Europe/Zagreb
  • Europe/Zaporozhye
  • Europe/Zurich
  • Indian/Antananarivo
  • Indian/Chagos
  • Indian/Christmas
  • Indian/Cocos
  • Indian/Comoro
  • Indian/Kerguelen
  • Indian/Mahe
  • Indian/Maldives
  • Indian/Mauritius
  • Indian/Mayotte
  • Indian/Reunion
  • Pacific/Apia
  • Pacific/Auckland
  • Pacific/Bougainville
  • Pacific/Chatham
  • Pacific/Chuuk
  • Pacific/Easter
  • Pacific/Efate
  • Pacific/Fakaofo
  • Pacific/Fiji
  • Pacific/Funafuti
  • Pacific/Galapagos
  • Pacific/Gambier
  • Pacific/Guadalcanal
  • Pacific/Guam
  • Pacific/Honolulu
  • Pacific/Kanton
  • Pacific/Kiritimati
  • Pacific/Kosrae
  • Pacific/Kwajalein
  • Pacific/Majuro
  • Pacific/Marquesas
  • Pacific/Midway
  • Pacific/Nauru
  • Pacific/Niue
  • Pacific/Norfolk
  • Pacific/Noumea
  • Pacific/Pago_Pago
  • Pacific/Palau
  • Pacific/Pitcairn
  • Pacific/Pohnpei
  • Pacific/Port_Moresby
  • Pacific/Rarotonga
  • Pacific/Saipan
  • Pacific/Tahiti
  • Pacific/Tarawa
  • Pacific/Tongatapu
  • Pacific/Wake
  • Pacific/Wallis
  • UTC
"},{"location":"webhookscript/date-locales.html","title":"List of available date function locales","text":"
  • aa
  • aa_DJ
  • aa_ER
  • aa_ER@saaho
  • aa_ET
  • af
  • af_NA
  • af_ZA
  • agq
  • agr
  • agr_PE
  • ak
  • ak_GH
  • am
  • am_ET
  • an
  • an_ES
  • anp
  • anp_IN
  • ar
  • ar_AE
  • ar_BH
  • ar_DJ
  • ar_DZ
  • ar_EG
  • ar_EH
  • ar_ER
  • ar_IL
  • ar_IN
  • ar_IQ
  • ar_JO
  • ar_KM
  • ar_KW
  • ar_LB
  • ar_LY
  • ar_MA
  • ar_MR
  • ar_OM
  • ar_PS
  • ar_QA
  • ar_SA
  • ar_SD
  • ar_SO
  • ar_SS
  • ar_SY
  • ar_Shakl
  • ar_TD
  • ar_TN
  • ar_YE
  • as
  • as_IN
  • asa
  • ast
  • ast_ES
  • ayc
  • ayc_PE
  • az
  • az_AZ
  • az_Cyrl
  • az_IR
  • az_Latn
  • bas
  • be
  • be_BY
  • be_BY@latin
  • bem
  • bem_ZM
  • ber
  • ber_DZ
  • ber_MA
  • bez
  • bg
  • bg_BG
  • bhb
  • bhb_IN
  • bho
  • bho_IN
  • bi
  • bi_VU
  • bm
  • bn
  • bn_BD
  • bn_IN
  • bo
  • bo_CN
  • bo_IN
  • br
  • br_FR
  • brx
  • brx_IN
  • bs
  • bs_BA
  • bs_Cyrl
  • bs_Latn
  • byn
  • byn_ER
  • ca
  • ca_AD
  • ca_ES
  • ca_ES_Valencia
  • ca_FR
  • ca_IT
  • ccp
  • ccp_IN
  • ce
  • ce_RU
  • cgg
  • chr
  • chr_US
  • cmn
  • cmn_TW
  • crh
  • crh_UA
  • cs
  • cs_CZ
  • csb
  • csb_PL
  • cu
  • cv
  • cv_RU
  • cy
  • cy_GB
  • da
  • da_DK
  • da_GL
  • dav
  • de
  • de_AT
  • de_BE
  • de_CH
  • de_DE
  • de_IT
  • de_LI
  • de_LU
  • dje
  • doi
  • doi_IN
  • dsb
  • dsb_DE
  • dua
  • dv
  • dv_MV
  • dyo
  • dz
  • dz_BT
  • ebu
  • ee
  • ee_TG
  • el
  • el_CY
  • el_GR
  • en
  • en_001
  • en_150
  • en_AG
  • en_AI
  • en_AS
  • en_AT
  • en_AU
  • en_BB
  • en_BE
  • en_BI
  • en_BM
  • en_BS
  • en_BW
  • en_BZ
  • en_CA
  • en_CC
  • en_CH
  • en_CK
  • en_CM
  • en_CX
  • en_CY
  • en_DE
  • en_DG
  • en_DK
  • en_DM
  • en_ER
  • en_FI
  • en_FJ
  • en_FK
  • en_FM
  • en_GB
  • en_GD
  • en_GG
  • en_GH
  • en_GI
  • en_GM
  • en_GU
  • en_GY
  • en_HK
  • en_IE
  • en_IL
  • en_IM
  • en_IN
  • en_IO
  • en_ISO
  • en_JE
  • en_JM
  • en_KE
  • en_KI
  • en_KN
  • en_KY
  • en_LC
  • en_LR
  • en_LS
  • en_MG
  • en_MH
  • en_MO
  • en_MP
  • en_MS
  • en_MT
  • en_MU
  • en_MW
  • en_MY
  • en_NA
  • en_NF
  • en_NG
  • en_NL
  • en_NR
  • en_NU
  • en_NZ
  • en_PG
  • en_PH
  • en_PK
  • en_PN
  • en_PR
  • en_PW
  • en_RW
  • en_SB
  • en_SC
  • en_SD
  • en_SE
  • en_SG
  • en_SH
  • en_SI
  • en_SL
  • en_SS
  • en_SX
  • en_SZ
  • en_TC
  • en_TK
  • en_TO
  • en_TT
  • en_TV
  • en_TZ
  • en_UG
  • en_UM
  • en_US
  • en_US_Posix
  • en_VC
  • en_VG
  • en_VI
  • en_VU
  • en_WS
  • en_ZA
  • en_ZM
  • en_ZW
  • eo
  • es
  • es_419
  • es_AR
  • es_BO
  • es_BR
  • es_BZ
  • es_CL
  • es_CO
  • es_CR
  • es_CU
  • es_DO
  • es_EA
  • es_EC
  • es_ES
  • es_GQ
  • es_GT
  • es_HN
  • es_IC
  • es_MX
  • es_NI
  • es_PA
  • es_PE
  • es_PH
  • es_PR
  • es_PY
  • es_SV
  • es_US
  • es_UY
  • es_VE
  • et
  • et_EE
  • eu
  • eu_ES
  • ewo
  • fa
  • fa_AF
  • fa_IR
  • ff
  • ff_CM
  • ff_GN
  • ff_MR
  • ff_SN
  • fi
  • fi_FI
  • fil
  • fil_PH
  • fo
  • fo_DK
  • fo_FO
  • fr
  • fr_BE
  • fr_BF
  • fr_BI
  • fr_BJ
  • fr_BL
  • fr_CA
  • fr_CD
  • fr_CF
  • fr_CG
  • fr_CH
  • fr_CI
  • fr_CM
  • fr_DJ
  • fr_DZ
  • fr_FR
  • fr_GA
  • fr_GF
  • fr_GN
  • fr_GP
  • fr_GQ
  • fr_HT
  • fr_KM
  • fr_LU
  • fr_MA
  • fr_MC
  • fr_MF
  • fr_MG
  • fr_ML
  • fr_MQ
  • fr_MR
  • fr_MU
  • fr_NC
  • fr_NE
  • fr_PF
  • fr_PM
  • fr_RE
  • fr_RW
  • fr_SC
  • fr_SN
  • fr_SY
  • fr_TD
  • fr_TG
  • fr_TN
  • fr_VU
  • fr_WF
  • fr_YT
  • fur
  • fur_IT
  • fy
  • fy_DE
  • fy_NL
  • ga
  • ga_IE
  • gd
  • gd_GB
  • gez
  • gez_ER
  • gez_ET
  • gl
  • gl_ES
  • gom
  • gom_Latn
  • gsw
  • gsw_CH
  • gsw_FR
  • gsw_LI
  • gu
  • gu_IN
  • guz
  • gv
  • gv_GB
  • ha
  • ha_GH
  • ha_NE
  • ha_NG
  • hak
  • hak_TW
  • haw
  • he
  • he_IL
  • hi
  • hi_IN
  • hif
  • hif_FJ
  • hne
  • hne_IN
  • hr
  • hr_BA
  • hr_HR
  • hsb
  • hsb_DE
  • ht
  • ht_HT
  • hu
  • hu_HU
  • hy
  • hy_AM
  • i18n
  • ia
  • ia_FR
  • id
  • id_ID
  • ig
  • ig_NG
  • ii
  • ik
  • ik_CA
  • in
  • is
  • is_IS
  • it
  • it_CH
  • it_IT
  • it_SM
  • it_VA
  • iu
  • iu_CA
  • iw
  • ja
  • ja_JP
  • jgo
  • jmc
  • jv
  • ka
  • ka_GE
  • kab
  • kab_DZ
  • kam
  • kde
  • kea
  • khq
  • ki
  • kk
  • kk_KZ
  • kkj
  • kl
  • kl_GL
  • kln
  • km
  • km_KH
  • kn
  • kn_IN
  • ko
  • ko_KP
  • ko_KR
  • kok
  • kok_IN
  • ks
  • ks_IN
  • ks_IN@devanagari
  • ksb
  • ksf
  • ksh
  • ku
  • ku_TR
  • kw
  • kw_GB
  • ky
  • ky_KG
  • lag
  • lb
  • lb_LU
  • lg
  • lg_UG
  • li
  • li_NL
  • lij
  • lij_IT
  • lkt
  • ln
  • ln_AO
  • ln_CD
  • ln_CF
  • ln_CG
  • lo
  • lo_LA
  • lrc
  • lrc_IQ
  • lt
  • lt_LT
  • lu
  • luo
  • luy
  • lv
  • lv_LV
  • lzh
  • lzh_TW
  • mag
  • mag_IN
  • mai
  • mai_IN
  • mas
  • mas_TZ
  • mer
  • mfe
  • mfe_MU
  • mg
  • mg_MG
  • mgh
  • mgo
  • mhr
  • mhr_RU
  • mi
  • mi_NZ
  • miq
  • miq_NI
  • mjw
  • mjw_IN
  • mk
  • mk_MK
  • ml
  • ml_IN
  • mn
  • mn_MN
  • mni
  • mni_IN
  • mo
  • mr
  • mr_IN
  • ms
  • ms_BN
  • ms_MY
  • ms_SG
  • mt
  • mt_MT
  • mua
  • my
  • my_MM
  • mzn
  • nan
  • nan_TW
  • nan_TW@latin
  • naq
  • nb
  • nb_NO
  • nb_SJ
  • nd
  • nds
  • nds_DE
  • nds_NL
  • ne
  • ne_IN
  • ne_NP
  • nhn
  • nhn_MX
  • niu
  • niu_NU
  • nl
  • nl_AW
  • nl_BE
  • nl_BQ
  • nl_CW
  • nl_NL
  • nl_SR
  • nl_SX
  • nmg
  • nn
  • nn_NO
  • nnh
  • no
  • nr
  • nr_ZA
  • nso
  • nso_ZA
  • nus
  • nyn
  • oc
  • oc_FR
  • om
  • om_ET
  • om_KE
  • or
  • or_IN
  • os
  • os_RU
  • pa
  • pa_Arab
  • pa_Guru
  • pa_IN
  • pa_PK
  • pap
  • pap_AW
  • pap_CW
  • pl
  • pl_PL
  • prg
  • ps
  • ps_AF
  • pt
  • pt_AO
  • pt_BR
  • pt_CH
  • pt_CV
  • pt_GQ
  • pt_GW
  • pt_LU
  • pt_MO
  • pt_MZ
  • pt_PT
  • pt_ST
  • pt_TL
  • qu
  • qu_BO
  • qu_EC
  • quz
  • quz_PE
  • raj
  • raj_IN
  • rm
  • rn
  • ro
  • ro_MD
  • ro_RO
  • rof
  • ru
  • ru_BY
  • ru_KG
  • ru_KZ
  • ru_MD
  • ru_RU
  • ru_UA
  • rw
  • rw_RW
  • rwk
  • sa
  • sa_IN
  • sah
  • sah_RU
  • saq
  • sat
  • sat_IN
  • sbp
  • sc
  • sc_IT
  • sd
  • sd_IN
  • sd_IN@devanagari
  • se
  • se_FI
  • se_NO
  • se_SE
  • seh
  • ses
  • sg
  • sgs
  • sgs_LT
  • sh
  • shi
  • shi_Latn
  • shi_Tfng
  • shn
  • shn_MM
  • shs
  • shs_CA
  • si
  • si_LK
  • sid
  • sid_ET
  • sk
  • sk_SK
  • sl
  • sl_SI
  • sm
  • sm_WS
  • smn
  • sn
  • so
  • so_DJ
  • so_ET
  • so_KE
  • so_SO
  • sq
  • sq_AL
  • sq_MK
  • sq_XK
  • sr
  • sr_Cyrl
  • sr_Cyrl_BA
  • sr_Cyrl_ME
  • sr_Cyrl_XK
  • sr_Latn
  • sr_Latn_BA
  • sr_Latn_ME
  • sr_Latn_XK
  • sr_ME
  • sr_RS
  • sr_RS@latin
  • ss
  • ss_ZA
  • st
  • st_ZA
  • sv
  • sv_AX
  • sv_FI
  • sv_SE
  • sw
  • sw_CD
  • sw_KE
  • sw_TZ
  • sw_UG
  • szl
  • szl_PL
  • ta
  • ta_IN
  • ta_LK
  • ta_MY
  • ta_SG
  • tcy
  • tcy_IN
  • te
  • te_IN
  • teo
  • teo_KE
  • tet
  • tg
  • tg_TJ
  • th
  • th_TH
  • the
  • the_NP
  • ti
  • ti_ER
  • ti_ET
  • tig
  • tig_ER
  • tk
  • tk_TM
  • tl
  • tl_PH
  • tlh
  • tn
  • tn_ZA
  • to
  • to_TO
  • tpi
  • tpi_PG
  • tr
  • tr_CY
  • tr_TR
  • ts
  • ts_ZA
  • tt
  • tt_RU
  • tt_RU@iqtelif
  • twq
  • tzl
  • tzm
  • tzm_Latn
  • ug
  • ug_CN
  • uk
  • uk_UA
  • unm
  • unm_US
  • ur
  • ur_IN
  • ur_PK
  • uz
  • uz_Arab
  • uz_Cyrl
  • uz_Latn
  • uz_UZ
  • uz_UZ@cyrillic
  • vai
  • vai_Latn
  • vai_Vaii
  • ve
  • ve_ZA
  • vi
  • vi_VN
  • vo
  • vun
  • wa
  • wa_BE
  • wae
  • wae_CH
  • wal
  • wal_ET
  • wo
  • wo_SN
  • xh
  • xh_ZA
  • xog
  • yav
  • yi
  • yi_US
  • yo
  • yo_BJ
  • yo_NG
  • yue
  • yue_HK
  • yue_Hans
  • yue_Hant
  • yuw
  • yuw_PG
  • zgh
  • zh
  • zh_CN
  • zh_HK
  • zh_Hans
  • zh_Hans_HK
  • zh_Hans_MO
  • zh_Hans_SG
  • zh_Hant
  • zh_Hant_HK
  • zh_Hant_MO
  • zh_Hant_TW
  • zh_MO
  • zh_SG
  • zh_TW
  • zh_YUE
  • zu
  • zu_ZA
"},{"location":"webhookscript/examples.html","title":"WebhookScript Examples","text":"

Info

Do you have a nice example to share with other users? Or looking for even more examples? Take a look at the WebhookScript example repository, and make a pull request if you want to contribute: Webhook.site Script Repository

"},{"location":"webhookscript/examples.html#hmac-validation","title":"HMAC validation","text":"

The following script uses the hmac() function and the sha256 algorithm to verify a HMAC signature, which is commonly used to verify webhooks. In this example, the secret is secret and the signature comes from the incoming request's x-signature HTTP header.

If the signature doesn't match, further action execution is stopped and the URL immediately respond with a 401 status code.

hmac = hmac(var('request.content'), 'sha256', 'secret');\nsignature = var('request.header.x-signature', '');\nif (hmac != signature) {\nrespond('Unauthorized', 401);\n}\n
"},{"location":"webhookscript/examples.html#jwt","title":"JWT","text":"

An example acquiring an access token from the DocuSign API using JWT and the WebhookScript sign() function:

private_key = '-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBA...\n-----END RSA PRIVATE KEY-----';\nheader = json_encode([\n'alg': 'RS256',\n'typ': 'JWT'\n])\ncurrentTimestamp = now().date_format('X').to_number()\nbody = json_encode([\n\"iss\": \"00000000-0000-0000-0000-000000000000\",\n\"sub\": \"00000000-0000-0000-0000-000000000000\",\n\"aud\": \"account-d.docusign.com\",\n\"iat\": currentTimestamp,\n\"exp\": currentTimestamp + 6000,\n\"scope\": \"impersonation signature\"\n])\ntoken = base64url_encode(header) + \".\" + base64url_encode(body)\nsignature = base64url_encode(sign(token, private_key, 'sha256'))\njwt = token + \".\" + signature\ncontent = query([\n'grant_type': 'urn:ietf:params:oauth:grant-type:jwt-bearer',\n'assertion': jwt\n])\nheaders = ['Content-Type: application/x-www-form-urlencoded']\nresponse = request('https://account-d.docusign.com/oauth/token', content, 'POST', headers)\nif (response['status'] != 200) {\necho('Could not get token: ' + response['content'])\nstop()\n}\nresponse_json = json_decode(response['content'])\necho('Got access token: ' + response_json['access_token'])\n
"},{"location":"webhookscript/examples.html#convert-a-date","title":"Convert a date","text":"

In this example, if we assume the variable $mydate$ is set to 2021-07-26T16:23:50+03:00, the variable will be overwritten to 2021.07.26 16:23 for actions running after the WebhookScript action.

input = var('$mydate$')\noutput = date_format(input, 'YYYY.MM.DD HH:mm')\nset('$mydate$', output)\n

More information about available date format characters.

"},{"location":"webhookscript/examples.html#request-counter","title":"Request counter","text":"

This script uses Global Variables to keep track of the amount of requests sent to a Webhook.site URL within the last 10 minutes.

Once the 10 minutes are up, it sends a request to another endpoint with the amount of requests and the date, and then it resets the counter.

period = 600 // 10 minutes in seconds\ncurrentPeriod = var('current_period', now())\ncounter = var('counter', 0).to_number()\ncurrentPeriodSecs = date_interval(currentPeriod)\nif (currentPeriodSecs < period) {\ncounter = counter + 1\nstore('counter', counter)\n} else {\n// Above 10 minutes, reset and send request\nstore('counter', 0)\nstore('current_period', now())\nrequest(\n'https://webhook.site/14fea227-60ab-4291-b679-12b8c104c78e', json_encode([\n\"counter\": counter,\n\"timestamp\": now(),\n]),\n'POST'\n)\n}\necho('count : {}'.format(counter))\necho('period: {}'.format(currentPeriodSecs))\n
"},{"location":"webhookscript/examples.html#parse-and-loop-through-json","title":"Parse and loop through JSON","text":"

This example shows various ways of iterating through JSON arrays, comparing data and rearranging it to another format.

First, it loops through the items array, verifying that the item must have a group ID that a specific one from an array.

Second, it changes the fields array from an array of objects to a key-value object using the name and value fields.

// Define input as a JSON string\njson = '{\n    \"items\": [\n        {\n            \"first_name\": \"Jack\",\n            \"last_name\": \"Daniels\",\n            \"phone\": \"+1 100-555-999\",\n            \"group_ids\": [346, 46456, 23423],\n            \"fields\": [\n              {\n                \"id\": 45698,\n                \"name\": \"birthday\",\n                \"value\": \"1990-01-01\"\n              },\n              {\n                \"id\": 344,\n                \"name\": \"car\",\n                \"value\": \"BMW M2\"\n              }\n            ]\n        },\n        {\n            \"first_name\": \"Jim\",\n            \"last_name\": \"Beam\",\n            \"phone\": \"+1 123-555-788\",\n            \"group_ids\": [3456, 43546, 234234, 456456],\n            \"fields\": [\n              {\n                \"id\": 45698,\n                \"name\": \"birthday\",\n                \"value\": \"1987-05-01\"\n              },\n              {\n                \"id\": 344,\n                \"name\": \"car\",\n                \"value\": \"Toyota Corolla\"\n              },\n              {\n                \"id\": 248,\n                \"name\": \"nickname\",\n                \"value\": \"Jimmie\"\n              }\n            ]\n        }\n    ]\n}'\n// Decode to array\ndata = json_decode(json)\n// Define an array of valid groups\nvalid_groups = [43546, 999999]\n// Loop over items\nfor (item in data['items']) {\n// Per default, item does not have a valid group.\nhas_valid_group = false\n// Loop through each group ID in the data\nfor (group_id in item['group_ids']) {\n// Does the \"valid_groups\" array contain this group ID?\nif (valid_groups.contains(group_id)) {\nhas_valid_group = true\n}\n}\nif (has_valid_group) {\necho(item['first_name'] + ' did not have a valid group.') } else {\necho(item['first_name'] + ' has a valid group.') }\n// Extract \"fields\" into an array of key => value\nfields = []\nfor (field in item['fields']) {\nfields[field['name']] = field['value']\n}\necho(json_encode(fields))\n}\n

Returns the following output:

Jack has a valid group.\n{\n    \"birthday\": \"1990-01-01\",\n    \"car\": \"BMW M2\"\n}\nJim did not have a valid group.\n{\n    \"birthday\": \"1987-05-01\",\n    \"car\": \"Toyota Corolla\",\n    \"nickname\": \"Jimmie\"\n}\n
"},{"location":"webhookscript/examples.html#loop-through-and-compare-items","title":"Loop through and compare items","text":"

In this example, we loop through a series of items and pick the item that's contained in a string.

location = 'test ABC example';\ncompares = [\n'123': 'token1',\n'ABC': 'token2',\n'DEF': 'token3',\n]\ntoken = ''; // Default value\nfor (compare in array_keys(compares)) {\nif (location.contains(compare)) {\ntoken = compares[compare]\n}\n}\ndump(token) // token2\n
"},{"location":"webhookscript/examples.html#submit-request-with-escaped-json","title":"Submit request with escaped JSON","text":"

If you're building a JSON object, we recommend doing it in WebhookScript instead of typing JSON in the Send Request action type (If you do anyway, we recommend using the .json Variable Modifier, More info here).

In this example, one of the JSON values contain HTML generated using the string_format function.

html_template = '<b><u>New {} lead</u></b><br>\n<br>\nLocation: {}<br>\nMessage from customer:<br>\n<div style=\"background:#CCC\">{}</div>'\nhtml_message = string_format(\nhtml_template,\nvar('lead_type'),\nvar('location'),\nvar('message')\n)\npayload = json_encode([\n'lead': [\n'firstname': var('firstname'),\n'lastname': var('lastname'),\n'html': html_message\n]\n])\nrequest(\n'https://example.com/leads',\npayload,\n'POST',\n['Content-Type: application/json']\n)\n
"},{"location":"webhookscript/examples.html#validate-request","title":"Validate request","text":"

In this example, we use a common method of verifying webhooks by taking a hash of its contents concatenated to a secret. It demonstrates the way WebhookScript can get various information about the request by using the get_variable() function, as well as string concatenation, hashing, if statements and returning responses with content, status codes and headers using respond(), which halts execution.

verification_secret = \"JHRlc3RTY3JpcHRTZWNyZXQ\"\nverification_challenge = var(\"request.header.x-request-verification\")\nverification_result = hash(var(\"request.content\") + verification_secret, \"sha256\")\nif (!verification_challenge or verification_challenge != verification_result) {\nrespond(\"Invalid request\", 500)\n}\nrespond(\"Successful request\", 200)\n
"},{"location":"webhookscript/examples.html#send-a-x-www-form-urlencoded-request","title":"Send a x-www-form-urlencoded request","text":"
content = query([\n'country': 'Cura\u00e7ao', 'population': 158665\n])\nheaders = ['Content-Type: application/x-www-form-urlencoded'];\nresponse = request('https://example.com', content, 'POST', headers);\n
"},{"location":"webhookscript/examples.html#transform-and-resend","title":"Transform and resend","text":"

In the following, an incoming request is JSON decoded to an array, transformed and sent to \"Web Service 1\". Then the output is saved and passed on to \"Web Service 2\" in XML format. Basic error handling and validation is demonstrated.

// Configuration, fetched from the users' Global Variables in Control Panel\nws1_api_key = var('WS1_KEY')\nws2_user_token = var('WS1_USER_TOKEN')\n// Function for error handling which stops processing further actions/code and returns an error message\nfunction error (message) {\necho('Error: {}'.format(message))\nrespond(json_encode(['error': message]), 500)\n}\n// Parse original request\norig_req = json_decode(var('request.content'))\n// If the JSON was invalid\nif (!orig_req) {\nerror('Invalid request')\n}\n// Send request to Web Service 1, using format() for string placeholders\n// with JSON decoded values from the incoming request body\nws1_url = 'https://ws1.example.com/3.0/lists/{}/interest-categories/{}/interests'.format(\norig_req['listId'],\norig_req['groupId']\n)\nws1_content = [\n'first_name': orig_req['firstName'],\n'last_name': orig_req['lastName']\n]\nws1_response = request(\nws1_url,\njson_encode(ws1_content),\n'POST',\n['Authorization: Basic ' + ws1_api_key]\n)\n// Don't go further if the Web Service 1 step didn't succeed\nif (ws1_response['status'] != 200) {\necho(ws1_response['content']); // Log content to output\nerror('Invalid response from WS1')\n}\n// Get a value from the Web Service 1 request\nws1_response_id = json_decode(ws1_response)['id']\n// Pass response on to Web Service 2 in XML format, using a multi-line string and format()\nws2_content = '\n  <qdbapi>\n    <usertoken>{}</usertoken>\n    <listid>{}</listid>\n    <field fid=\"7\">{}</field>\n  </qdbapi>'.format(ws2_user_token, orig_req['listId'], ws1_group_id)\nws2_response = request(\n'https://ws2.example.com/db/zzzzzz',\nws2_content,\n'POST', [\n\"Action: API_EditRecord\", \"Content-Type: application/xml\"\n]\n)\nif (ws2_response['status'] != 200) {\necho(ws2_response['content']); // Log content to debug log\nerror('Invalid response from WS2')\n}\n// Output the WS2 response content to debug output\necho(ws2_response['content'])\nrespond('OK', 200)\n
"},{"location":"webhookscript/examples.html#telegram-bot","title":"Telegram bot","text":"

The Messaging service Telegram allows bots using their API. The general principle is this:

  1. Create a Bot using the /newbot command sent to the BotFather Telegram User
  2. Using the bot token sent from BotFather, use the Telegram API to create a Webhook subscription (using your Webhook.site URL)
  3. Add some logic using WebhookScript!

Note: Everywhere you see TELEGRAM_TOKEN, replace it with the token you got from BotFather!

"},{"location":"webhookscript/examples.html#subscribe-to-webhook","title":"Subscribe to Webhook","text":"

To create the Webhook subscription, change the token and the Webhook.site URL to your own and go to the following URL in your browser:

https://api.telegram.org/botTELEGRAM_TOKEN/setWebhook?url=https://webhook.site/a1351781

You should get a response similar to this:

{\n\"ok\": true,\n\"result\": true,\n\"description\": \"Webhook was set\"\n}\n
"},{"location":"webhookscript/examples.html#first-incoming-webhook","title":"First incoming Webhook","text":"

When you add your bot to your Telegram contacts list, Telegram automatically sends a /start command to the bot, which triggers a Webhook similar to this:

{\n\"update_id\": 176446573,\n\"message\": {\n\"message_id\": 1,\n\"from\": {\n\"id\": 2346545645,\n\"is_bot\": false,\n\"first_name\": \"Simon\",\n\"language_code\": \"en\"\n},\n\"chat\": {\n\"id\": 34534673234,\n\"first_name\": \"Simon\",\n\"type\": \"private\"\n},\n\"date\": 1581706369,\n\"text\": \"/start\",\n\"entities\": [\n{\n\"offset\": 0,\n\"length\": 6,\n\"type\": \"bot_command\"\n}\n]\n}\n}\n

You should be able to see this in the Webhook.site requests list.

From this, we have all the parts needed to build a script that answers to commands:

// Telegram API token\ntoken = 'TELEGRAM_TOKEN';\ncontent = json_decode(var('$request.content$'));\nmsg = content['message']['text'];\nresponse = \"Couldn't come up with anything witty.\";\nif (msg == \"How's it going?\") {\nresponse = 'Pretty good.'\n}\nif (msg == r\"You're (.*)\") {\nmatch = regex_extract_first(r\"You're (.*)\", msg)\nresponse = 'No, YOU are {}'.format(match);\n}\nif (msg == \"/start\") {\nresponse = \"Hi! I'm WebhookBot.\"\n}\nurl = 'https://api.telegram.org/bot{}/sendMessage'.format(token)\njson = [\n'chat_id': content['message']['chat']['id'],\n'text': response\n]\nrequest(url, json_encode(json), 'POST');\n

Things to note:

  • The API token is added to the script, but could also have been saved in Global Variables in Control Panel and fetched out with the var() function.
  • The third if-statement uses regex matching to provide a dynamic response. Someone typing \"You're a bot\" would receive \"No, YOU are a bot\"
  • Finally, we JSON encode a WebhookScript array and send it using the request() function.

Simply copy this script into a WebhookScript Custom Action (remember to change the token!), and click Save Action.

Then, you can interact with the bot using the Telegram app:

And that's it! Congratulations on your bot. It's not very smart, but from here, the possibilities are endless!

"},{"location":"webhookscript/examples.html#building-html-content","title":"Building HTML content","text":"

The following script builds a piece of HTML content using the string_format function, based on previously defined variables, and shows how to use a function to return different content based on input.

After this, it sends a JSON request (by converting an array to JSON via the json_encode function) containing the HTML using basic Bearer authentication.

function alert_class() {\nif (status == 'Operational') { return 'success'; }\nif (status == 'Degraded Performance') { return 'warning'; }\nif (string_contains(status, 'Disruption')) { return 'danger'; }\n}\ntemplate = '\n  <div class=\"alert alert-{}\">\n    <h2 class=\"alert-title\">{} - {}</h2>\n    <p>\n      {}<br />\n      State: {}<br />\n      Component affected: {}\n    </p>\n    <p>{}</p>\n  </div>';\npostbody = string_format(\ntemplate,\nalert_class(),\nmessage,\nstate,\ncomponent,\nto_date('now').date_format('LLLL')\n)\njson = [\n'alert': [\n'title': '{} - {}'.format(component, state),\n'body': postbody,\n'draft': false,\n'types': ['alert']\n],\n]\nrequest(\n'http://example.com/alerts',\njson_encode(json),\n'POST',\n[\n'Content-Type: application/json',\n'Authorization: Basic {}'.format(token)\n]\n)\n
"},{"location":"webhookscript/examples.html#uploading-and-parsing-csv-file","title":"Uploading and parsing CSV file","text":"

With this script, a file upload form is displayed when visiting the URL. After submitting the form, the CSV file is processed and validated (in this example, there must be more than 2 rows). If it can't be validated, an error message is shown. Finally, the user is shown an \"Upload successful\" message if the CSV file is valid.

url = var('request.url')\nset_header('content-type', 'text/html');\n// Display file upload form and exit if HTTP method is not POST\nif (var('request.method') != 'POST') {\nrespond('\n        <html>\n            <head><title>Upload CSV</title></head>\n            <body>\n                <h1>Upload CSV</h1>\n                <form action=\"{}\" method=\"POST\" enctype=\"multipart/form-data\">\n                    <input type=\"file\" name=\"file\"/>\n                    <button type=\"submit\">Upload</button>\n                </form>\n            </body>\n        </html>\n    '.format(url))\n}\n// Use a comma as delimiter and treat first row (0) as header row\narray = csv_to_array(var('request.file.file.content'), ',', 0)\n// If CSV can't be parsed, or there's less than 2 rows, fail\nif (!array or array.length() < 2) {\nrespond('\n        <h1>Could not parse CSV</h1>\n        <a href=\"{}\">Upload again</a>\n    '.format(url));\n}\n// Display the parsed CSV in JSON format \nrespond('\n    <h1>Upload successful</h1>\n    <pre>{}</pre>\n    <p>\n        <a href=\"{}\">Upload again</a>\n    </p>\n'.format(json_encode(array), url))\n
"},{"location":"webhookscript/functions.html","title":"Functions","text":"

The functions page has been split up in multiple sub-pages, please start here.

"},{"location":"webhookscript/reference.html","title":"Language Reference","text":"

These are the functions that can be used in your script, and includes various utility functions and functions to interact with your Webhook.site URL.

"},{"location":"webhookscript/reference.html#syntax","title":"Syntax","text":"

The language is built with a familiar PHP/JS/C-like syntax. Statements are separated using the ; character, but this is only required for multiple statements on the same line:

  • Using semicolons (recommended):

    a = 1 + 2; b = a + 3;\nc = b - a;\n

  • Using newlines:

    a = 1 + 2\nb = a + 3\nc = b - a\n

"},{"location":"webhookscript/reference.html#data-types","title":"Data types","text":"

The language has 6 data types:

  • Bool
  • Number
  • String
  • Regex
  • Array
  • Function
"},{"location":"webhookscript/reference.html#boolean","title":"Boolean","text":"

Example usage:

a = true;\nb = 1 == 2; // false\nc = b == false; // true\nd = c == \"hello\"; // ERR: Cannot compare 'bool' and 'string'\ne = \"hello\" == r\"[0-9]\"; // false\nf = \"hello\" == r\"l{2}\"; // true\n

"},{"location":"webhookscript/reference.html#number","title":"Number","text":"

Both integer and float values are supported.

Example usage:

a = 4 - 3; // 1\nb = a / 3; // 0.333...\n
"},{"location":"webhookscript/reference.html#string","title":"String","text":"

This data types represents a series of characters. Multi-byte characters (accents, diacritics) are treated properly.

Example usage:

a = \"hello\";\nb = \"w\u00f3\u00f3\u00f3rld!\";\nc = a + \" \" + b; // \"hello w\u00f3\u00f3\u00f3rld!\"\n

"},{"location":"webhookscript/reference.html#regex","title":"Regex","text":"

Regex data type exists for advanced string matching. It is defined using the r\"...\" literal (a string literal prefixed with r) and treated as PCRE (Perl-compatible) regular expressions (the same as within PHP itself) with Unicode mode enabled.

Example usage:

a = \"facebook\";\nb = r\"[o]{2}.*\";\nc = a == b; // true\n

"},{"location":"webhookscript/reference.html#array","title":"Array","text":"

Arrays are untyped (PHP-style) containers that can accomodate multiple values of different (or same) types. Optionally, array index can be defined for a value. By default, integer index starting from the lowest index found (or from 0) is used, but strings can also be used.

Example usage:

a = [\"abc\", 123, 4: true, false, r\"[A-Z]+\"];\n// Resulting array: [0: \"abc\", 1: 123, 4: true, 5: false, 6: r\"[A-Z]+\"]\nb = json_encode([\"the_number\": 123, \"other_numbers\": [42, 1337, 80085]])\n// Result:\n// {\n//     \"the_number\": 123,\n//     \"other_numbers\": [\n//         42,\n//         1337,\n//         80085\n//     ]\n// }\n

"},{"location":"webhookscript/reference.html#ranges","title":"Ranges","text":"

Simple way of defining ranges between numbers is provided via the a..[s..]b range syntax.

  • a is the from value.
  • b is the to value, inclusive, if it is not \"skipped\" due to a rather large step (see below).
  • s (optionally) is the step value which to use.

Example usage:

a = 1..4; // (array) [0: 1, 1: 2, 4: 3, 5: 4]\nb = 1..2..4; // (array) [0: 1, 1: 3]\nc = 10..4..16; // (array) [0: 10, 1: 14]\n_x = 3\n_y = 6\n_z = 2\nd = _x.._z.._y; // (array) [0: 3, 1: 5]\n
Return value of such \"range literal\" is a new array having values that are based on the range's parameters.

"},{"location":"webhookscript/reference.html#functions","title":"Functions","text":"

Function is a value type that represents a \"unit\" of some self-contained logic. In WebhookScript they have their own type and are treated as first-class citizens: they can be stored inside variables and passed around as such. Direct invocation of an anonymous function is supported, provided that the anonymous function's definition is enclosed in parentheses. A function does capture its surrounding variables.

Example usage:

// Traditional definition.\nfunction sub(a, b) {\nreturn a - b;\n}\n// A variable \"sub\" that holds the \"sub()\" function is now defined in current scope.\nsub(1, 2); // Returns -1\n// Storing a function value into a variable.\n// Note: This is equivalent to the previous definition.\nsub_2 = function(a, b) {\nreturn a - b;\n};\n// A variable \"sub_2\" that holds the \"sub_2()\" function is now defined in current scope.\nsub_2(1, 2); // Returns -1\n// Creating a function with alternative, short syntax.\n// Note: This is equivalent all of the previous definitions.\nsub_3 = (a, b) => {\nreturn a - b;\n};\n// A variable \"sub_3\" that holds the \"sub_3()\" function is now defined in current scope.\nsub_3(1, 2); // Returns -1\n// Creating and using an anonymous function directly.\n// Using an alternative, short syntax.\n((a, b) => {\nreturn a - b;\n})(1, 2); // Returns -1\n

"},{"location":"webhookscript/reference.html#chained-functions","title":"Chained functions","text":"

In addition to classical function invocation, WebhookScript additionaly supports Uniform Function Call Syntax (UFCS) as a way to call functions \"on values\". Essentially, it means that calling foo(bar); is equivalent to calling bar.foo(), or - to provide an example with additional parameters - that calling foo(bar, 1, true, \"something\"); is equivalent to calling bar.foo(1, true, \"something\").

"},{"location":"webhookscript/reference.html#value-type-based-inference-of-called-function-name","title":"Value-type based inference of called function name","text":"

When using chained function invocation, the interpreter will try to find the most fitting function to call. \"Most fitting\" meaning that when the client calls bar() function on a value having the string type, WebhookScript will try to find and use the string_bar() first. If such function is not defined, only then will the interpreter use the original bar() function.

Consider this a syntactic sugar to make coding in WebhookScript a bit more user-friendly. Because of this the user is able to call \"something\".length() on a string the same way as calling [1, 2, 3].length() on an array, even though there are in fact two separate functions string_length() and array_length() invoked behind the scenes.

"},{"location":"webhookscript/reference.html#operators","title":"Operators","text":"

Plethora of well known operators can be used to define relationships between and/or affect various values. Different operators can have various effects on various data types, some of which are covered down below.

"},{"location":"webhookscript/reference.html#precedence","title":"Precedence","text":"

Precedence of various operators is defined as follows (from highest to lowest): - ( ... ) (parentheses) - ! (logical not) - *, / (multiplication/division) - +, - (addition/subtraction) - ==, !=, >=, <=, >, < (comparison) - and (logical and) - or (logical not) - = (assignment)

"},{"location":"webhookscript/reference.html#precedence-example","title":"Precedence example","text":"Raw source Equivalent to 1 + 2 + 3 + 4 ((1 + 2) + 3) + 4 1 - 2 + 3 - 4 ((1 - 2) + 3) - 4 1 + 2 * 3 + 4 1 + (2 * 3) + 4 1 + 2 * 3 / 4 1 + ((2 * 3) / 4) 1 + -2 * 3 / 4 1 + (((-2) * 3) / 4) 1 and 2 or 3 and 4 (1 and 2) or (3 and 4) 1 or 2 or 3 and 4 (1 or 2) or (3 and 4) 1 or !2 or !3 and 4 (1 or (!2)) or ((!3) and 4)) x = true or false and true x = (true or (false and true)) x = a == b x = (a == b) x = a > 5 and b < 6 x = ((a > 5) and (b < 6))"},{"location":"webhookscript/reference.html#logical-operators","title":"Logical operators","text":"
  • and
    • Returns true if both operands are truthy.
    • Otherwise returns false.
  • or
    • Returns true if either one (or both) operand is truthy.
    • Otherwise returns false.
"},{"location":"webhookscript/reference.html#negation","title":"Negation","text":"
  • !
    • Negate the value located after this operator.
    • Examples:
      a = true;\nb = !a; // false\nc = !b; // true\nd = !!b; // false\n
"},{"location":"webhookscript/reference.html#assignment","title":"Assignment","text":"
  • =
    • Assigns some value to a variable.
    • Can also be used to insert values to values that support it (eg. arrays).
    • Examples:
      a = 1;\nb = \"a word\";\nc = false;\nd = r\"regul[ar]+\";\ne = [\"x\", \"b\": \"z\"];\ne[\"c\"] = \"x\"; // e == [\"x\", \"b\": \"z\", \"c\": \"x\"]\n
"},{"location":"webhookscript/reference.html#addition-and-multiplication","title":"Addition and multiplication","text":"
  • +, -
    • Performs addition (subtraction) of two values.
      • Numbers:
        • + Add two numbers.
        • - Subtract two numbers.
      • Strings:
        • + Concatenate two strings.
        • - Removes all occurences of the right side from the left side.
        • - (if the right side is a Regex value) Removes all matches of the regex from the left side string.
    • Examples:
      a = 5 + 4 // (number) 9\nb = 5 - 4; // (number) 1\nc = \"a word and number \" + 5.to_string(); // (string) \"a word and number 5\"\nd = \"a word and number {}\".format(5); // (string) \"a word and number 5\"\ne = \"a word\" + \" and one more\"; // (string) \"a word and one more\"\nf = \"a word\" - \"or\"; // (string) \"a wd\"\ng = \"regular expressions\" - r\"regul[ar]+\\s*\"; // (string) \"expressions\"\n_x = 5 + \"4\" // ERR: Cannot use operator '+' with 'number' and 'string'\n_x = \"a word and number \" + 5; // ERR: Cannot use operator '+' with 'number' and 'string'\n
  • *, /
    • Performs multiplication (division) of two values.
      • Numbers:
        • + Multiply two numbers.
        • - Divide two numbers.
    • Examples:
      a = 1 * -2; // (number) -2\nb = 2 * 3; // (number) 6\nc = 2 * \"3\"; // (string) \"33\"\nd = \"3\" * 4; // (string) \"3333\"\ne = 5 / 4; // (number) 1.25\ng = 5 / 5; // (number) 1\n_x = \"2\" * \"3\"; // ERR: Cannot use operator '*' with 'string' and 'string'\n_x = 5 / \"4\"; // ERR: Cannot use operator '/' with 'number' and 'string'\n_x = \"20\" / 4; // ERR: Cannot use operator '/' with 'string' and 'number'\n
"},{"location":"webhookscript/reference.html#control-structures","title":"Control structures","text":"

You can control the flow of your program with several kinds of statements the language provides.

"},{"location":"webhookscript/reference.html#if-construct","title":"if construct","text":"

The if construct - as in all other programming languages - allows you to dynamically branch your program flow based on some conditions during runtime.

"},{"location":"webhookscript/reference.html#examples","title":"Examples","text":"
a = true;\nif (a) {\nb = 1;\n}\n// b == 1\n
c = false;\nif (c) {\nd = 1;\n} else {\nd = 2;\n}\n// d == 2\n
a = false;\nb = true;\nc = 5;\nif (a or b) {\nd = 1;\nif (d < c) {\ne = d + c;\n}\n}\n// d == 1, e == 6\n
"},{"location":"webhookscript/reference.html#for-construct","title":"for construct","text":"

The for construct allows you to iterate over a value that supports it (array or string values), while performing a task on that collection's single item.

"},{"location":"webhookscript/reference.html#examples_1","title":"Examples","text":"
txt = \"123456789\";\nresult = [];\nfor (n in txt) {\nif (5 > n.to_number() > 0) {\nresult.push(n);\n}\n}\n// result == [0: \"1\", 1: \"2\", 2: \"3\", 3: \"4\"]\n
prices = [100, 200, 300, 600, 1200];\nsentence_template = \"This costs {} units of money!\";\nresults = [];\nfor (price in prices) {\nresults.push(sentence_template.format(price));\n}\n// results == [\n//   0: \"This costs 100 units of money!\",\n//   1: \"This costs 200 units of money!\",\n//   2: \"This costs 300 units of money!\",\n//   3: \"This costs 600 units of money!\",\n//   4: \"This costs 1200 units of money!\"\n// ]\n

Note: The flow of program inside the for cycle can be controlled further by using the continue and break statements.

"},{"location":"webhookscript/reference.html#while-construct","title":"while construct","text":"

The while construct does a thing if a specified condition is met (if the condition expression has a truthy value).

c = 0;\nwhile (c < 100) {\ntotal = total + c;\nc = c + 1;\n}\n// total == 4950\n

Note: The flow of program inside the while cycle can be controlled further by using the continue and break statements.

"},{"location":"webhookscript/functions/array.html","title":"Arrays","text":""},{"location":"webhookscript/functions/array.html#array_containsarray-array-stringnumber-needle-bool","title":"array_contains(array array, string/number needle) : bool","text":"

Returns true or false depending on whether array contains a value equal to needle.

To check whether a key exists, use the array_has function.

employees = [6547: 'Simon', 235345: 'Jack', 4657: 'Jim']\ndd(array_contains(employees, 'Simon'))\n// -> true\n
"},{"location":"webhookscript/functions/array.html#array_chunkarray-array-number-count-bool-preserve_keys-false-array","title":"array_chunk(array array, number count, bool preserve_keys = false) : array","text":"

Splits a single array into chunks of count. When preserve_keys is set to true, the array keys are preserved.

test_arr = [\n'a': 123,\n'b': 234,\n'c': 345,\n'd': 345, 'e': 456\n]\ndump(array_chunk(test_arr, 2, true))\n// -> [0: [\"a\": 123, \"b\": 234], 1: [\"c\": 345, \"d\": 345], 2: [\"e\": 456]]\ndump(array_chunk(test_arr, 2, false))\n// -> [0: [0: 123, 1: 234], 1: [0: 345, 1: 345], 2: [0: 456]]\n
"},{"location":"webhookscript/functions/array.html#array_copyarray-array-array","title":"array_copy(array array) : array","text":"

Returns a copy of array

"},{"location":"webhookscript/functions/array.html#array_diffarray-array1-array-array2-array","title":"array_diff(array array1, array array2) : array","text":"

Returns the items of array1 that are not present in array2 while keeping the array indices.

"},{"location":"webhookscript/functions/array.html#array_getarray-array-stringnumber-index-any-default-any","title":"array_get(array array, string/number index, any default) : any","text":""},{"location":"webhookscript/functions/array.html#array_hasarray-array-stringnumber-key-bool","title":"array_has(array array, string/number key) : bool","text":"

Returns true if array contains key, and false if it does not.

To check whether a value exists, use the array_contains function.

employees = [6547: 'Simon', 235345: 'Jack', 4657: 'Jim']\ndd(array_has(employees, 235345))\n// -> true\n
"},{"location":"webhookscript/functions/array.html#array_joinarray-array-string-joiner-string","title":"array_join(array array, string joiner) : string","text":"

Returns a string where all the values are joined by joiner.

['hello', 'world'].join(',')\n-> \"hello,world\"\n
"},{"location":"webhookscript/functions/array.html#array_keysarray-array-array","title":"array_keys(array array) : array","text":"

Returns the keys of an array.

"},{"location":"webhookscript/functions/array.html#array_lengtharray-array-number","title":"array_length(array array) : number","text":""},{"location":"webhookscript/functions/array.html#array_maparray-array-func-function","title":"array_map(array array, func function)","text":"

Runs function with each array value, and returns array with key as result.

employees = ['Simon', 'Jack', 'Jim']\nresult = array_map(employees, function (employee) {\nreturn 'Hello, '+employee+'!'\n})\ndd(result)\n// -> [0: \"Hello, Simon!\", 1: \"Hello, Jack!\", 2: \"Hello, Jim!\"]\n
"},{"location":"webhookscript/functions/array.html#array_mergearray-array1-array-array2-array","title":"array_merge(array array1, array array2): array","text":"

Merges 2 arrays into a single array.

test1 = [123, 234, 345]\ntest2 = [345, 456]\ndump(array_merge(test1, test2))\n// -> [0: 123, 1: 234, 2: 345, 3: 345, 4: 456]\n
"},{"location":"webhookscript/functions/array.html#array_number_ofarray-stringnumber-value-number","title":"array_number_of(array, string/number value) : number","text":"

Returns amount of value

"},{"location":"webhookscript/functions/array.html#array_poparray-array-any","title":"array_pop(array array) : any","text":"

Pop element off end of array

"},{"location":"webhookscript/functions/array.html#array_pusharray-array-any-value-any","title":"array_push(array array, any value) : any","text":"

Adds value to end of array and returns value

"},{"location":"webhookscript/functions/array.html#array_randomarray-array-any","title":"array_random(array array) : any","text":"

Returns random value of array

"},{"location":"webhookscript/functions/array.html#array_rangearray-array-int-offset-int-length-0-bool-preserve_keys-false-array","title":"array_range(array array, int offset, ?int length = 0, ?bool preserve_keys = false) : array","text":"

Returns a range of array, starting from offset, and returns the amount specified in length if set (otherwise until the end of the array.)

If preserve_keys is true, the result has the array keys preserved.

array = ['one', 'two', 'three', 'four', 'five']\ndump(array_slice(array, 2))\n// [0: \"three\", 1: \"four\", 2: \"five\"]\ndump(array_slice(array, 2, 2))\n// [0: \"three\", 1: \"four\"]\ndump(array_range(array, -3, 2))\n// [0: \"three\", 1: \"four\"]\n
"},{"location":"webhookscript/functions/array.html#array_reversearray-array-array","title":"array_reverse(array array) : array","text":"

Returns array in reverse order

employees = [6547: 'Simon', 235345: 'Jack', 4657: 'Jim']\ndd(array_reverse(employees))\n// -> [0: \"Jim\", 1: \"Jack\", 2: \"Simon\"]\n
"},{"location":"webhookscript/functions/array.html#array_shufflearray-array-array","title":"array_shuffle(array array) : array","text":"

Returns shuffled version of array

"},{"location":"webhookscript/functions/array.html#array_sortarray-array-array","title":"array_sort(array array) : array","text":"

Sorts array by its values. Keys are kept as-is.

"},{"location":"webhookscript/functions/array.html#array_splicearray-array-int-offset-int-length-array-replacement-array","title":"array_splice(array array, int offset, ?int length, array replacement) : array","text":"

Removes length amount of values from array, starting from offset (if offset is negative, starts from the end of the array.)

If replacement is specified, the removed values are replaced with it.

array = ['one', 'two', 'three', 'four', 'five']\ndump(array_splice(array, 2, 2))\n// [0: \"one\", 1: \"two\", 2: \"five\"]\ndump(array_splice(array, 2, 2, ['hello']))\n// [0: \"one\", 1: \"two\", 2: \"hello\", 3: \"five\"]\n
"},{"location":"webhookscript/functions/array.html#array_valuesarray-array-array","title":"array_values(array array) : array","text":"

Returns the values of an array.

employees = [6547: 'Simon', 235345: 'Jack', 4657: 'Jim']\ndd(array_values(employees))\n// -> [0: \"Simon\", 1: \"Jack\", 2: \"Jim\"]\n
"},{"location":"webhookscript/functions/array.html#to_arrayarray-array-array","title":"to_array(array array) : array","text":"

Returns array.

"},{"location":"webhookscript/functions/bool.html","title":"Booleans","text":""},{"location":"webhookscript/functions/bool.html#bool_andbool-value1-bool-value2-bool","title":"bool_and(bool value1, bool value2): bool","text":"

Returns value1 && value2

"},{"location":"webhookscript/functions/bool.html#bool_notbool-value-bool","title":"bool_not(bool value) : bool","text":"

Returns !value

"},{"location":"webhookscript/functions/bool.html#is_emptyany-value-bool","title":"is_empty(any value): bool","text":"

Returns true if:

  • value is \"\" (empty string)
  • value is [] (empty array)
  • value is null
"},{"location":"webhookscript/functions/bool.html#is_nullany-value-bool","title":"is_null(any value) : bool","text":"

Returns true if value is null. An alternative to if (value == null) that won't break when value isn't null due to type checking.

Example:

value = 'example'\nif (is_null(value)) {\n// Won't trigger a type error\n}\n
"},{"location":"webhookscript/functions/bool.html#to_boolstringnumberarraybool-value-bool","title":"to_bool(string/number/array/bool value) : bool","text":"

Casts value to a bool.

"},{"location":"webhookscript/functions/date.html","title":"Date and Time Manipulation","text":""},{"location":"webhookscript/functions/date.html#supported-date-and-time-formats","title":"Supported date and time formats","text":"

In WebhookScript, dates are not a specific type, but rather expressed as strings that WebhookScript will attempt to parse using a very powerful date parsing engine.

WebhookScript supports a variety of date formats, and functions taking a date will attempt to guess the format of the input string in order to parse the date into a ISO-8601 format

If possible, it's recommended to use the ISO-8601 format, for example 2020-05-27T04:00:00.000000Z.

  • List of date format characters for the to_date and date_format functions.

  • List of locales/translations available for date display functions

  • List of Timezone names

"},{"location":"webhookscript/functions/date.html#recognized-date-formats","title":"Recognized date formats","text":"

In addition to automatically recognizing date strings like ISO-8601, WebhookScript has ability to recognize the following special formats.

  • now
  • +4 day, -2 month - adds or subtracts to the current date and time, can be suffixed to other dates
    • Other units supported: second, minute, hour, day, fortnight, week, month, year
  • next Thursday
  • last Monday
  • first day of January 2008
  • first Saturday of July 2008
  • Monday next week
  • @1215282385 - UNIX timestamp

For more information, PHP Supported Date and Time Formats.

"},{"location":"webhookscript/functions/date.html#nowstring-timezone-string","title":"now(?string timezone) : string","text":"

Returns the current date in ISO-8601 format, using timezone, if specified.

now()\n// -> 2022-12-15T11:00:00.000000Z\nnow('America/Los_Angeles')\n// -> 2022-12-15T03:00:00.000000-08:00\n
"},{"location":"webhookscript/functions/date.html#to_datestring-date-string-input_format-locale-locale-string-timezone-bool-keep_timezone-false-string","title":"to_date(string date, ?string input_format, ?locale locale, ?string timezone, bool keep_timezone = false): ?string","text":"

Returns a ISO-8601 formatted date string in UTC time from the provided date string.

If specified, input_format is used to parse the date without having to guess the format (see the Date Format Characters specification.) Otherwise, see Recognized date formats.

If the keep_timezone parameter is set to true, the resulting date string will keep the timezone. The locale parameter will attempt to parse the date using the specified locale.

If the date is invalid or could not be guessed, null is returned.

// Current date and time\n'now'.to_date()\n// -> 2020-11-25T00:00:00.000000Z\n// Relative formats\n'first monday august 2019'.to_date()\n// Automatic format guessing\n'2020-01-01 23:02:01'.to_date()\n// Timezone handling\n'2020-01-01 23:02:01'.to_date(null, null, 'GMT-5')\n// -> \"2020-01-02T04:02:01.000000Z\", interpreted as GMT-5 and converted to UTC\n'2020-01-01 23:02:01'.to_date(null, null, 'GMT-5', true)\n// -> \"2020-01-01T23:02:01.000000-05:00\", date keeps timezone\n// Unix timestamp\n'@1215282385'.to_date()\n// Custom date format\n'2/4/12 06:03'.to_date('M/D/YY HH:mm')\n// -> 2012-02-04T06:03:00.000000Z\n// To escape characters in the format string, backslashes can be used\n'2020-01-05 12h30m15s'.to_date('YYYY-MM-DD HH\\\\hmm\\\\mss\\\\s')\n// -> 2020-01-05T12:30:15.000000Z\n
"},{"location":"webhookscript/functions/date.html#date_formatstring-date-string-format-string-locale-string-timezone-string","title":"date_format(string date, ?string format, ?string locale, ?string timezone): string","text":"

Returns a date converted to the format specified in format. date is automatically parsed and can be a date string (ISO-8601 recommended) or one of the recognized date formats.

For a full list of date format characters, see the Date Format Characters specification.

If format is not specified, a default human readable readable string is returned.

date_format('2008-07-05T18:26:25.000000Z', 'YYYY-MM-DD') // -> 2008-07-05\ndate_format('2008-07-05T18:26:25.000000Z', 'LLLL', 'da') // -> l\u00f8rdag d. 5. juli 2008 kl. 18:26\ndate_format('2020-01-01T23:02:01.000000-05:00', 'LLLL', null, 'GMT+2') // -> Thursday, January 2, 2020 6:02 AM\ndate_format('now', 'x')\n// -> 1606329669220 (current date in UNIX timestamp with microseconds)\n// Add 1 hour to an existing date (see Recognized date formats above)\ndate_format('2021-10-28 11:28:55 +1 hour', 'YYYY-MM-DD HH:mm:ss')\n// -> 2021-10-28 12:28:55\n
"},{"location":"webhookscript/functions/date.html#date_to_arraystring-array","title":"date_to_array(string): array","text":"

Returns an array containing all the components of a given date.

dump(date_to_array('2008-07-05T18:26:25.324542Z'))\n// [\n//   \"year\": 2008,\n//   \"month\": 7,\n//   \"day\": 5,\n//   \"dayOfWeek\": 6,\n//   \"dayOfYear\": 187,\n//   \"hour\": 18,\n//   \"minute\": 26,\n//   \"second\": 25,\n//   \"micro\": 324542,\n//   \"timestamp\": 1215282385,\n//   \"formatted\": \"2008-07-05 18:26:25\",\n//   \"timezone\": \"Z\"\n// ]\n
"},{"location":"webhookscript/functions/date.html#date_intervalstring-date1-string-date2-string-format-stringint","title":"date_interval(string date1, ?string date2, ?string format): string/int","text":"

Calculates the interval between date1 and date2. When date2 is unspecified/null, now is used.

If no format string is specified, the interval is returned as the number of seconds between the dates, with the number being negative if date2 is before date1.

For the format string, the PHP DateInterval format specification is used.

date_interval('2008-07-16T23:13:26.234212Z', '2008-07-05T18:26:25.324542Z') // -> -967620\ndate_interval(\n'2008-07-16T23:13:26.234212Z',\n'2008-07-05T18:26:25.324542Z',\n'%d days, %h hours, %i minutes'\n)\n// -> 11 days, 4 hours, 47 minutes\n
"},{"location":"webhookscript/functions/date.html#date_interval_humanstring-date1-string-date2-string-locale-stringint","title":"date_interval_human(string date1, ?string date2, ?string locale): string/int","text":"

Formats the difference between 2 dates in a way that's easy to read for humans.

If no locale is specified, English is used. When date2 is unspecified/null, now is used.

date_interval_human(\n'2008-07-16T23:13:26.234212Z',\n'2008-07-05T18:26:25.324542Z'\n)\n// -> 1 week after\ndate_interval_human(\n'2008-07-16T23:13:26.234212Z',\n'2008-07-05T18:26:25.324542Z',\n'es'\n)\n// -> 1 semana despu\u00e9s\n
"},{"location":"webhookscript/functions/files.html","title":"File handling","text":"

When you send an email, or send a multipart/form-data request, files are extracted as the file.*.* variables, but you can also loop over files using WebhookScript.

"},{"location":"webhookscript/functions/files.html#filesstring-name-array","title":"files(string name) : array","text":"

Returns an array of files, with the following keys:

  • id - unique file ID
  • filename - original filename
  • size - size of the file in bytes
  • content-type - mime content type of the file
dump(files())\n// [\n//   0: [\n//     \"id\": \"76b7274a-e806-4f72-ba49-85ad05926ef0\", \n//     \"filename\": \"Screen Shot 2020-06-05 at 2.15.29 PM.png\", \n//     \"size\": 1203671, \n//     \"content_type\": \"image/png\"\n//   ]\n// ]\n// Filtering files by type\nfor (file in files()) {\nif (r'.*\\.png'.match(file['filename'])) {\ndump(file['filename'] + ' is png.')\n}\n}\n// \"Screen Shot 2020-06-05 at 2.15.29 PM.png is png.\"\n
"},{"location":"webhookscript/functions/files.html#file_contentstring-fileid-string","title":"file_content(string fileId) : string","text":"

Returns the content of a specific file, using the id key from the files() function above.

firstFile = array_get(files(), 0)\nfileContent = file_contents(firstFile['id']);\n
"},{"location":"webhookscript/functions/flow.html","title":"Flow Control and Responses","text":""},{"location":"webhookscript/functions/flow.html#script-execution","title":"Script Execution","text":""},{"location":"webhookscript/functions/flow.html#actionstring-action_type-array-parameters-array","title":"action(string action_type, array parameters) : array","text":"

Runs Custom Actions in WebhookScript. Can be used to loop over items in a way that not possible using the visual Custom Actions editor.

The function returns an array of runtime variables which can be used to fetch the result of an action that sets a variable, like google_sheets_get_values.

The action_types and their parameters can be seen here.

The following action extracts a list of files from an array of objects in a JSON array and uploads each file to Dropbox using the dropbox_upload_file action.

Example

In this example, we assume that the request content sent to the Webhook.site URL contains the following:

{\n\"files\": [\n{\n\"url\": \"https://example.com/path/980e683e-9bd7-4512-bc0e-acfd6e022a81\",\n\"name\": \"example_1.png\"\n},\n{\n\"url\": \"https://example.com/path/c8e1282f-46a7-45ab-9699-0472ff9ab96c\",\n\"name\": \"example_2.png\"\n}\n]\n}\n

In the script, the request contents are JSON decoded and looped over. For each item, the file's URL is downloaded and a Dropbox Upload File action is executed.

files = json_path(var('request.content'), '.files.*')\nfor (file_info in files) {\n// Download file from URL\nfile_download = request(file_info['url'])\n// Generate a destination path for the Dropbox file\ndestination_path = '/Example Files/%s'.format(file_info['name'])\n// Execute Dropbox Upload File action\naction(\n'dropbox_upload_file',\n[\n'path': destination_path,\n'body': file_download['content'],\n'mode': 'update',\n'provider_id': providerId\n]\n)\n}\n
"},{"location":"webhookscript/functions/flow.html#delayint-seconds-string-code-deprecated","title":"delay(int seconds, string code) [deprecated]","text":"

Warning

This function has been deprecated and should no longer be used. As an alternative, it's recommended that you mark a WebhookScript Custom Action as Queued. More info here.

Executes code in the future. Any output will be stored on the request and will show with a \"Was delayed\" label.

The code will not inherit the execution scope.

In this example, the format function is used to prepare the code string with a URL, causing {} to be replaced with with https://example.com.

code = '\n  request(\n      \"{}\",\n      \\'{\"message\": \"Hello World!\"}\\',\n      \"POST\"\n  )\n'\nurl = 'https://example.com'\ndelay(5, code.format(url));\n

The maximum amount of seconds allowed is 604800 (7 days).

"},{"location":"webhookscript/functions/flow.html#dont_save","title":"dont_save()","text":"

Marks the request so it is not saved in Webhook.site, which is useful when receiving a large amount of requests. The request can still be seen when it comes in, but will not be available through through the app later, or through the API. The action is useful in cases where e.g. a URL receive a large amount of requests.

"},{"location":"webhookscript/functions/flow.html#execstring-code-any","title":"exec(string code) : any","text":"

Executes code in code and returns the result. The code will inherit the execution scope.

"},{"location":"webhookscript/functions/flow.html#importstring-url-any","title":"import(string url) : any","text":"

Downloads code located at url and returns the result. The code will inherit the execution scope.

As an example, this can be used if you want to re-use code. Just upload it to a server or e.g. Github and use it in different WebhookScript actions.

result = import('https://raw.githubusercontent.com/webhooksite/scripts/ec22946a83ea85f607fcc6bff83f9d81ed2fe4ed/hello_world.ws')\necho(result) // value\n
"},{"location":"webhookscript/functions/flow.html#stop","title":"stop()","text":"

Stops Custom Action execution.

"},{"location":"webhookscript/functions/flow.html#responses","title":"Responses","text":""},{"location":"webhookscript/functions/flow.html#respondstring-content-int-status-array-headers","title":"respond(string content, int status, array headers)","text":"

Stops Custom Action execution and return a response immediately.

"},{"location":"webhookscript/functions/flow.html#set_contentstring-content","title":"set_content(string content)","text":"

Sets or overwrites the response content of the URL. Script execution continues.

"},{"location":"webhookscript/functions/flow.html#set_headerstring-header_name-string-header_value","title":"set_header(string header_name, string header_value)","text":"

Sets or overwrites a response header of the URL. Script execution continues.

"},{"location":"webhookscript/functions/flow.html#set_responsestring-content-int-status-array-headers","title":"set_response(string content, int status, array headers)","text":"

Sets or overwrites response content, status and headers in single function. Script execution continues.

headers should be an array of strings e.g. [\"X-Example: Value\", \"X-Foo: Bar\"].

"},{"location":"webhookscript/functions/flow.html#set_statusnumber-status","title":"set_status(number status)","text":"

Sets or overwrites the HTTP response status of the current URL. Script execution continues.

"},{"location":"webhookscript/functions/general.html","title":"General","text":""},{"location":"webhookscript/functions/general.html#about-functions","title":"About Functions","text":"

These are the functions that can be used in your script, and includes various utility functions and functions to interact with your Webhook.site URL.

"},{"location":"webhookscript/functions/general.html#chaining","title":"Chaining","text":"

Functions can be chained directly to a primitive (strings, numbers, arrays).

These two statements are equivalent:

'Hello World'.echo()\n
echo('Hello World')\n

They can even be chained, for example:

'Hello World'.hash('md5').echo() 

Furthermore, functions that begin in a type can be referenced without it, for example, when calling the format function with the first argument being a string, the language infers that actually the string_format function should be used.

echo(string_format('hello %s', 'world')) // hello world\n'hello %s'.format('world').echo() // hello world\n

Read more about functions in the reference.

"},{"location":"webhookscript/functions/general.html#custom-functions","title":"Custom functions","text":"

Define your own functions like this:

function sub(a, b) {\nreturn a - b;\n}\n

Read more about functions in the reference.

"},{"location":"webhookscript/functions/general.html#debugging-and-output","title":"Debugging and output","text":""},{"location":"webhookscript/functions/general.html#echostring-string","title":"echo(...string string)","text":"

Adds string to script debug output.

"},{"location":"webhookscript/functions/general.html#ddany-value","title":"dd(...any value)","text":"

Stops Custom Action execution and adds value to script debug output.

"},{"location":"webhookscript/functions/general.html#dumpany-value","title":"dump(...any value)","text":"

Adds value as a decoded string to script debug output.

"},{"location":"webhookscript/functions/general.html#types","title":"Types","text":""},{"location":"webhookscript/functions/general.html#typeany-value-string","title":"type(any value) : string","text":"

Returns the type name of a value, e.g. \"string\".

"},{"location":"webhookscript/functions/math.html","title":"Math and Numbers","text":""},{"location":"webhookscript/functions/math.html#trigonometry","title":"Trigonometry","text":""},{"location":"webhookscript/functions/math.html#atannumber-number-number","title":"atan(number number) : number","text":""},{"location":"webhookscript/functions/math.html#cosnumber-number-number","title":"cos(number number) : number","text":""},{"location":"webhookscript/functions/math.html#sinnumber-number-number","title":"sin(number number) : number","text":""},{"location":"webhookscript/functions/math.html#tannumber-number-number","title":"tan(number number) : number","text":""},{"location":"webhookscript/functions/math.html#hexadecimal-binary","title":"Hexadecimal & Binary","text":""},{"location":"webhookscript/functions/math.html#bin2hexstring-data-string","title":"bin2hex(string data): string","text":"

Converts a binary tring to a hexadecimal representation.

"},{"location":"webhookscript/functions/math.html#hex2binstring-hex_string-string","title":"hex2bin(string hex_string) : ?string","text":""},{"location":"webhookscript/functions/math.html#num2hexnumber-number-string","title":"num2hex(number number) : string","text":""},{"location":"webhookscript/functions/math.html#hex2numstring-hex_string-number","title":"hex2num(string hex_string) : number","text":""},{"location":"webhookscript/functions/math.html#general","title":"General","text":""},{"location":"webhookscript/functions/math.html#absnumber-number-number","title":"abs(number number) : number","text":""},{"location":"webhookscript/functions/math.html#ceilnumber-number-number","title":"ceil(number number) : number","text":"

Rounds a number up to nearest integer.

"},{"location":"webhookscript/functions/math.html#floornumber-number-number","title":"floor(number number) : number","text":"

Rounds a number down to nearest integer.

"},{"location":"webhookscript/functions/math.html#is_numericany-value-bool","title":"is_numeric(any value) : bool","text":"

Returns true if value is numeric.

Examples:

  • 12345 returns true.
  • \"1.0\" returns true.
  • null returns false.
"},{"location":"webhookscript/functions/math.html#maxarray-numbers-number","title":"max(array numbers) : number","text":""},{"location":"webhookscript/functions/math.html#minarray-numbers-number","title":"min(array numbers) : number","text":""},{"location":"webhookscript/functions/math.html#modnumber-number-number-divisor-number","title":"mod(number number, number divisor) : number","text":"

Returns the remainder after number is divided by divisor.

"},{"location":"webhookscript/functions/math.html#number_lengthnumber-number-number","title":"number_length(number number) : number","text":""},{"location":"webhookscript/functions/math.html#pi-number","title":"pi() : number","text":"

Returns the value of Pi.

"},{"location":"webhookscript/functions/math.html#pownumber-number-number-power-number","title":"pow(number number, number power) : number","text":""},{"location":"webhookscript/functions/math.html#randnumber-min-number-max-number","title":"rand(number min, number max) : number","text":"

Returns a random number between min and max.

"},{"location":"webhookscript/functions/math.html#roundnumber-number-number-precision-number","title":"round(number number, number precision) : number","text":"

Rounds a number up with specified precision (number of digits after decimal point.)

round(1.39, 1) // -> 1.4\n
"},{"location":"webhookscript/functions/math.html#sqrtnumber-number-number","title":"sqrt(number number) : number","text":""},{"location":"webhookscript/functions/math.html#to_numberany-value-number","title":"to_number(any value) : number","text":""},{"location":"webhookscript/functions/network.html","title":"Network and HTTP","text":""},{"location":"webhookscript/functions/network.html#http","title":"HTTP","text":""},{"location":"webhookscript/functions/network.html#queryarray-form_values-string","title":"query(array form_values) : string","text":"

Converts an associative array into a form-style string, used for e.g. application/x-www-form-urlencoded requests or HTTP query strings.

query(['country': 'Cura\u00e7ao', 'population': 158665]) // country=Cura%C3%A7ao&population=158665\n
"},{"location":"webhookscript/functions/network.html#httpstring-url-array-options-array","title":"http(string url, array options) : array","text":"

Sends a HTTP request and returns an array with the following keys containing response data:

  • content (contains a cURL error message in case of an error)
  • status (null in case of an error)
  • headers
  • url
"},{"location":"webhookscript/functions/network.html#options-array","title":"Options array","text":"

The options array can contain the following keys; none are required.

  • mode - string, one of: text (default), multipart, urlencoded, forward
  • content - string, body content, used when mode is text
  • method - string, HTTP method, e.g. POST
  • multipart - array of arrays, used when mode is multipart, containing keys:
    • name - required, string, form item name
    • filename - string
    • content-type - string
    • content - string
  • urlencoded - array of arrays, used when mode is urlencoded, containing keys:
    • name - required, string, form item name
    • value - string
  • headers - array of strings, HTTP headers
  • skip_ssl_verification - default false, skips TLS/SSL certificiate validation for HTTPS requests
  • timeout - number, default 5, timeout in seconds
"},{"location":"webhookscript/functions/network.html#post-request","title":"POST Request","text":"

To send a simple POST request containing e.g. JSON data, use the following:

http(\n'https://example.com',\n[\n'method': 'POST', 'content': '{\"example\": \"json\"}', 'headers': ['Content-Type: application/json']\n]\n)\n
"},{"location":"webhookscript/functions/network.html#formmultipart-request","title":"form/multipart request","text":"
http(\n'https://example.com', [\n'method': 'POST',\n'mode': 'multipart', 'multipart': [\n[\n'name': 'value1',\n'content': 'This is a value',\n]\n]\n]\n)\n
"},{"location":"webhookscript/functions/network.html#requeststring-url-string-body-string-method-get-array-headers-bool-override-false-timeout-5-array","title":"request(string url, string body, string method = 'GET', array headers, bool override = false, timeout = 5) : array","text":"

Sends a HTTP request and returns an array with the following keys containing response data:

  • content (contains a cURL error message in case of an error)
  • status (null in case of an error)
  • headers
  • url

The headers should be an array of strings, for example:

[\n'Content-Type: application/json',\n'Accept: application/json, text/plain, */*'\n]\n

To get a JSON document, validate if valid JSON, and get a property:

response = request('https://example.com')\ndecoded = json_decode(response['content'])\nif (decoded) {\nvalue = decoded['value']\n}\n

If override is set to true, none of the content from the original request is included (e.g. query strings, headers, content.)

"},{"location":"webhookscript/functions/network.html#multipartstring-url-array-items-string-method-post-array-headers-num-timeout-array","title":"multipart(string url, array items, string method = 'POST', array headers, num timeout) : array","text":"

Sends a HTTP Multipart request, e.g. for uploading files.

name (the form name value) and content are required in the items array; the rest is optional.

timeout specifies the request timeout in seconds.

The return value is an array with the following keys containing response data:

  • content (contains a cURL error message in case of an error)
  • status (null in case of an error)
  • headers
  • url

Example:

multipart(\n'https://example.com/file-upload', [\n[\n'name': 'file[]',\n'filename': 'file1.txt',\n'content': 'hello world',\n'headers': ['Header1': 'value', 'Header2': 'othervalue']\n],\n[\n'name': 'client_id',\n'content': 'abcd123',\n]\n],\n'POST',\n['Api-Key: xxxx']\n)\n
"},{"location":"webhookscript/functions/network.html#url_decodestring-value-string","title":"url_decode(string value) : string","text":"

Returns an URL-decoded version of value.

"},{"location":"webhookscript/functions/network.html#url_encodestring-value-string","title":"url_encode(string value) : string","text":"

Returns an URL-encoded version of value.

url_encode('here\\'s a value') // here%27s+a+value\n
"},{"location":"webhookscript/functions/string.html","title":"Strings","text":""},{"location":"webhookscript/functions/string.html#general-string-functions","title":"General string functions","text":""},{"location":"webhookscript/functions/string.html#string_containsstring-subject-numberstringregex-value-bool","title":"string_contains(string subject, number/string/regex value) : bool","text":"

Returns boolean if subject contains value

"},{"location":"webhookscript/functions/string.html#string_find_firststring-subject-numberstring-value-number","title":"string_find_first(string subject, number/string value) : number","text":"

Returns position of value in subject, or false if not found

"},{"location":"webhookscript/functions/string.html#string_find_laststring-subject-numberstring-value-number","title":"string_find_last(string subject, number/string value) : number","text":"

Returns position of value in subject, or false if not found

"},{"location":"webhookscript/functions/string.html#string_formatstring-formatstring-any-items-string","title":"string_format(string formatString, ...any items) : string","text":"

Sprintf-like formatting of formatString with items, see PHP sprintf docs.

"},{"location":"webhookscript/functions/string.html#string_joinstring-subject-array-items-numberstringboolarray-string","title":"string_join(string subject, array items (number/string/bool/array)) : string","text":"

Joins items with string subject

"},{"location":"webhookscript/functions/string.html#string_lengthstring-string-number","title":"string_length(string string) : number","text":"

Returns length of string (multibyte-aware)

"},{"location":"webhookscript/functions/string.html#string_lowerstring-string-string","title":"string_lower(string string) : string","text":"

Converts string to lowercase (multibyte-aware)

"},{"location":"webhookscript/functions/string.html#string_number_ofstring-string-number","title":"string_number_of(string string) : number","text":"

Returns number value of string

"},{"location":"webhookscript/functions/string.html#string_randomnumber-length-string","title":"string_random(number length) : string","text":"

Returns a random string of length using the A\u2013Z,a\u2013z,0\u20139 alphabet.

"},{"location":"webhookscript/functions/string.html#string_replacestring-subject-stringregexarray-search-string-replace-string","title":"string_replace(string subject, string/regex/array search, string replace) : string","text":"

Replaces string search with replace found in subject.

string_replace('this is a sentence', 'sentence', 'string') // -> this is a string\nstring_replace('this is great', r'(.*) is (.*)', '$1 was $2') // -> this was great\n
"},{"location":"webhookscript/functions/string.html#string_replacestring-subject-array-replace_pairs-string","title":"string_replace(string subject, array replace_pairs) : string","text":"

Replaces items found in subject using the replace_pairs array:

string_replace(\"hello, it's good\", [\n'hello': 'hi',\n'good': 'great'\n]) // -> hi, it's great\n
"},{"location":"webhookscript/functions/string.html#string_reversestring-subject-string","title":"string_reverse(string subject) : string","text":"

Reverses string subject

"},{"location":"webhookscript/functions/string.html#string_slicestring-subject-number-from-number-to-null-string","title":"string_slice(string subject, number from, number to = null) : string","text":"

Extracts a segment of a string. Multibyte-aware.

string_slice('hello world', 0, 5) returns hello.

string_slice('hello world', 6) returns world.

"},{"location":"webhookscript/functions/string.html#string_shufflestring-string-string","title":"string_shuffle(string string) : string","text":"

Returns string where the individual characters has been shuffled.

"},{"location":"webhookscript/functions/string.html#string_splitstring-subject-stringregex-delimiter-array","title":"string_split(string subject, string/regex delimiter) : array","text":"

Returns array of split string subject with delimiter

"},{"location":"webhookscript/functions/string.html#string_titlestring-string-string","title":"string_title(string string) : string","text":"

Returns string converted to title case.

string_title('hello world') returns Hello World.

"},{"location":"webhookscript/functions/string.html#string_upperstring-string-string","title":"string_upper(string string) : string","text":"

Converts string to UPPERCASE (multibyte-aware).

"},{"location":"webhookscript/functions/string.html#to_regexstring-regex-regex","title":"to_regex(string regex) : regex","text":"

Converts a regex string to a regex type

"},{"location":"webhookscript/functions/string.html#to_stringstringnumberbool-value-string","title":"to_string(string/number/bool value) : string","text":"

Returns value as string

"},{"location":"webhookscript/functions/string.html#trimstring-string-string","title":"trim(string string): string","text":"

Returns string with space, tab and newline characters removed from the beginning and end of the string.

"},{"location":"webhookscript/functions/string.html#uuid-string","title":"uuid() : string","text":"

Returns a random v4 UUID.

"},{"location":"webhookscript/functions/string.html#csv","title":"CSV","text":""},{"location":"webhookscript/functions/string.html#csv_to_arraystring-content-string-delimiter-int-header_offset-string-enclosure-string-escape-array","title":"csv_to_array(string content, string delimiter, ?int header_offset, string enclosure, string escape) : array","text":"

Takes a CSV string and outputs to an array, with each row being an item in the array.

  • content should be a string containing the CSV document.
  • delimiter will explicitly set the CSV delimiter the parser will attempt to use (e.g. ;). Must be a single character. Defaults to , (comma.)
  • header_offset, when specified, causes the output array item's keys to be set to the header values. Setting to 0 will mark the first row as the header row.
  • enclosure sets the field enclosure character. Must be a single character. Defaults to \" (double quote.)
  • escape sets the field escape character. Must be a single character. Defaults to \\ (backslash.)
csv_content = 'firstname,lastname,title\n\"M. J.\",Plumley,\"Sr. Developer\"\nEmily,\"Jenna Platt\",\"Chief Information Officer\"'\narray = csv_to_array(csv_content, ',', 0)\necho(json_encode(array))\n// [\n//     {\n//         \"firstname\": \"John\",\n//         \"lastname\": \"Doe\",\n//         \"title\": \"Sr. Developer\"\n//     },\n//     {\n//         \"firstname\": \"Emily\",\n//         \"lastname\": \"Jenna Platt\",\n//         \"title\": \"Chief Information Officer\"\n//     }\n// ]\n
"},{"location":"webhookscript/functions/string.html#base64","title":"Base64","text":""},{"location":"webhookscript/functions/string.html#base64_decodestring-string-string","title":"base64_decode(string string) : string","text":"

Returns a base64-decoded string.

"},{"location":"webhookscript/functions/string.html#base64url_decodestring-string-string","title":"base64url_decode(string string) : string","text":"

Returns a base64url-decoded string.

If the base64 string was encoded using URL-friendly base64url format, this function should be used rather the regular base64_decode function.

"},{"location":"webhookscript/functions/string.html#base64_encodestring-string-string","title":"base64_encode(string string) : string","text":"

Returns base64-encoded string.

"},{"location":"webhookscript/functions/string.html#base64url_encodestring-string-string","title":"base64url_encode(string string) : string","text":"

Returns a URL-friendly base64url-encoded string, where characters +, / have been replaced by - and _, and any = padding characters have been removed.

"},{"location":"webhookscript/functions/string.html#hashing","title":"Hashing","text":""},{"location":"webhookscript/functions/string.html#hashstringnumber-value-string-algo-string","title":"hash(string/number value, string algo) : string","text":"

Returns a hashed version of value using the algo algorithm.

'hello world'.hash('md5')  // 5eb63bbbe01eeed093cb22bb8f5acdc3\n

The following built-in algorithms are available: md2, md4, md5, sha1, sha224, sha256, sha384, sha512/224, sha512/256, sha512, sha3-224, sha3-256, sha3-384, sha3-512, ripemd128, ripemd160, ripemd256, ripemd320, whirlpool, tiger128,3, tiger160,3, tiger192,3, tiger128,4, tiger160,4, tiger192,4, snefru, snefru256, gost, gost-crypto, adler32, crc32, crc32b, fnv132, fnv1a32, fnv164, fnv1a64, joaat, haval128,3, haval160,3, haval192,3, haval224,3, haval256,3, haval128,4, haval160,4, haval192,4, haval224,4, haval256,4, haval128,5, haval160,5, haval192,5, haval224,5, haval256,5.

"},{"location":"webhookscript/functions/string.html#hmacstring-value-string-algo-string-secret-string","title":"hmac(string value, string algo, string secret) : string","text":"

Returns the calculated message digest/hash in a hexadecimal formatted as a string.

For a list of possible values for algo, see hash() above.

See also binary and hexadecimal conversion functions.

In the following example, the hash needs to be converted to binary, and then to base64, to match the signature.

hmac = hmac(var('request.content'), 'sha256', 'insert_secret_here');\nsignature = var('request.header.x-signature', '');\nhash = base64_encode(hex2bin(hmac))\nif (hash != signature) {\nrespond('Unauthorized', 401);\n}\n
"},{"location":"webhookscript/functions/string.html#cryptography","title":"Cryptography","text":"

List of available algorithms for functions in the Cryptography section:

  • blake2b512
  • blake2s256
  • md4
  • md5
  • md5-sha1
  • ripemd160
  • sha1
  • sha224
  • sha256
  • sha3-224
  • sha3-256
  • sha3-384
  • sha3-512
  • sha384
  • sha512
  • sha512-224
  • sha512-256
  • shake128
  • shake256
  • sm3
  • whirlpool
"},{"location":"webhookscript/functions/string.html#signstring-value-string-private_key-string-algo-falsestring","title":"sign(string value, string private_key, string algo) : false/string","text":"

Signs value using private_key and algo. Returns signature on success, false on failure.

For an example using sign() for JWT authorization, see here.

"},{"location":"webhookscript/functions/string.html#digeststring-value-string-algo-falsestring","title":"digest(string value, string algo) : false/string","text":"

Returns a cryptographic digest of value using algo. Returns false on failure.

"},{"location":"webhookscript/functions/string.html#verifystring-value-string-signature-string-public_key-string-algo-truefalse","title":"verify(string value, string signature, string public_key, string algo) : true/false","text":"

Verifies value using signature, public_key and algo

"},{"location":"webhookscript/functions/string.html#html-and-markdown","title":"HTML and Markdown","text":""},{"location":"webhookscript/functions/string.html#html_strip_tagsstring-string-string","title":"html_strip_tags(string string) : string","text":"

Returns a string with all HTML tags removed.

html_strip_tags('<b>test</b>') returns test.

"},{"location":"webhookscript/functions/string.html#html_to_textstring-string-string","title":"html_to_text(string string) : string","text":"

Converts HTML to plaintext. A more aggressive version of html_strip_tags.

html_to_text('<b>test</b>') returns test.

"},{"location":"webhookscript/functions/string.html#html_decodestring-string-string","title":"html_decode(string string) : string","text":"

Decodes all HTML entities (for example, &nbsp;) to normal characters.

"},{"location":"webhookscript/functions/string.html#html_encodestring-string-string","title":"html_encode(string string) : string","text":"

Replaces characters in a string with HTML encoded versions.

"},{"location":"webhookscript/functions/string.html#markdown_to_htmlstring-string-bool-safe_mode-false-string","title":"markdown_to_html(string string, bool safe_mode = false) : string","text":"

Converts a Markdown string to HTML.

markdown_to_html('# Hello world') returns <h1>Hello world</h1>.

If safe_mode is set to true, characters like <, > are HTML-entity encoded.

"},{"location":"webhookscript/functions/string.html#json","title":"JSON","text":""},{"location":"webhookscript/functions/string.html#json_decodestring-json-array","title":"json_decode(string json) : array","text":"

Decodes json and returns an array.

array = json_decode(var('request.content'))\n
"},{"location":"webhookscript/functions/string.html#json_encodearray-array-bool-format-true-string","title":"json_encode(array array, bool format = true) : string","text":"

Takes an array and encodes it as a JSON string.

Per default, the JSON array is formatted with whitespace. To turn it off, set format to false.

"},{"location":"webhookscript/functions/string.html#json_pathstring-json-string-jsonpath-bool-return_first-true-string","title":"json_path(string json, string jsonpath, bool return_first = true) : string","text":"

Returns the result of a json string parsed using the JSONPath functionality.

Per default, if there's just one match (e.g. if matching on a property value that's a string), this value is returned. To always return an array, set return_first to false.

dump(json_path('{\"v\": []}', 'v[*]', false))\ndump(json_path('{\"v\": []}', 'v[*]'))\n// []\n// \"\"\ndump(json_path('{\"v\": [\"item1\"]}', 'v[*]', false))\ndump(json_path('{\"v\": [\"item1\"]}', 'v[*]'))\n// [0: \"item1\"]\n// \"item1\"\ndump(json_path('{\"v\": [\"item1\", \"item2\"]}', 'v[*]', false))\ndump(json_path('{\"v\": [\"item1\", \"item2\"]}', 'v[*]'))\n// [0: \"item1\", 1: \"item2\"]\n// [0: \"item1\", 1: \"item2\"]\n
"},{"location":"webhookscript/functions/string.html#json_escapestring-json-string","title":"json_escape(string json) : string","text":"

JSON-escapes all special JSON characters like double quotes, newlines, etc.

"},{"location":"webhookscript/functions/string.html#regex","title":"Regex","text":""},{"location":"webhookscript/functions/string.html#preg_matchstring-regex-string-subject-arrayfalse","title":"preg_match(string regex, string subject) : array/false","text":"

Returns the matching values as an array, or false if the regex did not match. Supports regex pattern modifiers.

// Returns anything enclosed within <html> tags in a string\nhtml = preg_match('/<html>(.*)<\\\\/html>/s', content)\n
"},{"location":"webhookscript/functions/string.html#regex_extractregex-regex-string-subject-arrayfalse","title":"regex_extract(regex regex, string subject) : array/false","text":"

Returns the matching string and all match groups as an array, and false on failure.

input = \"You're a good bot\"\noutput = regex_extract(r\"You're (\\w) (.*)\", input)\ndump(output) // [0: \"You're a good bot\", 1: \"a\", 2: \"good bot\"]\n
"},{"location":"webhookscript/functions/string.html#regex_extract_firstregex-regex-string-subject-any-default-stringfalse","title":"regex_extract_first(regex regex, string subject, any default) : string/false","text":"

Returns the first match group of a regex, and false (or default, if set) on failure.

input = \"You're a good bot\"\noutput = regex_extract(r\"You're (.*)\", input)\ndump(output) // \"a good bot\"\ninput = \"Hello world\"\noutput = regex_extract(r\"You're (.*)\", input, 'no value')\ndump(output) // \"no value\"\n
"},{"location":"webhookscript/functions/string.html#regex_matchregex-regex-string-subject-stringfalse","title":"regex_match(regex regex, string subject) : string/false","text":"

Returns the first matching string, otherwise false.

input = \"You're a good bot\"\noutput = regex_match(r\"You're .*\", input)\ndump(output) // \"You're a good bot\"\n
"},{"location":"webhookscript/functions/string.html#regex_to_stringregex-regex-string","title":"regex_to_string(regex regex) : string","text":"

Returns the regex converted to a string

"},{"location":"webhookscript/functions/string.html#xml","title":"XML","text":""},{"location":"webhookscript/functions/string.html#xml2arraystring-xml-array","title":"xml2array(string xml) : array","text":"

Converts XML to a WebhookScript array. This can be useful for parsing XML, or e.g. converting XML to JSON.

Note that this function is opinionated - there's no one way to convert XML to an array as XML has more features than WebhookScript arrays. Therefore the function attempts to carry over all the data by automatically generating properties like @value and @attributes depending on the input data.

For example, the following XML:

<orders>\n<record>\n<Name type=\"full\">John Doe</Name>\n<Reference>49690</Reference>\n</record>\n<record>\n<Name type=\"username\">someone@example.com</Name>\n<Reference>49690</Reference>\n</record>\n</orders>\n

Converts to JSON via the following script:

json_encode(xml2array(var('request.content')))\n

Which returns:

{\n\"orders\": {\n\"record\": [\n{\n\"Name\": {\n\"@value\": \"John Doe\",\n\"@attributes\": {\n\"type\": \"full\"\n}\n},\n\"Reference\": 49690\n},\n{\n\"Name\": {\n\"@value\": \"someone@example.com\",\n\"@attributes\": {\n\"type\": \"username\"\n}\n},\n\"Reference\": 49690\n}\n]\n}\n}\n
"},{"location":"webhookscript/functions/string.html#xpathstring-xpath-string-input-stringnull","title":"xpath(string xpath, string input): string/null","text":"

Returns the first result of an XPath query on XML document input.

Given a request with the following content:

<?xml version=\"1.0\"?>\n<organization name=\"ExampleCo\">\n<employees>\n<employee id=\"1\">Jack</employee>\n<employee id=\"2\">Ann</employee>\n</employees>\n</organization>\n
  • xpath(var('$request.content$'), '//employee[1]') // returns \"Jack\"
  • var('$request.content$').xpath('//employee[1]') // returns \"Jack\"

More information and examples regarding XPath.

"},{"location":"webhookscript/functions/string.html#xpath_allstring-xpath-string-input-stringnull","title":"xpath_all(string xpath, string input): string/null","text":"

Returns the results of an XPath query on XML document input as an array.

Given a request with the following content:

<?xml version=\"1.0\"?>\n<organization name=\"ExampleCo\">\n<employees>\n<employee id=\"1\">Jack</employee>\n<employee id=\"2\">Ann</employee>\n</employees>\n</organization>\n
  • xpath_all(var('$request.content$'), '//employee]') // returns [0: \"Jack\", 1: \"Ann\"]
  • var('$request.content$').xpath('//employee') // returns [0: \"Jack\", 1: \"Ann\"]

More information and examples regarding XPath.

"},{"location":"webhookscript/functions/string.html#special-string-functions","title":"Special string functions","text":""},{"location":"webhookscript/functions/string.html#convert_kanastring-mode-string","title":"convert_kana(string, mode) : string","text":"

Performs a \"han-kaku\" - \"zen-kaku\" conversion for string string. This function is only useful for Japanese. See here for more info.

"},{"location":"webhookscript/functions/variables.html","title":"Custom Action Variables","text":"

These functions lets you interface with other Custom Actions by getting and setting variables from them. These functions are also how you retrieve Global Variables defined in the Control Panel.

"},{"location":"webhookscript/functions/variables.html#varstring-variable_name-stringnumber-default-mixed","title":"var(string variable_name, ?string/number default) : mixed","text":"

Retrieves the value of a Variable or Global Variable (defined in the Control Panel). The surrounding dollar signs are not mandatory.

Returns null (or the value of default) if the variable does not exist.

var('request.header.x-request-verification') // returns value of the `x-request-verification` header\n
"},{"location":"webhookscript/functions/variables.html#setstring-variable_name-string-variable_value","title":"set(string variable_name, string variable_value)","text":"

Exports a Variable for use in downstream actions, like the Set Runtime Variable action.

For example, the following code:

set('myvar', 'Hello world')\n

Would cause the string $myvar$ to be replaced with Hello world in all subsequent actions.

"},{"location":"webhookscript/functions/variables.html#storestring-global_variable_name-any-value-any","title":"store(string global_variable_name, any value): any","text":"

Permanently creates or updates a Global Variable (as defined in Control Panel.)

The value can also be retrieved with the var() function in subsequent action executions.

"},{"location":"webhookscript/functions/variables.html#deletestring-global_variable_name","title":"delete(string global_variable_name)","text":"

Deletes a global variable.

"},{"location":"webhookscript/functions/variables.html#variables-array","title":"variables : array","text":"

A variable (not a function) containing an associative array with all available Webhook.site variables.

user_agent = variables['request.header.user-agent']\n
"}]} \ No newline at end of file diff --git a/sitemap.xml b/sitemap.xml new file mode 100644 index 0000000..be350b0 --- /dev/null +++ b/sitemap.xml @@ -0,0 +1,208 @@ + + + + https://docs.webhook.site/index.html + 2024-04-24 + daily + + + https://docs.webhook.site/cli.html + 2024-04-24 + daily + + + https://docs.webhook.site/custom-actions.html + 2024-04-24 + daily + + + https://docs.webhook.site/dnshook.html + 2024-04-24 + daily + + + https://docs.webhook.site/faq.html + 2024-04-24 + daily + + + https://docs.webhook.site/jobs.html + 2024-04-24 + daily + + + https://docs.webhook.site/news.html + 2024-04-24 + daily + + + https://docs.webhook.site/open-source.html + 2024-04-24 + daily + + + https://docs.webhook.site/premium.html + 2024-04-24 + daily + + + https://docs.webhook.site/pro.html + 2024-04-24 + daily + + + https://docs.webhook.site/schedules.html + 2024-04-24 + daily + + + https://docs.webhook.site/api/about.html + 2024-04-24 + daily + + + https://docs.webhook.site/api/action-types.html + 2024-04-24 + daily + + + https://docs.webhook.site/api/custom-actions.html + 2024-04-24 + daily + + + https://docs.webhook.site/api/date-expressions.html + 2024-04-24 + daily + + + https://docs.webhook.site/api/examples.html + 2024-04-24 + daily + + + https://docs.webhook.site/api/global-variables.html + 2024-04-24 + daily + + + https://docs.webhook.site/api/groups.html + 2024-04-24 + daily + + + https://docs.webhook.site/api/requests.html + 2024-04-24 + daily + + + https://docs.webhook.site/api/schedules.html + 2024-04-24 + daily + + + https://docs.webhook.site/api/templates.html + 2024-04-24 + daily + + + https://docs.webhook.site/api/tokens.html + 2024-04-24 + daily + + + https://docs.webhook.site/custom-actions/action-types.html + 2024-04-24 + daily + + + https://docs.webhook.site/custom-actions/examples.html + 2024-04-24 + daily + + + https://docs.webhook.site/custom-actions/variables.html + 2024-04-24 + daily + + + https://docs.webhook.site/webhookscript/index.html + 2024-04-24 + daily + + + https://docs.webhook.site/webhookscript/date-format.html + 2024-04-24 + daily + + + https://docs.webhook.site/webhookscript/date-locales.html + 2024-04-24 + daily + + + https://docs.webhook.site/webhookscript/examples.html + 2024-04-24 + daily + + + https://docs.webhook.site/webhookscript/functions.html + 2024-04-24 + daily + + + https://docs.webhook.site/webhookscript/reference.html + 2024-04-24 + daily + + + https://docs.webhook.site/webhookscript/functions/array.html + 2024-04-24 + daily + + + https://docs.webhook.site/webhookscript/functions/bool.html + 2024-04-24 + daily + + + https://docs.webhook.site/webhookscript/functions/date.html + 2024-04-24 + daily + + + https://docs.webhook.site/webhookscript/functions/files.html + 2024-04-24 + daily + + + https://docs.webhook.site/webhookscript/functions/flow.html + 2024-04-24 + daily + + + https://docs.webhook.site/webhookscript/functions/general.html + 2024-04-24 + daily + + + https://docs.webhook.site/webhookscript/functions/math.html + 2024-04-24 + daily + + + https://docs.webhook.site/webhookscript/functions/network.html + 2024-04-24 + daily + + + https://docs.webhook.site/webhookscript/functions/string.html + 2024-04-24 + daily + + + https://docs.webhook.site/webhookscript/functions/variables.html + 2024-04-24 + daily + + \ No newline at end of file diff --git a/sitemap.xml.gz b/sitemap.xml.gz new file mode 100644 index 0000000..b37a50f Binary files /dev/null and b/sitemap.xml.gz differ diff --git a/stylesheets/extra.css b/stylesheets/extra.css new file mode 100644 index 0000000..89ee490 --- /dev/null +++ b/stylesheets/extra.css @@ -0,0 +1,93 @@ +:root { + --md-primary-bg-color: white; + --md-primary-fg-color: black; +} + +body, input { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + -webkit-font-smoothing: auto; +} + +.md-header-nav__topic { + font-weight: bold; +} + +.md-header__title, .md-header-nav__title { + font-size: 18px; + font-weight: 400; + color: #9d9d9d; + margin-left: 0; +} + +.md-header[data-md-state=shadow] { + box-shadow: none; +} + +/* NAV */ + +.md-sidebar--primary .md-nav__title { + display: none; +} + +.md-nav__link--active { + font-weight: bold; +} + + +/* BODY */ + +.md-typeset a { + text-decoration: underline; + color: #337ab7; +} + +.md-typeset code { + color: rgb(205, 0, 103); +} + +.md-typeset pre > code { + color: black; +} + +.md-typeset h1 { + font-size: 30px; + font-weight: 500; + color: black; + letter-spacing: normal; + border-bottom: 1px solid #eee; + padding-bottom: 10px; + line-height: 1.1; +} + +.md-typeset h2 { + border-bottom: 1px solid #eee; + margin-top: 2.5em; + margin-bottom: 1em; +} + +.md-typeset h3 { + font-weight: 600; + font-size: 0.95rem; +} + +.md-typeset h4 { + color: #7c7c7c; + text-transform: uppercase; + font-size: 0.7rem; + font-weight: 900; + margin-top: 1.2rem; +} + +.md-nav--primary > .md-nav__list > .md-nav__item:first-of-type { + margin-bottom: 30px; + opacity: .6; +} + +.md-nav__item--nested>.md-nav__link { + cursor: default; + color: #999; +} + +.md-nav__item--nested>.md-nav__link:hover { + color: #999; +} diff --git a/webhookscript.html b/webhookscript.html new file mode 100644 index 0000000..dc1535d --- /dev/null +++ b/webhookscript.html @@ -0,0 +1,15 @@ + + + + + + Redirecting... + + + + + + +Redirecting... + + diff --git a/webhookscript/date-format.html b/webhookscript/date-format.html new file mode 100644 index 0000000..708a3fa --- /dev/null +++ b/webhookscript/date-format.html @@ -0,0 +1,1820 @@ + + + + + + + + + + + + + + + + + + + + Date format characters - Webhook.site Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + + + + + + +

Date format characters

+

WebhookScript uses the ISO format for converting and formatting dates, and the format is compatible with the Moment.js format method.

+

The following examples are based on the date 2017-01-05 17:04:05.084512.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CodeExampleDescription
OD5Day number with alternative numbers such as 三 for 3 if locale is ja_JP
OM1Month number with alternative numbers such as ၀၂ for 2 if locale is my_MM
OY2017Year number with alternative numbers such as ۱۹۹۸ for 1998 if locale is fa
OH1724-hours number with alternative numbers such as ႑႓ for 13 if locale is shn_MM
Oh512-hours number with alternative numbers such as 十一 for 11 if locale is lzh_TW
Om4Minute number with alternative numbers such as ୫୭ for 57 if locale is or
Os5Second number with alternative numbers such as 十五 for 15 if locale is ja_JP
D5Day of month number (from 1 to 31)
DD05Day of month number with trailing zero (from 01 to 31)
Do5thDay of month with ordinal suffix (from 1st to 31th), translatable
d4Day of week number (from 0 (Sunday) to 6 (Saturday))
ddThMinified day name (from Su to Sa), transatable
dddThuShort day name (from Sun to Sat), transatable
ddddThursdayDay name (from Sunday to Saturday), transatable
DDD5Day of year number (from 1 to 366)
DDDD005Day of year number with trailing zeros (3 digits, from 001 to 366)
DDDo5thDay of year number with ordinal suffix (from 1st to 366th), translatable
e4Day of week number (from 0 (Sunday) to 6 (Saturday)), similar to "d" but this one is translatable (takes first day of week of the current locale)
E4Day of week number (from 1 (Monday) to 7 (Sunday))
H17Hour from 0 to 23
HH17Hour with trailing zero from 00 to 23
h5Hour from 0 to 12
hh05Hour with trailing zero from 00 to 12
k17Hour from 1 to 24
kk17Hour with trailing zero from 01 to 24
L04/09/1986Date (in local format)
LLSeptember 4 1986Month name, day of month, year
LLLSeptember 4 1986 8:30 PMMonth name, day of month, year, time
LLLLThursday, September 4 1986 8:30 PMDay of week, month name, day of month, year, time
LT8:30 PMTime (without seconds)
LTS8:30:00 PMTime (with seconds)
m4Minute from 0 to 59
mm04Minute with trailing zero from 00 to 59
apmMeridiem am/pm
APMMeridiem AM/PM
s5Second from 0 to 59
ss05Second with trailing zero from 00 to 59
S0Second tenth
SS08Second hundredth (on 2 digits with trailing zero)
SSS084Millisecond (on 3 digits with trailing zeros)
SSSS0845Second ten thousandth (on 4 digits with trailing zeros)
SSSSS08451Second hundred thousandth (on 5 digits with trailing zeros)
SSSSSS084512Microsecond (on 6 digits with trailing zeros)
SSSSSSS0845120Second ten millionth (on 7 digits with trailing zeros)
SSSSSSSS08451200Second hundred millionth (on 8 digits with trailing zeros)
SSSSSSSSS084512000Nanosecond (on 9 digits with trailing zeros)
M1Month from 1 to 12
MM01Month with trailing zero from 01 to 12
MMMJanShort month name, translatable
MMMMJanuaryMonth name, translatable
Mo1stMonth with ordinal suffix from 1st to 12th, translatable
Q1Quarter from 1 to 4
Qo1stQuarter with ordinal suffix from 1st to 4th, translatable
G2017ISO week year (see ISO week date)
GG2017ISO week year (on 2 digits with trailing zero)
GGG2017ISO week year (on 3 digits with trailing zeros)
GGGG2017ISO week year (on 4 digits with trailing zeros)
GGGGG02017ISO week year (on 5 digits with trailing zeros)
g2017Week year according to locale settings, translatable
gg2017Week year according to locale settings (on 2 digits with trailing zero), translatable
ggg2017Week year according to locale settings (on 3 digits with trailing zeros), translatable
gggg2017Week year according to locale settings (on 4 digits with trailing zeros), translatable
ggggg02017Week year according to locale settings (on 5 digits with trailing zeros), translatable
W1ISO week number in the year (see ISO week date)
WW01ISO week number in the year (on 2 digits with trailing zero)
Wo1stISO week number in the year with ordinal suffix, translatable
w1Week number in the year according to locale settings, translatable
ww01Week number in the year according to locale settings (on 2 digits with trailing zero)
wo1stWeek number in the year according to locale settings with ordinal suffix, translatable
x1483635845085Millisecond-precision timestamp (same as date.getTime() in JavaScript)
X1483635845Timestamp (number of seconds since 1970-01-01)
Y2017Full year from -9999 to 9999
YY17Year on 2 digits from 00 to 99
YYYY2017Year on 4 digits from 0000 to 9999
YYYYY02017Year on 5 digits from 00000 to 09999
YYYYYY+002017Year on 5 digits with sign from -09999 to +09999
zUTCAbbreviated time zone name
zzUTCTime zone name
Z+00:00Time zone offset HH:mm
ZZ+0000Time zone offset HHmm
+

Source: Carbon Docs

+

Timezone List

+
    +
  • Africa/Abidjan
  • +
  • Africa/Accra
  • +
  • Africa/Addis_Ababa
  • +
  • Africa/Algiers
  • +
  • Africa/Asmara
  • +
  • Africa/Bamako
  • +
  • Africa/Bangui
  • +
  • Africa/Banjul
  • +
  • Africa/Bissau
  • +
  • Africa/Blantyre
  • +
  • Africa/Brazzaville
  • +
  • Africa/Bujumbura
  • +
  • Africa/Cairo
  • +
  • Africa/Casablanca
  • +
  • Africa/Ceuta
  • +
  • Africa/Conakry
  • +
  • Africa/Dakar
  • +
  • Africa/Dar_es_Salaam
  • +
  • Africa/Djibouti
  • +
  • Africa/Douala
  • +
  • Africa/El_Aaiun
  • +
  • Africa/Freetown
  • +
  • Africa/Gaborone
  • +
  • Africa/Harare
  • +
  • Africa/Johannesburg
  • +
  • Africa/Juba
  • +
  • Africa/Kampala
  • +
  • Africa/Khartoum
  • +
  • Africa/Kigali
  • +
  • Africa/Kinshasa
  • +
  • Africa/Lagos
  • +
  • Africa/Libreville
  • +
  • Africa/Lome
  • +
  • Africa/Luanda
  • +
  • Africa/Lubumbashi
  • +
  • Africa/Lusaka
  • +
  • Africa/Malabo
  • +
  • Africa/Maputo
  • +
  • Africa/Maseru
  • +
  • Africa/Mbabane
  • +
  • Africa/Mogadishu
  • +
  • Africa/Monrovia
  • +
  • Africa/Nairobi
  • +
  • Africa/Ndjamena
  • +
  • Africa/Niamey
  • +
  • Africa/Nouakchott
  • +
  • Africa/Ouagadougou
  • +
  • Africa/Porto-Novo
  • +
  • Africa/Sao_Tome
  • +
  • Africa/Tripoli
  • +
  • Africa/Tunis
  • +
  • Africa/Windhoek
  • +
  • America/Adak
  • +
  • America/Anchorage
  • +
  • America/Anguilla
  • +
  • America/Antigua
  • +
  • America/Araguaina
  • +
  • America/Argentina/Buenos_Aires
  • +
  • America/Argentina/Catamarca
  • +
  • America/Argentina/Cordoba
  • +
  • America/Argentina/Jujuy
  • +
  • America/Argentina/La_Rioja
  • +
  • America/Argentina/Mendoza
  • +
  • America/Argentina/Rio_Gallegos
  • +
  • America/Argentina/Salta
  • +
  • America/Argentina/San_Juan
  • +
  • America/Argentina/San_Luis
  • +
  • America/Argentina/Tucuman
  • +
  • America/Argentina/Ushuaia
  • +
  • America/Aruba
  • +
  • America/Asuncion
  • +
  • America/Atikokan
  • +
  • America/Bahia
  • +
  • America/Bahia_Banderas
  • +
  • America/Barbados
  • +
  • America/Belem
  • +
  • America/Belize
  • +
  • America/Blanc-Sablon
  • +
  • America/Boa_Vista
  • +
  • America/Bogota
  • +
  • America/Boise
  • +
  • America/Cambridge_Bay
  • +
  • America/Campo_Grande
  • +
  • America/Cancun
  • +
  • America/Caracas
  • +
  • America/Cayenne
  • +
  • America/Cayman
  • +
  • America/Chicago
  • +
  • America/Chihuahua
  • +
  • America/Costa_Rica
  • +
  • America/Creston
  • +
  • America/Cuiaba
  • +
  • America/Curacao
  • +
  • America/Danmarkshavn
  • +
  • America/Dawson
  • +
  • America/Dawson_Creek
  • +
  • America/Denver
  • +
  • America/Detroit
  • +
  • America/Dominica
  • +
  • America/Edmonton
  • +
  • America/Eirunepe
  • +
  • America/El_Salvador
  • +
  • America/Fort_Nelson
  • +
  • America/Fortaleza
  • +
  • America/Glace_Bay
  • +
  • America/Goose_Bay
  • +
  • America/Grand_Turk
  • +
  • America/Grenada
  • +
  • America/Guadeloupe
  • +
  • America/Guatemala
  • +
  • America/Guayaquil
  • +
  • America/Guyana
  • +
  • America/Halifax
  • +
  • America/Havana
  • +
  • America/Hermosillo
  • +
  • America/Indiana/Indianapolis
  • +
  • America/Indiana/Knox
  • +
  • America/Indiana/Marengo
  • +
  • America/Indiana/Petersburg
  • +
  • America/Indiana/Tell_City
  • +
  • America/Indiana/Vevay
  • +
  • America/Indiana/Vincennes
  • +
  • America/Indiana/Winamac
  • +
  • America/Inuvik
  • +
  • America/Iqaluit
  • +
  • America/Jamaica
  • +
  • America/Juneau
  • +
  • America/Kentucky/Louisville
  • +
  • America/Kentucky/Monticello
  • +
  • America/Kralendijk
  • +
  • America/La_Paz
  • +
  • America/Lima
  • +
  • America/Los_Angeles
  • +
  • America/Lower_Princes
  • +
  • America/Maceio
  • +
  • America/Managua
  • +
  • America/Manaus
  • +
  • America/Marigot
  • +
  • America/Martinique
  • +
  • America/Matamoros
  • +
  • America/Mazatlan
  • +
  • America/Menominee
  • +
  • America/Merida
  • +
  • America/Metlakatla
  • +
  • America/Mexico_City
  • +
  • America/Miquelon
  • +
  • America/Moncton
  • +
  • America/Monterrey
  • +
  • America/Montevideo
  • +
  • America/Montserrat
  • +
  • America/Nassau
  • +
  • America/New_York
  • +
  • America/Nipigon
  • +
  • America/Nome
  • +
  • America/Noronha
  • +
  • America/North_Dakota/Beulah
  • +
  • America/North_Dakota/Center
  • +
  • America/North_Dakota/New_Salem
  • +
  • America/Nuuk
  • +
  • America/Ojinaga
  • +
  • America/Panama
  • +
  • America/Pangnirtung
  • +
  • America/Paramaribo
  • +
  • America/Phoenix
  • +
  • America/Port-au-Prince
  • +
  • America/Port_of_Spain
  • +
  • America/Porto_Velho
  • +
  • America/Puerto_Rico
  • +
  • America/Punta_Arenas
  • +
  • America/Rainy_River
  • +
  • America/Rankin_Inlet
  • +
  • America/Recife
  • +
  • America/Regina
  • +
  • America/Resolute
  • +
  • America/Rio_Branco
  • +
  • America/Santarem
  • +
  • America/Santiago
  • +
  • America/Santo_Domingo
  • +
  • America/Sao_Paulo
  • +
  • America/Scoresbysund
  • +
  • America/Sitka
  • +
  • America/St_Barthelemy
  • +
  • America/St_Johns
  • +
  • America/St_Kitts
  • +
  • America/St_Lucia
  • +
  • America/St_Thomas
  • +
  • America/St_Vincent
  • +
  • America/Swift_Current
  • +
  • America/Tegucigalpa
  • +
  • America/Thule
  • +
  • America/Thunder_Bay
  • +
  • America/Tijuana
  • +
  • America/Toronto
  • +
  • America/Tortola
  • +
  • America/Vancouver
  • +
  • America/Whitehorse
  • +
  • America/Winnipeg
  • +
  • America/Yakutat
  • +
  • America/Yellowknife
  • +
  • Antarctica/Casey
  • +
  • Antarctica/Davis
  • +
  • Antarctica/DumontDUrville
  • +
  • Antarctica/Macquarie
  • +
  • Antarctica/Mawson
  • +
  • Antarctica/McMurdo
  • +
  • Antarctica/Palmer
  • +
  • Antarctica/Rothera
  • +
  • Antarctica/Syowa
  • +
  • Antarctica/Troll
  • +
  • Antarctica/Vostok
  • +
  • Arctic/Longyearbyen
  • +
  • Asia/Aden
  • +
  • Asia/Almaty
  • +
  • Asia/Amman
  • +
  • Asia/Anadyr
  • +
  • Asia/Aqtau
  • +
  • Asia/Aqtobe
  • +
  • Asia/Ashgabat
  • +
  • Asia/Atyrau
  • +
  • Asia/Baghdad
  • +
  • Asia/Bahrain
  • +
  • Asia/Baku
  • +
  • Asia/Bangkok
  • +
  • Asia/Barnaul
  • +
  • Asia/Beirut
  • +
  • Asia/Bishkek
  • +
  • Asia/Brunei
  • +
  • Asia/Chita
  • +
  • Asia/Choibalsan
  • +
  • Asia/Colombo
  • +
  • Asia/Damascus
  • +
  • Asia/Dhaka
  • +
  • Asia/Dili
  • +
  • Asia/Dubai
  • +
  • Asia/Dushanbe
  • +
  • Asia/Famagusta
  • +
  • Asia/Gaza
  • +
  • Asia/Hebron
  • +
  • Asia/Ho_Chi_Minh
  • +
  • Asia/Hong_Kong
  • +
  • Asia/Hovd
  • +
  • Asia/Irkutsk
  • +
  • Asia/Jakarta
  • +
  • Asia/Jayapura
  • +
  • Asia/Jerusalem
  • +
  • Asia/Kabul
  • +
  • Asia/Kamchatka
  • +
  • Asia/Karachi
  • +
  • Asia/Kathmandu
  • +
  • Asia/Khandyga
  • +
  • Asia/Kolkata
  • +
  • Asia/Krasnoyarsk
  • +
  • Asia/Kuala_Lumpur
  • +
  • Asia/Kuching
  • +
  • Asia/Kuwait
  • +
  • Asia/Macau
  • +
  • Asia/Magadan
  • +
  • Asia/Makassar
  • +
  • Asia/Manila
  • +
  • Asia/Muscat
  • +
  • Asia/Nicosia
  • +
  • Asia/Novokuznetsk
  • +
  • Asia/Novosibirsk
  • +
  • Asia/Omsk
  • +
  • Asia/Oral
  • +
  • Asia/Phnom_Penh
  • +
  • Asia/Pontianak
  • +
  • Asia/Pyongyang
  • +
  • Asia/Qatar
  • +
  • Asia/Qostanay
  • +
  • Asia/Qyzylorda
  • +
  • Asia/Riyadh
  • +
  • Asia/Sakhalin
  • +
  • Asia/Samarkand
  • +
  • Asia/Seoul
  • +
  • Asia/Shanghai
  • +
  • Asia/Singapore
  • +
  • Asia/Srednekolymsk
  • +
  • Asia/Taipei
  • +
  • Asia/Tashkent
  • +
  • Asia/Tbilisi
  • +
  • Asia/Tehran
  • +
  • Asia/Thimphu
  • +
  • Asia/Tokyo
  • +
  • Asia/Tomsk
  • +
  • Asia/Ulaanbaatar
  • +
  • Asia/Urumqi
  • +
  • Asia/Ust-Nera
  • +
  • Asia/Vientiane
  • +
  • Asia/Vladivostok
  • +
  • Asia/Yakutsk
  • +
  • Asia/Yangon
  • +
  • Asia/Yekaterinburg
  • +
  • Asia/Yerevan
  • +
  • Atlantic/Azores
  • +
  • Atlantic/Bermuda
  • +
  • Atlantic/Canary
  • +
  • Atlantic/Cape_Verde
  • +
  • Atlantic/Faroe
  • +
  • Atlantic/Madeira
  • +
  • Atlantic/Reykjavik
  • +
  • Atlantic/South_Georgia
  • +
  • Atlantic/St_Helena
  • +
  • Atlantic/Stanley
  • +
  • Australia/Adelaide
  • +
  • Australia/Brisbane
  • +
  • Australia/Broken_Hill
  • +
  • Australia/Darwin
  • +
  • Australia/Eucla
  • +
  • Australia/Hobart
  • +
  • Australia/Lindeman
  • +
  • Australia/Lord_Howe
  • +
  • Australia/Melbourne
  • +
  • Australia/Perth
  • +
  • Australia/Sydney
  • +
  • Europe/Amsterdam
  • +
  • Europe/Andorra
  • +
  • Europe/Astrakhan
  • +
  • Europe/Athens
  • +
  • Europe/Belgrade
  • +
  • Europe/Berlin
  • +
  • Europe/Bratislava
  • +
  • Europe/Brussels
  • +
  • Europe/Bucharest
  • +
  • Europe/Budapest
  • +
  • Europe/Busingen
  • +
  • Europe/Chisinau
  • +
  • Europe/Copenhagen
  • +
  • Europe/Dublin
  • +
  • Europe/Gibraltar
  • +
  • Europe/Guernsey
  • +
  • Europe/Helsinki
  • +
  • Europe/Isle_of_Man
  • +
  • Europe/Istanbul
  • +
  • Europe/Jersey
  • +
  • Europe/Kaliningrad
  • +
  • Europe/Kiev
  • +
  • Europe/Kirov
  • +
  • Europe/Lisbon
  • +
  • Europe/Ljubljana
  • +
  • Europe/London
  • +
  • Europe/Luxembourg
  • +
  • Europe/Madrid
  • +
  • Europe/Malta
  • +
  • Europe/Mariehamn
  • +
  • Europe/Minsk
  • +
  • Europe/Monaco
  • +
  • Europe/Moscow
  • +
  • Europe/Oslo
  • +
  • Europe/Paris
  • +
  • Europe/Podgorica
  • +
  • Europe/Prague
  • +
  • Europe/Riga
  • +
  • Europe/Rome
  • +
  • Europe/Samara
  • +
  • Europe/San_Marino
  • +
  • Europe/Sarajevo
  • +
  • Europe/Saratov
  • +
  • Europe/Simferopol
  • +
  • Europe/Skopje
  • +
  • Europe/Sofia
  • +
  • Europe/Stockholm
  • +
  • Europe/Tallinn
  • +
  • Europe/Tirane
  • +
  • Europe/Ulyanovsk
  • +
  • Europe/Uzhgorod
  • +
  • Europe/Vaduz
  • +
  • Europe/Vatican
  • +
  • Europe/Vienna
  • +
  • Europe/Vilnius
  • +
  • Europe/Volgograd
  • +
  • Europe/Warsaw
  • +
  • Europe/Zagreb
  • +
  • Europe/Zaporozhye
  • +
  • Europe/Zurich
  • +
  • Indian/Antananarivo
  • +
  • Indian/Chagos
  • +
  • Indian/Christmas
  • +
  • Indian/Cocos
  • +
  • Indian/Comoro
  • +
  • Indian/Kerguelen
  • +
  • Indian/Mahe
  • +
  • Indian/Maldives
  • +
  • Indian/Mauritius
  • +
  • Indian/Mayotte
  • +
  • Indian/Reunion
  • +
  • Pacific/Apia
  • +
  • Pacific/Auckland
  • +
  • Pacific/Bougainville
  • +
  • Pacific/Chatham
  • +
  • Pacific/Chuuk
  • +
  • Pacific/Easter
  • +
  • Pacific/Efate
  • +
  • Pacific/Fakaofo
  • +
  • Pacific/Fiji
  • +
  • Pacific/Funafuti
  • +
  • Pacific/Galapagos
  • +
  • Pacific/Gambier
  • +
  • Pacific/Guadalcanal
  • +
  • Pacific/Guam
  • +
  • Pacific/Honolulu
  • +
  • Pacific/Kanton
  • +
  • Pacific/Kiritimati
  • +
  • Pacific/Kosrae
  • +
  • Pacific/Kwajalein
  • +
  • Pacific/Majuro
  • +
  • Pacific/Marquesas
  • +
  • Pacific/Midway
  • +
  • Pacific/Nauru
  • +
  • Pacific/Niue
  • +
  • Pacific/Norfolk
  • +
  • Pacific/Noumea
  • +
  • Pacific/Pago_Pago
  • +
  • Pacific/Palau
  • +
  • Pacific/Pitcairn
  • +
  • Pacific/Pohnpei
  • +
  • Pacific/Port_Moresby
  • +
  • Pacific/Rarotonga
  • +
  • Pacific/Saipan
  • +
  • Pacific/Tahiti
  • +
  • Pacific/Tarawa
  • +
  • Pacific/Tongatapu
  • +
  • Pacific/Wake
  • +
  • Pacific/Wallis
  • +
  • UTC
  • +
+ +
+
+ + + Last update: + April 6, 2024 10:34:57 + + + +
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/webhookscript/date-locales.html b/webhookscript/date-locales.html new file mode 100644 index 0000000..9d48c39 --- /dev/null +++ b/webhookscript/date-locales.html @@ -0,0 +1,1802 @@ + + + + + + + + + + + + + + + + + + + + List of available date function locales - Webhook.site Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + + + + + + +

List of available date function locales

+
    +
  • aa
  • +
  • aa_DJ
  • +
  • aa_ER
  • +
  • aa_ER@saaho
  • +
  • aa_ET
  • +
  • af
  • +
  • af_NA
  • +
  • af_ZA
  • +
  • agq
  • +
  • agr
  • +
  • agr_PE
  • +
  • ak
  • +
  • ak_GH
  • +
  • am
  • +
  • am_ET
  • +
  • an
  • +
  • an_ES
  • +
  • anp
  • +
  • anp_IN
  • +
  • ar
  • +
  • ar_AE
  • +
  • ar_BH
  • +
  • ar_DJ
  • +
  • ar_DZ
  • +
  • ar_EG
  • +
  • ar_EH
  • +
  • ar_ER
  • +
  • ar_IL
  • +
  • ar_IN
  • +
  • ar_IQ
  • +
  • ar_JO
  • +
  • ar_KM
  • +
  • ar_KW
  • +
  • ar_LB
  • +
  • ar_LY
  • +
  • ar_MA
  • +
  • ar_MR
  • +
  • ar_OM
  • +
  • ar_PS
  • +
  • ar_QA
  • +
  • ar_SA
  • +
  • ar_SD
  • +
  • ar_SO
  • +
  • ar_SS
  • +
  • ar_SY
  • +
  • ar_Shakl
  • +
  • ar_TD
  • +
  • ar_TN
  • +
  • ar_YE
  • +
  • as
  • +
  • as_IN
  • +
  • asa
  • +
  • ast
  • +
  • ast_ES
  • +
  • ayc
  • +
  • ayc_PE
  • +
  • az
  • +
  • az_AZ
  • +
  • az_Cyrl
  • +
  • az_IR
  • +
  • az_Latn
  • +
  • bas
  • +
  • be
  • +
  • be_BY
  • +
  • be_BY@latin
  • +
  • bem
  • +
  • bem_ZM
  • +
  • ber
  • +
  • ber_DZ
  • +
  • ber_MA
  • +
  • bez
  • +
  • bg
  • +
  • bg_BG
  • +
  • bhb
  • +
  • bhb_IN
  • +
  • bho
  • +
  • bho_IN
  • +
  • bi
  • +
  • bi_VU
  • +
  • bm
  • +
  • bn
  • +
  • bn_BD
  • +
  • bn_IN
  • +
  • bo
  • +
  • bo_CN
  • +
  • bo_IN
  • +
  • br
  • +
  • br_FR
  • +
  • brx
  • +
  • brx_IN
  • +
  • bs
  • +
  • bs_BA
  • +
  • bs_Cyrl
  • +
  • bs_Latn
  • +
  • byn
  • +
  • byn_ER
  • +
  • ca
  • +
  • ca_AD
  • +
  • ca_ES
  • +
  • ca_ES_Valencia
  • +
  • ca_FR
  • +
  • ca_IT
  • +
  • ccp
  • +
  • ccp_IN
  • +
  • ce
  • +
  • ce_RU
  • +
  • cgg
  • +
  • chr
  • +
  • chr_US
  • +
  • cmn
  • +
  • cmn_TW
  • +
  • crh
  • +
  • crh_UA
  • +
  • cs
  • +
  • cs_CZ
  • +
  • csb
  • +
  • csb_PL
  • +
  • cu
  • +
  • cv
  • +
  • cv_RU
  • +
  • cy
  • +
  • cy_GB
  • +
  • da
  • +
  • da_DK
  • +
  • da_GL
  • +
  • dav
  • +
  • de
  • +
  • de_AT
  • +
  • de_BE
  • +
  • de_CH
  • +
  • de_DE
  • +
  • de_IT
  • +
  • de_LI
  • +
  • de_LU
  • +
  • dje
  • +
  • doi
  • +
  • doi_IN
  • +
  • dsb
  • +
  • dsb_DE
  • +
  • dua
  • +
  • dv
  • +
  • dv_MV
  • +
  • dyo
  • +
  • dz
  • +
  • dz_BT
  • +
  • ebu
  • +
  • ee
  • +
  • ee_TG
  • +
  • el
  • +
  • el_CY
  • +
  • el_GR
  • +
  • en
  • +
  • en_001
  • +
  • en_150
  • +
  • en_AG
  • +
  • en_AI
  • +
  • en_AS
  • +
  • en_AT
  • +
  • en_AU
  • +
  • en_BB
  • +
  • en_BE
  • +
  • en_BI
  • +
  • en_BM
  • +
  • en_BS
  • +
  • en_BW
  • +
  • en_BZ
  • +
  • en_CA
  • +
  • en_CC
  • +
  • en_CH
  • +
  • en_CK
  • +
  • en_CM
  • +
  • en_CX
  • +
  • en_CY
  • +
  • en_DE
  • +
  • en_DG
  • +
  • en_DK
  • +
  • en_DM
  • +
  • en_ER
  • +
  • en_FI
  • +
  • en_FJ
  • +
  • en_FK
  • +
  • en_FM
  • +
  • en_GB
  • +
  • en_GD
  • +
  • en_GG
  • +
  • en_GH
  • +
  • en_GI
  • +
  • en_GM
  • +
  • en_GU
  • +
  • en_GY
  • +
  • en_HK
  • +
  • en_IE
  • +
  • en_IL
  • +
  • en_IM
  • +
  • en_IN
  • +
  • en_IO
  • +
  • en_ISO
  • +
  • en_JE
  • +
  • en_JM
  • +
  • en_KE
  • +
  • en_KI
  • +
  • en_KN
  • +
  • en_KY
  • +
  • en_LC
  • +
  • en_LR
  • +
  • en_LS
  • +
  • en_MG
  • +
  • en_MH
  • +
  • en_MO
  • +
  • en_MP
  • +
  • en_MS
  • +
  • en_MT
  • +
  • en_MU
  • +
  • en_MW
  • +
  • en_MY
  • +
  • en_NA
  • +
  • en_NF
  • +
  • en_NG
  • +
  • en_NL
  • +
  • en_NR
  • +
  • en_NU
  • +
  • en_NZ
  • +
  • en_PG
  • +
  • en_PH
  • +
  • en_PK
  • +
  • en_PN
  • +
  • en_PR
  • +
  • en_PW
  • +
  • en_RW
  • +
  • en_SB
  • +
  • en_SC
  • +
  • en_SD
  • +
  • en_SE
  • +
  • en_SG
  • +
  • en_SH
  • +
  • en_SI
  • +
  • en_SL
  • +
  • en_SS
  • +
  • en_SX
  • +
  • en_SZ
  • +
  • en_TC
  • +
  • en_TK
  • +
  • en_TO
  • +
  • en_TT
  • +
  • en_TV
  • +
  • en_TZ
  • +
  • en_UG
  • +
  • en_UM
  • +
  • en_US
  • +
  • en_US_Posix
  • +
  • en_VC
  • +
  • en_VG
  • +
  • en_VI
  • +
  • en_VU
  • +
  • en_WS
  • +
  • en_ZA
  • +
  • en_ZM
  • +
  • en_ZW
  • +
  • eo
  • +
  • es
  • +
  • es_419
  • +
  • es_AR
  • +
  • es_BO
  • +
  • es_BR
  • +
  • es_BZ
  • +
  • es_CL
  • +
  • es_CO
  • +
  • es_CR
  • +
  • es_CU
  • +
  • es_DO
  • +
  • es_EA
  • +
  • es_EC
  • +
  • es_ES
  • +
  • es_GQ
  • +
  • es_GT
  • +
  • es_HN
  • +
  • es_IC
  • +
  • es_MX
  • +
  • es_NI
  • +
  • es_PA
  • +
  • es_PE
  • +
  • es_PH
  • +
  • es_PR
  • +
  • es_PY
  • +
  • es_SV
  • +
  • es_US
  • +
  • es_UY
  • +
  • es_VE
  • +
  • et
  • +
  • et_EE
  • +
  • eu
  • +
  • eu_ES
  • +
  • ewo
  • +
  • fa
  • +
  • fa_AF
  • +
  • fa_IR
  • +
  • ff
  • +
  • ff_CM
  • +
  • ff_GN
  • +
  • ff_MR
  • +
  • ff_SN
  • +
  • fi
  • +
  • fi_FI
  • +
  • fil
  • +
  • fil_PH
  • +
  • fo
  • +
  • fo_DK
  • +
  • fo_FO
  • +
  • fr
  • +
  • fr_BE
  • +
  • fr_BF
  • +
  • fr_BI
  • +
  • fr_BJ
  • +
  • fr_BL
  • +
  • fr_CA
  • +
  • fr_CD
  • +
  • fr_CF
  • +
  • fr_CG
  • +
  • fr_CH
  • +
  • fr_CI
  • +
  • fr_CM
  • +
  • fr_DJ
  • +
  • fr_DZ
  • +
  • fr_FR
  • +
  • fr_GA
  • +
  • fr_GF
  • +
  • fr_GN
  • +
  • fr_GP
  • +
  • fr_GQ
  • +
  • fr_HT
  • +
  • fr_KM
  • +
  • fr_LU
  • +
  • fr_MA
  • +
  • fr_MC
  • +
  • fr_MF
  • +
  • fr_MG
  • +
  • fr_ML
  • +
  • fr_MQ
  • +
  • fr_MR
  • +
  • fr_MU
  • +
  • fr_NC
  • +
  • fr_NE
  • +
  • fr_PF
  • +
  • fr_PM
  • +
  • fr_RE
  • +
  • fr_RW
  • +
  • fr_SC
  • +
  • fr_SN
  • +
  • fr_SY
  • +
  • fr_TD
  • +
  • fr_TG
  • +
  • fr_TN
  • +
  • fr_VU
  • +
  • fr_WF
  • +
  • fr_YT
  • +
  • fur
  • +
  • fur_IT
  • +
  • fy
  • +
  • fy_DE
  • +
  • fy_NL
  • +
  • ga
  • +
  • ga_IE
  • +
  • gd
  • +
  • gd_GB
  • +
  • gez
  • +
  • gez_ER
  • +
  • gez_ET
  • +
  • gl
  • +
  • gl_ES
  • +
  • gom
  • +
  • gom_Latn
  • +
  • gsw
  • +
  • gsw_CH
  • +
  • gsw_FR
  • +
  • gsw_LI
  • +
  • gu
  • +
  • gu_IN
  • +
  • guz
  • +
  • gv
  • +
  • gv_GB
  • +
  • ha
  • +
  • ha_GH
  • +
  • ha_NE
  • +
  • ha_NG
  • +
  • hak
  • +
  • hak_TW
  • +
  • haw
  • +
  • he
  • +
  • he_IL
  • +
  • hi
  • +
  • hi_IN
  • +
  • hif
  • +
  • hif_FJ
  • +
  • hne
  • +
  • hne_IN
  • +
  • hr
  • +
  • hr_BA
  • +
  • hr_HR
  • +
  • hsb
  • +
  • hsb_DE
  • +
  • ht
  • +
  • ht_HT
  • +
  • hu
  • +
  • hu_HU
  • +
  • hy
  • +
  • hy_AM
  • +
  • i18n
  • +
  • ia
  • +
  • ia_FR
  • +
  • id
  • +
  • id_ID
  • +
  • ig
  • +
  • ig_NG
  • +
  • ii
  • +
  • ik
  • +
  • ik_CA
  • +
  • in
  • +
  • is
  • +
  • is_IS
  • +
  • it
  • +
  • it_CH
  • +
  • it_IT
  • +
  • it_SM
  • +
  • it_VA
  • +
  • iu
  • +
  • iu_CA
  • +
  • iw
  • +
  • ja
  • +
  • ja_JP
  • +
  • jgo
  • +
  • jmc
  • +
  • jv
  • +
  • ka
  • +
  • ka_GE
  • +
  • kab
  • +
  • kab_DZ
  • +
  • kam
  • +
  • kde
  • +
  • kea
  • +
  • khq
  • +
  • ki
  • +
  • kk
  • +
  • kk_KZ
  • +
  • kkj
  • +
  • kl
  • +
  • kl_GL
  • +
  • kln
  • +
  • km
  • +
  • km_KH
  • +
  • kn
  • +
  • kn_IN
  • +
  • ko
  • +
  • ko_KP
  • +
  • ko_KR
  • +
  • kok
  • +
  • kok_IN
  • +
  • ks
  • +
  • ks_IN
  • +
  • ks_IN@devanagari
  • +
  • ksb
  • +
  • ksf
  • +
  • ksh
  • +
  • ku
  • +
  • ku_TR
  • +
  • kw
  • +
  • kw_GB
  • +
  • ky
  • +
  • ky_KG
  • +
  • lag
  • +
  • lb
  • +
  • lb_LU
  • +
  • lg
  • +
  • lg_UG
  • +
  • li
  • +
  • li_NL
  • +
  • lij
  • +
  • lij_IT
  • +
  • lkt
  • +
  • ln
  • +
  • ln_AO
  • +
  • ln_CD
  • +
  • ln_CF
  • +
  • ln_CG
  • +
  • lo
  • +
  • lo_LA
  • +
  • lrc
  • +
  • lrc_IQ
  • +
  • lt
  • +
  • lt_LT
  • +
  • lu
  • +
  • luo
  • +
  • luy
  • +
  • lv
  • +
  • lv_LV
  • +
  • lzh
  • +
  • lzh_TW
  • +
  • mag
  • +
  • mag_IN
  • +
  • mai
  • +
  • mai_IN
  • +
  • mas
  • +
  • mas_TZ
  • +
  • mer
  • +
  • mfe
  • +
  • mfe_MU
  • +
  • mg
  • +
  • mg_MG
  • +
  • mgh
  • +
  • mgo
  • +
  • mhr
  • +
  • mhr_RU
  • +
  • mi
  • +
  • mi_NZ
  • +
  • miq
  • +
  • miq_NI
  • +
  • mjw
  • +
  • mjw_IN
  • +
  • mk
  • +
  • mk_MK
  • +
  • ml
  • +
  • ml_IN
  • +
  • mn
  • +
  • mn_MN
  • +
  • mni
  • +
  • mni_IN
  • +
  • mo
  • +
  • mr
  • +
  • mr_IN
  • +
  • ms
  • +
  • ms_BN
  • +
  • ms_MY
  • +
  • ms_SG
  • +
  • mt
  • +
  • mt_MT
  • +
  • mua
  • +
  • my
  • +
  • my_MM
  • +
  • mzn
  • +
  • nan
  • +
  • nan_TW
  • +
  • nan_TW@latin
  • +
  • naq
  • +
  • nb
  • +
  • nb_NO
  • +
  • nb_SJ
  • +
  • nd
  • +
  • nds
  • +
  • nds_DE
  • +
  • nds_NL
  • +
  • ne
  • +
  • ne_IN
  • +
  • ne_NP
  • +
  • nhn
  • +
  • nhn_MX
  • +
  • niu
  • +
  • niu_NU
  • +
  • nl
  • +
  • nl_AW
  • +
  • nl_BE
  • +
  • nl_BQ
  • +
  • nl_CW
  • +
  • nl_NL
  • +
  • nl_SR
  • +
  • nl_SX
  • +
  • nmg
  • +
  • nn
  • +
  • nn_NO
  • +
  • nnh
  • +
  • no
  • +
  • nr
  • +
  • nr_ZA
  • +
  • nso
  • +
  • nso_ZA
  • +
  • nus
  • +
  • nyn
  • +
  • oc
  • +
  • oc_FR
  • +
  • om
  • +
  • om_ET
  • +
  • om_KE
  • +
  • or
  • +
  • or_IN
  • +
  • os
  • +
  • os_RU
  • +
  • pa
  • +
  • pa_Arab
  • +
  • pa_Guru
  • +
  • pa_IN
  • +
  • pa_PK
  • +
  • pap
  • +
  • pap_AW
  • +
  • pap_CW
  • +
  • pl
  • +
  • pl_PL
  • +
  • prg
  • +
  • ps
  • +
  • ps_AF
  • +
  • pt
  • +
  • pt_AO
  • +
  • pt_BR
  • +
  • pt_CH
  • +
  • pt_CV
  • +
  • pt_GQ
  • +
  • pt_GW
  • +
  • pt_LU
  • +
  • pt_MO
  • +
  • pt_MZ
  • +
  • pt_PT
  • +
  • pt_ST
  • +
  • pt_TL
  • +
  • qu
  • +
  • qu_BO
  • +
  • qu_EC
  • +
  • quz
  • +
  • quz_PE
  • +
  • raj
  • +
  • raj_IN
  • +
  • rm
  • +
  • rn
  • +
  • ro
  • +
  • ro_MD
  • +
  • ro_RO
  • +
  • rof
  • +
  • ru
  • +
  • ru_BY
  • +
  • ru_KG
  • +
  • ru_KZ
  • +
  • ru_MD
  • +
  • ru_RU
  • +
  • ru_UA
  • +
  • rw
  • +
  • rw_RW
  • +
  • rwk
  • +
  • sa
  • +
  • sa_IN
  • +
  • sah
  • +
  • sah_RU
  • +
  • saq
  • +
  • sat
  • +
  • sat_IN
  • +
  • sbp
  • +
  • sc
  • +
  • sc_IT
  • +
  • sd
  • +
  • sd_IN
  • +
  • sd_IN@devanagari
  • +
  • se
  • +
  • se_FI
  • +
  • se_NO
  • +
  • se_SE
  • +
  • seh
  • +
  • ses
  • +
  • sg
  • +
  • sgs
  • +
  • sgs_LT
  • +
  • sh
  • +
  • shi
  • +
  • shi_Latn
  • +
  • shi_Tfng
  • +
  • shn
  • +
  • shn_MM
  • +
  • shs
  • +
  • shs_CA
  • +
  • si
  • +
  • si_LK
  • +
  • sid
  • +
  • sid_ET
  • +
  • sk
  • +
  • sk_SK
  • +
  • sl
  • +
  • sl_SI
  • +
  • sm
  • +
  • sm_WS
  • +
  • smn
  • +
  • sn
  • +
  • so
  • +
  • so_DJ
  • +
  • so_ET
  • +
  • so_KE
  • +
  • so_SO
  • +
  • sq
  • +
  • sq_AL
  • +
  • sq_MK
  • +
  • sq_XK
  • +
  • sr
  • +
  • sr_Cyrl
  • +
  • sr_Cyrl_BA
  • +
  • sr_Cyrl_ME
  • +
  • sr_Cyrl_XK
  • +
  • sr_Latn
  • +
  • sr_Latn_BA
  • +
  • sr_Latn_ME
  • +
  • sr_Latn_XK
  • +
  • sr_ME
  • +
  • sr_RS
  • +
  • sr_RS@latin
  • +
  • ss
  • +
  • ss_ZA
  • +
  • st
  • +
  • st_ZA
  • +
  • sv
  • +
  • sv_AX
  • +
  • sv_FI
  • +
  • sv_SE
  • +
  • sw
  • +
  • sw_CD
  • +
  • sw_KE
  • +
  • sw_TZ
  • +
  • sw_UG
  • +
  • szl
  • +
  • szl_PL
  • +
  • ta
  • +
  • ta_IN
  • +
  • ta_LK
  • +
  • ta_MY
  • +
  • ta_SG
  • +
  • tcy
  • +
  • tcy_IN
  • +
  • te
  • +
  • te_IN
  • +
  • teo
  • +
  • teo_KE
  • +
  • tet
  • +
  • tg
  • +
  • tg_TJ
  • +
  • th
  • +
  • th_TH
  • +
  • the
  • +
  • the_NP
  • +
  • ti
  • +
  • ti_ER
  • +
  • ti_ET
  • +
  • tig
  • +
  • tig_ER
  • +
  • tk
  • +
  • tk_TM
  • +
  • tl
  • +
  • tl_PH
  • +
  • tlh
  • +
  • tn
  • +
  • tn_ZA
  • +
  • to
  • +
  • to_TO
  • +
  • tpi
  • +
  • tpi_PG
  • +
  • tr
  • +
  • tr_CY
  • +
  • tr_TR
  • +
  • ts
  • +
  • ts_ZA
  • +
  • tt
  • +
  • tt_RU
  • +
  • tt_RU@iqtelif
  • +
  • twq
  • +
  • tzl
  • +
  • tzm
  • +
  • tzm_Latn
  • +
  • ug
  • +
  • ug_CN
  • +
  • uk
  • +
  • uk_UA
  • +
  • unm
  • +
  • unm_US
  • +
  • ur
  • +
  • ur_IN
  • +
  • ur_PK
  • +
  • uz
  • +
  • uz_Arab
  • +
  • uz_Cyrl
  • +
  • uz_Latn
  • +
  • uz_UZ
  • +
  • uz_UZ@cyrillic
  • +
  • vai
  • +
  • vai_Latn
  • +
  • vai_Vaii
  • +
  • ve
  • +
  • ve_ZA
  • +
  • vi
  • +
  • vi_VN
  • +
  • vo
  • +
  • vun
  • +
  • wa
  • +
  • wa_BE
  • +
  • wae
  • +
  • wae_CH
  • +
  • wal
  • +
  • wal_ET
  • +
  • wo
  • +
  • wo_SN
  • +
  • xh
  • +
  • xh_ZA
  • +
  • xog
  • +
  • yav
  • +
  • yi
  • +
  • yi_US
  • +
  • yo
  • +
  • yo_BJ
  • +
  • yo_NG
  • +
  • yue
  • +
  • yue_HK
  • +
  • yue_Hans
  • +
  • yue_Hant
  • +
  • yuw
  • +
  • yuw_PG
  • +
  • zgh
  • +
  • zh
  • +
  • zh_CN
  • +
  • zh_HK
  • +
  • zh_Hans
  • +
  • zh_Hans_HK
  • +
  • zh_Hans_MO
  • +
  • zh_Hans_SG
  • +
  • zh_Hant
  • +
  • zh_Hant_HK
  • +
  • zh_Hant_MO
  • +
  • zh_Hant_TW
  • +
  • zh_MO
  • +
  • zh_SG
  • +
  • zh_TW
  • +
  • zh_YUE
  • +
  • zu
  • +
  • zu_ZA
  • +
+ +
+
+ + + Last update: + April 6, 2024 10:34:57 + + + +
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/webhookscript/examples.html b/webhookscript/examples.html new file mode 100644 index 0000000..331a5e6 --- /dev/null +++ b/webhookscript/examples.html @@ -0,0 +1,1761 @@ + + + + + + + + + + + + + + + + + + + + + + + + Examples - Webhook.site Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + + + + + +
+
+ + + + + + + + + + + + + +

WebhookScript Examples

+
+

Info

+

Do you have a nice example to share with other users? Or looking for even more examples? Take a look at the WebhookScript example repository, and make a pull request if you want to contribute: Webhook.site Script Repository

+
+

HMAC validation

+

The following script uses the hmac() function and the sha256 algorithm to verify a HMAC signature, which is commonly used to verify webhooks. In this example, the secret is secret and the signature comes from the incoming request's x-signature HTTP header.

+

If the signature doesn't match, further action execution is stopped and the URL immediately respond with a 401 status code.

+
hmac = hmac(var('request.content'), 'sha256', 'secret');
+signature = var('request.header.x-signature', '');
+
+if (hmac != signature) {
+    respond('Unauthorized', 401);
+}
+
+

JWT

+

An example acquiring an access token from the DocuSign API using JWT and the WebhookScript sign() function:

+
private_key = '-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBA...
+-----END RSA PRIVATE KEY-----';
+
+header = json_encode([
+    'alg': 'RS256',
+    'typ': 'JWT'
+])
+
+currentTimestamp = now().date_format('X').to_number()
+
+body = json_encode([
+    "iss": "00000000-0000-0000-0000-000000000000",
+    "sub": "00000000-0000-0000-0000-000000000000",
+    "aud": "account-d.docusign.com",
+    "iat": currentTimestamp,
+    "exp": currentTimestamp + 6000,
+    "scope": "impersonation signature"
+])
+
+token = base64url_encode(header) + "." + base64url_encode(body)
+signature = base64url_encode(sign(token, private_key, 'sha256'))
+jwt = token + "." + signature
+
+content = query([
+    'grant_type': 'urn:ietf:params:oauth:grant-type:jwt-bearer',
+    'assertion': jwt
+])
+headers = ['Content-Type: application/x-www-form-urlencoded']
+response = request('https://account-d.docusign.com/oauth/token', content, 'POST', headers)
+
+if (response['status'] != 200) {
+    echo('Could not get token: ' + response['content'])
+    stop()
+}
+
+response_json = json_decode(response['content'])
+echo('Got access token: ' + response_json['access_token'])
+
+

Convert a date

+

In this example, if we assume the variable $mydate$ is set to 2021-07-26T16:23:50+03:00, the variable will be overwritten to 2021.07.26 16:23 for actions running after the WebhookScript action.

+
input = var('$mydate$')
+
+output = date_format(input, 'YYYY.MM.DD HH:mm')
+
+set('$mydate$', output)
+
+

More information about available date format characters.

+

Request counter

+

This script uses Global Variables to keep track of the amount of requests sent to a Webhook.site URL within the last 10 minutes.

+

Once the 10 minutes are up, it sends a request to another endpoint with the amount of requests and the date, and then it resets the counter.

+
period = 600 // 10 minutes in seconds
+currentPeriod = var('current_period', now())
+counter = var('counter', 0).to_number()
+
+currentPeriodSecs = date_interval(currentPeriod)
+
+if (currentPeriodSecs < period) {
+    counter = counter + 1
+    store('counter', counter)
+} else {
+    // Above 10 minutes, reset and send request
+    store('counter', 0)
+    store('current_period', now())
+    request(
+        'https://webhook.site/14fea227-60ab-4291-b679-12b8c104c78e', 
+        json_encode([
+            "counter": counter,
+            "timestamp": now(),
+        ]),
+        'POST'
+    )
+}
+
+echo('count : {}'.format(counter))
+echo('period: {}'.format(currentPeriodSecs))
+
+

Parse and loop through JSON

+

This example shows various ways of iterating through JSON arrays, comparing data and rearranging it to another format.

+

First, it loops through the items array, verifying that the item must have a group ID that a specific one from an array.

+

Second, it changes the fields array from an array of objects to a key-value object using the name and value fields.

+
// Define input as a JSON string
+json = '{
+    "items": [
+        {
+            "first_name": "Jack",
+            "last_name": "Daniels",
+            "phone": "+1 100-555-999",
+            "group_ids": [346, 46456, 23423],
+            "fields": [
+              {
+                "id": 45698,
+                "name": "birthday",
+                "value": "1990-01-01"
+              },
+              {
+                "id": 344,
+                "name": "car",
+                "value": "BMW M2"
+              }
+            ]
+        },
+        {
+            "first_name": "Jim",
+            "last_name": "Beam",
+            "phone": "+1 123-555-788",
+            "group_ids": [3456, 43546, 234234, 456456],
+            "fields": [
+              {
+                "id": 45698,
+                "name": "birthday",
+                "value": "1987-05-01"
+              },
+              {
+                "id": 344,
+                "name": "car",
+                "value": "Toyota Corolla"
+              },
+              {
+                "id": 248,
+                "name": "nickname",
+                "value": "Jimmie"
+              }
+            ]
+        }
+    ]
+}'
+
+// Decode to array
+data = json_decode(json)
+
+// Define an array of valid groups
+valid_groups = [43546, 999999]
+
+// Loop over items
+for (item in data['items']) {
+    // Per default, item does not have a valid group.
+    has_valid_group = false
+
+    // Loop through each group ID in the data
+    for (group_id in item['group_ids']) {
+        // Does the "valid_groups" array contain this group ID?
+        if (valid_groups.contains(group_id)) {
+            has_valid_group = true
+        }
+    }
+
+    if (has_valid_group) {
+        echo(item['first_name'] + ' did not have a valid group.') 
+    } else {
+        echo(item['first_name'] + ' has a valid group.') 
+    }
+
+    // Extract "fields" into an array of key => value
+    fields = []
+    for (field in item['fields']) {
+      fields[field['name']] = field['value']
+    }
+
+    echo(json_encode(fields))
+}
+
+

Returns the following output:

+
Jack has a valid group.
+{
+    "birthday": "1990-01-01",
+    "car": "BMW M2"
+}
+Jim did not have a valid group.
+{
+    "birthday": "1987-05-01",
+    "car": "Toyota Corolla",
+    "nickname": "Jimmie"
+}
+
+

Loop through and compare items

+

In this example, we loop through a series of items and pick the item that's contained in a string.

+
location = 'test ABC example';
+
+compares = [
+  '123': 'token1',
+  'ABC': 'token2',
+  'DEF': 'token3',
+]
+
+token = ''; // Default value
+
+for (compare in array_keys(compares)) {
+    if (location.contains(compare)) {
+        token = compares[compare]
+    }
+}
+
+dump(token) // token2
+
+

Submit request with escaped JSON

+

If you're building a JSON object, we recommend doing it in WebhookScript instead of typing JSON in the Send Request action type (If you do anyway, we recommend using the .json Variable Modifier, More info here).

+

In this example, one of the JSON values contain HTML generated using the string_format function.

+
html_template = '<b><u>New {} lead</u></b><br>
+<br>
+Location: {}<br>
+Message from customer:<br>
+<div style="background:#CCC">{}</div>'
+
+html_message = string_format(
+    html_template,
+    var('lead_type'),
+    var('location'),
+    var('message')
+)
+
+payload = json_encode([
+    'lead': [
+        'firstname': var('firstname'),
+        'lastname': var('lastname'),
+        'html': html_message
+    ]
+])
+
+
+request(
+  'https://example.com/leads',
+   payload,
+   'POST',
+   ['Content-Type: application/json']
+)
+
+

Validate request

+

In this example, we use a common method of verifying webhooks by taking a hash of its contents concatenated to a secret. It demonstrates the way WebhookScript can get various information about the request by using the get_variable() function, as well as string concatenation, hashing, if statements and returning responses with content, status codes and headers using respond(), which halts execution.

+
verification_secret = "JHRlc3RTY3JpcHRTZWNyZXQ"
+verification_challenge = var("request.header.x-request-verification")
+verification_result = hash(var("request.content") + verification_secret, "sha256")
+
+if (!verification_challenge or verification_challenge != verification_result) {
+    respond("Invalid request", 500)
+}
+
+respond("Successful request", 200)
+
+

Send a x-www-form-urlencoded request

+
content = query([
+    'country': 'Curaçao', 
+    'population': 158665
+])
+headers = ['Content-Type: application/x-www-form-urlencoded'];
+response = request('https://example.com', content, 'POST', headers);
+
+

Transform and resend

+

In the following, an incoming request is JSON decoded to an array, transformed and sent to "Web Service 1". Then the output is saved and passed on to "Web Service 2" in XML format. Basic error handling and validation is demonstrated.

+
// Configuration, fetched from the users' Global Variables in Control Panel
+ws1_api_key = var('WS1_KEY')
+ws2_user_token = var('WS1_USER_TOKEN')
+
+// Function for error handling which stops processing further actions/code and returns an error message
+function error (message) {
+    echo('Error: {}'.format(message))
+    respond(json_encode(['error': message]), 500)
+}
+
+// Parse original request
+orig_req = json_decode(var('request.content'))
+
+// If the JSON was invalid
+if (!orig_req) {
+  error('Invalid request')
+}
+
+// Send request to Web Service 1, using format() for string placeholders
+// with JSON decoded values from the incoming request body
+ws1_url = 'https://ws1.example.com/3.0/lists/{}/interest-categories/{}/interests'.format(
+  orig_req['listId'],
+  orig_req['groupId']
+)
+
+ws1_content = [
+  'first_name': orig_req['firstName'],
+  'last_name': orig_req['lastName']
+]
+ws1_response = request(
+    ws1_url,
+    json_encode(ws1_content),
+    'POST',
+    ['Authorization: Basic ' + ws1_api_key]
+)
+
+// Don't go further if the Web Service 1 step didn't succeed
+if (ws1_response['status'] != 200) {
+  echo(ws1_response['content']); // Log content to output
+  error('Invalid response from WS1')
+}
+
+// Get a value from the Web Service 1 request
+ws1_response_id = json_decode(ws1_response)['id']
+
+// Pass response on to Web Service 2 in XML format, using a multi-line string and format()
+ws2_content = '
+  <qdbapi>
+    <usertoken>{}</usertoken>
+    <listid>{}</listid>
+    <field fid="7">{}</field>
+  </qdbapi>'.format(ws2_user_token, orig_req['listId'], ws1_group_id)
+
+ws2_response = request(
+  'https://ws2.example.com/db/zzzzzz',
+  ws2_content,
+  'POST', 
+  [
+    "Action: API_EditRecord", 
+    "Content-Type: application/xml"
+  ]
+)
+
+if (ws2_response['status'] != 200) {
+  echo(ws2_response['content']); // Log content to debug log
+  error('Invalid response from WS2')
+}
+
+// Output the WS2 response content to debug output
+echo(ws2_response['content'])
+respond('OK', 200)
+
+

Telegram bot

+

The Messaging service Telegram allows bots using their API. The general principle is this:

+
    +
  1. Create a Bot using the /newbot command sent to the BotFather Telegram User
  2. +
  3. Using the bot token sent from BotFather, use the Telegram API to create a Webhook subscription (using your Webhook.site URL)
  4. +
  5. Add some logic using WebhookScript!
  6. +
+

Note: Everywhere you see TELEGRAM_TOKEN, replace it with the token you got from BotFather!

+

Subscribe to Webhook

+

To create the Webhook subscription, change the token and the Webhook.site URL to your own and go to the following URL in your browser:

+

https://api.telegram.org/botTELEGRAM_TOKEN/setWebhook?url=https://webhook.site/a1351781

+

You should get a response similar to this:

+
{
+  "ok": true,
+  "result": true,
+  "description": "Webhook was set"
+}
+
+

First incoming Webhook

+

When you add your bot to your Telegram contacts list, Telegram automatically sends a /start command to the bot, which triggers a Webhook similar to this:

+
{
+  "update_id": 176446573,
+  "message": {
+    "message_id": 1,
+    "from": {
+      "id": 2346545645,
+      "is_bot": false,
+      "first_name": "Simon",
+      "language_code": "en"
+    },
+    "chat": {
+      "id": 34534673234,
+      "first_name": "Simon",
+      "type": "private"
+    },
+    "date": 1581706369,
+    "text": "/start",
+    "entities": [
+      {
+        "offset": 0,
+        "length": 6,
+        "type": "bot_command"
+      }
+    ]
+  }
+}
+
+

You should be able to see this in the Webhook.site requests list.

+

From this, we have all the parts needed to build a script that answers to commands:

+
// Telegram API token
+token = 'TELEGRAM_TOKEN';
+
+content = json_decode(var('$request.content$'));
+msg = content['message']['text'];
+response = "Couldn't come up with anything witty.";
+
+if (msg == "How's it going?") {
+    response = 'Pretty good.'
+}
+
+if (msg == r"You're (.*)") {
+    match = regex_extract_first(r"You're (.*)", msg)
+    response = 'No, YOU are {}'.format(match);
+}
+
+if (msg == "/start") {
+    response = "Hi! I'm WebhookBot."
+}
+
+url = 'https://api.telegram.org/bot{}/sendMessage'.format(token)
+
+json = [
+    'chat_id': content['message']['chat']['id'],
+    'text': response
+]
+
+request(url, json_encode(json), 'POST');
+
+

Things to note:

+
    +
  • The API token is added to the script, but could also have been saved in Global Variables in Control Panel and fetched out with the var() function.
  • +
  • The third if-statement uses regex matching to provide a dynamic response. Someone typing "You're a bot" would receive "No, YOU are a bot"
  • +
  • Finally, we JSON encode a WebhookScript array and send it using the request() function.
  • +
+

Simply copy this script into a WebhookScript Custom Action (remember to change the token!), and click Save Action.

+

"WebhookScript" Telegram Bot screenshot

+

Then, you can interact with the bot using the Telegram app:

+

"WebhookScript" Telegram Bot screenshot

+

And that's it! Congratulations on your bot. It's not very smart, but from here, the possibilities are endless!

+

Building HTML content

+

The following script builds a piece of HTML content using the string_format function, based on previously defined variables, and shows how to use a function to return different content based on input.

+

After this, it sends a JSON request (by converting an array to JSON via the json_encode function) containing the HTML using basic Bearer authentication.

+
function alert_class() {
+    if (status == 'Operational') { return 'success'; }
+    if (status == 'Degraded Performance') { return 'warning'; }
+    if (string_contains(status, 'Disruption')) { return 'danger'; }
+}
+
+template = '
+  <div class="alert alert-{}">
+    <h2 class="alert-title">{} - {}</h2>
+    <p>
+      {}<br />
+      State: {}<br />
+      Component affected: {}
+    </p>
+    <p>{}</p>
+  </div>';
+
+postbody = string_format(
+  template,
+  alert_class(),
+  message,
+  state,
+  component,
+  to_date('now').date_format('LLLL')
+)
+
+json = [
+  'alert': [
+    'title': '{} - {}'.format(component, state),
+    'body': postbody,
+    'draft': false,
+    'types': ['alert']
+  ],
+]
+
+request(
+  'http://example.com/alerts',
+  json_encode(json),
+  'POST',
+  [
+    'Content-Type: application/json',
+    'Authorization: Basic {}'.format(token)
+  ]
+)
+
+

Uploading and parsing CSV file

+

With this script, a file upload form is displayed when visiting the URL. After submitting the form, the CSV file is processed and validated (in this example, there must be more than 2 rows). If it can't be validated, an error message is shown. Finally, the user is shown an "Upload successful" message if the CSV file is valid.

+
url = var('request.url')
+set_header('content-type', 'text/html');
+
+// Display file upload form and exit if HTTP method is not POST
+if (var('request.method') != 'POST') {
+    respond('
+        <html>
+            <head><title>Upload CSV</title></head>
+            <body>
+                <h1>Upload CSV</h1>
+                <form action="{}" method="POST" enctype="multipart/form-data">
+                    <input type="file" name="file"/>
+                    <button type="submit">Upload</button>
+                </form>
+            </body>
+        </html>
+    '.format(url))
+}
+
+// Use a comma as delimiter and treat first row (0) as header row
+array = csv_to_array(var('request.file.file.content'), ',', 0)
+
+// If CSV can't be parsed, or there's less than 2 rows, fail
+if (!array or array.length() < 2) {
+    respond('
+        <h1>Could not parse CSV</h1>
+        <a href="{}">Upload again</a>
+    '.format(url));
+}
+
+// Display the parsed CSV in JSON format 
+respond('
+    <h1>Upload successful</h1>
+    <pre>{}</pre>
+    <p>
+        <a href="{}">Upload again</a>
+    </p>
+'.format(json_encode(array), url))
+
+ +
+
+ + + Last update: + April 6, 2024 10:34:57 + + + +
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/webhookscript/functions.html b/webhookscript/functions.html new file mode 100644 index 0000000..7f2b332 --- /dev/null +++ b/webhookscript/functions.html @@ -0,0 +1,971 @@ + + + + + + + + + + + + + + + + + + + + Functions - Webhook.site Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+ + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + + + + + + +

The functions page has been split up in multiple sub-pages, please start here.

+ +
+
+ + + Last update: + April 6, 2024 10:34:57 + + + +
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/webhookscript/functions/array.html b/webhookscript/functions/array.html new file mode 100644 index 0000000..02ba90d --- /dev/null +++ b/webhookscript/functions/array.html @@ -0,0 +1,1447 @@ + + + + + + + + + + + + + + + + + + + + + + + + Arrays - Webhook.site Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + + + + + +
+
+ + + + + + + + + + + + + +

Arrays

+ +

array_contains(array array, string/number needle) : bool

+

Returns true or false depending on whether array contains a value equal to needle.

+

To check whether a key exists, use the array_has function.

+
employees = [6547: 'Simon', 235345: 'Jack', 4657: 'Jim']
+
+dd(array_contains(employees, 'Simon'))
+// -> true
+
+

array_chunk(array array, number count, bool preserve_keys = false) : array

+

Splits a single array into chunks of count. When preserve_keys is set to true, the array keys are preserved.

+
test_arr = [
+    'a': 123,
+    'b': 234,
+    'c': 345,
+    'd': 345, 
+    'e': 456
+]
+
+dump(array_chunk(test_arr, 2, true))
+// -> [0: ["a": 123, "b": 234], 1: ["c": 345, "d": 345], 2: ["e": 456]]
+
+dump(array_chunk(test_arr, 2, false))
+// -> [0: [0: 123, 1: 234], 1: [0: 345, 1: 345], 2: [0: 456]]
+
+

array_copy(array array) : array

+

Returns a copy of array

+

array_diff(array array1, array array2) : array

+

Returns the items of array1 that are not present in array2 while keeping the array indices.

+

array_get(array array, string/number index, any default) : any

+

array_has(array array, string/number key) : bool

+

Returns true if array contains key, and false if it does not.

+

To check whether a value exists, use the array_contains function.

+
employees = [6547: 'Simon', 235345: 'Jack', 4657: 'Jim']
+
+dd(array_has(employees, 235345))
+// -> true
+
+

array_join(array array, string joiner) : string

+

Returns a string where all the values are joined by joiner.

+
['hello', 'world'].join(',')
+-> "hello,world"
+
+

array_keys(array array) : array

+

Returns the keys of an array.

+

array_length(array array) : number

+

array_map(array array, func function)

+

Runs function with each array value, and returns array with key as result.

+
employees = ['Simon', 'Jack', 'Jim']
+
+result = array_map(employees, function (employee) {
+    return 'Hello, '+employee+'!'
+})
+
+dd(result)
+
+// -> [0: "Hello, Simon!", 1: "Hello, Jack!", 2: "Hello, Jim!"]
+
+

array_merge(array array1, array array2): array

+

Merges 2 arrays into a single array.

+
test1 = [123, 234, 345]
+test2 = [345, 456]
+
+dump(array_merge(test1, test2))
+
+// -> [0: 123, 1: 234, 2: 345, 3: 345, 4: 456]
+
+

array_number_of(array, string/number value) : number

+

Returns amount of value

+

array_pop(array array) : any

+

Pop element off end of array

+

array_push(array array, any value) : any

+

Adds value to end of array and returns value

+

array_random(array array) : any

+

Returns random value of array

+

array_range(array array, int offset, ?int length = 0, ?bool preserve_keys = false) : array

+

Returns a range of array, starting from offset, and returns the amount specified in length if set (otherwise until the end of the array.)

+

If preserve_keys is true, the result has the array keys preserved.

+
array = ['one', 'two', 'three', 'four', 'five']
+
+dump(array_slice(array, 2))
+// [0: "three", 1: "four", 2: "five"]
+
+dump(array_slice(array, 2, 2))
+// [0: "three", 1: "four"]
+
+dump(array_range(array, -3, 2))
+// [0: "three", 1: "four"]
+
+

array_reverse(array array) : array

+

Returns array in reverse order

+
employees = [6547: 'Simon', 235345: 'Jack', 4657: 'Jim']
+
+dd(array_reverse(employees))
+// -> [0: "Jim", 1: "Jack", 2: "Simon"]
+
+

array_shuffle(array array) : array

+

Returns shuffled version of array

+

array_sort(array array) : array

+

Sorts array by its values. Keys are kept as-is.

+

array_splice(array array, int offset, ?int length, array replacement) : array

+

Removes length amount of values from array, starting from offset (if offset is negative, starts from the end of the array.)

+

If replacement is specified, the removed values are replaced with it.

+
array = ['one', 'two', 'three', 'four', 'five']
+
+dump(array_splice(array, 2, 2))
+// [0: "one", 1: "two", 2: "five"]
+
+dump(array_splice(array, 2, 2, ['hello']))
+// [0: "one", 1: "two", 2: "hello", 3: "five"]
+
+

array_values(array array) : array

+

Returns the values of an array.

+
employees = [6547: 'Simon', 235345: 'Jack', 4657: 'Jim']
+
+dd(array_values(employees))
+
+// -> [0: "Simon", 1: "Jack", 2: "Jim"]
+
+

to_array(array array) : array

+

Returns array.

+ +
+
+ + + Last update: + April 6, 2024 10:34:57 + + + +
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/webhookscript/functions/bool.html b/webhookscript/functions/bool.html new file mode 100644 index 0000000..cfc2fe8 --- /dev/null +++ b/webhookscript/functions/bool.html @@ -0,0 +1,1110 @@ + + + + + + + + + + + + + + + + + + + + + + + + Booleans - Webhook.site Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + + + + + +
+
+ + + + + + + + + + + + + +

Booleans

+ +

bool_and(bool value1, bool value2): bool

+

Returns value1 && value2

+

bool_not(bool value) : bool

+

Returns !value

+

is_empty(any value): bool

+

Returns true if:

+
    +
  • value is "" (empty string)
  • +
  • value is [] (empty array)
  • +
  • value is null
  • +
+

is_null(any value) : bool

+

Returns true if value is null. An alternative to if (value == null) that won't break when value isn't null due to type checking.

+

Example:

+
value = 'example'
+if (is_null(value)) {
+  // Won't trigger a type error
+}
+
+

to_bool(string/number/array/bool value) : bool

+

Casts value to a bool.

+ +
+
+ + + Last update: + April 6, 2024 10:34:57 + + + +
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/webhookscript/functions/date.html b/webhookscript/functions/date.html new file mode 100644 index 0000000..96e54a8 --- /dev/null +++ b/webhookscript/functions/date.html @@ -0,0 +1,1289 @@ + + + + + + + + + + + + + + + + + + + + + + + + Dates - Webhook.site Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + + + + + +
+
+ + + + + + + + + + + + + +

Date and Time Manipulation

+

Supported date and time formats

+

In WebhookScript, dates are not a specific type, but rather expressed as strings that WebhookScript will attempt to parse using a very powerful date parsing engine.

+

WebhookScript supports a variety of date formats, and functions taking a date will attempt to guess the format of the input string in order to parse the date into a ISO-8601 format

+

If possible, it's recommended to use the ISO-8601 format, for example 2020-05-27T04:00:00.000000Z.

+ +

Recognized date formats

+

In addition to automatically recognizing date strings like ISO-8601, WebhookScript has ability to recognize the following special formats.

+
    +
  • now
  • +
  • +4 day, -2 month - adds or subtracts to the current date and time, can be suffixed to other dates
      +
    • Other units supported: second, minute, hour, day, fortnight, week, month, year
    • +
    +
  • +
  • next Thursday
  • +
  • last Monday
  • +
  • first day of January 2008
  • +
  • first Saturday of July 2008
  • +
  • Monday next week
  • +
  • @1215282385 - UNIX timestamp
  • +
+

For more information, PHP Supported Date and Time Formats.

+

now(?string timezone) : string

+

Returns the current date in ISO-8601 format, using timezone, if specified.

+
now()
+// -> 2022-12-15T11:00:00.000000Z
+
+now('America/Los_Angeles')
+// -> 2022-12-15T03:00:00.000000-08:00
+
+

to_date(string date, ?string input_format, ?locale locale, ?string timezone, bool keep_timezone = false): ?string

+

Returns a ISO-8601 formatted date string in UTC time from the provided date string.

+

If specified, input_format is used to parse the date without having to guess the format (see the Date Format Characters specification.) Otherwise, see Recognized date formats.

+

If the keep_timezone parameter is set to true, the resulting date string will keep the timezone. The locale parameter will attempt to parse the date using the specified locale.

+

If the date is invalid or could not be guessed, null is returned.

+
// Current date and time
+'now'.to_date()
+// -> 2020-11-25T00:00:00.000000Z
+
+// Relative formats
+'first monday august 2019'.to_date()
+
+// Automatic format guessing
+'2020-01-01 23:02:01'.to_date()
+
+// Timezone handling
+'2020-01-01 23:02:01'.to_date(null, null, 'GMT-5')
+// -> "2020-01-02T04:02:01.000000Z", interpreted as GMT-5 and converted to UTC
+
+'2020-01-01 23:02:01'.to_date(null, null, 'GMT-5', true)
+// -> "2020-01-01T23:02:01.000000-05:00", date keeps timezone
+
+// Unix timestamp
+'@1215282385'.to_date()
+
+// Custom date format
+'2/4/12 06:03'.to_date('M/D/YY HH:mm')
+// -> 2012-02-04T06:03:00.000000Z
+
+// To escape characters in the format string, backslashes can be used
+'2020-01-05 12h30m15s'.to_date('YYYY-MM-DD HH\\hmm\\mss\\s')
+// -> 2020-01-05T12:30:15.000000Z
+
+

date_format(string date, ?string format, ?string locale, ?string timezone): string

+

Returns a date converted to the format specified in format. date is automatically parsed and can be a date string (ISO-8601 recommended) or one of the recognized date formats.

+

For a full list of date format characters, see the Date Format Characters specification.

+

If format is not specified, a default human readable readable string is returned.

+
date_format('2008-07-05T18:26:25.000000Z', 'YYYY-MM-DD') 
+// -> 2008-07-05
+
+date_format('2008-07-05T18:26:25.000000Z', 'LLLL', 'da') 
+// -> lørdag d. 5. juli 2008 kl. 18:26
+
+date_format('2020-01-01T23:02:01.000000-05:00', 'LLLL', null, 'GMT+2') 
+// -> Thursday, January 2, 2020 6:02 AM
+
+date_format('now', 'x')
+// -> 1606329669220 (current date in UNIX timestamp with microseconds)
+
+// Add 1 hour to an existing date (see Recognized date formats above)
+date_format('2021-10-28 11:28:55 +1 hour', 'YYYY-MM-DD HH:mm:ss')
+// -> 2021-10-28 12:28:55
+
+

date_to_array(string): array

+

Returns an array containing all the components of a given date.

+
dump(date_to_array('2008-07-05T18:26:25.324542Z'))
+
+// [
+//   "year": 2008,
+//   "month": 7,
+//   "day": 5,
+//   "dayOfWeek": 6,
+//   "dayOfYear": 187,
+//   "hour": 18,
+//   "minute": 26,
+//   "second": 25,
+//   "micro": 324542,
+//   "timestamp": 1215282385,
+//   "formatted": "2008-07-05 18:26:25",
+//   "timezone": "Z"
+// ]
+
+

date_interval(string date1, ?string date2, ?string format): string/int

+

Calculates the interval between date1 and date2. When date2 is unspecified/null, now is used.

+

If no format string is specified, the interval is returned as the number of seconds between the dates, with the number being negative if date2 is before date1.

+

For the format string, the PHP DateInterval format specification is used.

+
date_interval('2008-07-16T23:13:26.234212Z', '2008-07-05T18:26:25.324542Z') 
+// -> -967620
+
+date_interval(
+    '2008-07-16T23:13:26.234212Z',
+    '2008-07-05T18:26:25.324542Z',
+    '%d days, %h hours, %i minutes'
+)
+// -> 11 days, 4 hours, 47 minutes
+
+

date_interval_human(string date1, ?string date2, ?string locale): string/int

+

Formats the difference between 2 dates in a way that's easy to read for humans.

+

If no locale is specified, English is used. When date2 is unspecified/null, now is used.

+
date_interval_human(
+    '2008-07-16T23:13:26.234212Z',
+    '2008-07-05T18:26:25.324542Z'
+)
+// -> 1 week after
+
+date_interval_human(
+    '2008-07-16T23:13:26.234212Z',
+    '2008-07-05T18:26:25.324542Z',
+    'es'
+)
+// -> 1 semana después
+
+ +
+
+ + + Last update: + April 6, 2024 10:34:57 + + + +
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/webhookscript/functions/files.html b/webhookscript/functions/files.html new file mode 100644 index 0000000..0cb709c --- /dev/null +++ b/webhookscript/functions/files.html @@ -0,0 +1,1081 @@ + + + + + + + + + + + + + + + + + + + + + + + + File handling - Webhook.site Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + + + + + + +

File handling

+ +

When you send an email, or send a multipart/form-data request, files are extracted as the file.*.* variables, but you can also loop over files using WebhookScript.

+

files(string name) : array

+

Returns an array of files, with the following keys:

+
    +
  • id - unique file ID
  • +
  • filename - original filename
  • +
  • size - size of the file in bytes
  • +
  • content-type - mime content type of the file
  • +
+
dump(files())
+
+// [
+//   0: [
+//     "id": "76b7274a-e806-4f72-ba49-85ad05926ef0", 
+//     "filename": "Screen Shot 2020-06-05 at 2.15.29 PM.png", 
+//     "size": 1203671, 
+//     "content_type": "image/png"
+//   ]
+// ]
+
+// Filtering files by type
+for (file in files()) {
+    if (r'.*\.png'.match(file['filename'])) {
+        dump(file['filename'] + ' is png.')
+    }
+}
+
+// "Screen Shot 2020-06-05 at 2.15.29 PM.png is png."
+
+

file_content(string fileId) : string

+

Returns the content of a specific file, using the id key from the files() function above.

+
firstFile = array_get(files(), 0)
+fileContent = file_contents(firstFile['id']);
+
+ +
+
+ + + Last update: + April 6, 2024 10:34:57 + + + +
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/webhookscript/functions/flow.html b/webhookscript/functions/flow.html new file mode 100644 index 0000000..8ddaf38 --- /dev/null +++ b/webhookscript/functions/flow.html @@ -0,0 +1,1315 @@ + + + + + + + + + + + + + + + + + + + + + + + + Flow Control and Responses - Webhook.site Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + + + + + +
+
+ + + + + + + + + + + + + +

Flow Control and Responses

+ +

Script Execution

+

action(string action_type, array parameters) : array

+

Runs Custom Actions in WebhookScript. Can be used to loop over items in a way that not possible using the visual Custom Actions editor.

+

The function returns an array of runtime variables which can be used to fetch the result of an action that sets a variable, like google_sheets_get_values.

+

The action_types and their parameters can be seen here.

+

The following action extracts a list of files from an array of objects in a JSON array and uploads each file to Dropbox using the dropbox_upload_file action.

+

Example

+

In this example, we assume that the request content sent to the Webhook.site URL contains the following:

+
{
+  "files": [
+    {
+      "url": "https://example.com/path/980e683e-9bd7-4512-bc0e-acfd6e022a81",
+      "name": "example_1.png"
+    },
+    {
+      "url": "https://example.com/path/c8e1282f-46a7-45ab-9699-0472ff9ab96c",
+      "name": "example_2.png"
+    }
+  ]
+}
+
+

In the script, the request contents are JSON decoded and looped over. For each item, the file's URL is downloaded and a Dropbox Upload File action is executed.

+
files = json_path(var('request.content'), '.files.*')
+
+for (file_info in files) {
+
+  // Download file from URL
+  file_download = request(file_info['url'])
+
+  // Generate a destination path for the Dropbox file
+  destination_path = '/Example Files/%s'.format(file_info['name'])
+
+  // Execute Dropbox Upload File action
+  action(
+    'dropbox_upload_file',
+    [
+      'path': destination_path,
+      'body': file_download['content'],
+      'mode': 'update',
+      'provider_id': providerId
+    ]
+  )
+
+}
+
+

delay(int seconds, string code) [deprecated]

+
+

Warning

+

This function has been deprecated and should no longer be used. As an alternative, it's recommended that you mark a WebhookScript Custom Action as Queued. More info here.

+
+

Executes code in the future. Any output will be stored on the request and will show with a "Was delayed" label.

+

The code will not inherit the execution scope.

+

In this example, the format function is used to prepare the code string with a URL, causing {} to be replaced with with https://example.com.

+
code = '
+  request(
+      "{}",
+      \'{"message": "Hello World!"}\',
+      "POST"
+  )
+'
+
+url = 'https://example.com'
+
+delay(5, code.format(url));
+
+

The maximum amount of seconds allowed is 604800 (7 days).

+

dont_save()

+

Marks the request so it is not saved in Webhook.site, which is useful when receiving a large amount of requests. The request can still be seen when it comes in, but will not be available through through the app later, or through the API. The action is useful in cases where e.g. a URL receive a large amount of requests.

+

exec(string code) : any

+

Executes code in code and returns the result. The code will inherit the execution scope.

+

import(string url) : any

+

Downloads code located at url and returns the result. The code will inherit the execution scope.

+

As an example, this can be used if you want to re-use code. Just upload it to a server or e.g. Github and use it in different WebhookScript actions.

+
result = import('https://raw.githubusercontent.com/webhooksite/scripts/ec22946a83ea85f607fcc6bff83f9d81ed2fe4ed/hello_world.ws')
+echo(result) // value
+
+

stop()

+

Stops Custom Action execution.

+

Responses

+

respond(string content, int status, array headers)

+

Stops Custom Action execution and return a response immediately.

+

set_content(string content)

+

Sets or overwrites the response content of the URL. Script execution continues.

+

set_header(string header_name, string header_value)

+

Sets or overwrites a response header of the URL. Script execution continues.

+

set_response(string content, int status, array headers)

+

Sets or overwrites response content, status and headers in single function. Script execution continues.

+

headers should be an array of strings e.g. ["X-Example: Value", "X-Foo: Bar"].

+

set_status(number status)

+

Sets or overwrites the HTTP response status of the current URL. Script execution continues.

+ +
+
+ + + Last update: + April 6, 2024 10:34:57 + + + +
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/webhookscript/functions/general.html b/webhookscript/functions/general.html new file mode 100644 index 0000000..fff751b --- /dev/null +++ b/webhookscript/functions/general.html @@ -0,0 +1,1216 @@ + + + + + + + + + + + + + + + + + + + + + + + + General - Webhook.site Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + + + + + + +

General

+ +

About Functions

+

These are the functions that can be used in your script, and includes various utility functions and functions to interact with your Webhook.site URL.

+

Chaining

+

Functions can be chained directly to a primitive (strings, numbers, arrays).

+

These two statements are equivalent:

+
'Hello World'.echo()
+
+
echo('Hello World')
+
+

They can even be chained, for example:

+
'Hello World'.hash('md5').echo() 
+
+

Furthermore, functions that begin in a type can be referenced without it, for example, when calling the format function with the first argument being a string, the language infers that actually the string_format function should be used.

+
echo(string_format('hello %s', 'world')) // hello world
+
+'hello %s'.format('world').echo() // hello world
+
+

Read more about functions in the reference.

+

Custom functions

+

Define your own functions like this:

+
function sub(a, b) {
+    return a - b;
+}
+
+

Read more about functions in the reference.

+

Debugging and output

+

echo(...string string)

+

Adds string to script debug output.

+

dd(...any value)

+

Stops Custom Action execution and adds value to script debug output.

+

dump(...any value)

+

Adds value as a decoded string to script debug output.

+

Types

+

type(any value) : string

+

Returns the type name of a value, e.g. "string".

+ +
+
+ + + Last update: + April 6, 2024 10:34:57 + + + +
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/webhookscript/functions/math.html b/webhookscript/functions/math.html new file mode 100644 index 0000000..c54913a --- /dev/null +++ b/webhookscript/functions/math.html @@ -0,0 +1,1446 @@ + + + + + + + + + + + + + + + + + + + + + + + + Math and Numbers - Webhook.site Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + + + + + +
+
+ + + + + + + + + + + + + +

Math and Numbers

+ +

Trigonometry

+

atan(number number) : number

+

cos(number number) : number

+

sin(number number) : number

+

tan(number number) : number

+

Hexadecimal & Binary

+

bin2hex(string data): string

+

Converts a binary tring to a hexadecimal representation.

+

hex2bin(string hex_string) : ?string

+

num2hex(number number) : string

+

hex2num(string hex_string) : number

+

General

+

abs(number number) : number

+

ceil(number number) : number

+

Rounds a number up to nearest integer.

+

floor(number number) : number

+

Rounds a number down to nearest integer.

+

is_numeric(any value) : bool

+

Returns true if value is numeric.

+

Examples:

+
    +
  • 12345 returns true.
  • +
  • "1.0" returns true.
  • +
  • null returns false.
  • +
+

max(array numbers) : number

+

min(array numbers) : number

+

mod(number number, number divisor) : number

+

Returns the remainder after number is divided by divisor.

+

number_length(number number) : number

+

pi() : number

+

Returns the value of Pi.

+

pow(number number, number power) : number

+

rand(number min, number max) : number

+

Returns a random number between min and max.

+

round(number number, number precision) : number

+

Rounds a number up with specified precision (number of digits after decimal point.)

+
round(1.39, 1) // -> 1.4
+
+

sqrt(number number) : number

+

to_number(any value) : number

+ +
+
+ + + Last update: + April 6, 2024 10:34:57 + + + +
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/webhookscript/functions/network.html b/webhookscript/functions/network.html new file mode 100644 index 0000000..3fbca30 --- /dev/null +++ b/webhookscript/functions/network.html @@ -0,0 +1,1303 @@ + + + + + + + + + + + + + + + + + + + + + + + + Network and HTTP - Webhook.site Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + + + + + +
+
+ + + + + + + + + + + + + +

Network and HTTP

+ +

HTTP

+

query(array form_values) : string

+

Converts an associative array into a form-style string, used for e.g. application/x-www-form-urlencoded requests or HTTP query strings.

+
query(['country': 'Curaçao', 'population': 158665]) 
+// country=Cura%C3%A7ao&population=158665
+
+

http(string url, array options) : array

+

Sends a HTTP request and returns an array with the following keys containing response data:

+
    +
  • content (contains a cURL error message in case of an error)
  • +
  • status (null in case of an error)
  • +
  • headers
  • +
  • url
  • +
+

Options array

+

The options array can contain the following keys; none are required.

+
    +
  • mode - string, one of: text (default), multipart, urlencoded, forward
  • +
  • content - string, body content, used when mode is text
  • +
  • method - string, HTTP method, e.g. POST
  • +
  • multipart - array of arrays, used when mode is multipart, containing keys:
      +
    • name - required, string, form item name
    • +
    • filename - string
    • +
    • content-type - string
    • +
    • content - string
    • +
    +
  • +
  • urlencoded - array of arrays, used when mode is urlencoded, containing keys:
      +
    • name - required, string, form item name
    • +
    • value - string
    • +
    +
  • +
  • headers - array of strings, HTTP headers
  • +
  • skip_ssl_verification - default false, skips TLS/SSL certificiate validation for HTTPS requests
  • +
  • timeout - number, default 5, timeout in seconds
  • +
+

POST Request

+

To send a simple POST request containing e.g. JSON data, use the following:

+
http(
+    'https://example.com',
+    [
+        'method': 'POST', 
+        'content': '{"example": "json"}', 
+        'headers': ['Content-Type: application/json']
+    ]
+)
+
+

form/multipart request

+
http(
+    'https://example.com', 
+    [
+        'method': 'POST',
+        'mode': 'multipart', 
+        'multipart': [
+            [
+                'name': 'value1',
+                'content': 'This is a value',
+            ]
+        ]
+    ]
+)
+
+

request(string url, string body, string method = 'GET', array headers, bool override = false, timeout = 5) : array

+

Sends a HTTP request and returns an array with the following keys containing response data:

+
    +
  • content (contains a cURL error message in case of an error)
  • +
  • status (null in case of an error)
  • +
  • headers
  • +
  • url
  • +
+

The headers should be an array of strings, for example:

+
[
+  'Content-Type: application/json',
+  'Accept: application/json, text/plain, */*'
+]
+
+

To get a JSON document, validate if valid JSON, and get a property:

+
response = request('https://example.com')
+
+decoded = json_decode(response['content'])
+if (decoded) {
+  value = decoded['value']
+}
+
+

If override is set to true, none of the content from the original request is included (e.g. query strings, headers, content.)

+

multipart(string url, array items, string method = 'POST', array headers, num timeout) : array

+

Sends a HTTP Multipart request, e.g. for uploading files.

+

name (the form name value) and content are required in the items array; the rest is optional.

+

timeout specifies the request timeout in seconds.

+

The return value is an array with the following keys containing response data:

+
    +
  • content (contains a cURL error message in case of an error)
  • +
  • status (null in case of an error)
  • +
  • headers
  • +
  • url
  • +
+

Example:

+
multipart(
+  'https://example.com/file-upload', [
+    [
+      'name': 'file[]',
+      'filename': 'file1.txt',
+      'content': 'hello world',
+      'headers': ['Header1': 'value', 'Header2': 'othervalue']
+    ],
+    [
+      'name': 'client_id',
+      'content': 'abcd123',
+    ]
+  ],
+  'POST',
+  ['Api-Key: xxxx']
+)
+
+

url_decode(string value) : string

+

Returns an URL-decoded version of value.

+

url_encode(string value) : string

+

Returns an URL-encoded version of value.

+
url_encode('here\'s a value') // here%27s+a+value
+
+ +
+
+ + + Last update: + April 6, 2024 10:34:57 + + + +
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/webhookscript/functions/string.html b/webhookscript/functions/string.html new file mode 100644 index 0000000..92dd5bb --- /dev/null +++ b/webhookscript/functions/string.html @@ -0,0 +1,2270 @@ + + + + + + + + + + + + + + + + + + + + + + + + Strings - Webhook.site Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + + + + + + +

Strings

+ +

General string functions

+

string_contains(string subject, number/string/regex value) : bool

+

Returns boolean if subject contains value

+

string_find_first(string subject, number/string value) : number

+

Returns position of value in subject, or false if not found

+

string_find_last(string subject, number/string value) : number

+

Returns position of value in subject, or false if not found

+

string_format(string formatString, ...any items) : string

+

Sprintf-like formatting of formatString with items, see PHP sprintf docs.

+

string_join(string subject, array items (number/string/bool/array)) : string

+

Joins items with string subject

+

string_length(string string) : number

+

Returns length of string (multibyte-aware)

+

string_lower(string string) : string

+

Converts string to lowercase (multibyte-aware)

+

string_number_of(string string) : number

+

Returns number value of string

+

string_random(number length) : string

+

Returns a random string of length using the A–Z,a–z,0–9 alphabet.

+

string_replace(string subject, string/regex/array search, string replace) : string

+

Replaces string search with replace found in subject.

+
string_replace('this is a sentence', 'sentence', 'string') // -> this is a string
+
+string_replace('this is great', r'(.*) is (.*)', '$1 was $2') // -> this was great
+
+

string_replace(string subject, array replace_pairs) : string

+

Replaces items found in subject using the replace_pairs array:

+
string_replace("hello, it's good", [
+    'hello': 'hi',
+    'good': 'great'
+]) // -> hi, it's great
+
+

string_reverse(string subject) : string

+

Reverses string subject

+

string_slice(string subject, number from, number to = null) : string

+

Extracts a segment of a string. Multibyte-aware.

+

string_slice('hello world', 0, 5) returns hello.

+

string_slice('hello world', 6) returns world.

+

string_shuffle(string string) : string

+

Returns string where the individual characters has been shuffled.

+

string_split(string subject, string/regex delimiter) : array

+

Returns array of split string subject with delimiter

+

string_title(string string) : string

+

Returns string converted to title case.

+

string_title('hello world') returns Hello World.

+

string_upper(string string) : string

+

Converts string to UPPERCASE (multibyte-aware).

+

to_regex(string regex) : regex

+

Converts a regex string to a regex type

+

to_string(string/number/bool value) : string

+

Returns value as string

+

trim(string string): string

+

Returns string with space, tab and newline characters removed from the beginning and end of the string.

+

uuid() : string

+

Returns a random v4 UUID.

+

CSV

+

csv_to_array(string content, string delimiter, ?int header_offset, string enclosure, string escape) : array

+

Takes a CSV string and outputs to an array, with each row being an item in the array.

+
    +
  • content should be a string containing the CSV document.
  • +
  • delimiter will explicitly set the CSV delimiter the parser will attempt to use (e.g. ;). Must be a single character. Defaults to , (comma.)
  • +
  • header_offset, when specified, causes the output array item's keys to be set to the header values. Setting to 0 will mark the first row as the header row.
  • +
  • enclosure sets the field enclosure character. Must be a single character. Defaults to " (double quote.)
  • +
  • escape sets the field escape character. Must be a single character. Defaults to \ (backslash.)
  • +
+
csv_content = 'firstname,lastname,title
+"M. J.",Plumley,"Sr. Developer"
+Emily,"Jenna Platt","Chief Information Officer"'
+
+array = csv_to_array(csv_content, ',', 0)
+
+echo(json_encode(array))
+
+// [
+//     {
+//         "firstname": "John",
+//         "lastname": "Doe",
+//         "title": "Sr. Developer"
+//     },
+//     {
+//         "firstname": "Emily",
+//         "lastname": "Jenna Platt",
+//         "title": "Chief Information Officer"
+//     }
+// ]
+
+

Base64

+

base64_decode(string string) : string

+

Returns a base64-decoded string.

+

base64url_decode(string string) : string

+

Returns a base64url-decoded string.

+

If the base64 string was encoded using URL-friendly base64url format, this function should be used rather the regular base64_decode function.

+

base64_encode(string string) : string

+

Returns base64-encoded string.

+

base64url_encode(string string) : string

+

Returns a URL-friendly base64url-encoded string, where characters +, / have been replaced by - and _, and any = padding characters have been removed.

+

Hashing

+

hash(string/number value, string algo) : string

+

Returns a hashed version of value using the algo algorithm.

+

'hello world'.hash('md5')  // 5eb63bbbe01eeed093cb22bb8f5acdc3
+
+

+

The following built-in algorithms are available: md2, md4, md5, sha1, sha224, sha256, sha384, sha512/224, sha512/256, sha512, sha3-224, sha3-256, sha3-384, sha3-512, ripemd128, ripemd160, ripemd256, ripemd320, whirlpool, tiger128,3, tiger160,3, tiger192,3, tiger128,4, tiger160,4, tiger192,4, snefru, snefru256, gost, gost-crypto, adler32, crc32, crc32b, fnv132, fnv1a32, fnv164, fnv1a64, joaat, haval128,3, haval160,3, haval192,3, haval224,3, haval256,3, haval128,4, haval160,4, haval192,4, haval224,4, haval256,4, haval128,5, haval160,5, haval192,5, haval224,5, haval256,5.

+

hmac(string value, string algo, string secret) : string

+

Returns the calculated message digest/hash in a hexadecimal formatted as a string.

+

For a list of possible values for algo, see hash() above.

+

See also binary and hexadecimal conversion functions.

+

In the following example, the hash needs to be converted to binary, and then to base64, to match the signature.

+
hmac = hmac(var('request.content'), 'sha256', 'insert_secret_here');
+signature = var('request.header.x-signature', '');
+hash = base64_encode(hex2bin(hmac))
+
+if (hash != signature) {
+    respond('Unauthorized', 401);
+}
+
+

Cryptography

+

List of available algorithms for functions in the Cryptography section:

+
    +
  • blake2b512
  • +
  • blake2s256
  • +
  • md4
  • +
  • md5
  • +
  • md5-sha1
  • +
  • ripemd160
  • +
  • sha1
  • +
  • sha224
  • +
  • sha256
  • +
  • sha3-224
  • +
  • sha3-256
  • +
  • sha3-384
  • +
  • sha3-512
  • +
  • sha384
  • +
  • sha512
  • +
  • sha512-224
  • +
  • sha512-256
  • +
  • shake128
  • +
  • shake256
  • +
  • sm3
  • +
  • whirlpool
  • +
+

sign(string value, string private_key, string algo) : false/string

+

Signs value using private_key and algo. Returns signature on success, false on failure.

+

For an example using sign() for JWT authorization, see here.

+

digest(string value, string algo) : false/string

+

Returns a cryptographic digest of value using algo. Returns false on failure.

+

verify(string value, string signature, string public_key, string algo) : true/false

+

Verifies value using signature, public_key and algo

+

HTML and Markdown

+

html_strip_tags(string string) : string

+

Returns a string with all HTML tags removed.

+

html_strip_tags('<b>test</b>') returns test.

+

html_to_text(string string) : string

+

Converts HTML to plaintext. A more aggressive version of html_strip_tags.

+

html_to_text('<b>test</b>') returns test.

+

html_decode(string string) : string

+

Decodes all HTML entities (for example, &nbsp;) to normal characters.

+

html_encode(string string) : string

+

Replaces characters in a string with HTML encoded versions.

+

markdown_to_html(string string, bool safe_mode = false) : string

+

Converts a Markdown string to HTML.

+

markdown_to_html('# Hello world') returns <h1>Hello world</h1>.

+

If safe_mode is set to true, characters like <, > are HTML-entity encoded.

+

JSON

+

json_decode(string json) : array

+

Decodes json and returns an array.

+
array = json_decode(var('request.content'))
+
+

json_encode(array array, bool format = true) : string

+

Takes an array and encodes it as a JSON string.

+

Per default, the JSON array is formatted with whitespace. To turn it off, set format to false.

+

json_path(string json, string jsonpath, bool return_first = true) : string

+

Returns the result of a json string parsed using the JSONPath functionality.

+

Per default, if there's just one match (e.g. if matching on a property value that's a string), this value is returned. To always return an array, set return_first to false.

+
dump(json_path('{"v": []}', 'v[*]', false))
+dump(json_path('{"v": []}', 'v[*]'))
+// []
+// ""
+
+dump(json_path('{"v": ["item1"]}', 'v[*]', false))
+dump(json_path('{"v": ["item1"]}', 'v[*]'))
+// [0: "item1"]
+// "item1"
+
+dump(json_path('{"v": ["item1", "item2"]}', 'v[*]', false))
+dump(json_path('{"v": ["item1", "item2"]}', 'v[*]'))
+// [0: "item1", 1: "item2"]
+// [0: "item1", 1: "item2"]
+
+

json_escape(string json) : string

+

JSON-escapes all special JSON characters like double quotes, newlines, etc.

+

Regex

+

preg_match(string regex, string subject) : array/false

+

Returns the matching values as an array, or false if the regex did not match. Supports regex pattern modifiers.

+
// Returns anything enclosed within <html> tags in a string
+html = preg_match('/<html>(.*)<\\/html>/s', content)
+
+

regex_extract(regex regex, string subject) : array/false

+

Returns the matching string and all match groups as an array, and false on failure.

+
input = "You're a good bot"
+
+output = regex_extract(r"You're (\w) (.*)", input)
+
+dump(output) // [0: "You're a good bot", 1: "a", 2: "good bot"]
+
+

regex_extract_first(regex regex, string subject, any default) : string/false

+

Returns the first match group of a regex, and false (or default, if set) on failure.

+
input = "You're a good bot"
+output = regex_extract(r"You're (.*)", input)
+dump(output) // "a good bot"
+
+input = "Hello world"
+output = regex_extract(r"You're (.*)", input, 'no value')
+dump(output) // "no value"
+
+

regex_match(regex regex, string subject) : string/false

+

Returns the first matching string, otherwise false.

+
input = "You're a good bot"
+
+output = regex_match(r"You're .*", input)
+
+dump(output) // "You're a good bot"
+
+

regex_to_string(regex regex) : string

+

Returns the regex converted to a string

+

XML

+

xml2array(string xml) : array

+

Converts XML to a WebhookScript array. This can be useful for parsing XML, or e.g. converting XML to JSON.

+

Note that this function is opinionated - there's no one way to convert XML to an array as XML has more features than WebhookScript arrays. Therefore the function attempts to carry over all the data by automatically generating properties like @value and @attributes depending on the input data.

+

For example, the following XML:

+
<orders>
+  <record>
+    <Name type="full">John Doe</Name>
+    <Reference>49690</Reference>
+  </record>
+  <record>
+    <Name type="username">someone@example.com</Name>
+    <Reference>49690</Reference>
+  </record>
+</orders>
+
+

Converts to JSON via the following script:

+
json_encode(xml2array(var('request.content')))
+
+

Which returns:

+
{
+  "orders": {
+    "record": [
+      {
+        "Name": {
+          "@value": "John Doe",
+          "@attributes": {
+            "type": "full"
+          }
+        },
+        "Reference": 49690
+      },
+      {
+        "Name": {
+          "@value": "someone@example.com",
+          "@attributes": {
+            "type": "username"
+          }
+        },
+        "Reference": 49690
+      }
+    ]
+  }
+}
+
+

xpath(string xpath, string input): string/null

+

Returns the first result of an XPath query on XML document input.

+

Given a request with the following content:

+
<?xml version="1.0"?>
+<organization name="ExampleCo">
+  <employees>
+    <employee id="1">Jack</employee>
+    <employee id="2">Ann</employee>
+  </employees>
+</organization>
+
+
    +
  • xpath(var('$request.content$'), '//employee[1]') // returns "Jack"
  • +
  • var('$request.content$').xpath('//employee[1]') // returns "Jack"
  • +
+

More information and examples regarding XPath.

+

xpath_all(string xpath, string input): string/null

+

Returns the results of an XPath query on XML document input as an array.

+

Given a request with the following content:

+
<?xml version="1.0"?>
+<organization name="ExampleCo">
+  <employees>
+    <employee id="1">Jack</employee>
+    <employee id="2">Ann</employee>
+  </employees>
+</organization>
+
+
    +
  • xpath_all(var('$request.content$'), '//employee]') // returns [0: "Jack", 1: "Ann"]
  • +
  • var('$request.content$').xpath('//employee') // returns [0: "Jack", 1: "Ann"]
  • +
+

More information and examples regarding XPath.

+

Special string functions

+

convert_kana(string, mode) : string

+

Performs a "han-kaku" - "zen-kaku" conversion for string string. This function is only useful for Japanese. See here for more info.

+ +
+
+ + + Last update: + April 6, 2024 10:34:57 + + + +
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/webhookscript/functions/variables.html b/webhookscript/functions/variables.html new file mode 100644 index 0000000..5164190 --- /dev/null +++ b/webhookscript/functions/variables.html @@ -0,0 +1,1110 @@ + + + + + + + + + + + + + + + + + + + + + + + + Custom Action Variables - Webhook.site Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + + + + + +
+
+ + + + + + + + + + + + + +

Custom Action Variables

+ +

These functions lets you interface with other Custom Actions by getting and setting variables from them. These functions are also how you retrieve Global Variables defined in the Control Panel.

+

var(string variable_name, ?string/number default) : mixed

+

Retrieves the value of a Variable or Global Variable (defined in the Control Panel). The surrounding dollar signs are not mandatory.

+

Returns null (or the value of default) if the variable does not exist.

+
var('request.header.x-request-verification') // returns value of the `x-request-verification` header
+
+

set(string variable_name, string variable_value)

+

Exports a Variable for use in downstream actions, like the Set Runtime Variable action.

+

For example, the following code:

+
set('myvar', 'Hello world')
+
+

Would cause the string $myvar$ to be replaced with Hello world in all subsequent actions.

+

store(string global_variable_name, any value): any

+

Permanently creates or updates a Global Variable (as defined in Control Panel.)

+

The value can also be retrieved with the var() function in subsequent action executions.

+

delete(string global_variable_name)

+

Deletes a global variable.

+

variables : array

+

A variable (not a function) containing an associative array with all available Webhook.site variables.

+
user_agent = variables['request.header.user-agent']
+
+ +
+
+ + + Last update: + April 6, 2024 10:34:57 + + + +
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/webhookscript/index.html b/webhookscript/index.html new file mode 100644 index 0000000..718b149 --- /dev/null +++ b/webhookscript/index.html @@ -0,0 +1,1195 @@ + + + + + + + + + + + + + + + + + + + + + + + + WebhookScript - Webhook.site Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + + + + + + +

About WebhookScript

+

"WebhookScript" Custom Action screenshot

+

WebhookScript is an easy to use scripting language designed for executing Web-related actions on incoming requests.

+

While the other actions like Extract Regex and Send Email allows you to create flows in a visual editor, WebhookScript makes it quicker to create more advanced logic.

+

WebhookScript can be combined with other Custom Actions as data can be shared between them using Variables.

+

Syntax

+

The syntax is very similar to PHP and JavaScript. See also the full language specification.

+
products = [
+  'apple':     ['price': 10],
+  'blueberry': ['price': 1],
+  'cake':      ['price': 550]
+]
+
+shouldAddVat = var('request.query.vat');
+selectedProduct = var('request.query.product');
+
+if (!selectedProduct) {
+    respond('Please select a product!', 500)
+}
+
+price = products[selectedProduct]['price'];
+
+if (shouldAddVat == 1) {
+    price = price * 1.25;
+}
+
+respond(
+    'Your price is {}'.format(price),
+    200
+);
+
+

Variables in WebhookScript

+

Custom Action Variables in WebhookScript behave a little differently than other action types: in the code, they will not be replaced automatically like in other action types.

+

Instead, to interface with Custom Action Variables (created in previous actions, or default variables provided for each request or email), the function var() can be used.

+

The dollar-sign syntax (e.g. $request.content$) is optional when using the var() function, and the following two statements are equivalent: var('$request.content$') / var('request.content').

+

In addition, set() can be used to export a variable from your script to further downstream actions. store() is used to permanently set a Global Variable.

+

About the Editor

+

"WebhookScript" Custom Action screenshot

+

Shortcuts

+

The shortcuts are available when the editor is focused.

+ + + + + + + + + + + + + + + + + + + + +
WindowsMacShortcut
Alt-RAlt-RTest code (update Debug Panel)
Ctrl-SCmd-SSave action without exiting
+

Debug Panel

+

Below the editor is the "debug panel" containing data relating to the current and previous actions:

+
    +
  • +

    Debug outputs shows the outputs of all the actions, with the current action being edited or created marked in blue.

    +
  • +
  • +

    Response shows details of the response of the URL formatted in JSON.

    +
  • +
  • +

    Variables is a table of all current available variables for use in the script with the var() function or variables array.

    +
  • +
+

Fullscreen Mode

+

To enable fullscreen mode, click the Expand button in the upper right corner to make the editor take up more screen space. Click again to disengage fullscreen mode.

+ +
+
+ + + Last update: + April 6, 2024 10:34:57 + + + +
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/webhookscript/reference.html b/webhookscript/reference.html new file mode 100644 index 0000000..6c609ad --- /dev/null +++ b/webhookscript/reference.html @@ -0,0 +1,1816 @@ + + + + + + + + + + + + + + + + + + + + + + + + Reference - Webhook.site Docs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ + + + + + + + + + + + + +

Language Reference

+

These are the functions that can be used in your script, and includes various utility functions and functions to interact with your Webhook.site URL.

+

Syntax

+

The language is built with a familiar PHP/JS/C-like syntax. Statements are separated using the ; character, but this is only required for multiple statements on the same line:

+
    +
  • +

    Using semicolons (recommended): +

    a = 1 + 2; b = a + 3;
    +c = b - a;
    +

    +
  • +
  • +

    Using newlines: +

    a = 1 + 2
    +b = a + 3
    +c = b - a
    +

    +
  • +
+

Data types

+

The language has 6 data types:

+
    +
  • Bool
  • +
  • Number
  • +
  • String
  • +
  • Regex
  • +
  • Array
  • +
  • Function
  • +
+

Boolean

+

Example usage: +

a = true;
+b = 1 == 2; // false
+c = b == false; // true
+d = c == "hello"; // ERR: Cannot compare 'bool' and 'string'
+e = "hello" == r"[0-9]"; // false
+f = "hello" == r"l{2}"; // true
+

+

Number

+

Both integer and float values are supported.

+

Example usage:

+
a = 4 - 3; // 1
+b = a / 3; // 0.333...
+
+

String

+

This data types represents a series of characters. Multi-byte characters (accents, diacritics) are treated properly.

+

Example usage: +

a = "hello";
+b = "wóóórld!";
+c = a + " " + b; // "hello wóóórld!"
+

+

Regex

+

Regex data type exists for advanced string matching. It is defined using the r"..." literal (a string literal prefixed with r) and treated as PCRE (Perl-compatible) regular expressions (the same as within PHP itself) with Unicode mode enabled.

+

Example usage: +

a = "facebook";
+b = r"[o]{2}.*";
+c = a == b; // true
+

+

Array

+

Arrays are untyped (PHP-style) containers that can accomodate multiple values of different (or same) types. Optionally, array index can be defined for a value. By default, integer index starting from the lowest index found (or from 0) is used, but strings can also be used.

+

Example usage: +

a = ["abc", 123, 4: true, false, r"[A-Z]+"];
+// Resulting array: [0: "abc", 1: 123, 4: true, 5: false, 6: r"[A-Z]+"]
+
+b = json_encode(["the_number": 123, "other_numbers": [42, 1337, 80085]])
+// Result:
+// {
+//     "the_number": 123,
+//     "other_numbers": [
+//         42,
+//         1337,
+//         80085
+//     ]
+// }
+

+

Ranges

+

Simple way of defining ranges between numbers is provided via the a..[s..]b range syntax.

+
    +
  • a is the from value.
  • +
  • b is the to value, inclusive, if it is not "skipped" due to a rather large step (see below).
  • +
  • s (optionally) is the step value which to use.
  • +
+

Example usage: +

a = 1..4; // (array) [0: 1, 1: 2, 4: 3, 5: 4]
+b = 1..2..4; // (array) [0: 1, 1: 3]
+c = 10..4..16; // (array) [0: 10, 1: 14]
+_x = 3
+_y = 6
+_z = 2
+d = _x.._z.._y; // (array) [0: 3, 1: 5]
+
+Return value of such "range literal" is a new array having values that are based on the range's parameters.

+

Functions

+

Function is a value type that represents a "unit" of some self-contained logic. In WebhookScript they have their own type and are treated as first-class citizens: they can be stored inside variables and passed around as such. Direct invocation of an anonymous function is supported, provided that the anonymous function's definition is enclosed in parentheses. A function does capture its surrounding variables.

+

Example usage: +

// Traditional definition.
+function sub(a, b) {
+    return a - b;
+}
+
+// A variable "sub" that holds the "sub()" function is now defined in current scope.
+sub(1, 2); // Returns -1
+
+// Storing a function value into a variable.
+// Note: This is equivalent to the previous definition.
+sub_2 = function(a, b) {
+    return a - b;
+};
+
+// A variable "sub_2" that holds the "sub_2()" function is now defined in current scope.
+sub_2(1, 2); // Returns -1
+
+// Creating a function with alternative, short syntax.
+// Note: This is equivalent all of the previous definitions.
+sub_3 = (a, b) => {
+    return a - b;
+};
+
+// A variable "sub_3" that holds the "sub_3()" function is now defined in current scope.
+sub_3(1, 2); // Returns -1
+
+// Creating and using an anonymous function directly.
+// Using an alternative, short syntax.
+((a, b) => {
+    return a - b;
+})(1, 2); // Returns -1
+

+

Chained functions

+

In addition to classical function invocation, WebhookScript additionaly supports Uniform Function Call Syntax (UFCS) as a way to call functions "on values". Essentially, it means that calling foo(bar); is equivalent to calling bar.foo(), or - to provide an example with additional parameters - that calling foo(bar, 1, true, "something"); is equivalent to calling bar.foo(1, true, "something").

+

Value-type based inference of called function name

+

When using chained function invocation, the interpreter will try to find the most fitting function to call. "Most fitting" meaning that when the client calls bar() function on a value having the string type, WebhookScript will try to find and use the string_bar() first. If such function is not defined, only then will the interpreter use the original bar() function.

+

Consider this a syntactic sugar to make coding in WebhookScript a bit more user-friendly. Because of this the user is able to call "something".length() on a string the same way as calling [1, 2, 3].length() on an array, even though there are in fact two separate functions string_length() and array_length() invoked behind the scenes.

+

Operators

+

Plethora of well known operators can be used to define relationships between and/or affect various values. Different operators can have various effects on various data types, some of which are covered down below.

+

Precedence

+

Precedence of various operators is defined as follows (from highest to lowest): +- ( ... ) (parentheses) +- ! (logical not) +- *, / (multiplication/division) +- +, - (addition/subtraction) +- ==, !=, >=, <=, >, < (comparison) +- and (logical and) +- or (logical not) +- = (assignment)

+
Precedence example
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Raw sourceEquivalent to
1 + 2 + 3 + 4((1 + 2) + 3) + 4
1 - 2 + 3 - 4((1 - 2) + 3) - 4
1 + 2 * 3 + 41 + (2 * 3) + 4
1 + 2 * 3 / 41 + ((2 * 3) / 4)
1 + -2 * 3 / 41 + (((-2) * 3) / 4)
1 and 2 or 3 and 4(1 and 2) or (3 and 4)
1 or 2 or 3 and 4(1 or 2) or (3 and 4)
1 or !2 or !3 and 4(1 or (!2)) or ((!3) and 4))
x = true or false and truex = (true or (false and true))
x = a == bx = (a == b)
x = a > 5 and b < 6x = ((a > 5) and (b < 6))
+

Logical operators

+
    +
  • and
      +
    • Returns true if both operands are truthy.
    • +
    • Otherwise returns false.
    • +
    +
  • +
  • or
      +
    • Returns true if either one (or both) operand is truthy.
    • +
    • Otherwise returns false.
    • +
    +
  • +
+

Negation

+
    +
  • !
      +
    • Negate the value located after this operator.
    • +
    • Examples: +
      a = true;
      +b = !a; // false
      +c = !b; // true
      +d = !!b; // false
      +
    • +
    +
  • +
+

Assignment

+
    +
  • =
      +
    • Assigns some value to a variable.
    • +
    • Can also be used to insert values to values that support it (eg. arrays).
    • +
    • Examples: +
      a = 1;
      +b = "a word";
      +c = false;
      +d = r"regul[ar]+";
      +e = ["x", "b": "z"];
      +e["c"] = "x"; // e == ["x", "b": "z", "c": "x"]
      +
    • +
    +
  • +
+

Addition and multiplication

+
    +
  • +, -
      +
    • Performs addition (subtraction) of two values.
        +
      • Numbers:
          +
        • + Add two numbers.
        • +
        • - Subtract two numbers.
        • +
        +
      • +
      • Strings:
          +
        • + Concatenate two strings.
        • +
        • - Removes all occurences of the right side from the left side.
        • +
        • - (if the right side is a Regex value) Removes all matches of the regex from the left side string.
        • +
        +
      • +
      +
    • +
    • Examples: +
      a = 5 + 4 // (number) 9
      +b = 5 - 4; // (number) 1
      +c = "a word and number " + 5.to_string(); // (string) "a word and number 5"
      +d = "a word and number {}".format(5); // (string) "a word and number 5"
      +e = "a word" + " and one more"; // (string) "a word and one more"
      +f = "a word" - "or"; // (string) "a wd"
      +g = "regular expressions" - r"regul[ar]+\s*"; // (string) "expressions"
      +_x = 5 + "4" // ERR: Cannot use operator '+' with 'number' and 'string'
      +_x = "a word and number " + 5; // ERR: Cannot use operator '+' with 'number' and 'string'
      +
    • +
    +
  • +
  • *, /
      +
    • Performs multiplication (division) of two values.
        +
      • Numbers:
          +
        • + Multiply two numbers.
        • +
        • - Divide two numbers.
        • +
        +
      • +
      +
    • +
    • Examples: +
      a = 1 * -2; // (number) -2
      +b = 2 * 3; // (number) 6
      +c = 2 * "3"; // (string) "33"
      +d = "3" * 4; // (string) "3333"
      +e = 5 / 4; // (number) 1.25
      +g = 5 / 5; // (number) 1
      +_x = "2" * "3"; // ERR: Cannot use operator '*' with 'string' and 'string'
      +_x = 5 / "4"; // ERR: Cannot use operator '/' with 'number' and 'string'
      +_x = "20" / 4; // ERR: Cannot use operator '/' with 'string' and 'number'
      +
    • +
    +
  • +
+

Control structures

+

You can control the flow of your program with several kinds of statements the language provides.

+

if construct

+

The if construct - as in all other programming languages - allows you to dynamically branch your program flow based on some conditions during runtime.

+

Examples

+
a = true;
+if (a) {
+    b = 1;
+}
+// b == 1
+
+
c = false;
+if (c) {
+    d = 1;
+} else {
+    d = 2;
+}
+// d == 2
+
+
a = false;
+b = true;
+c = 5;
+if (a or b) {
+    d = 1;
+    if (d < c) {
+        e = d + c;
+    }
+}
+// d == 1, e == 6
+
+

for construct

+

The for construct allows you to iterate over a value that supports it (array or string values), while performing a task on that collection's single item.

+

Examples

+
txt = "123456789";
+result = [];
+for (n in txt) {
+    if (5 > n.to_number() > 0) {
+        result.push(n);
+    }
+}
+// result == [0: "1", 1: "2", 2: "3", 3: "4"]
+
+
prices = [100, 200, 300, 600, 1200];
+sentence_template = "This costs {} units of money!";
+results = [];
+for (price in prices) {
+    results.push(sentence_template.format(price));
+}
+// results == [
+//   0: "This costs 100 units of money!",
+//   1: "This costs 200 units of money!",
+//   2: "This costs 300 units of money!",
+//   3: "This costs 600 units of money!",
+//   4: "This costs 1200 units of money!"
+// ]
+
+

Note: The flow of program inside the for cycle can be controlled further by using the continue and break statements.

+

while construct

+

The while construct does a thing if a specified condition is met (if the condition expression has a truthy value).

+
c = 0;
+while (c < 100) {
+    total = total + c;
+    c = c + 1;
+}
+// total == 4950
+
+

Note: The flow of program inside the while cycle can be controlled further by using the continue and break statements.

+ +
+
+ + + Last update: + April 6, 2024 10:34:57 + + + +
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file