Execute commands and scripts with a webhook

Executing commands on a host machine

Relay agent lets executing any commands or scripts on a host machine when webhooks are received. To use this functionality, use --relayer exec option together with --command python (or any other command such as node) followed by optional arguments. For example to execute python script in a file called my-script.py:

relay forward --bucket my-bucket-name --relayer exec --command python my-script.py

Here:

  • –bucket specifies which bucket to subscribe to
  • –relayer specifies exec relayer (by default it would forward to an HTTP endpoint)
  • –command is the main command to execute, for bash scripts you would use bash command
  • my-script.py is the optional script/application file

This script will receive webhook data through standard input (stdin). You can read this data and optionally return a response. Response will be visible in the webhook log through the Webhook Relay web interface.

Executed script will always be marked with status code 200 even though it will not be forwarded to a destination by the relay agent. When running in a --relayer exec mode, agent will only execute commands without forwarding webhooks. To also forward webhooks, launch a second agent.

Python example

Here is a simple Python script that will read from standard input and save the webhook payload into a file with a timestamp.

import sys
from time import gmtime, strftime
import datetime

payload = sys.stdin.read()

now = datetime.datetime.now()
timestamp = str(now.strftime("%Y%m%d_%H:%M:%S"))

filename = "webhook-" + timestamp + ".json"

file = open(filename,"w") 
file.write(payload)
file.close()

print("received")

Default input mode

By default relay agent only sends request body through the stdin into the script:

relay forward --bucket forward-a --relayer exec --command python my-script.py
Executing command on webhooks: 
https://my.webhookrelay.com/v1/webhooks/1eff80d0-b258-4175-983c-b03f8961608d -> python my-script.py
[i] Please ensure that your buckets have at least one internal output destination, otherwise this agent will not receive webhooks.

Now, send a webhook:

curl --request POST \
  --url https://my.webhookrelay.com/v1/webhooks/1eff80d0-b258-4175-983c-b03f8961608d \
  --data '{
    "msg": "webhook msg"
}'

File contents will be:

{
    "msg": "webhook msg"
}

JSON input mode

Launching relay agent you should see that it’s now executing commands instead of forwarding webhooks:

relay forward --bucket forward-a --relayer exec --input-mode json --command python my-script.py
Executing command on webhooks: 
https://my.webhookrelay.com/v1/webhooks/1eff80d0-b258-4175-983c-b03f8961608d -> python my-script.py
[i] Please ensure that your buckets have at least one internal output destination, otherwise this agent will not receive webhooks. 

Let’s send another webhook:

curl --request POST \
  --url https://my.webhookrelay.com/v1/webhooks/1eff80d0-b258-4175-983c-b03f8961608d \
  --data '{
    "msg": "webhook msg"
}'

You should now see a file created with contents:

{
  "type": "webhook",
  "meta": {
    "bucked_id": "e1ea4726-89e1-4983-84ac-fc92cb153647",
    "bucket_name": "forward-a",
    "input_id": "1eff80d0-b258-4175-983c-b03f8961608d",
    "input_name": "Default public endpoint",
    "output_name": "https://bin.webhookrelay.com/#/bins/f8235d2a-2156-4b3e-a110-0cfd9ab3a3fa",
    "output_destination": "https://bin.webhookrelay.com/v1/webhooks/84575fa2-4d9d-4aa4-942f-4e5ffea52dae"
  },
  "headers": {
    "Accept": [
      "*/*"
    ],
    "Content-Length": [
      "25"
    ],
    "User-Agent": [
      "insomnia/6.6.2"
    ],
  },
  "query": "",
  "body": "{\n\t\"msg\": \"webhook msg\"\n}",
  "method": "POST",
  "status": "",
  "message": ""
}

Background service configuration

To execute commands when running in a background service mode add additional ‘relayer’ section:

version: "v1"
key: your-secret-key # will be encrypted on startup
secret: your-secret  # will be encrypted on startup
buckets:
  - bucket-1-name
  - bucket-2-name
relayer:
  type: exec
  # inputMode: json # uncomment to receive full JSON payload with headers, query and other metadata
  timeout: 2 # timeout in seconds
  command: python
  commandArgs: [ 'my-script.py' ]

Debugging scripts and commands

To debug your commands you can use standard shell pipes. For example to try the previous Python example without Webhook Relay:

echo my-data-here | python my-script.py

Or, if your test data is in a file:

cat test_data.json | python my-script.py