Warning
This repo is a work in progress! Needing both cleaning up and documenting.
A small Go daemon that exposes HTTP endpoints to trigger local actions.
It allows sending files, URLs, or commands from external clients to your machine over HTTP.
I'm using HTTP shortcuts on Android
Define hooks β send HTTP requests β execute actions locally.
Warning
This daemon can execute local commands and write files.
- Add a new token to the configuration file
$XDG_CONFIG_HOME/goaird/config.json - Do not expose it to the public internet
Accepts multipart/form-data requests and stores files on disk.
Fields:
destination: Target directoryfilename_strategy(wip): How filenames are preserved or generatedallowed_mime_types(optional): Restrict accepted file typesmax_size_mb(optional): Limit upload size
Executes a local command using a templated payload.
Fields:
command_template.command: Binary to executecommand_template.args: Arguments (supports templating, e.g.{{payload.url}})timeout_seconds: Execution timeoutallowed_actions: Whitelist of accepted actions from the request
The daemon is configured via a JSON file that defines the server settings and a list of hooks. Each hook maps an HTTP endpoint to a specific action (e.g., file upload or command execution).
Details
{
"server": {
"address": ":8080",
"token": "change-default-token-1234"
},
"hooks": [
{
"name": "upload-files",
"type": "upload",
"endpoint": "/files",
"method": "POST",
"destination": "~/dls/goairdrop/upload",
"filename_strategy": "original",
"notify": true
},
{
"name": "ytcast",
"type": "command",
"endpoint": "/yt",
"method": "POST",
"command_template": {
"command": "ytcast",
"args": ["-d", "shield", "{{payload.url}}"],
"timeout_seconds": 10
},
"allowed_actions": ["open"],
"notify": true
},
{
"name": "upload-images",
"type": "upload",
"endpoint": "/images",
"method": "POST",
"destination": "~/dls/goairdrop/images",
"filename_strategy": "original",
"notify": true
},
{
"name": "open-url",
"type": "command",
"endpoint": "/url",
"method": "POST",
"command_template": {
"command": "xdg-open",
"args": ["{{payload.url}}"],
"timeout_seconds": 10
},
"allowed_actions": ["open"],
"notify": true
},
{
"name": "bills",
"type": "upload",
"endpoint": "/bills",
"method": "POST",
"destination": "~/app/service/paperless-ngx/consume",
"allowed_mime_types": [
"image/png",
"image/jpeg",
"image/webp",
"application/pdf"
],
"filename_strategy": "original",
"notify": true
}
]
}$ goaird -h
Usage: goaird [flag] [args]
Flags:
-H, --hook show hook details <name>
-l, --list list hooks
-g, --gen generate curl from hook <name>
-w, --webui enable web UI
-V, --version print version
-v, --verbose verbose output# Send a URL to open with `xdg-open`
curl -X POST http://localhost:8080/url \
-H "Content-Type: application/json" \
-d '{"url":"https://kernel.org","action":"open"}'
# Send youtube video to Chromecast device using ytcast
curl -X POST http://localhost:8080/yt \
-H "Content-Type: application/json" \
-d '{"url":"https://www.youtube.com/watch?v=dQw4w9WgXcQ","action":"open"}'
# Send file to the bills endpoint
curl -X POST http://localhost:8080/bills \
-H "Content-Type: multipart/form-data" \
-F "file=@./invoice.pdf"
# Upload all JPG images in the current directory
curl -X POST http://localhost:8080/images \
-H "Content-Type: multipart/form-data" \
-F "files=@./*.jpg"- Authentication (token-based)
- Web UI improvements
- Hook validation and schema
- Hooks (type: command, upload)
- Simple WebUI for hook's edition (access:
http://localhost:8080/config)
- Simple WebUI for hook's edition (access:
- Send
text/files- Filename strategy (UUID, timestamp, hash, original)
- Add logger
- Execute command with
payload - Add Auth/Security
- Link with QR-Code?
- Linux notification
- Add action to notification?
