Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

notify: add markdown support for wechat #2309

Merged
merged 9 commits into from
Jul 6, 2020
35 changes: 26 additions & 9 deletions config/notifiers.go
Original file line number Diff line number Diff line change
Expand Up @@ -396,21 +396,38 @@ type WechatConfig struct {

HTTPConfig *commoncfg.HTTPClientConfig `yaml:"http_config,omitempty" json:"http_config,omitempty"`

APISecret Secret `yaml:"api_secret,omitempty" json:"api_secret,omitempty"`
CorpID string `yaml:"corp_id,omitempty" json:"corp_id,omitempty"`
Message string `yaml:"message,omitempty" json:"message,omitempty"`
APIURL *URL `yaml:"api_url,omitempty" json:"api_url,omitempty"`
ToUser string `yaml:"to_user,omitempty" json:"to_user,omitempty"`
ToParty string `yaml:"to_party,omitempty" json:"to_party,omitempty"`
ToTag string `yaml:"to_tag,omitempty" json:"to_tag,omitempty"`
AgentID string `yaml:"agent_id,omitempty" json:"agent_id,omitempty"`
APISecret Secret `yaml:"api_secret,omitempty" json:"api_secret,omitempty"`
CorpID string `yaml:"corp_id,omitempty" json:"corp_id,omitempty"`
Message string `yaml:"message,omitempty" json:"message,omitempty"`
APIURL *URL `yaml:"api_url,omitempty" json:"api_url,omitempty"`
ToUser string `yaml:"to_user,omitempty" json:"to_user,omitempty"`
ToParty string `yaml:"to_party,omitempty" json:"to_party,omitempty"`
ToTag string `yaml:"to_tag,omitempty" json:"to_tag,omitempty"`
AgentID string `yaml:"agent_id,omitempty" json:"agent_id,omitempty"`
MessageType string `yaml:"message_type,omitempty" json:"message_type,omitempty"`
deamwork marked this conversation as resolved.
Show resolved Hide resolved
}

const wechatValidTypesRe = `^(text|markdown)$`
deamwork marked this conversation as resolved.
Show resolved Hide resolved

var wechatTypeMatcher = regexp.MustCompile(wechatValidTypesRe)

// UnmarshalYAML implements the yaml.Unmarshaler interface.
func (c *WechatConfig) UnmarshalYAML(unmarshal func(interface{}) error) error {
*c = DefaultWechatConfig
type plain WechatConfig
return unmarshal((*plain)(c))
if err := unmarshal((*plain)(c)); err != nil {
return err
}

if c.MessageType == "" {
c.MessageType = "text"
}

if !wechatTypeMatcher.MatchString(c.MessageType) {
return errors.Errorf("WeChat message type %q does not match valid options %s", c.MessageType, wechatValidTypesRe)
}

return nil
}

// OpsGenieConfig configures notifications via OpsGenie.
Expand Down
15 changes: 15 additions & 0 deletions config/notifiers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,21 @@ func TestOpsgenieTypeMatcher(t *testing.T) {
}
}

func TestWeChatTypeMatcher(t *testing.T) {
good := []string{"text", "markdown"}
for _, g := range good {
if !wechatTypeMatcher.MatchString(g) {
t.Fatalf("failed to match with %s", g)
}
}
bad := []string{"TEXT", "MarkDOwn"}
for _, b := range bad {
if wechatTypeMatcher.MatchString(b) {
t.Errorf("mistakenly match with %s", b)
}
}
}

func newBoolPointer(b bool) *bool {
return &b
}
2 changes: 2 additions & 0 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -711,6 +711,8 @@ API](http://admin.wechat.com/wiki/index.php?title=Customer_Service_Messages).

# API request data as defined by the WeChat API.
[ message: <tmpl_string> | default = '{{ template "wechat.default.message" . }}' ]
# Type of the message type, supported values are `text` and `markdown`.
[ message_type: <string> | default = 'text' ]
[ agent_id: <string> | default = '{{ template "wechat.default.agent_id" . }}' ]
[ to_user: <string> | default = '{{ template "wechat.default.to_user" . }}' ]
[ to_party: <string> | default = '{{ template "wechat.default.to_party" . }}' ]
Expand Down
30 changes: 19 additions & 11 deletions notify/wechat/wechat.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,14 @@ type token struct {
}

type weChatMessage struct {
Text weChatMessageContent `yaml:"text,omitempty" json:"text,omitempty"`
ToUser string `yaml:"touser,omitempty" json:"touser,omitempty"`
ToParty string `yaml:"toparty,omitempty" json:"toparty,omitempty"`
Totag string `yaml:"totag,omitempty" json:"totag,omitempty"`
AgentID string `yaml:"agentid,omitempty" json:"agentid,omitempty"`
Safe string `yaml:"safe,omitempty" json:"safe,omitempty"`
Type string `yaml:"msgtype,omitempty" json:"msgtype,omitempty"`
Text weChatMessageContent `yaml:"text,omitempty" json:"text,omitempty"`
ToUser string `yaml:"touser,omitempty" json:"touser,omitempty"`
ToParty string `yaml:"toparty,omitempty" json:"toparty,omitempty"`
Totag string `yaml:"totag,omitempty" json:"totag,omitempty"`
AgentID string `yaml:"agentid,omitempty" json:"agentid,omitempty"`
Safe string `yaml:"safe,omitempty" json:"safe,omitempty"`
Type string `yaml:"msgtype,omitempty" json:"msgtype,omitempty"`
Markdown weChatMessageContent `yaml:"markdown,omitempty" json:"markdown,omitempty"`
}

type weChatMessageContent struct {
Expand Down Expand Up @@ -135,16 +136,23 @@ func (n *Notifier) Notify(ctx context.Context, as ...*types.Alert) (bool, error)
}

msg := &weChatMessage{
Text: weChatMessageContent{
Content: tmpl(n.conf.Message),
},
ToUser: tmpl(n.conf.ToUser),
ToParty: tmpl(n.conf.ToParty),
Totag: tmpl(n.conf.ToTag),
AgentID: tmpl(n.conf.AgentID),
Type: "text",
deamwork marked this conversation as resolved.
Show resolved Hide resolved
Type: n.conf.MessageType,
Safe: "0",
deamwork marked this conversation as resolved.
Show resolved Hide resolved
}

if msg.Type == "markdown" {
msg.Markdown = weChatMessageContent{
Content: tmpl(n.conf.Message),
}
} else {
msg.Text = weChatMessageContent{
Content: tmpl(n.conf.Message),
}
}
if err != nil {
return false, fmt.Errorf("templating error: %s", err)
}
Expand Down
23 changes: 23 additions & 0 deletions notify/wechat/wechat_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,26 @@ func TestWechatRedactedURLOnNotify(t *testing.T) {

test.AssertNotifyLeaksNoSecret(t, ctx, notifier, secret, token)
}

func TestWechatMessageTypeSelector(t *testing.T) {
secret, token := "secret", "token"
ctx, u, fn := test.GetContextWithCancelingURL(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, `{"access_token":"%s"}`, token)
})
defer fn()

notifier, err := New(
&config.WechatConfig{
APIURL: &config.URL{URL: u},
HTTPConfig: &commoncfg.HTTPClientConfig{},
CorpID: "corpid",
APISecret: config.Secret(secret),
MessageType: "markdown",
},
test.CreateTmpl(t),
log.NewNopLogger(),
)
require.NoError(t, err)

test.AssertNotifyLeaksNoSecret(t, ctx, notifier, secret, token)
}