- You want to run some code in response to a webhook, like a github push.
- You have some code on your Raspberry Pi that you want to run from work (great in combination with ngrok).
- That's pretty much it.
Hapttic listens for incoming HTTP connections. When it receives a connection, it dumps all relevant data (headers, path, parameters, the body and other stuff) into a JSON object and calls a bash script with this object as its parameters.
The basic idea is pretty similar. The main advantage of hapttic is ease of setup with a simple Docker image that lets you quickly connect a shell script to a http endpoint.
docker run --rm -p 8080:8080 --name hapttic timonych/hapttic:v2.0.0
cat <<EOF > ~/shellScript.sh
#!/bin/sh
echo \$1
EOF
Then run the following command to spin up the docker container that runs hapttic:
docker run --rm -p 8080:8080 -v ~/shellScript.sh:/usr/src/app/shellScript.sh --name hapttic timonych/hapttic:v2.0.0 -script "./shellScript.sh"
curl http://localhost:8080 -d '{"key" : "value"}'
cat <<EOF > ~/hapttic-config.yml
bind: 0.0.0.0
port: 8080
error: false
scripts:
# rootPath: scriptPath (Relative Path according to hapttic Path)
# rootPath should start with /. If not prefix / will be addedd automaticaly
script1: ./shellScripts/script1.sh
/script2: ./shellScripts/script2.sh
EOF
mkdir -p ~/shellScripts
cat <<EOF > ~/shellScripts/script1.sh
#!/bin/sh
echo "This is $(basename \$0)"
echo \$1 2>&1
EOF
cat <<EOF > ~/shellScripts/script2.sh
#!/bin/sh
echo "This is $(basename \$0)"
echo \$1 2>&1
EOF
Then run the following command to spin up the docker container that runs hapttic:
docker run --rm -p 8080:8080 -v ~/shellScripts:/usr/app/shellScripts -v ~/hapttic-config.yml:/config.yml --name hapttic timonych/hapttic:v2.0.0 -config "/config.yml"
curl http://localhost:8080/script1 -d '{"key1" : "value1"}'
curl http://localhost:8080/script2 -d '{"key2" : "value2"}'
REQUEST=$1
SECRET_TOKEN=$(jq -r '.Header."X-My-Secret"[0]' <(echo $REQUEST))
if [[ "$SECRET_TOKEN" != "SECRET" ]]; then
echo "Incorrect secret token"
exit -1
fi
curl https://www.example.com/api/call/in/response/to/webhookThis request handling script can be run with curl -H "X-My-Secret: SECRET" http://localhost:8080
The jsoendermann/hapttic Dockerfile includes jq and curl, if you need any other command in your request handling script, you should create your own image.
The JSON object your request handling script gets called with is a subset of Go's http.Request. It's defined in hapttic.go as marshallableRequest. For documentation on http.Request, see the official net/http page.
You can add encryption by putting an nginx proxy in front of it with a docker-compose file like so:
version: '3'
volumes:
vhost:
html:
services:
nginx-proxy:
restart: always
image: jwilder/nginx-proxy
ports:
- 80:80
- 443:443
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- /var/certs:/etc/nginx/certs:ro
- vhost:/etc/nginx/vhost.d
- html:/usr/share/nginx/html
labels:
- "com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy=true"
letsencrypt-nginx-proxy-companion:
restart: always
image: jrcs/letsencrypt-nginx-proxy-companion
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- /var/certs:/etc/nginx/certs:rw
- vhost:/etc/nginx/vhost.d
- html:/usr/share/nginx/html
hapttic:
restart: always
image: jsoendermann/hapttic
environment:
- VIRTUAL_HOST=hapttic.your.domain.com # Replace this
- LETSENCRYPT_HOST=hapttic.your.domain.com # Replace this
- LETSENCRYPT_EMAIL=your@email.address # Replace this
volumes:
- /my-request-handler.sh:/hapttic_request_handler.sh # Replace this
command: ["-file", "/hapttic_request_handler.sh"]
depends_on:
- nginx-proxy
- letsencrypt-nginx-proxy-companion