feat: 完成一般消息通知能力的开发
This commit is contained in:
+88
@@ -0,0 +1,88 @@
|
||||
package notice
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func Text(content string) Message {
|
||||
return Message{Type: MessageText, Content: content}
|
||||
}
|
||||
|
||||
func ColorText(segments ...TextSegment) Message {
|
||||
return Message{Type: MessageColorText, Segments: segments}
|
||||
}
|
||||
|
||||
func Markdown(title, content string) Message {
|
||||
return Message{Type: MessageMarkdown, Title: title, Content: content}
|
||||
}
|
||||
|
||||
func Card(content CardContent) Message {
|
||||
return Message{Type: MessageCard, Card: &content}
|
||||
}
|
||||
|
||||
func validateMessage(message Message) error {
|
||||
switch message.Type {
|
||||
case MessageText:
|
||||
if strings.TrimSpace(message.Content) == "" {
|
||||
return fmt.Errorf("%w: text content is empty", ErrInvalidMessage)
|
||||
}
|
||||
case MessageMarkdown:
|
||||
if strings.TrimSpace(message.Content) == "" {
|
||||
return fmt.Errorf("%w: markdown content is empty", ErrInvalidMessage)
|
||||
}
|
||||
case MessageColorText:
|
||||
nonEmpty := false
|
||||
for _, segment := range message.Segments {
|
||||
if strings.TrimSpace(segment.Text) != "" {
|
||||
nonEmpty = true
|
||||
}
|
||||
if !validColor(segment.Color) {
|
||||
return fmt.Errorf("%w: unsupported color %q", ErrInvalidMessage, segment.Color)
|
||||
}
|
||||
}
|
||||
if !nonEmpty {
|
||||
return fmt.Errorf("%w: color text segments are empty", ErrInvalidMessage)
|
||||
}
|
||||
case MessageCard:
|
||||
if message.Card == nil {
|
||||
return fmt.Errorf("%w: card content is nil", ErrInvalidMessage)
|
||||
}
|
||||
if strings.TrimSpace(message.Card.Title) == "" && strings.TrimSpace(message.Card.Markdown) == "" {
|
||||
return fmt.Errorf("%w: card title and markdown are empty", ErrInvalidMessage)
|
||||
}
|
||||
if !validTheme(message.Card.Theme) {
|
||||
return fmt.Errorf("%w: unsupported card theme %q", ErrInvalidMessage, message.Card.Theme)
|
||||
}
|
||||
for _, action := range message.Card.Actions {
|
||||
parsed, err := url.ParseRequestURI(strings.TrimSpace(action.URL))
|
||||
if strings.TrimSpace(action.Text) == "" || err != nil || parsed.Scheme != "https" || parsed.Host == "" {
|
||||
return fmt.Errorf("%w: card action requires text and HTTPS URL", ErrInvalidMessage)
|
||||
}
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("%w: unsupported message type %q", ErrInvalidMessage, message.Type)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func validColor(color Color) bool {
|
||||
switch color {
|
||||
case "", ColorDefault, ColorInfo, ColorSuccess, ColorWarning, ColorDanger, ColorMuted:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func validTheme(theme CardTheme) bool {
|
||||
switch theme {
|
||||
case "", CardThemeDefault, CardThemeBlue, CardThemeWathet, CardThemeTurquoise, CardThemeGreen,
|
||||
CardThemeYellow, CardThemeOrange, CardThemeRed, CardThemeCarmine, CardThemeViolet,
|
||||
CardThemePurple, CardThemeIndigo, CardThemeGrey:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user