From 18a19096d3fb76867ad0883b7b6ecaf036137a84 Mon Sep 17 00:00:00 2001 From: Fu Diwei Date: Sun, 27 Apr 2025 23:44:01 +0800 Subject: [PATCH] feat: add dingtalk, lark, and wecom bot webhook --- internal/domain/access.go | 13 ++++ internal/domain/provider.go | 14 ++-- internal/notify/providers.go | 40 +++++++++++ internal/notify/providers_deprecated.go | 4 +- .../notifier/providers/dingtalk/dingtalk.go | 13 +++- ui/public/imgs/providers/dingtalk.svg | 1 + ui/public/imgs/providers/lark.svg | 1 + ui/public/imgs/providers/wecom.svg | 1 + ui/src/components/access/AccessForm.tsx | 9 +++ .../access/AccessFormDingTalkBotConfig.tsx | 68 +++++++++++++++++++ .../access/AccessFormLarkBotConfig.tsx | 57 ++++++++++++++++ .../access/AccessFormWeComBotConfig.tsx | 57 ++++++++++++++++ ui/src/domain/access.ts | 16 +++++ ui/src/domain/provider.ts | 19 +++++- ui/src/domain/settings.ts | 39 +++++++++++ ui/src/i18n/locales/en/nls.access.json | 12 ++++ ui/src/i18n/locales/en/nls.provider.json | 3 + ui/src/i18n/locales/zh/nls.access.json | 12 ++++ ui/src/i18n/locales/zh/nls.provider.json | 3 + 19 files changed, 372 insertions(+), 10 deletions(-) create mode 100644 ui/public/imgs/providers/dingtalk.svg create mode 100644 ui/public/imgs/providers/lark.svg create mode 100644 ui/public/imgs/providers/wecom.svg create mode 100644 ui/src/components/access/AccessFormDingTalkBotConfig.tsx create mode 100644 ui/src/components/access/AccessFormLarkBotConfig.tsx create mode 100644 ui/src/components/access/AccessFormWeComBotConfig.tsx diff --git a/internal/domain/access.go b/internal/domain/access.go index a9079cf7..fd36417c 100644 --- a/internal/domain/access.go +++ b/internal/domain/access.go @@ -98,6 +98,11 @@ type AccessConfigForDeSEC struct { Token string `json:"token"` } +type AccessConfigForDingTalkBot struct { + WebhookUrl string `json:"webhookUrl"` + Secret string `json:"secret"` +} + type AccessConfigForDNSLA struct { ApiId string `json:"apiId"` ApiSecret string `json:"apiSecret"` @@ -160,6 +165,10 @@ type AccessConfigForKubernetes struct { KubeConfig string `json:"kubeConfig,omitempty"` } +type AccessConfigForLarkBot struct { + WebhookUrl string `json:"webhookUrl"` +} + type AccessConfigForMattermost struct { ServerUrl string `json:"serverUrl"` Username string `json:"username"` @@ -270,6 +279,10 @@ type AccessConfigForWebhook struct { DefaultDataForNotification string `json:"defaultDataForNotification,omitempty"` } +type AccessConfigForWeComBot struct { + WebhookUrl string `json:"webhookUrl"` +} + type AccessConfigForWestcn struct { Username string `json:"username"` ApiPassword string `json:"password"` diff --git a/internal/domain/provider.go b/internal/domain/provider.go index ca9fb9df..cb2ae3c9 100644 --- a/internal/domain/provider.go +++ b/internal/domain/provider.go @@ -29,6 +29,7 @@ const ( AccessProviderTypeCTCCCloud = AccessProviderType("ctcccloud") // 联通云(预留) AccessProviderTypeCUCCCloud = AccessProviderType("cucccloud") // 天翼云(预留) AccessProviderTypeDeSEC = AccessProviderType("desec") + AccessProviderTypeDingTalkBot = AccessProviderType("dingtalkbot") AccessProviderTypeDNSLA = AccessProviderType("dnsla") AccessProviderTypeDogeCloud = AccessProviderType("dogecloud") AccessProviderTypeDynv6 = AccessProviderType("dynv6") @@ -43,6 +44,7 @@ const ( AccessProviderTypeHuaweiCloud = AccessProviderType("huaweicloud") AccessProviderTypeJDCloud = AccessProviderType("jdcloud") AccessProviderTypeKubernetes = AccessProviderType("k8s") + AccessProviderTypeLarkBot = AccessProviderType("larkbot") AccessProviderTypeLetsEncrypt = AccessProviderType("letsencrypt") AccessProviderTypeLetsEncryptStaging = AccessProviderType("letsencryptstaging") AccessProviderTypeLocal = AccessProviderType("local") @@ -67,6 +69,7 @@ const ( AccessProviderTypeVolcEngine = AccessProviderType("volcengine") AccessProviderTypeWangsu = AccessProviderType("wangsu") AccessProviderTypeWebhook = AccessProviderType("webhook") + AccessProviderTypeWeComBot = AccessProviderType("wecombot") AccessProviderTypeWestcn = AccessProviderType("westcn") AccessProviderTypeZeroSSL = AccessProviderType("zerossl") ) @@ -234,8 +237,11 @@ type NotificationProviderType string NOTICE: If you add new constant, please keep ASCII order. */ const ( - NotificationProviderTypeEmail = NotificationProviderType(AccessProviderTypeEmail) - NotificationProviderTypeMattermost = NotificationProviderType(AccessProviderTypeMattermost) - NotificationProviderTypeTelegram = NotificationProviderType(AccessProviderTypeTelegram) - NotificationProviderTypeWebhook = NotificationProviderType(AccessProviderTypeWebhook) + NotificationProviderTypeDingTalkBot = NotificationProviderType(AccessProviderTypeDingTalkBot) + NotificationProviderTypeEmail = NotificationProviderType(AccessProviderTypeEmail) + NotificationProviderTypeLarkBot = NotificationProviderType(AccessProviderTypeLarkBot) + NotificationProviderTypeMattermost = NotificationProviderType(AccessProviderTypeMattermost) + NotificationProviderTypeTelegram = NotificationProviderType(AccessProviderTypeTelegram) + NotificationProviderTypeWebhook = NotificationProviderType(AccessProviderTypeWebhook) + NotificationProviderTypeWeComBot = NotificationProviderType(AccessProviderTypeWeComBot) ) diff --git a/internal/notify/providers.go b/internal/notify/providers.go index 40b069fe..c57b9c82 100644 --- a/internal/notify/providers.go +++ b/internal/notify/providers.go @@ -6,10 +6,13 @@ import ( "github.com/usual2970/certimate/internal/domain" "github.com/usual2970/certimate/internal/pkg/core/notifier" + pDingTalk "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/dingtalk" pEmail "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/email" + pLark "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/lark" pMattermost "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/mattermost" pTelegram "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/telegram" pWebhook "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/webhook" + pWeCom "github.com/usual2970/certimate/internal/pkg/core/notifier/providers/wecom" httputil "github.com/usual2970/certimate/internal/pkg/utils/http" maputil "github.com/usual2970/certimate/internal/pkg/utils/map" ) @@ -26,6 +29,19 @@ func createNotifierProvider(options *notifierProviderOptions) (notifier.Notifier NOTICE: If you add new constant, please keep ASCII order. */ switch options.Provider { + case domain.NotificationProviderTypeDingTalkBot: + { + access := domain.AccessConfigForDingTalkBot{} + if err := maputil.Populate(options.ProviderAccessConfig, &access); err != nil { + return nil, fmt.Errorf("failed to populate provider access config: %w", err) + } + + return pDingTalk.NewNotifier(&pDingTalk.NotifierConfig{ + WebhookUrl: access.WebhookUrl, + Secret: access.Secret, + }) + } + case domain.NotificationProviderTypeEmail: { access := domain.AccessConfigForEmail{} @@ -44,6 +60,18 @@ func createNotifierProvider(options *notifierProviderOptions) (notifier.Notifier }) } + case domain.NotificationProviderTypeLarkBot: + { + access := domain.AccessConfigForLarkBot{} + if err := maputil.Populate(options.ProviderAccessConfig, &access); err != nil { + return nil, fmt.Errorf("failed to populate provider access config: %w", err) + } + + return pLark.NewNotifier(&pLark.NotifierConfig{ + WebhookUrl: access.WebhookUrl, + }) + } + case domain.NotificationProviderTypeMattermost: { access := domain.AccessConfigForMattermost{} @@ -107,6 +135,18 @@ func createNotifierProvider(options *notifierProviderOptions) (notifier.Notifier AllowInsecureConnections: access.AllowInsecureConnections, }) } + + case domain.NotificationProviderTypeWeComBot: + { + access := domain.AccessConfigForWeComBot{} + if err := maputil.Populate(options.ProviderAccessConfig, &access); err != nil { + return nil, fmt.Errorf("failed to populate provider access config: %w", err) + } + + return pWeCom.NewNotifier(&pWeCom.NotifierConfig{ + WebhookUrl: access.WebhookUrl, + }) + } } return nil, fmt.Errorf("unsupported notifier provider '%s'", options.Provider) diff --git a/internal/notify/providers_deprecated.go b/internal/notify/providers_deprecated.go index 43eadf71..1e862866 100644 --- a/internal/notify/providers_deprecated.go +++ b/internal/notify/providers_deprecated.go @@ -35,8 +35,8 @@ func createNotifierProviderUseGlobalSettings(channel domain.NotifyChannelType, c case domain.NotifyChannelTypeDingTalk: return pDingTalk.NewNotifier(&pDingTalk.NotifierConfig{ - AccessToken: maputil.GetString(channelConfig, "accessToken"), - Secret: maputil.GetString(channelConfig, "secret"), + WebhookUrl: "https://oapi.dingtalk.com/robot/send?access_token=" + maputil.GetString(channelConfig, "accessToken"), + Secret: maputil.GetString(channelConfig, "secret"), }) case domain.NotifyChannelTypeEmail: diff --git a/internal/pkg/core/notifier/providers/dingtalk/dingtalk.go b/internal/pkg/core/notifier/providers/dingtalk/dingtalk.go index cc394eae..9eb94dcf 100644 --- a/internal/pkg/core/notifier/providers/dingtalk/dingtalk.go +++ b/internal/pkg/core/notifier/providers/dingtalk/dingtalk.go @@ -2,7 +2,9 @@ package dingtalk import ( "context" + "fmt" "log/slog" + "net/url" "github.com/nikoksr/notify/service/dingding" @@ -10,8 +12,8 @@ import ( ) type NotifierConfig struct { - // 钉钉机器人的 Token。 - AccessToken string `json:"accessToken"` + // 钉钉机器人的 Webhook 地址。 + WebhookUrl string `json:"webhookUrl"` // 钉钉机器人的 Secret。 Secret string `json:"secret"` } @@ -44,8 +46,13 @@ func (n *NotifierProvider) WithLogger(logger *slog.Logger) notifier.Notifier { } func (n *NotifierProvider) Notify(ctx context.Context, subject string, message string) (res *notifier.NotifyResult, err error) { + webhookUrl, err := url.Parse(n.config.WebhookUrl) + if err != nil { + return nil, fmt.Errorf("invalid webhook url: %w", err) + } + srv := dingding.New(&dingding.Config{ - Token: n.config.AccessToken, + Token: webhookUrl.Query().Get("access_token"), Secret: n.config.Secret, }) diff --git a/ui/public/imgs/providers/dingtalk.svg b/ui/public/imgs/providers/dingtalk.svg new file mode 100644 index 00000000..24d3881a --- /dev/null +++ b/ui/public/imgs/providers/dingtalk.svg @@ -0,0 +1 @@ + diff --git a/ui/public/imgs/providers/lark.svg b/ui/public/imgs/providers/lark.svg new file mode 100644 index 00000000..ab32e57c --- /dev/null +++ b/ui/public/imgs/providers/lark.svg @@ -0,0 +1 @@ + diff --git a/ui/public/imgs/providers/wecom.svg b/ui/public/imgs/providers/wecom.svg new file mode 100644 index 00000000..e99e59a7 --- /dev/null +++ b/ui/public/imgs/providers/wecom.svg @@ -0,0 +1 @@ + diff --git a/ui/src/components/access/AccessForm.tsx b/ui/src/components/access/AccessForm.tsx index 6f820bb3..85ad8a78 100644 --- a/ui/src/components/access/AccessForm.tsx +++ b/ui/src/components/access/AccessForm.tsx @@ -25,6 +25,7 @@ import AccessFormCloudflareConfig from "./AccessFormCloudflareConfig"; import AccessFormClouDNSConfig from "./AccessFormClouDNSConfig"; import AccessFormCMCCCloudConfig from "./AccessFormCMCCCloudConfig"; import AccessFormDeSECConfig from "./AccessFormDeSECConfig"; +import AccessFormDingTalkBotConfig from "./AccessFormDingTalkBotConfig"; import AccessFormDNSLAConfig from "./AccessFormDNSLAConfig"; import AccessFormDogeCloudConfig from "./AccessFormDogeCloudConfig"; import AccessFormDynv6Config from "./AccessFormDynv6Config"; @@ -37,6 +38,7 @@ import AccessFormGoogleTrustServicesConfig from "./AccessFormGoogleTrustServices import AccessFormHuaweiCloudConfig from "./AccessFormHuaweiCloudConfig"; import AccessFormJDCloudConfig from "./AccessFormJDCloudConfig"; import AccessFormKubernetesConfig from "./AccessFormKubernetesConfig"; +import AccessFormLarkBotConfig from "./AccessFormLarkBotConfig"; import AccessFormMattermostConfig from "./AccessFormMattermostConfig"; import AccessFormNamecheapConfig from "./AccessFormNamecheapConfig"; import AccessFormNameDotComConfig from "./AccessFormNameDotComConfig"; @@ -57,6 +59,7 @@ import AccessFormVercelConfig from "./AccessFormVercelConfig"; import AccessFormVolcEngineConfig from "./AccessFormVolcEngineConfig"; import AccessFormWangsuConfig from "./AccessFormWangsuConfig"; import AccessFormWebhookConfig from "./AccessFormWebhookConfig"; +import AccessFormWeComBotConfig from "./AccessFormWeComBotConfig"; import AccessFormWestcnConfig from "./AccessFormWestcnConfig"; import AccessFormZeroSSLConfig from "./AccessFormZeroSSLConfig"; @@ -183,6 +186,8 @@ const AccessForm = forwardRef(({ className, return ; case ACCESS_PROVIDERS.DESEC: return ; + case ACCESS_PROVIDERS.DINGTALKBOT: + return ; case ACCESS_PROVIDERS.DNSLA: return ; case ACCESS_PROVIDERS.DOGECLOUD: @@ -207,6 +212,8 @@ const AccessForm = forwardRef(({ className, return ; case ACCESS_PROVIDERS.KUBERNETES: return ; + case ACCESS_PROVIDERS.LARKBOT: + return ; case ACCESS_PROVIDERS.MATTERMOST: return ; case ACCESS_PROVIDERS.NAMECHEAP: @@ -252,6 +259,8 @@ const AccessForm = forwardRef(({ className, {...nestedFormProps} /> ); + case ACCESS_PROVIDERS.WECOMBOT: + return ; case ACCESS_PROVIDERS.WESTCN: return ; case ACCESS_PROVIDERS.ZEROSSL: diff --git a/ui/src/components/access/AccessFormDingTalkBotConfig.tsx b/ui/src/components/access/AccessFormDingTalkBotConfig.tsx new file mode 100644 index 00000000..35aebf6e --- /dev/null +++ b/ui/src/components/access/AccessFormDingTalkBotConfig.tsx @@ -0,0 +1,68 @@ +import { useTranslation } from "react-i18next"; +import { Form, type FormInstance, Input } from "antd"; +import { createSchemaFieldRule } from "antd-zod"; +import { z } from "zod"; + +import { type AccessConfigForDingTalkBot } from "@/domain/access"; + +type AccessFormDingTalkBotConfigFieldValues = Nullish; + +export type AccessFormDingTalkBotConfigProps = { + form: FormInstance; + formName: string; + disabled?: boolean; + initialValues?: AccessFormDingTalkBotConfigFieldValues; + onValuesChange?: (values: AccessFormDingTalkBotConfigFieldValues) => void; +}; + +const initFormModel = (): AccessFormDingTalkBotConfigFieldValues => { + return { + webhookUrl: "", + secret: "", + }; +}; + +const AccessFormDingTalkBotConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormDingTalkBotConfigProps) => { + const { t } = useTranslation(); + + const formSchema = z.object({ + webhookUrl: z.string().url(t("common.errmsg.url_invalid")), + secret: z.string().nonempty(t("access.form.dingtalkbot_secret.placeholder")).trim(), + }); + const formRule = createSchemaFieldRule(formSchema); + + const handleFormChange = (_: unknown, values: z.infer) => { + onValuesChange?.(values); + }; + + return ( +
+ } + > + + + + } + > + + +
+ ); +}; + +export default AccessFormDingTalkBotConfig; diff --git a/ui/src/components/access/AccessFormLarkBotConfig.tsx b/ui/src/components/access/AccessFormLarkBotConfig.tsx new file mode 100644 index 00000000..2a07505e --- /dev/null +++ b/ui/src/components/access/AccessFormLarkBotConfig.tsx @@ -0,0 +1,57 @@ +import { useTranslation } from "react-i18next"; +import { Form, type FormInstance, Input } from "antd"; +import { createSchemaFieldRule } from "antd-zod"; +import { z } from "zod"; + +import { type AccessConfigForLarkBot } from "@/domain/access"; + +type AccessFormLarkBotConfigFieldValues = Nullish; + +export type AccessFormLarkBotConfigProps = { + form: FormInstance; + formName: string; + disabled?: boolean; + initialValues?: AccessFormLarkBotConfigFieldValues; + onValuesChange?: (values: AccessFormLarkBotConfigFieldValues) => void; +}; + +const initFormModel = (): AccessFormLarkBotConfigFieldValues => { + return { + webhookUrl: "", + }; +}; + +const AccessFormLarkBotConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormLarkBotConfigProps) => { + const { t } = useTranslation(); + + const formSchema = z.object({ + webhookUrl: z.string().url(t("common.errmsg.url_invalid")), + }); + const formRule = createSchemaFieldRule(formSchema); + + const handleFormChange = (_: unknown, values: z.infer) => { + onValuesChange?.(values); + }; + + return ( +
+ } + > + + +
+ ); +}; + +export default AccessFormLarkBotConfig; diff --git a/ui/src/components/access/AccessFormWeComBotConfig.tsx b/ui/src/components/access/AccessFormWeComBotConfig.tsx new file mode 100644 index 00000000..16a205f5 --- /dev/null +++ b/ui/src/components/access/AccessFormWeComBotConfig.tsx @@ -0,0 +1,57 @@ +import { useTranslation } from "react-i18next"; +import { Form, type FormInstance, Input } from "antd"; +import { createSchemaFieldRule } from "antd-zod"; +import { z } from "zod"; + +import { type AccessConfigForWeComBot } from "@/domain/access"; + +type AccessFormWeComBotConfigFieldValues = Nullish; + +export type AccessFormWeComBotConfigProps = { + form: FormInstance; + formName: string; + disabled?: boolean; + initialValues?: AccessFormWeComBotConfigFieldValues; + onValuesChange?: (values: AccessFormWeComBotConfigFieldValues) => void; +}; + +const initFormModel = (): AccessFormWeComBotConfigFieldValues => { + return { + webhookUrl: "", + }; +}; + +const AccessFormWeComBotConfig = ({ form: formInst, formName, disabled, initialValues, onValuesChange }: AccessFormWeComBotConfigProps) => { + const { t } = useTranslation(); + + const formSchema = z.object({ + webhookUrl: z.string().url(t("common.errmsg.url_invalid")), + }); + const formRule = createSchemaFieldRule(formSchema); + + const handleFormChange = (_: unknown, values: z.infer) => { + onValuesChange?.(values); + }; + + return ( +
+ } + > + + +
+ ); +}; + +export default AccessFormWeComBotConfig; diff --git a/ui/src/domain/access.ts b/ui/src/domain/access.ts index 9396e892..b7c54306 100644 --- a/ui/src/domain/access.ts +++ b/ui/src/domain/access.ts @@ -22,6 +22,7 @@ export interface AccessModel extends BaseModel { | AccessConfigForClouDNS | AccessConfigForCMCCCloud | AccessConfigForDeSEC + | AccessConfigForDingTalkBot | AccessConfigForDNSLA | AccessConfigForDogeCloud | AccessConfigForDynv6 @@ -34,6 +35,7 @@ export interface AccessModel extends BaseModel { | AccessConfigForHuaweiCloud | AccessConfigForJDCloud | AccessConfigForKubernetes + | AccessConfigForLarkBot | AccessConfigForMattermost | AccessConfigForNamecheap | AccessConfigForNameDotCom @@ -53,6 +55,7 @@ export interface AccessModel extends BaseModel { | AccessConfigForVolcEngine | AccessConfigForWangsu | AccessConfigForWebhook + | AccessConfigForWeComBot | AccessConfigForWestcn | AccessConfigForZeroSSL ); @@ -143,6 +146,11 @@ export type AccessConfigForDeSEC = { token: string; }; +export type AccessConfigForDingTalkBot = { + webhookUrl: string; + secret?: string; +}; + export type AccessConfigForDNSLA = { apiId: string; apiSecret: string; @@ -205,6 +213,10 @@ export type AccessConfigForKubernetes = { kubeConfig?: string; }; +export type AccessConfigForLarkBot = { + webhookUrl: string; +}; + export type AccessConfigForMattermost = { serverUrl: string; username: string; @@ -315,6 +327,10 @@ export type AccessConfigForWebhook = { defaultDataForNotification?: string; }; +export type AccessConfigForWeComBot = { + webhookUrl: string; +}; + export type AccessConfigForWestcn = { username: string; apiPassword: string; diff --git a/ui/src/domain/provider.ts b/ui/src/domain/provider.ts index 43bc6bba..73cc7e7d 100644 --- a/ui/src/domain/provider.ts +++ b/ui/src/domain/provider.ts @@ -21,6 +21,7 @@ export const ACCESS_PROVIDERS = Object.freeze({ CLOUDNS: "cloudns", CMCCCLOUD: "cmcccloud", DESEC: "desec", + DINGTALKBOT: "dingtalkbot", DNSLA: "dnsla", DOGECLOUD: "dogecloud", DYNV6: "dynv6", @@ -33,6 +34,7 @@ export const ACCESS_PROVIDERS = Object.freeze({ HUAWEICLOUD: "huaweicloud", JDCLOUD: "jdcloud", KUBERNETES: "k8s", + LARKBOT: "larkbot", LETSENCRYPT: "letsencrypt", LETSENCRYPTSTAGING: "letsencryptstaging", LOCAL: "local", @@ -56,6 +58,7 @@ export const ACCESS_PROVIDERS = Object.freeze({ VOLCENGINE: "volcengine", WANGSU: "wangsu", WEBHOOK: "webhook", + WECOMBOT: "wecombot", WESTCN: "westcn", ZEROSSL: "zerossl", } as const); @@ -142,6 +145,9 @@ export const accessProvidersMap: Map [ @@ -514,10 +520,13 @@ export const deploymentProvidersMap: Map [ + [ + [NOTIFICATION_PROVIDERS.EMAIL], + [NOTIFICATION_PROVIDERS.WEBHOOK], + [NOTIFICATION_PROVIDERS.DINGTALKBOT], + [NOTIFICATION_PROVIDERS.LARKBOT], + [NOTIFICATION_PROVIDERS.WECOMBOT], + [NOTIFICATION_PROVIDERS.MATTERMOST], + [NOTIFICATION_PROVIDERS.TELEGRAM], + ].map(([type]) => [ type, { type: type as CAProviderType, diff --git a/ui/src/domain/settings.ts b/ui/src/domain/settings.ts index 5f732a35..a711f543 100644 --- a/ui/src/domain/settings.ts +++ b/ui/src/domain/settings.ts @@ -87,12 +87,18 @@ export type NotifyChannelsSettingsContent = { [NOTIFY_CHANNELS.WECOM]?: WeComNotifyChannelConfig; }; +/** + * @deprecated + */ export type BarkNotifyChannelConfig = { deviceKey: string; serverUrl: string; enabled?: boolean; }; +/** + * @deprecated + */ export type EmailNotifyChannelConfig = { smtpHost: string; smtpPort: number; @@ -104,12 +110,18 @@ export type EmailNotifyChannelConfig = { enabled?: boolean; }; +/** + * @deprecated + */ export type DingTalkNotifyChannelConfig = { accessToken: string; secret: string; enabled?: boolean; }; +/** + * @deprecated + */ export type GotifyNotifyChannelConfig = { url: string; token: string; @@ -117,11 +129,17 @@ export type GotifyNotifyChannelConfig = { enabled?: boolean; }; +/** + * @deprecated + */ export type LarkNotifyChannelConfig = { webhookUrl: string; enabled?: boolean; }; +/** + * @deprecated + */ export type MattermostNotifyChannelConfig = { serverUrl: string; channel: string; @@ -130,38 +148,59 @@ export type MattermostNotifyChannelConfig = { enabled?: boolean; }; +/** + * @deprecated + */ export type PushoverNotifyChannelConfig = { token: string; user: string; enabled?: boolean; }; +/** + * @deprecated + */ export type PushPlusNotifyChannelConfig = { token: string; enabled?: boolean; }; +/** + * @deprecated + */ export type ServerChanNotifyChannelConfig = { url: string; enabled?: boolean; }; +/** + * @deprecated + */ export type TelegramNotifyChannelConfig = { apiToken: string; chatId: string; enabled?: boolean; }; +/** + * @deprecated + */ export type WebhookNotifyChannelConfig = { url: string; enabled?: boolean; }; +/** + * @deprecated + */ export type WeComNotifyChannelConfig = { webhookUrl: string; enabled?: boolean; }; +/** + * @deprecated + */ export type NotifyChannel = { type: string; name: string; diff --git a/ui/src/i18n/locales/en/nls.access.json b/ui/src/i18n/locales/en/nls.access.json index d94c7871..46fbb48e 100644 --- a/ui/src/i18n/locales/en/nls.access.json +++ b/ui/src/i18n/locales/en/nls.access.json @@ -145,6 +145,12 @@ "access.form.desec_token.label": "deSEC token", "access.form.desec_token.placeholder": "Please enter deSEC token", "access.form.desec_token.tooltip": "For more information, see https://desec.readthedocs.io/en/latest/auth/tokens.html", + "access.form.dingtalkbot_webhook_url.label": "DingTalk bot Webhook URL", + "access.form.dingtalkbot_webhook_url.placeholder": "Please enter DingTalk bot Webhook URL", + "access.form.dingtalkbot_webhook_url.tooltip": "For more information, see https://open.dingtalk.com/document/orgapp/obtain-the-webhook-address-of-a-custom-robot", + "access.form.dingtalkbot_secret.label": "DingTalk bot secret", + "access.form.dingtalkbot_secret.placeholder": "Please enter DingTalk bot secret", + "access.form.dingtalkbot_secret.tooltip": "For more information, see https://open.dingtalk.com/document/orgapp/customize-robot-security-settings", "access.form.dnsla_api_id.label": "DNS.LA API ID", "access.form.dnsla_api_id.placeholder": "Please enter DNS.LA API ID", "access.form.dnsla_api_id.tooltip": "For more information, see https://www.dns.la/docs/ApiDoc", @@ -216,6 +222,9 @@ "access.form.k8s_kubeconfig.placeholder": "Please enter KubeConfig file", "access.form.k8s_kubeconfig.upload": "Choose File ...", "access.form.k8s_kubeconfig.tooltip": "For more information, see https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/

Leave it blank to use the Pod's ServiceAccount.", + "access.form.larkbot_webhook_url.label": "Lark bot Webhook URL", + "access.form.larkbot_webhook_url.placeholder": "Please enter Lark bot Webhook URL", + "access.form.larkbot_webhook_url.tooltip": "For more information, see https://www.feishu.cn/hc/en-US/articles/807992406756", "access.form.mattermost_server_url.label": "Mattermost server URL", "access.form.mattermost_server_url.placeholder": "Please enter Mattermost server URL", "access.form.mattermost_username.label": "Mattermost username", @@ -364,6 +373,9 @@ "access.form.webhook_allow_insecure_conns.tooltip": "Allowing insecure connections may lead to data leak or tampering. Use this option only when under trusted networks.", "access.form.webhook_allow_insecure_conns.switch.on": "Allow", "access.form.webhook_allow_insecure_conns.switch.off": "Disallow", + "access.form.wecombot_webhook_url.label": "WeCom bot Webhook URL", + "access.form.wecombot_webhook_url.placeholder": "Please enter WeCom bot Webhook URL", + "access.form.wecombot_webhook_url.tooltip": "For more information, see https://open.work.weixin.qq.com/help2/pc/18401", "access.form.westcn_username.label": "West.cn username", "access.form.westcn_username.placeholder": "Please enter West.cn username", "access.form.westcn_username.tooltip": "For more information, see https://www.west.cn/CustomerCenter/doc/apiv2.html", diff --git a/ui/src/i18n/locales/en/nls.provider.json b/ui/src/i18n/locales/en/nls.provider.json index da51d283..9829faab 100644 --- a/ui/src/i18n/locales/en/nls.provider.json +++ b/ui/src/i18n/locales/en/nls.provider.json @@ -52,6 +52,7 @@ "provider.ctcccloud": "China Telecom Cloud (State Cloud)", "provider.cucccloud": "China Unicom Cloud", "provider.desec": "deSEC", + "provider.dingtalkbot": "DingTalk Bot", "provider.dnsla": "DNS.LA", "provider.dogecloud": "Doge Cloud", "provider.dogecloud.cdn": "Doge Cloud - CDN (Content Delivery Network)", @@ -81,6 +82,7 @@ "provider.jdcloud.vod": "JD Cloud - VOD (Video on Demand)", "provider.kubernetes": "Kubernetes", "provider.kubernetes.secret": "Kubernetes - Secret", + "provider.larkbot": "Lark Bot", "provider.letsencrypt": "Let's Encrypt", "provider.letsencryptstaging": "Let's Encrypt Staging Environment", "provider.local": "Local deployment", @@ -134,6 +136,7 @@ "provider.wangsu": "Wangsu Cloud", "provider.wangsu.cdnpro": "Wangsu Cloud - CDN Pro", "provider.webhook": "Webhook", + "provider.wecombot": "WeCom Bot", "provider.westcn": "West.cn", "provider.zerossl": "ZeroSSL", diff --git a/ui/src/i18n/locales/zh/nls.access.json b/ui/src/i18n/locales/zh/nls.access.json index 81f87672..11da4d0e 100644 --- a/ui/src/i18n/locales/zh/nls.access.json +++ b/ui/src/i18n/locales/zh/nls.access.json @@ -139,6 +139,12 @@ "access.form.desec_token.label": "deSEC Token", "access.form.desec_token.placeholder": "请输入 deSEC Token", "access.form.desec_token.tooltip": "这是什么?请参阅 https://desec.readthedocs.io/en/latest/auth/tokens.html", + "access.form.dingtalkbot_webhook_url.label": "钉钉群机器人 Webhook 地址", + "access.form.dingtalkbot_webhook_url.placeholder": "请输入钉钉群机器人 Webhook 地址", + "access.form.dingtalkbot_webhook_url.tooltip": "这是什么?请参阅 https://open.dingtalk.com/document/orgapp/obtain-the-webhook-address-of-a-custom-robot", + "access.form.dingtalkbot_secret.label": "钉钉群机器人加签密钥", + "access.form.dingtalkbot_secret.placeholder": "请输入钉钉群机器人加签密钥", + "access.form.dingtalkbot_secret.tooltip": "这是什么?请参阅 https://open.dingtalk.com/document/orgapp/customize-robot-security-settings", "access.form.dnsla_api_id.label": "DNS.LA API ID", "access.form.dnsla_api_id.placeholder": "请输入 DNS.LA API ID", "access.form.dnsla_api_id.tooltip": "这是什么?请参阅 https://www.dns.la/docs/ApiDoc", @@ -210,6 +216,9 @@ "access.form.k8s_kubeconfig.placeholder": "请选择 KubeConfig 文件", "access.form.k8s_kubeconfig.upload": "选择文件", "access.form.k8s_kubeconfig.tooltip": "这是什么?请参阅 https://kubernetes.io/zh-cn/docs/concepts/configuration/organize-cluster-access-kubeconfig/

为空时,将使用 Pod 的 ServiceAccount 作为凭证。", + "access.form.larkbot_webhook_url.label": "飞书群机器人 Webhook 地址", + "access.form.larkbot_webhook_url.placeholder": "请输入飞书群机器人 Webhook 地址", + "access.form.larkbot_webhook_url.tooltip": "这是什么?请参阅 https://www.feishu.cn/hc/zh-CN/articles/807992406756", "access.form.mattermost_server_url.label": "Mattermost 服务地址", "access.form.mattermost_server_url.placeholder": "请输入 Mattermost 服务地址", "access.form.mattermost_username.label": "Mattermost 用户名", @@ -364,6 +373,9 @@ "access.form.webhook_allow_insecure_conns.tooltip": "忽略 SSL/TLS 证书错误可能导致数据泄露或被篡改。建议仅在可信网络下启用。", "access.form.webhook_allow_insecure_conns.switch.on": "允许", "access.form.webhook_allow_insecure_conns.switch.off": "不允许", + "access.form.wecombot_webhook_url.label": "企业微信群机器人 Webhook 地址", + "access.form.wecombot_webhook_url.placeholder": "请输入企业微信群机器人 Webhook 地址", + "access.form.wecombot_webhook_url.tooltip": "这是什么?请参阅 https://open.work.weixin.qq.com/help2/pc/18401", "access.form.westcn_username.label": "西部数码用户名", "access.form.westcn_username.placeholder": "请输入西部数码用户名", "access.form.westcn_username.tooltip": "这是什么?请参阅 https://www.west.cn/CustomerCenter/doc/apiv2.html", diff --git a/ui/src/i18n/locales/zh/nls.provider.json b/ui/src/i18n/locales/zh/nls.provider.json index aa48abb6..28c3ad82 100644 --- a/ui/src/i18n/locales/zh/nls.provider.json +++ b/ui/src/i18n/locales/zh/nls.provider.json @@ -52,6 +52,7 @@ "provider.ctcccloud": "联通云", "provider.cucccloud": "天翼云", "provider.desec": "deSEC", + "provider.dingtalkbot": "钉钉群机器人", "provider.dnsla": "DNS.LA", "provider.dogecloud": "多吉云", "provider.dogecloud.cdn": "多吉云 - 内容分发网络 CDN", @@ -81,6 +82,7 @@ "provider.jdcloud.vod": "京东云 - 视频点播", "provider.kubernetes": "Kubernetes", "provider.kubernetes.secret": "Kubernetes - Secret", + "provider.larkbot": "飞书群机器人", "provider.letsencrypt": "Let's Encrypt", "provider.letsencryptstaging": "Let's Encrypt 测试环境", "provider.local": "本地部署", @@ -134,6 +136,7 @@ "provider.wangsu": "网宿云", "provider.wangsu.cdnpro": "网宿云 - CDN Pro", "provider.webhook": "Webhook", + "provider.wecombot": "企业微信群机器人", "provider.westcn": "西部数码", "provider.zerossl": "ZeroSSL",