refactor: reimplement larkbot notifier, drop thrird-party deps

This commit is contained in:
Fu Diwei
2025-10-30 20:18:15 +08:00
parent 1ae61549a1
commit ecb2da4fe0
+46 -15
View File
@@ -2,11 +2,13 @@ package larkbot
import (
"context"
"encoding/json"
"errors"
"fmt"
"log/slog"
"net/url"
"github.com/go-lark/lark"
"github.com/go-resty/resty/v2"
"github.com/certimate-go/certimate/pkg/core"
)
@@ -17,8 +19,9 @@ type NotifierProviderConfig struct {
}
type NotifierProvider struct {
config *NotifierProviderConfig
logger *slog.Logger
config *NotifierProviderConfig
logger *slog.Logger
httpClient *resty.Client
}
var _ core.Notifier = (*NotifierProvider)(nil)
@@ -28,9 +31,14 @@ func NewNotifierProvider(config *NotifierProviderConfig) (*NotifierProvider, err
return nil, errors.New("the configuration of the notifier provider is nil")
}
client := resty.New().
SetHeader("Content-Type", "application/json").
SetHeader("User-Agent", "certimate")
return &NotifierProvider{
config: config,
logger: slog.Default(),
config: config,
logger: slog.Default(),
httpClient: client,
}, nil
}
@@ -43,17 +51,40 @@ func (n *NotifierProvider) SetLogger(logger *slog.Logger) {
}
func (n *NotifierProvider) Notify(ctx context.Context, subject string, message string) (*core.NotifyResult, error) {
bot := lark.NewNotificationBot(n.config.WebhookUrl)
content := lark.NewPostBuilder().
Title(subject).
TextTag(message, 1, false).
Render()
msg := lark.NewMsgBuffer(lark.MsgPost).Post(content)
resp, err := bot.PostNotificationV2(msg.Build())
webhookUrl, err := url.Parse(n.config.WebhookUrl)
if err != nil {
return nil, fmt.Errorf("lark api error: %w", err)
} else if resp.Code != 0 {
return nil, fmt.Errorf("lark api error: code='%d', message='%s'", resp.Code, resp.Msg)
return nil, fmt.Errorf("lark api error: invalid webhook url: %w", err)
} else {
const hostname = "open.larksuite.com"
const hostname_cn = "open.feishu.cn"
if webhookUrl.Hostname() != hostname && webhookUrl.Hostname() != hostname_cn {
n.logger.Warn(fmt.Sprintf("the webhook url hostname is not '%s' or '%s', please make sure it is correct", hostname, hostname_cn))
}
}
// REF: https://open.feishu.cn/document/client-docs/bot-v3/add-custom-bot
// REF: https://open.larksuite.com/document/client-docs/bot-v3/add-custom-bot
var result struct {
Code int `json:"code"`
Message string `json:"msg"`
}
req := n.httpClient.R().
SetContext(ctx).
SetBody(map[string]any{
"msg_type": "text",
"content": map[string]string{
"text": subject + "\n\n" + message,
},
})
resp, err := req.Post(webhookUrl.String())
if err != nil {
return nil, fmt.Errorf("lark api error: failed to send request: %w", err)
} else if resp.IsError() {
return nil, fmt.Errorf("lark api error: unexpected status code: %d, resp: %s", resp.StatusCode(), resp.String())
} else if err := json.Unmarshal(resp.Body(), &result); err != nil {
return nil, fmt.Errorf("lark api error: failed to unmarshal response: %w", err)
} else if result.Code != 0 {
return nil, fmt.Errorf("lark api error: code='%d', msg='%s'", result.Code, result.Message)
}
return &core.NotifyResult{}, nil