mirror of
https://github.com/ncarlier/webhookd.git
synced 2025-04-05 18:03:41 +00:00
feat(): transmit HTTP headers as env variables to the script
This commit is contained in:
parent
c2a17414f9
commit
2e803598d2
25
README.md
25
README.md
|
@ -87,11 +87,17 @@ data: done
|
|||
|
||||
### Webhook parameters
|
||||
|
||||
You can add query parameters to the webhook URL.
|
||||
Those parameters will be available as environment variables into the shell
|
||||
script.
|
||||
You can also send a payload (text/plain or application/json) as request body.
|
||||
This payload will be transmit to the shell script as first parameter.
|
||||
You have several way to provide parameters to your webhook script:
|
||||
|
||||
- URL query parameters and HTTP headers are converted into environment
|
||||
variables.
|
||||
Variable names follows "snakecase" naming convention.
|
||||
Therefore the name can be altered.
|
||||
|
||||
*ex: `CONTENT-TYPE` will become `content_type`.*
|
||||
|
||||
- Body content (text/plain or application/json) is transmit to the script as
|
||||
parameter.
|
||||
|
||||
*Example:*
|
||||
|
||||
|
@ -100,7 +106,8 @@ The script:
|
|||
```bash
|
||||
#!/bin/bash
|
||||
|
||||
echo "Environment parameters: foo=$foo"
|
||||
echo "Query parameter: foo=$foo"
|
||||
echo "Header parameter: user-agent=$user_agent"
|
||||
echo "Script parameters: $1"
|
||||
```
|
||||
|
||||
|
@ -110,9 +117,11 @@ data: Hook work request "echo" queued...
|
|||
|
||||
data: Running echo script...
|
||||
|
||||
data: Environment parameters: foo=bar
|
||||
data: Query parameter: foo=bar
|
||||
|
||||
data: Script parameters: {"foo": "bar"}
|
||||
data: Header parameter: user-agent=curl/7.52.1
|
||||
|
||||
data: Script parameter: {"foo": "bar"}
|
||||
|
||||
data: done
|
||||
```
|
||||
|
|
|
@ -43,6 +43,7 @@ func WebhookHandler(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
params := tools.QueryParamsToShellVars(r.URL.Query())
|
||||
log.Printf("Calling hook script \"%s\" with params %s...\n", script, params)
|
||||
params = append(params, tools.HTTPHeadersToShellVars(r.Header)...)
|
||||
|
||||
// Create work
|
||||
work := new(worker.WorkRequest)
|
||||
|
|
59
pkg/tools/http.go
Normal file
59
pkg/tools/http.go
Normal file
|
@ -0,0 +1,59 @@
|
|||
package tools
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
// ToSnakeCase convert string to snakecase.
|
||||
func ToSnakeCase(in string) string {
|
||||
runes := []rune(in)
|
||||
length := len(runes)
|
||||
|
||||
var out []rune
|
||||
for i := 0; i < length; i++ {
|
||||
if i > 0 && unicode.IsUpper(runes[i]) && ((i+1 < length && unicode.IsLower(runes[i+1])) || unicode.IsLower(runes[i-1])) {
|
||||
out = append(out, '_')
|
||||
}
|
||||
out = append(out, unicode.ToLower(runes[i]))
|
||||
}
|
||||
|
||||
return strings.Replace(string(out), "-", "", -1)
|
||||
}
|
||||
|
||||
// QueryParamsToShellVars convert URL query parameters to shell vars.
|
||||
func QueryParamsToShellVars(q url.Values) []string {
|
||||
var params []string
|
||||
for k, v := range q {
|
||||
var buf bytes.Buffer
|
||||
value, err := url.QueryUnescape(strings.Join(v[:], ","))
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
buf.WriteString(ToSnakeCase(k))
|
||||
buf.WriteString("=")
|
||||
buf.WriteString(value)
|
||||
params = append(params, buf.String())
|
||||
}
|
||||
return params
|
||||
}
|
||||
|
||||
// HTTPHeadersToShellVars convert HTTP headers to shell vars.
|
||||
func HTTPHeadersToShellVars(h http.Header) []string {
|
||||
var params []string
|
||||
for k, v := range h {
|
||||
var buf bytes.Buffer
|
||||
value, err := url.QueryUnescape(strings.Join(v[:], ","))
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
buf.WriteString(ToSnakeCase(k))
|
||||
buf.WriteString("=")
|
||||
buf.WriteString(value)
|
||||
params = append(params, buf.String())
|
||||
}
|
||||
return params
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
package tools
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"net/url"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var matchFirstCap = regexp.MustCompile("(.)([A-Z][a-z]+)")
|
||||
var matchAllCap = regexp.MustCompile("([a-z0-9])([A-Z])")
|
||||
|
||||
// ToSnakeCase convert string to snakecase.
|
||||
func ToSnakeCase(str string) string {
|
||||
snake := matchFirstCap.ReplaceAllString(str, "${1}_${2}")
|
||||
snake = matchAllCap.ReplaceAllString(snake, "${1}_${2}")
|
||||
return strings.ToLower(snake)
|
||||
}
|
||||
|
||||
// QueryParamsToShellVars convert URL query parameters to shell vars.
|
||||
func QueryParamsToShellVars(q url.Values) []string {
|
||||
var params []string
|
||||
for k, v := range q {
|
||||
var buf bytes.Buffer
|
||||
buf.WriteString(ToSnakeCase(k))
|
||||
buf.WriteString("=")
|
||||
buf.WriteString(url.QueryEscape(strings.Join(v[:], ",")))
|
||||
params = append(params, buf.String())
|
||||
}
|
||||
return params
|
||||
}
|
|
@ -5,6 +5,8 @@ echo "Running test script..."
|
|||
echo "Environment parameters:"
|
||||
echo "firstname: $firstname"
|
||||
echo "lastname: $lastname"
|
||||
echo "user-agent: $user_agent"
|
||||
echo "x-api-key: $x_api_key"
|
||||
|
||||
echo "Script parameters: $1"
|
||||
|
||||
|
|
|
@ -10,5 +10,6 @@ curl -H "Content-Type: application/json" \
|
|||
|
||||
echo "Test hook"
|
||||
curl -H "Content-Type: application/json" \
|
||||
-H "X-API-Key: test" \
|
||||
--data @test.json \
|
||||
$URL/test?firstname=obi-wan\&lastname=kenobi
|
||||
|
|
Loading…
Reference in New Issue
Block a user