mirror of
https://github.com/clem109/drone-wechat.git
synced 2026-06-04 18:33:45 +08:00
first big commit
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
# drone-wechat
|
# drone-wechat (WORK IN PROGRESS)
|
||||||
|
|
||||||
Drone plugin to send build status notifications via WeChat for Work. For usage
|
Drone plugin to send build status notifications via WeChat for Work. For usage
|
||||||
information please look at [the docs](DOCS.md).
|
information please look at [the docs](DOCS.md).
|
||||||
@@ -18,18 +18,21 @@ go build
|
|||||||
Build the Docker image with the following commands:
|
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
|
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -a -tags netgo -o release/linux/amd64/drone-wechat
|
||||||
docker build --rm -t plugins/webhook .
|
docker build --rm -t plugins/drone-wechat .
|
||||||
```
|
```
|
||||||
|
|
||||||
### Usage
|
### Usage
|
||||||
|
|
||||||
```
|
```
|
||||||
docker run --rm \
|
docker run --rm \
|
||||||
-e PLUGIN_URLS=https://bbc.com/... \
|
-e PLUGIN_ACCESS_TOKEN=accesstoken \
|
||||||
-e PLUGIN_HEADERS="HEADER1=value1" \
|
-e PLUGIN_AGENT_ID=agentid \
|
||||||
-e PLUGIN_USERNAME=drone \
|
-e PLUGIN_DEBUG=true \
|
||||||
-e PLUGIN_PASSWORD=password \
|
-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_OWNER=octocat \
|
||||||
-e DRONE_REPO_NAME=hello-world \
|
-e DRONE_REPO_NAME=hello-world \
|
||||||
-e DRONE_COMMIT_SHA=7fd1a60b01f91b314f59955a4e4d4e80d8edf11d \
|
-e DRONE_COMMIT_SHA=7fd1a60b01f91b314f59955a4e4d4e80d8edf11d \
|
||||||
@@ -39,5 +42,5 @@ docker run --rm \
|
|||||||
-e DRONE_BUILD_STATUS=success \
|
-e DRONE_BUILD_STATUS=success \
|
||||||
-e DRONE_BUILD_LINK=http://github.com/octocat/hello-world \
|
-e DRONE_BUILD_LINK=http://github.com/octocat/hello-world \
|
||||||
-e DRONE_TAG=1.0.0 \
|
-e DRONE_TAG=1.0.0 \
|
||||||
plugins/webhook
|
plugins/drone-wechat
|
||||||
```
|
```
|
||||||
|
|||||||
Binary file not shown.
@@ -23,15 +23,27 @@ func main() {
|
|||||||
EnvVar: "PLUGIN_METHOD",
|
EnvVar: "PLUGIN_METHOD",
|
||||||
Value: "POST",
|
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{
|
cli.StringFlag{
|
||||||
Name: "access-token",
|
Name: "access-token",
|
||||||
Usage: "The access token for authorization",
|
Usage: "The access token for authorization",
|
||||||
EnvVar: "PLUGIN_ACCESS_TOKEN,WEBHOOK_ACCESS_TOKEN",
|
EnvVar: "PLUGIN_ACCESS_TOKEN,WEBHOOK_ACCESS_TOKEN",
|
||||||
},
|
},
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "agentid",
|
||||||
|
Usage: "Agent ID",
|
||||||
|
EnvVar: "PLUGIN_AGENT_ID,WEBHOOK_AGENT_ID",
|
||||||
|
},
|
||||||
cli.StringFlag{
|
cli.StringFlag{
|
||||||
Name: "msgtype",
|
Name: "msgtype",
|
||||||
Usage: "The type of message, either text, textcard",
|
Usage: "The type of message, either text, textcard",
|
||||||
EnvVar: "PLUGIN_MSGTYPE,WEBHOOK_MSGTYPE",
|
EnvVar: "PLUGIN_MSGTYPE,WEBHOOK_MSGTYPE",
|
||||||
|
Value: "textcard",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
cli.StringFlag{
|
||||||
Name: "content-type",
|
Name: "content-type",
|
||||||
@@ -50,22 +62,32 @@ func main() {
|
|||||||
Usage: "Party ID to send messages to",
|
Usage: "Party ID to send messages to",
|
||||||
EnvVar: "PLUGIN_TO_PARTY",
|
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{
|
cli.StringFlag{
|
||||||
Name: "safe",
|
Name: "safe",
|
||||||
Usage: "Whether to make this message confidential or not, 0 is false, 1 is true. Defaults to false",
|
Usage: "Whether to make this message confidential or not, 0 is false, 1 is true. Defaults to false",
|
||||||
EnvVar: "PLUGIN_SAFE",
|
EnvVar: "PLUGIN_SAFE",
|
||||||
Value: "0",
|
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{
|
cli.BoolFlag{
|
||||||
Name: "debug",
|
Name: "debug",
|
||||||
Usage: "enable debug information",
|
Usage: "enable debug information",
|
||||||
@@ -191,14 +213,17 @@ func run(c *cli.Context) error {
|
|||||||
Config: Config{
|
Config: Config{
|
||||||
Method: c.String("method"),
|
Method: c.String("method"),
|
||||||
AccessToken: c.String("access-token"),
|
AccessToken: c.String("access-token"),
|
||||||
|
Agentid: c.Int("agentid"),
|
||||||
MsgType: c.String("msgtype"),
|
MsgType: c.String("msgtype"),
|
||||||
ToUser: c.StringSlice("touser"),
|
URL: c.String("url"),
|
||||||
ToParty: c.StringSlice("toparty"),
|
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"),
|
Safe: c.Bool("safe"),
|
||||||
Content: c.String("content"),
|
|
||||||
ContentType: c.String("content-type"),
|
ContentType: c.String("content-type"),
|
||||||
Template: c.String("template"),
|
|
||||||
Headers: c.StringSlice("headers"),
|
|
||||||
Debug: c.Bool("debug"),
|
Debug: c.Bool("debug"),
|
||||||
SkipVerify: c.Bool("skip-verify"),
|
SkipVerify: c.Bool("skip-verify"),
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -7,9 +7,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -41,16 +38,19 @@ type (
|
|||||||
Config struct {
|
Config struct {
|
||||||
Method string
|
Method string
|
||||||
AccessToken string
|
AccessToken string
|
||||||
MsgType string
|
Agentid int `json:"agentid"`
|
||||||
ToUser []string
|
MsgType string `json:"msgtype"`
|
||||||
ToParty []string
|
URL string
|
||||||
|
MsgURL string
|
||||||
|
BtnTxt string
|
||||||
|
ToUser string `json:"touser"`
|
||||||
|
ToParty string `json:"toparty"`
|
||||||
Safe bool
|
Safe bool
|
||||||
Content string
|
|
||||||
ContentType string
|
ContentType string
|
||||||
Template string
|
|
||||||
Headers []string
|
|
||||||
Debug bool
|
Debug bool
|
||||||
SkipVerify bool
|
SkipVerify bool
|
||||||
|
Title string `json:"title"`
|
||||||
|
Description string `json:"description"`
|
||||||
}
|
}
|
||||||
|
|
||||||
Job struct {
|
Job struct {
|
||||||
@@ -69,7 +69,7 @@ func (p Plugin) Exec() error {
|
|||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
var b []byte
|
var b []byte
|
||||||
|
|
||||||
if p.Config.Content == "" {
|
if p.Config.Title == "" {
|
||||||
data := struct {
|
data := struct {
|
||||||
Repo Repo `json:"repo"`
|
Repo Repo `json:"repo"`
|
||||||
Build Build `json:"build"`
|
Build Build `json:"build"`
|
||||||
@@ -81,12 +81,25 @@ func (p Plugin) Exec() error {
|
|||||||
}
|
}
|
||||||
b = buf.Bytes()
|
b = buf.Bytes()
|
||||||
} else {
|
} else {
|
||||||
txt, err := RenderTrim(p.Config.Template, p)
|
textCard := struct {
|
||||||
if err != nil {
|
Title string `json:"title"`
|
||||||
return err
|
Description string `json:"description"`
|
||||||
}
|
MsgURL string `json:"url"`
|
||||||
text := txt
|
BtnTxt string `json:"btntext"`
|
||||||
b = []byte(text)
|
}{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,35 +108,13 @@ func (p Plugin) Exec() error {
|
|||||||
// and content_type values will be applied to
|
// and content_type values will be applied to
|
||||||
// every webhook request.
|
// 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 {
|
req, err := http.NewRequest("POST", url, bytes.NewBuffer(b))
|
||||||
uri, err := url.Parse(rawurl)
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
|
||||||
if err != nil {
|
// client := &http.Client{}
|
||||||
fmt.Printf("Error: Failed to parse the hook URL. %s\n", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
client := http.DefaultClient
|
||||||
if p.Config.SkipVerify {
|
if p.Config.SkipVerify {
|
||||||
@@ -133,6 +124,7 @@ func (p Plugin) Exec() error {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := client.Do(req)
|
resp, err := client.Do(req)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -142,6 +134,11 @@ func (p Plugin) Exec() error {
|
|||||||
|
|
||||||
defer resp.Body.Close()
|
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 {
|
if p.Config.Debug || resp.StatusCode >= http.StatusBadRequest {
|
||||||
body, err := ioutil.ReadAll(resp.Body)
|
body, err := ioutil.ReadAll(resp.Body)
|
||||||
|
|
||||||
@@ -152,7 +149,6 @@ func (p Plugin) Exec() error {
|
|||||||
if p.Config.Debug {
|
if p.Config.Debug {
|
||||||
fmt.Printf(
|
fmt.Printf(
|
||||||
debugRespFormat,
|
debugRespFormat,
|
||||||
i+1,
|
|
||||||
req.URL,
|
req.URL,
|
||||||
req.Method,
|
req.Method,
|
||||||
req.Header,
|
req.Header,
|
||||||
@@ -163,13 +159,11 @@ func (p Plugin) Exec() error {
|
|||||||
} else {
|
} else {
|
||||||
fmt.Printf(
|
fmt.Printf(
|
||||||
respFormat,
|
respFormat,
|
||||||
i+1,
|
|
||||||
req.URL,
|
req.URL,
|
||||||
resp.Status,
|
resp.Status,
|
||||||
string(body),
|
string(body),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
Vendored
+1
-1
@@ -33,5 +33,5 @@
|
|||||||
"revisionTime": "2017-07-06T19:46:25Z"
|
"revisionTime": "2017-07-06T19:46:25Z"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"rootPath": "github.com/drone-plugins/drone-webhook"
|
"rootPath": "github.com/clem109/drone-wechat"
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user