diff --git a/internal/domain/domains.go b/internal/domain/domains.go
index 6a228fff..f3d04a53 100644
--- a/internal/domain/domains.go
+++ b/internal/domain/domains.go
@@ -23,7 +23,7 @@ type DeployConfig struct {
Config map[string]any `json:"config"`
}
-// 以字符串形式获取配置项。
+// Deprecated: 以字符串形式获取配置项。
//
// 入参:
// - key: 配置项的键。
@@ -34,7 +34,7 @@ func (dc *DeployConfig) GetConfigAsString(key string) string {
return maps.GetValueAsString(dc.Config, key)
}
-// 以字符串形式获取配置项。
+// Deprecated: 以字符串形式获取配置项。
//
// 入参:
// - key: 配置项的键。
@@ -46,7 +46,7 @@ func (dc *DeployConfig) GetConfigOrDefaultAsString(key string, defaultValue stri
return maps.GetValueOrDefaultAsString(dc.Config, key, defaultValue)
}
-// 以 32 位整数形式获取配置项。
+// Deprecated: 以 32 位整数形式获取配置项。
//
// 入参:
// - key: 配置项的键。
@@ -57,7 +57,7 @@ func (dc *DeployConfig) GetConfigAsInt32(key string) int32 {
return maps.GetValueAsInt32(dc.Config, key)
}
-// 以 32 位整数形式获取配置项。
+// Deprecated: 以 32 位整数形式获取配置项。
//
// 入参:
// - key: 配置项的键。
@@ -69,7 +69,7 @@ func (dc *DeployConfig) GetConfigOrDefaultAsInt32(key string, defaultValue int32
return maps.GetValueOrDefaultAsInt32(dc.Config, key, defaultValue)
}
-// 以布尔形式获取配置项。
+// Deprecated: 以布尔形式获取配置项。
//
// 入参:
// - key: 配置项的键。
@@ -80,7 +80,7 @@ func (dc *DeployConfig) GetConfigAsBool(key string) bool {
return maps.GetValueAsBool(dc.Config, key)
}
-// 以布尔形式获取配置项。
+// Deprecated: 以布尔形式获取配置项。
//
// 入参:
// - key: 配置项的键。
@@ -92,7 +92,7 @@ func (dc *DeployConfig) GetConfigOrDefaultAsBool(key string, defaultValue bool)
return maps.GetValueOrDefaultAsBool(dc.Config, key, defaultValue)
}
-// 以变量字典形式获取配置项。
+// Deprecated: 以变量字典形式获取配置项。
//
// 出参:
// - 变量字典。
@@ -119,7 +119,7 @@ func (dc *DeployConfig) GetConfigAsVariables() map[string]string {
return rs
}
-// GetDomain returns the domain from the deploy config
+// Deprecated: GetDomain returns the domain from the deploy config,
// if the domain is a wildcard domain, and wildcard is true, return the wildcard domain
func (dc *DeployConfig) GetDomain(wildcard ...bool) string {
val := dc.GetConfigAsString("domain")
diff --git a/internal/domain/notify.go b/internal/domain/notify.go
index 6c164f39..e307600c 100644
--- a/internal/domain/notify.go
+++ b/internal/domain/notify.go
@@ -1,13 +1,20 @@
package domain
+/*
+消息通知渠道常量值。
+
+ 注意:如果追加新的常量值,请保持以 ASCII 排序。
+ NOTICE: If you add new constant, please keep ASCII order.
+*/
const (
- NotifyChannelEmail = "email"
- NotifyChannelWebhook = "webhook"
- NotifyChannelDingtalk = "dingtalk"
- NotifyChannelLark = "lark"
- NotifyChannelTelegram = "telegram"
- NotifyChannelServerChan = "serverchan"
NotifyChannelBark = "bark"
+ NotifyChannelDingtalk = "dingtalk"
+ NotifyChannelEmail = "email"
+ NotifyChannelLark = "lark"
+ NotifyChannelServerChan = "serverchan"
+ NotifyChannelTelegram = "telegram"
+ NotifyChannelWebhook = "webhook"
+ NotifyChannelWeCom = "wecom"
)
type NotifyTestPushReq struct {
diff --git a/internal/notify/factory.go b/internal/notify/factory.go
index 3088f246..b77c7c91 100644
--- a/internal/notify/factory.go
+++ b/internal/notify/factory.go
@@ -12,6 +12,7 @@ import (
providerServerChan "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/serverchan"
providerTelegram "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/telegram"
providerWebhook "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/webhook"
+ providerWeCom "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/wecom"
"github.com/usual2970/certimate/internal/pkg/utils/maps"
)
@@ -64,6 +65,11 @@ func createNotifier(channel string, channelConfig map[string]any) (notifier.Noti
return providerWebhook.New(&providerWebhook.WebhookNotifierConfig{
Url: maps.GetValueAsString(channelConfig, "url"),
})
+
+ case domain.NotifyChannelWeCom:
+ return providerWeCom.New(&providerWeCom.WeComNotifierConfig{
+ WebhookUrl: maps.GetValueAsString(channelConfig, "webhookUrl"),
+ })
}
return nil, fmt.Errorf("unsupported notifier channel: %s", channelConfig)
diff --git a/internal/pkg/core/notifier/providers/lark/lark.go b/internal/pkg/core/notifier/providers/lark/lark.go
index 0ab94fbb..4714e280 100644
--- a/internal/pkg/core/notifier/providers/lark/lark.go
+++ b/internal/pkg/core/notifier/providers/lark/lark.go
@@ -10,7 +10,7 @@ import (
)
type LarkNotifierConfig struct {
- // 飞书 Webhook 地址。
+ // 飞书机器人 Webhook 地址。
WebhookUrl string `json:"webhookUrl"`
}
diff --git a/internal/pkg/core/notifier/providers/wecom/wecom.go b/internal/pkg/core/notifier/providers/wecom/wecom.go
new file mode 100644
index 00000000..20938009
--- /dev/null
+++ b/internal/pkg/core/notifier/providers/wecom/wecom.go
@@ -0,0 +1,58 @@
+package serverchan
+
+import (
+ "context"
+ "errors"
+ "net/http"
+
+ notifyHttp "github.com/nikoksr/notify/service/http"
+
+ "github.com/usual2970/certimate/internal/pkg/core/notifier"
+)
+
+type WeComNotifierConfig struct {
+ // 企业微信机器人 Webhook 地址。
+ WebhookUrl string `json:"webhookUrl"`
+}
+
+type WeComNotifier struct {
+ config *WeComNotifierConfig
+}
+
+var _ notifier.Notifier = (*WeComNotifier)(nil)
+
+func New(config *WeComNotifierConfig) (*WeComNotifier, error) {
+ if config == nil {
+ return nil, errors.New("config is nil")
+ }
+
+ return &WeComNotifier{
+ config: config,
+ }, nil
+}
+
+func (n *WeComNotifier) Notify(ctx context.Context, subject string, message string) (res *notifier.NotifyResult, err error) {
+ srv := notifyHttp.New()
+
+ srv.AddReceivers(¬ifyHttp.Webhook{
+ URL: n.config.WebhookUrl,
+ Header: http.Header{},
+ ContentType: "application/json",
+ Method: http.MethodPost,
+ BuildPayload: func(subject, message string) (payload any) {
+ return map[string]any{
+ "msgtype": "text",
+ "text": map[string]string{
+ "content": subject + "\n\n" + message,
+ },
+ }
+ },
+ })
+
+ err = srv.Send(ctx, subject, message)
+ if err != nil {
+ return nil, err
+ }
+
+ return ¬ifier.NotifyResult{}, nil
+}
diff --git a/internal/pkg/core/notifier/providers/wecom/wecom_test.go b/internal/pkg/core/notifier/providers/wecom/wecom_test.go
new file mode 100644
index 00000000..a9ac9d16
--- /dev/null
+++ b/internal/pkg/core/notifier/providers/wecom/wecom_test.go
@@ -0,0 +1,57 @@
+package serverchan_test
+
+import (
+ "context"
+ "flag"
+ "fmt"
+ "strings"
+ "testing"
+
+ provider "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/wecom"
+)
+
+const (
+ mockSubject = "test_subject"
+ mockMessage = "test_message"
+)
+
+var fWebhookUrl string
+
+func init() {
+ argsPrefix := "CERTIMATE_NOTIFIER_WECOM_"
+
+ flag.StringVar(&fWebhookUrl, argsPrefix+"WEBHOOKURL", "", "")
+}
+
+/*
+Shell command to run this test:
+
+ go test -v serverchan_test.go -args \
+ --CERTIMATE_NOTIFIER_WECOM_WEBHOOKURL="https://example.com/your-webhook-url" \
+*/
+func TestNotify(t *testing.T) {
+ flag.Parse()
+
+ t.Run("Notify", func(t *testing.T) {
+ t.Log(strings.Join([]string{
+ "args:",
+ fmt.Sprintf("WEBHOOKURL: %v", fWebhookUrl),
+ }, "\n"))
+
+ notifier, err := provider.New(&provider.WeComNotifierConfig{
+ WebhookUrl: fWebhookUrl,
+ })
+ if err != nil {
+ t.Errorf("err: %+v", err)
+ return
+ }
+
+ res, err := notifier.Notify(context.Background(), mockSubject, mockMessage)
+ if err != nil {
+ t.Errorf("err: %+v", err)
+ return
+ }
+
+ t.Logf("ok: %v", res)
+ })
+}
diff --git a/ui/src/components/notification/NotifyChannelEditForm.tsx b/ui/src/components/notification/NotifyChannelEditForm.tsx
index fc53e413..d93a6732 100644
--- a/ui/src/components/notification/NotifyChannelEditForm.tsx
+++ b/ui/src/components/notification/NotifyChannelEditForm.tsx
@@ -2,7 +2,7 @@ import { forwardRef, useImperativeHandle, useMemo, useState } from "react";
import { useCreation, useDeepCompareEffect } from "ahooks";
import { Form } from "antd";
-import { type NotifyChannelsSettingsContent } from "@/domain/settings";
+import { NOTIFY_CHANNELS, type NotifyChannelsSettingsContent } from "@/domain/settings";
import NotifyChannelEditFormBarkFields from "./NotifyChannelEditFormBarkFields";
import NotifyChannelEditFormDingTalkFields from "./NotifyChannelEditFormDingTalkFields";
import NotifyChannelEditFormEmailFields from "./NotifyChannelEditFormEmailFields";
@@ -10,13 +10,14 @@ import NotifyChannelEditFormLarkFields from "./NotifyChannelEditFormLarkFields";
import NotifyChannelEditFormServerChanFields from "./NotifyChannelEditFormServerChanFields";
import NotifyChannelEditFormTelegramFields from "./NotifyChannelEditFormTelegramFields";
import NotifyChannelEditFormWebhookFields from "./NotifyChannelEditFormWebhookFields";
+import NotifyChannelEditFormWeComFields from "./NotifyChannelEditFormWeComFields";
type NotifyChannelEditFormModelType = NotifyChannelsSettingsContent[keyof NotifyChannelsSettingsContent];
export type NotifyChannelEditFormProps = {
className?: string;
style?: React.CSSProperties;
- channel: keyof NotifyChannelsSettingsContent;
+ channel: string;
disabled?: boolean;
loading?: boolean;
model?: NotifyChannelEditFormModelType;
@@ -39,20 +40,22 @@ const NotifyChannelEditForm = forwardRef