package notice import ( "fmt" "strings" ) type weComRenderer struct{} func (weComRenderer) Capabilities() Capabilities { return Capabilities{Text: true, ColorText: true, Markdown: true, Card: true} } func (weComRenderer) Render(config Config, message Message) (renderedRequest, error) { body := map[string]any{} switch message.Type { case MessageText: body = map[string]any{"msgtype": "text", "text": map[string]any{"content": message.Content}} case MessageColorText: body = weComMarkdown(weComColorMarkdown(message.Segments)) case MessageMarkdown: body = weComMarkdown(message.Content) case MessageCard: if len(message.Card.Actions) == 0 { body = weComMarkdown(cardMarkdownFallback(message.Card)) break } horizontal := make([]any, 0, len(message.Card.Fields)) for _, field := range message.Card.Fields { horizontal = append(horizontal, map[string]any{"keyname": field.Name, "value": field.Value}) } jumps := make([]any, 0, len(message.Card.Actions)) for _, action := range message.Card.Actions { jumps = append(jumps, map[string]any{"type": 1, "title": action.Text, "url": action.URL}) } first := message.Card.Actions[0] body = map[string]any{"msgtype": "template_card", "template_card": map[string]any{ "card_type": "text_notice", "main_title": map[string]any{"title": plainTitle(message.Card.Title, "消息通知"), "desc": ""}, "sub_title_text": message.Card.Markdown, "horizontal_content_list": horizontal, "jump_list": jumps, "card_action": map[string]any{"type": 1, "url": first.URL}, }} } return marshalRequest(config.Webhook, body) } func (weComRenderer) ValidateResponse(response networkResponse) error { if err := validateHTTP(ChannelWeCom, response); err != nil { return err } code, message, err := responseStatus(response.Body, "errcode", "", "errmsg", "") if err != nil { return fmt.Errorf("notice: parse wecom response: %w", err) } if code != "0" { return &PlatformError{Channel: ChannelWeCom, Code: code, Message: message} } return nil } func weComMarkdown(content string) map[string]any { return map[string]any{"msgtype": "markdown", "markdown": map[string]any{"content": content}} } func weComColorMarkdown(segments []TextSegment) string { var builder strings.Builder for _, segment := range segments { content := escapeText(segment.Text) if segment.Bold { content = "**" + content + "**" } color := map[Color]string{ ColorInfo: "info", ColorSuccess: "info", ColorWarning: "warning", ColorDanger: "warning", ColorMuted: "comment", }[segment.Color] if color != "" { content = `` + content + `` } builder.WriteString(content) } return builder.String() }