diff --git a/DOCS.md b/DOCS.md index a89fae2..637bb2e 100644 --- a/DOCS.md +++ b/DOCS.md @@ -4,6 +4,8 @@ You will need to supply Drone with outgoing Webhook URLs. The following parameters are used to configure outgoing Webhooks: * `urls` - JSON payloads are sent to each URL listed here +* `method` - HTTP request method. Defaults to `POST` +* `header` - HTTP request header map The following is a sample Webhook configuration in your .drone.yml file: @@ -13,6 +15,8 @@ notify: urls: - https://your.webhook/... - https://your.other.webhook/... + header: + Authorization: pa55word ``` The following is an example Webhook payload (whitespace added): @@ -58,3 +62,25 @@ The following is an example Webhook payload (whitespace added): } } ``` + +## Custom Body + +In some cases you may want to submit a custom payload in the body of your hook. For the use case we expose the following additional parameters: + +* `template` - Go template to create a custom payload body. See [docs](https://golang.org/pkg/text/template/) +* `content_type` - HTTP request content type + +Example configuration that generate a custom Yaml payload: + +```yaml +notify: + webhook: + urls: + - https://your.webhook/... + - https://your.other.webhook/... + content_type: application/yaml + template: > + repo: {{.Repo.FullName}} + build: {{.Build.Number}} + commit: {{.Build.Commit}} +``` \ No newline at end of file diff --git a/main.go b/main.go index 1f92bc8..13bb380 100644 --- a/main.go +++ b/main.go @@ -3,18 +3,25 @@ package main import ( "bytes" "encoding/json" + "fmt" "net/http" + "net/url" "os" + "text/template" - "github.com/drone/drone-go/plugin" "github.com/drone/drone-go/drone" + "github.com/drone/drone-go/plugin" ) func main() { var repo = drone.Repo{} var build = drone.Build{} var vargs = struct { - Urls []string `json:"urls"` + Urls []string `json:"urls"` + Headers map[string]string `json:"header"` + Method string `json:"method"` + Template string `json:"template"` + ContentType string `json:"content_type"` }{} plugin.Param("repo", &repo) @@ -28,16 +35,56 @@ func main() { Build drone.Build `json:"build"` }{repo, build} - // json payload that will be posted - payload, err := json.Marshal(&data) - if err != nil { - os.Exit(1) + // set default values + if len(vargs.Method) == 0 { + vargs.Method = "POST" + } + if len(vargs.ContentType) == 0 { + vargs.ContentType = "application/json" + } + + // creates the payload. by default the payload + // is the build details in json format, but a custom + // template may also be used. + var buf bytes.Buffer + if len(vargs.Template) == 0 { + json.NewEncoder(&buf).Encode(&data) + + } else { + t, err := template.New("_").Parse(vargs.Template) + if err != nil { + fmt.Printf("Error parsing content template. %s\n", err) + os.Exit(1) + } + t.Execute(&buf, &data) + if err != nil { + fmt.Printf("Error executing content template. %s\n", err) + os.Exit(1) + } } // post payload to each url - for _, url := range vargs.Urls { - resp, err := http.Post(url, "application/json", bytes.NewBuffer(payload)) + for _, rawurl := range vargs.Urls { + + uri, err := url.Parse(rawurl) if err != nil { + fmt.Printf("Error parsing hook url. %s\n", err) + os.Exit(1) + } + + req, err := http.NewRequest(vargs.Method, uri.String(), &buf) + if err != nil { + fmt.Printf("Error creating http request. %s\n", err) + os.Exit(1) + } + req.Header.Set("Content-Type", vargs.ContentType) + for key, value := range vargs.Headers { + req.Header.Set(key, value) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + fmt.Printf("Error executing http request. %s\n", err) os.Exit(1) } resp.Body.Close()