diff --git a/src/client/components/modals/NotificationInfo/strategies/feishu.tsx b/src/client/components/modals/NotificationInfo/strategies/feishu.tsx new file mode 100644 index 0000000..143055f --- /dev/null +++ b/src/client/components/modals/NotificationInfo/strategies/feishu.tsx @@ -0,0 +1,33 @@ +import { Form, Input } from 'antd'; +import React from 'react'; +import { useTranslation } from '@i18next-toolkit/react'; + +export const NotificationFeishu: React.FC = React.memo(() => { + const { t } = useTranslation(); + + return ( + <> + + + +
+ {t('Read more')}:{' '} + + https://open.feishu.cn/document/client-docs/bot-v3/add-custom-bot?lang=en-US + +
+ + ); +}); +NotificationFeishu.displayName = 'NotificationFeishu'; diff --git a/src/client/components/modals/NotificationInfo/strategies/index.ts b/src/client/components/modals/NotificationInfo/strategies/index.ts index 91300de..3deac36 100644 --- a/src/client/components/modals/NotificationInfo/strategies/index.ts +++ b/src/client/components/modals/NotificationInfo/strategies/index.ts @@ -2,6 +2,7 @@ import React from 'react'; import { NotificationSMTP } from './smtp'; import { NotificationTelegram } from './telegram'; import { NotificationApprise } from './apprise'; +import { NotificationFeishu } from './feishu'; interface NotificationStrategy { label: string; @@ -25,4 +26,9 @@ export const notificationStrategies: NotificationStrategy[] = [ name: 'telegram', form: NotificationTelegram, }, + { + label: 'Feishu', + name: 'feishu', + form: NotificationFeishu, + }, ]; diff --git a/src/server/model/notification/provider/feishu.ts b/src/server/model/notification/provider/feishu.ts new file mode 100644 index 0000000..39cff3d --- /dev/null +++ b/src/server/model/notification/provider/feishu.ts @@ -0,0 +1,43 @@ +import { NotificationProvider } from './type'; +import { baseContentTokenizer } from '../token'; +import axios from 'axios'; + +interface FeishuPayload { + webhookUrl: string; +} + +// Fork from https://github.com/louislam/uptime-kuma/blob/HEAD/server/notification-providers/smtp.js +export const feishu: NotificationProvider = { + send: async (notification, title, message) => { + const payload = notification.payload as unknown as FeishuPayload; + const webhookUrl = payload.webhookUrl; + if ( + !webhookUrl.startsWith('https://open.feishu.cn/open-apis/bot/v2/hook') + ) { + throw new Error('Is not a valid feishu webhook url'); + } + + const content = baseContentTokenizer.parse(message); + + await axios.post(webhookUrl, { + msg_type: 'interactive', + card: { + elements: [ + { + tag: 'div', + text: { + content, + tag: 'plain_text', + }, + }, + ], + header: { + title: { + content: title, + tag: 'plain_text', + }, + }, + }, + }); + }, +}; diff --git a/src/server/model/notification/provider/index.ts b/src/server/model/notification/provider/index.ts index 08f4793..41a1160 100644 --- a/src/server/model/notification/provider/index.ts +++ b/src/server/model/notification/provider/index.ts @@ -1,4 +1,5 @@ import { apprise } from './apprise'; +import { feishu } from './feishu'; import { smtp } from './smtp'; import { telegram } from './telegram'; import type { NotificationProvider } from './type'; @@ -7,4 +8,5 @@ export const notificationProviders: Record = { smtp, apprise, telegram, + feishu, }; diff --git a/src/server/model/notification/token/tokenizer/base.ts b/src/server/model/notification/token/tokenizer/base.ts index 9c9ae6a..7ec183c 100644 --- a/src/server/model/notification/token/tokenizer/base.ts +++ b/src/server/model/notification/token/tokenizer/base.ts @@ -18,11 +18,11 @@ export class BaseContentTokenizer { } parseTitle(token: TitleContentToken) { - return token.content; + return token.content + '\n'; } parseParagraph(token: ParagraphContentToken) { - return token.content; + return token.content + '\n'; } parseNewline(token: NewlineContentToken) {