first big commit

This commit is contained in:
Clement Venard
2017-11-27 16:15:14 +08:00
parent 2e8ea83bbe
commit fa95cdc5fc
6 changed files with 165 additions and 143 deletions
+11 -8
View File
@@ -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
```
BIN
View File
Binary file not shown.
+40 -15
View File
@@ -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"),
},
+79 -85
View File
@@ -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
+35 -35
View File
@@ -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"
}