From 7463ca4b19f4757e41302640f740f4d71994a348 Mon Sep 17 00:00:00 2001
From: CaoMeiYouRen <996881204@qq.com>
Date: Sat, 9 Nov 2024 18:20:37 +0800
Subject: [PATCH] =?UTF-8?q?refactor:=20=E9=87=8D=E6=9E=84=20=E9=92=89?=
=?UTF-8?q?=E9=92=89=E6=9C=BA=E5=99=A8=E4=BA=BA=E6=8E=A8=E9=80=81=20?=
=?UTF-8?q?=E7=9A=84=E7=B1=BB=E5=9E=8B=E5=A3=B0=E6=98=8E?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
README.md | 2 +-
examples/01-example.ts | 4 +-
src/push/dingtalk.ts | 73 ++++++++++++++++++++++++++------
src/push/dingtalk/Markdown.ts | 53 ++++++++---------------
src/push/dingtalk/Text.ts | 40 +++++++----------
src/push/dingtalk/action-card.ts | 38 +++++++++++++++++
src/push/dingtalk/feed-card.ts | 19 +++++++++
src/push/dingtalk/link.ts | 17 ++++++++
src/push/dingtalk/template.ts | 68 -----------------------------
src/push/wechat-app.ts | 2 +-
10 files changed, 172 insertions(+), 144 deletions(-)
create mode 100644 src/push/dingtalk/action-card.ts
create mode 100644 src/push/dingtalk/feed-card.ts
create mode 100644 src/push/dingtalk/link.ts
delete mode 100644 src/push/dingtalk/template.ts
diff --git a/README.md b/README.md
index 0e9951c..23390c1 100644
--- a/README.md
+++ b/README.md
@@ -93,7 +93,7 @@ const dingtalk = new Dingtalk({
DINGTALK_ACCESS_TOKEN,
DINGTALK_SECRET,
})
-dingtalk.send('你好', '你好,我很可爱 - 钉钉机器人')
+dingtalk.send('你好', '你好,我很可爱 - 钉钉机器人', { msgtype: 'markdown' })
// 企业微信群机器人。官方文档:https://developer.work.weixin.qq.com/document/path/91770
// 企业微信群机器人的使用需要两人以上加入企业,如果个人使用微信推送建议使用 企业微信应用+微信插件 推送。虽然需要配置的内容更多了,但是无需下载企业微信,网页端即可完成操作。
diff --git a/examples/01-example.ts b/examples/01-example.ts
index 7e5bfd4..4e766fb 100644
--- a/examples/01-example.ts
+++ b/examples/01-example.ts
@@ -1,6 +1,6 @@
import { AxiosResponse } from 'axios'
import colors from '@colors/colors'
-import { ServerChanTurbo, ServerChanV3, CustomEmail, Dingtalk, WechatRobot, WechatApp, PushPlus, IGot, Qmsg, XiZhi, PushDeer, Discord, OneBot, Telegram, PushPlusTemplateType, CustomEmailType, OneBotMsgType, WechatRobotMsgType, WechatAppMsgType, PushPlusChannelType } from '../src'
+import { ServerChanTurbo, ServerChanV3, CustomEmail, Dingtalk, WechatRobot, WechatApp, PushPlus, IGot, Qmsg, XiZhi, PushDeer, Discord, OneBot, Telegram, PushPlusTemplateType, CustomEmailType, WechatRobotMsgType, WechatAppMsgType, PushPlusChannelType } from '../src'
import { warn } from '../src/utils/helper'
import { SendResponse } from '../src/interfaces/response'
@@ -64,7 +64,7 @@ export async function batchPushAllInOne(title: string, desp?: string): Promise
export interface DingtalkResponse {
errcode: number
@@ -79,7 +81,7 @@ export class Dingtalk implements Send {
return signStr
}
- private async push(message: MessageTemplateAbs): Promise> {
+ private async push(data: DingtalkOption): Promise> {
const timestamp = Date.now()
const sign = this.getSign(timestamp)
const result = await ajax({
@@ -93,7 +95,7 @@ export class Dingtalk implements Send {
sign,
access_token: this.ACCESS_TOKEN,
},
- data: message.get(),
+ data,
})
Debugger('Result is %s, %s。', result.data.errcode, result.data.errmsg)
if (result.data.errcode === 310000) {
@@ -114,11 +116,58 @@ export class Dingtalk implements Send {
*/
async send(title: string, desp?: string, option?: DingtalkOption): Promise> {
Debugger('title: "%s", desp: "%s", option: %O', title, desp, option)
- if (!desp) {
- return this.push(new Text(title))
+ switch (option.msgtype) {
+ case 'text':
+ return this.push({
+ msgtype: 'text',
+ text: {
+ content: `${title}${desp ? `\n${desp}` : ''}`,
+ },
+ ...option,
+ })
+ case 'markdown':
+ return this.push({
+ msgtype: 'markdown',
+ markdown: {
+ title,
+ text: `# ${title}${desp ? `\n\n${desp}` : ''}`,
+ },
+ ...option,
+ })
+ case 'link':
+ return this.push({
+ msgtype: 'link',
+ link: {
+ title,
+ text: desp || '',
+ picUrl: option?.link?.picUrl || '',
+ messageUrl: option.link?.messageUrl || '',
+ },
+ ...option,
+ })
+ case 'actionCard':
+ return this.push({
+ msgtype: 'actionCard',
+ actionCard: {
+ title,
+ text: desp || '',
+ btnOrientation: option?.actionCard?.btnOrientation || '0',
+ btns: (option?.actionCard as any)?.btns,
+ singleTitle: (option?.actionCard as any)?.singleTitle,
+ singleURL: (option?.actionCard as any)?.singleURL,
+ },
+ ...option,
+ })
+ case 'feedCard':
+ return this.push({
+ msgtype: 'feedCard',
+ feedCard: {
+ links: option?.feedCard?.links || [],
+ },
+ ...option,
+ })
+ default:
+ throw new Error('msgtype is required!')
}
- const markDown = new Markdown()
- markDown.setTitle(title).add(`# ${title}`).add(`${desp}`)
- return this.push(markDown)
}
}
diff --git a/src/push/dingtalk/Markdown.ts b/src/push/dingtalk/Markdown.ts
index 06ec92a..1c22509 100644
--- a/src/push/dingtalk/Markdown.ts
+++ b/src/push/dingtalk/Markdown.ts
@@ -1,39 +1,20 @@
-/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
-import { MessageTemplateAbs } from './template'
-
-class Markdown extends MessageTemplateAbs {
- items: string[]
- title: string
- constructor() {
- super()
- this.msgtype = 'markdown'
- this.canAt = true
- this.items = []
+/**
+ * 钉钉 markdown 消息
+ *
+ * @author CaoMeiYouRen
+ * @date 2024-11-09
+ * @export
+ * @interface Markdown
+ */
+export interface Markdown {
+ msgtype: 'markdown'
+ markdown: {
+ title: string
+ text: string
}
-
- setTitle(title: string) {
- this.title = title
- return this
- }
-
- add(text: string | string[]) {
- if (Array.isArray(text)) {
- this.items.concat(text)
- } else {
- this.items.push(text)
- }
-
- return this
- }
-
- get() {
- return this.render({
- markdown: {
- title: this.title,
- text: this.items.join('\n'),
- },
- })
+ at?: {
+ atMobiles?: string[]
+ atUserIds?: string[]
+ isAtAll?: boolean
}
}
-
-export { Markdown }
diff --git a/src/push/dingtalk/Text.ts b/src/push/dingtalk/Text.ts
index 3729cfd..d33eb82 100644
--- a/src/push/dingtalk/Text.ts
+++ b/src/push/dingtalk/Text.ts
@@ -1,27 +1,19 @@
-/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
-import { MessageTemplateAbs } from './template'
-
-class Text extends MessageTemplateAbs {
- content: string
- constructor(content: string) {
- super()
- this.msgtype = 'text'
- this.canAt = true
- this.setContent(content)
+/**
+ * 文本消息
+ *
+ * @author CaoMeiYouRen
+ * @date 2024-11-09
+ * @export
+ * @interface Text
+ */
+export interface Text {
+ msgtype: 'text'
+ text: {
+ content: string
}
-
- setContent(content: string) {
- this.content = content
- return this
- }
-
- get() {
- return this.render({
- text: {
- content: this.content,
- },
- })
+ at?: {
+ atMobiles?: string[]
+ atUserIds?: string[]
+ isAtAll?: boolean
}
}
-
-export { Text }
diff --git a/src/push/dingtalk/action-card.ts b/src/push/dingtalk/action-card.ts
new file mode 100644
index 0000000..763cec0
--- /dev/null
+++ b/src/push/dingtalk/action-card.ts
@@ -0,0 +1,38 @@
+// 整体跳转
+export type OverallJump = {
+ // 单个按钮的标题。设置此项和 singleURL 后,btns无效。
+ singleTitle: string
+ // 点击消息跳转的URL
+ singleURL: string
+}
+
+// 独立跳转
+export type IndependentJump = {
+ btns: {
+ // 按钮的标题
+ title: string
+ // 点击按钮触发的URL
+ actionURL: string
+ }[]
+}
+
+/**
+ * 动作卡片消息
+ *
+ * @author CaoMeiYouRen
+ * @date 2024-11-09
+ * @export
+ * @interface ActionCard
+ */
+export interface ActionCard {
+ msgtype: 'actionCard'
+ actionCard: {
+ // 首屏会话透出的展示内容
+ title: string
+ // markdown 格式的消息内容
+ text: string
+ // 0:按钮竖直排列;1:按钮横向排列
+ btnOrientation?: '0' | '1'
+ } & (OverallJump | IndependentJump)
+}
+
diff --git a/src/push/dingtalk/feed-card.ts b/src/push/dingtalk/feed-card.ts
new file mode 100644
index 0000000..b2ede30
--- /dev/null
+++ b/src/push/dingtalk/feed-card.ts
@@ -0,0 +1,19 @@
+export interface FeedCardLink {
+ title: string
+ messageURL: string
+ picURL: string
+}
+/**
+ * 订阅卡片消息
+ *
+ * @author CaoMeiYouRen
+ * @date 2024-11-09
+ * @export
+ * @interface FeedCard
+ */
+export interface FeedCard {
+ msgtype: 'feedCard'
+ feedCard: {
+ links: FeedCardLink[]
+ }
+}
diff --git a/src/push/dingtalk/link.ts b/src/push/dingtalk/link.ts
new file mode 100644
index 0000000..d9f1962
--- /dev/null
+++ b/src/push/dingtalk/link.ts
@@ -0,0 +1,17 @@
+/**
+ * 链接消息
+ *
+ * @author CaoMeiYouRen
+ * @date 2024-11-09
+ * @export
+ * @interface Link
+ */
+export interface Link {
+ msgtype: 'link'
+ link: {
+ text: string
+ title: string
+ picUrl?: string
+ messageUrl: string
+ }
+}
diff --git a/src/push/dingtalk/template.ts b/src/push/dingtalk/template.ts
deleted file mode 100644
index 49f9540..0000000
--- a/src/push/dingtalk/template.ts
+++ /dev/null
@@ -1,68 +0,0 @@
-/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
-class MessageTemplateAbs {
- canAt: boolean
- isAtAll: boolean
- atMobiles: Set
- atDingtalkIds: Set
- msgtype: string
- constructor() {
- this.canAt = false
- this.isAtAll = false
- this.atMobiles = new Set()
- this.atDingtalkIds = new Set()
- if (new.target === MessageTemplateAbs) {
- throw new Error('抽象类不可以实例化')
- }
- }
-
- render(options: unknown) {
- return Object.assign({
- msgtype: this.msgtype,
- }, options, this.canAt
- ? {
- at: {
- atMobiles: Array.from(this.atMobiles),
- atDingtalkIds: Array.from(this.atDingtalkIds),
- isAtAll: this.isAtAll,
- },
- }
- : {})
- }
-
- get(): any {
- throw new Error('抽象方法render不可以调用')
- }
-
- toJsonString(): string {
- throw new Error('抽象方法toJsonString不可以调用')
- }
-
- atAll() {
- this.isAtAll = true
- return this
- }
-
- atPhone(phones: string | string[]) {
- if (phones instanceof Array) {
- phones.forEach((phone) => {
- this.atMobiles.add(phone)
- })
- } else {
- this.atMobiles.add(phones)
- }
- return this
- }
-
- atId(ids: string | string[]) {
- if (ids instanceof Array) {
- ids.forEach((phone) => {
- this.atDingtalkIds.add(phone)
- })
- } else {
- this.atDingtalkIds.add(ids)
- }
- return this
- }
-}
-
-export { MessageTemplateAbs }
diff --git a/src/push/wechat-app.ts b/src/push/wechat-app.ts
index 501d9dd..a39a0c3 100644
--- a/src/push/wechat-app.ts
+++ b/src/push/wechat-app.ts
@@ -1,6 +1,6 @@
import debug from 'debug'
import { Send } from '../interfaces/send'
-import { error, warn } from '@/utils/helper'
+import { warn } from '@/utils/helper'
import { ajax } from '@/utils/ajax'
import { SendResponse } from '@/interfaces/response'