diff --git a/README.md b/README.md index a22fdd2..dae6e64 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# drone-wechat +# drone-wechat (WORK IN PROGRESS) Drone plugin to send build status notifications via WeChat for Work. For usage information please look at [the docs](DOCS.md). @@ -18,18 +18,21 @@ go build Build the Docker image with the following commands: ``` -GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -a -tags netgo -o release/linux/amd64/drone-webhook -docker build --rm -t plugins/webhook . +GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -a -tags netgo -o release/linux/amd64/drone-wechat +docker build --rm -t plugins/drone-wechat . ``` ### Usage ``` docker run --rm \ - -e PLUGIN_URLS=https://bbc.com/... \ - -e PLUGIN_HEADERS="HEADER1=value1" \ - -e PLUGIN_USERNAME=drone \ - -e PLUGIN_PASSWORD=password \ + -e PLUGIN_ACCESS_TOKEN=accesstoken \ + -e PLUGIN_AGENT_ID=agentid \ + -e PLUGIN_DEBUG=true \ + -e PLUGIN_MSG_URL=url \ + -e PLUGIN_BTN_TXT=true \ + -e PLUGIN_TITLE=title \ + -e PLUGIN_DESCRIPTION=description \ -e DRONE_REPO_OWNER=octocat \ -e DRONE_REPO_NAME=hello-world \ -e DRONE_COMMIT_SHA=7fd1a60b01f91b314f59955a4e4d4e80d8edf11d \ @@ -39,5 +42,5 @@ docker run --rm \ -e DRONE_BUILD_STATUS=success \ -e DRONE_BUILD_LINK=http://github.com/octocat/hello-world \ -e DRONE_TAG=1.0.0 \ - plugins/webhook + plugins/drone-wechat ``` diff --git a/drone-webhook b/drone-webhook deleted file mode 100755 index 27c1df4..0000000 Binary files a/drone-webhook and /dev/null differ diff --git a/main.go b/main.go index 227d843..9921140 100644 --- a/main.go +++ b/main.go @@ -23,15 +23,27 @@ func main() { EnvVar: "PLUGIN_METHOD", Value: "POST", }, + cli.StringFlag{ + Name: "url", + Usage: "wechat work url", + EnvVar: "PLUGIN_URL", + Value: "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=", + }, cli.StringFlag{ Name: "access-token", Usage: "The access token for authorization", EnvVar: "PLUGIN_ACCESS_TOKEN,WEBHOOK_ACCESS_TOKEN", }, + cli.StringFlag{ + Name: "agentid", + Usage: "Agent ID", + EnvVar: "PLUGIN_AGENT_ID,WEBHOOK_AGENT_ID", + }, cli.StringFlag{ Name: "msgtype", Usage: "The type of message, either text, textcard", EnvVar: "PLUGIN_MSGTYPE,WEBHOOK_MSGTYPE", + Value: "textcard", }, cli.StringFlag{ Name: "content-type", @@ -50,22 +62,32 @@ func main() { Usage: "Party ID to send messages to", EnvVar: "PLUGIN_TO_PARTY", }, + cli.StringFlag{ + Name: "title", + Usage: "Message title", + EnvVar: "PLUGIN_TITLE", + }, + cli.StringFlag{ + Name: "description", + Usage: "Description ", + EnvVar: "PLUGIN_DESCRIPTION", + }, + cli.StringFlag{ + Name: "msgurl", + Usage: "message url ", + EnvVar: "PLUGIN_MSG_URL", + }, + cli.StringFlag{ + Name: "btntxt", + Usage: "Button text ", + EnvVar: "PLUGIN_BTN_TXT", + }, cli.StringFlag{ Name: "safe", Usage: "Whether to make this message confidential or not, 0 is false, 1 is true. Defaults to false", EnvVar: "PLUGIN_SAFE", Value: "0", }, - cli.StringFlag{ - Name: "content", - Usage: "custom template for webhook", - EnvVar: "PLUGIN_CONTENT", - }, - cli.StringSliceFlag{ - Name: "headers", - Usage: "custom headers key map", - EnvVar: "PLUGIN_HEADERS", - }, cli.BoolFlag{ Name: "debug", Usage: "enable debug information", @@ -191,14 +213,17 @@ func run(c *cli.Context) error { Config: Config{ Method: c.String("method"), AccessToken: c.String("access-token"), + Agentid: c.Int("agentid"), MsgType: c.String("msgtype"), - ToUser: c.StringSlice("touser"), - ToParty: c.StringSlice("toparty"), + URL: c.String("url"), + MsgURL: c.String("msgurl"), + BtnTxt: c.String("btntxt"), + ToUser: c.String("touser"), + ToParty: c.String("toparty"), + Title: c.String("title"), + Description: c.String("description"), Safe: c.Bool("safe"), - Content: c.String("content"), ContentType: c.String("content-type"), - Template: c.String("template"), - Headers: c.StringSlice("headers"), Debug: c.Bool("debug"), SkipVerify: c.Bool("skip-verify"), }, diff --git a/plugin.go b/plugin.go index 5f42a39..3e7eb85 100644 --- a/plugin.go +++ b/plugin.go @@ -7,9 +7,6 @@ import ( "fmt" "io/ioutil" "net/http" - "net/url" - "os" - "strings" ) const ( @@ -41,16 +38,19 @@ type ( Config struct { Method string AccessToken string - MsgType string - ToUser []string - ToParty []string + Agentid int `json:"agentid"` + MsgType string `json:"msgtype"` + URL string + MsgURL string + BtnTxt string + ToUser string `json:"touser"` + ToParty string `json:"toparty"` Safe bool - Content string ContentType string - Template string - Headers []string Debug bool SkipVerify bool + Title string `json:"title"` + Description string `json:"description"` } Job struct { @@ -69,7 +69,7 @@ func (p Plugin) Exec() error { var buf bytes.Buffer var b []byte - if p.Config.Content == "" { + if p.Config.Title == "" { data := struct { Repo Repo `json:"repo"` Build Build `json:"build"` @@ -81,12 +81,25 @@ func (p Plugin) Exec() error { } b = buf.Bytes() } else { - txt, err := RenderTrim(p.Config.Template, p) - if err != nil { - return err - } - text := txt - b = []byte(text) + textCard := struct { + Title string `json:"title"` + Description string `json:"description"` + MsgURL string `json:"url"` + BtnTxt string `json:"btntext"` + }{p.Config.Title, p.Config.Description, p.Config.MsgURL, p.Config.BtnTxt} + data := struct { + ToUser string `json:"touser"` + MsgType string `json:"msgtype"` + Agentid int `json:"agentid"` + TextCard struct { + Title string `json:"title"` + Description string `json:"description"` + MsgURL string `json:"url"` + BtnTxt string `json:"btntext"` + } `json:"textcard"` + }{p.Config.ToUser, p.Config.MsgType, p.Config.Agentid, textCard} + + b, _ = json.Marshal(data) // []byte(data) } @@ -95,80 +108,61 @@ func (p Plugin) Exec() error { // and content_type values will be applied to // every webhook request. - // TODO: Construct URL for WeChat work + url := p.Config.URL + p.Config.AccessToken + fmt.Println("URL:>", url) - for i, rawurl := range p.Config.URLs { - uri, err := url.Parse(rawurl) + req, err := http.NewRequest("POST", url, bytes.NewBuffer(b)) + req.Header.Set("Content-Type", "application/json") + + // client := &http.Client{} + + client := http.DefaultClient + if p.Config.SkipVerify { + client = &http.Client{ + Transport: &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + }, + } + } + + resp, err := client.Do(req) + + if err != nil { + fmt.Printf("Error: Failed to execute the HTTP request. %s\n", err) + return err + } + + defer resp.Body.Close() + + fmt.Println("response Status:", resp.Status) + fmt.Println("response Headers:", resp.Header) + body, _ := ioutil.ReadAll(resp.Body) + fmt.Println("response Body:", string(body)) + + if p.Config.Debug || resp.StatusCode >= http.StatusBadRequest { + body, err := ioutil.ReadAll(resp.Body) if err != nil { - fmt.Printf("Error: Failed to parse the hook URL. %s\n", err) - os.Exit(1) + fmt.Printf("Error: Failed to read the HTTP response body. %s\n", err) } - r := bytes.NewReader(b) - - req, err := http.NewRequest(p.Config.Method, uri.String(), r) - - if err != nil { - fmt.Printf("Error: Failed to create the HTTP request. %s\n", err) - return err - } - - req.Header.Set("Content-Type", p.Config.ContentType) - - for _, value := range p.Config.Headers { - header := strings.Split(value, "=") - req.Header.Set(header[0], header[1]) - } - - if p.Config.Username != "" && p.Config.Password != "" { - req.SetBasicAuth(p.Config.Username, p.Config.Password) - } - - client := http.DefaultClient - if p.Config.SkipVerify { - client = &http.Client{ - Transport: &http.Transport{ - TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, - }, - } - } - resp, err := client.Do(req) - - if err != nil { - fmt.Printf("Error: Failed to execute the HTTP request. %s\n", err) - return err - } - - defer resp.Body.Close() - - if p.Config.Debug || resp.StatusCode >= http.StatusBadRequest { - body, err := ioutil.ReadAll(resp.Body) - - if err != nil { - fmt.Printf("Error: Failed to read the HTTP response body. %s\n", err) - } - - if p.Config.Debug { - fmt.Printf( - debugRespFormat, - i+1, - req.URL, - req.Method, - req.Header, - string(b), - resp.Status, - string(body), - ) - } else { - fmt.Printf( - respFormat, - i+1, - req.URL, - resp.Status, - string(body), - ) - } + if p.Config.Debug { + fmt.Printf( + debugRespFormat, + req.URL, + req.Method, + req.Header, + string(b), + resp.Status, + string(body), + ) + } else { + fmt.Printf( + respFormat, + req.URL, + resp.Status, + string(body), + ) } } return nil diff --git a/release/linux/amd64/drone-webhook b/release/linux/amd64/drone-wechat similarity index 59% rename from release/linux/amd64/drone-webhook rename to release/linux/amd64/drone-wechat index ecec952..de5ba12 100755 Binary files a/release/linux/amd64/drone-webhook and b/release/linux/amd64/drone-wechat differ diff --git a/vendor/vendor.json b/vendor/vendor.json index 906a4b9..272cce7 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -1,37 +1,37 @@ { - "comment": "", - "ignore": "test", - "package": [ - { - "checksumSHA1": "PZ4KJai7DnuJ2YNJ2v2l2BseB1g=", - "path": "github.com/aymerick/raymond", - "revision": "72acac2207479d21dd45898c2a4264246c818148", - "revisionTime": "2016-12-09T22:07:24Z" - }, - { - "checksumSHA1": "Rvn+RH9pwFno1w6W+mhWsj/PxlA=", - "path": "github.com/aymerick/raymond/ast", - "revision": "72acac2207479d21dd45898c2a4264246c818148", - "revisionTime": "2016-12-09T22:07:24Z" - }, - { - "checksumSHA1": "5SJwPK0MYtJt5YiE1BNc9Wl3+S0=", - "path": "github.com/aymerick/raymond/lexer", - "revision": "72acac2207479d21dd45898c2a4264246c818148", - "revisionTime": "2016-12-09T22:07:24Z" - }, - { - "checksumSHA1": "TCu/8QBP8TApLjSt13a7Qjnyxrs=", - "path": "github.com/aymerick/raymond/parser", - "revision": "72acac2207479d21dd45898c2a4264246c818148", - "revisionTime": "2016-12-09T22:07:24Z" - }, - { - "checksumSHA1": "9LeR7BH4PSu8LRDZ8bY7QY1HXJE=", - "path": "github.com/urfave/cli", - "revision": "4b90d79a682b4bf685762c7452db20f2a676ecb2", - "revisionTime": "2017-07-06T19:46:25Z" - } - ], - "rootPath": "github.com/drone-plugins/drone-webhook" + "comment": "", + "ignore": "test", + "package": [ + { + "checksumSHA1": "PZ4KJai7DnuJ2YNJ2v2l2BseB1g=", + "path": "github.com/aymerick/raymond", + "revision": "72acac2207479d21dd45898c2a4264246c818148", + "revisionTime": "2016-12-09T22:07:24Z" + }, + { + "checksumSHA1": "Rvn+RH9pwFno1w6W+mhWsj/PxlA=", + "path": "github.com/aymerick/raymond/ast", + "revision": "72acac2207479d21dd45898c2a4264246c818148", + "revisionTime": "2016-12-09T22:07:24Z" + }, + { + "checksumSHA1": "5SJwPK0MYtJt5YiE1BNc9Wl3+S0=", + "path": "github.com/aymerick/raymond/lexer", + "revision": "72acac2207479d21dd45898c2a4264246c818148", + "revisionTime": "2016-12-09T22:07:24Z" + }, + { + "checksumSHA1": "TCu/8QBP8TApLjSt13a7Qjnyxrs=", + "path": "github.com/aymerick/raymond/parser", + "revision": "72acac2207479d21dd45898c2a4264246c818148", + "revisionTime": "2016-12-09T22:07:24Z" + }, + { + "checksumSHA1": "9LeR7BH4PSu8LRDZ8bY7QY1HXJE=", + "path": "github.com/urfave/cli", + "revision": "4b90d79a682b4bf685762c7452db20f2a676ecb2", + "revisionTime": "2017-07-06T19:46:25Z" + } + ], + "rootPath": "github.com/clem109/drone-wechat" }