{"version":3,"sources":["../src/push/custom-email.ts","../src/utils/helper.ts","../src/utils/validate.ts","../src/push/dingtalk.ts","../src/utils/ajax.ts","../src/utils/crypto.ts","../src/push/discord.ts","../src/push/feishu.ts","../src/push/i-got.ts","../src/push/ntfy.ts","../src/push/one-bot.ts","../src/push/push-deer.ts","../src/push/push-plus.ts","../src/push/qmsg.ts","../src/push/server-chan-turbo.ts","../src/push/server-chan-v3.ts","../src/push/telegram.ts","../src/push/wechat-app.ts","../src/push/wechat-robot.ts","../src/push/xi-zhi.ts","../src/push/wx-pusher.ts","../src/one.ts"],"sourcesContent":["import debug from 'debug'\nimport nodemailer from 'nodemailer'\nimport SMTPTransport from 'nodemailer/lib/smtp-transport'\nimport Mail from 'nodemailer/lib/mailer'\nimport { Send } from '@/interfaces/send'\nimport { SendResponse } from '@/interfaces/response'\nimport { ConfigSchema, OptionSchema } from '@/interfaces/schema'\nimport { validate } from '@/utils/validate'\n\nconst Debugger = debug('push:custom-email')\n\nexport type CustomEmailType = 'text' | 'html'\nexport interface CustomEmailConfig {\n    /**\n     *  邮件类型\n     */\n    EMAIL_TYPE: CustomEmailType\n    /**\n     * 收件邮箱\n     */\n    EMAIL_TO_ADDRESS: string\n    /**\n     * 发件邮箱\n     */\n    EMAIL_AUTH_USER: string\n    /**\n     * 发件授权码(或密码)\n     */\n    EMAIL_AUTH_PASS: string\n    /**\n     * 发件域名\n     */\n    EMAIL_HOST: string\n    /**\n     * 发件端口\n     */\n    EMAIL_PORT: number\n}\n\nexport type CustomEmailConfigSchema = ConfigSchema<CustomEmailConfig>\n\nexport const customEmailConfigSchema: CustomEmailConfigSchema = {\n    EMAIL_TYPE: {\n        type: 'select',\n        title: '邮件类型',\n        description: '邮件类型',\n        required: true,\n        default: 'text',\n        options: [\n            {\n                label: '文本',\n                value: 'text',\n            },\n            {\n                label: 'HTML',\n                value: 'html',\n            },\n        ],\n    },\n    EMAIL_TO_ADDRESS: {\n        type: 'string',\n        title: '收件邮箱',\n        description: '收件邮箱',\n        required: true,\n        default: '',\n    },\n    EMAIL_AUTH_USER: {\n        type: 'string',\n        title: '发件邮箱',\n        description: '发件邮箱',\n        required: true,\n        default: '',\n    },\n    EMAIL_AUTH_PASS: {\n        type: 'string',\n        title: '发件授权码(或密码)',\n        description: '发件授权码(或密码)',\n        required: true,\n        default: '',\n    },\n    EMAIL_HOST: {\n        type: 'string',\n        title: '发件域名',\n        description: '发件域名',\n        required: true,\n        default: '',\n    },\n    EMAIL_PORT: {\n        type: 'number',\n        title: '发件端口',\n        description: '发件端口',\n        required: true,\n        default: 465,\n    },\n} as const\n\nexport type CustomEmailOption = Mail.Options\n\ntype OptionalCustomEmailOption = Pick<CustomEmailOption, 'to' | 'from' | 'subject' | 'text' | 'html'>\n\n/**\n * 由于 CustomEmailOption 的配置太多，所以不提供完整的 Schema，只提供部分配置 schema。\n * 如需使用完整的配置，请查看官方文档\n */\nexport type CustomEmailOptionSchema = OptionSchema<{\n    [K in keyof OptionalCustomEmailOption]: string\n}>\n\nexport const customEmailOptionSchema: CustomEmailOptionSchema = {\n    to: {\n        type: 'string',\n        title: '收件邮箱',\n        description: '收件邮箱',\n        required: false,\n        default: '',\n    },\n    from: {\n        type: 'string',\n        title: '发件邮箱',\n        description: '发件邮箱',\n        required: false,\n        default: '',\n    },\n    subject: {\n        type: 'string',\n        title: '邮件主题',\n        description: '邮件主题',\n        required: false,\n        default: '',\n    },\n    text: {\n        type: 'string',\n        title: '邮件内容',\n        description: '邮件内容',\n        required: false,\n        default: '',\n    },\n    html: {\n        type: 'string',\n        title: '邮件内容',\n        description: '邮件内容',\n        required: false,\n        default: '',\n    },\n} as const\n\n/**\n * 自定义邮件。官方文档: https://github.com/nodemailer/nodemailer\n *\n * @author CaoMeiYouRen\n * @date 2023-03-12\n * @export\n * @class CustomEmail\n */\nexport class CustomEmail implements Send {\n    // 命名空间\n    static readonly namespace = '自定义邮件'\n\n    static readonly configSchema = customEmailConfigSchema\n\n    static readonly optionSchema = customEmailOptionSchema\n\n    private config: CustomEmailConfig\n\n    private transporter: nodemailer.Transporter<SMTPTransport.SentMessageInfo, SMTPTransport.Options>\n\n    constructor(config: CustomEmailConfig) {\n        this.config = config\n        Debugger('CustomEmailConfig: %o', config)\n        // 根据 configSchema 验证 config\n        validate(config, CustomEmail.configSchema)\n        const { EMAIL_AUTH_USER, EMAIL_AUTH_PASS, EMAIL_HOST, EMAIL_PORT } = this.config\n        this.transporter = nodemailer.createTransport({\n            host: EMAIL_HOST,\n            port: Number(EMAIL_PORT),\n            auth: {\n                user: EMAIL_AUTH_USER,\n                pass: EMAIL_AUTH_PASS,\n            },\n        })\n    }\n\n    /**\n     * 释放资源（需要支持 Symbol.dispose）\n     *\n     * @author CaoMeiYouRen\n     * @date 2024-11-08\n     */\n    [Symbol.dispose](): void {\n        if (this.transporter) {\n            this.transporter.close()\n        }\n    }\n\n    /**\n     *\n     * @author CaoMeiYouRen\n     * @date 2024-11-08\n     * @param title 消息的标题\n     * @param [desp] 消息的内容，支持 html\n     * @param [option] 额外选项\n     */\n    async send(title: string, desp?: string, option?: CustomEmailOption): Promise<SendResponse<SMTPTransport.SentMessageInfo>> {\n        Debugger('title: \"%s\", desp: \"%s\", option: %o', title, desp, option)\n        const { EMAIL_TYPE, EMAIL_TO_ADDRESS, EMAIL_AUTH_USER } = this.config\n        if (!await this.transporter.verify()) {\n            throw new Error('自定义邮件的发件配置无效')\n        }\n        const { to: _to, ...args } = option || {}\n        const from = EMAIL_AUTH_USER\n        const to = _to || EMAIL_TO_ADDRESS\n        const type = EMAIL_TYPE\n        const response = await this.transporter.sendMail({\n            from,\n            to,\n            subject: title,\n            [type]: desp,\n            ...args,\n        })\n        if (typeof Symbol.dispose === 'undefined') { // 如果不支持 Symbol.dispose ，则手动释放\n            this.transporter.close()\n        }\n        Debugger('CustomEmail Response: %o', response)\n        if (response.response?.includes('250 OK')) {\n            return {\n                status: 200,\n                statusText: 'OK',\n                data: response,\n                headers: {},\n            }\n        }\n        return {\n            status: 500,\n            statusText: 'Internal Server Error',\n            data: response,\n            headers: {},\n        }\n    }\n}\n","let colors: any\n\nif (globalThis.process && typeof globalThis.process.on === 'function') {\n    import('@colors/colors').then((value) => {\n        colors = value.default\n    }).catch(console.error)\n}\n\nexport function warn(text: any): void {\n    if (colors) {\n        text = colors.yellow(text)\n    }\n    console.warn(text)\n}\n\nexport function error(text: any): void {\n    if (colors) {\n        text = colors.red(text)\n    }\n    console.error(text)\n}\n\nexport const logger = {\n    warn,\n    error,\n}\n\n/**\n * 检测是否为 http/https 开头的 url\n * @param url\n * @returns\n */\nexport const isHttpURL = (url: string): boolean => /^(https?:\\/\\/)/.test(url)\n\n/**\n * 检测是否为 socks/socks5 开头的 url\n * @param url\n * @returns\n */\nexport const isSocksUrl = (url: string): boolean => /^(socks5?:\\/\\/)/.test(url)\n\n/**\n * 判断是否为 null 或 undefined\n * @param value\n * @returns\n */\nexport function isNil(value: unknown): boolean {\n    return value === null || value === undefined\n}\n\n/**\n * 判断是否不为 null 且不为 undefined\n * @param value\n * @returns\n */\nexport function isNotNil(value: unknown): boolean {\n    return !isNil(value)\n}\n\n/**\n *  判断是否为 null 或 undefined 或 空字符串\n * @param value\n * @returns\n */\nexport function isEmpty(value: unknown): boolean {\n    return value === null || value === undefined || value === ''\n}\n/**\n * 判断是否不为 null 且不为 undefined 且不为 空字符串\n * @param value\n * @returns\n */\nexport function isNotEmpty(value: unknown): boolean {\n    return !isEmpty(value)\n}\n\n/**\n *  数组去重\n *\n * @author CaoMeiYouRen\n * @date 2025-03-05\n * @export\n * @template T\n * @param arr\n */\nexport function uniq<T>(arr: T[]): T[] {\n    return Array.from(new Set(arr))\n}\n","import { isEmpty } from './helper'\nimport { Config, ConfigSchema } from '@/interfaces/schema'\n\n/**\n * 验证配置是否符合 Schema 规则，如果不符合则抛出错误\n *\n * @author CaoMeiYouRen\n * @date 2024-11-17\n * @export\n * @template T\n * @param config\n * @param schema\n */\nexport function validate<T = Config>(config: T, schema: ConfigSchema<T>): void {\n    Object.keys(schema).forEach((key) => {\n        const item = schema[key]\n        const value = config[key]\n        if (!item.required && isEmpty(value)) {\n            return\n        }\n        if (item.required && isEmpty(value)) {\n            throw new Error(`\"${key}\" 字段是必须的！`)\n        }\n        if (item.type === 'select') {\n            const { options } = item as any\n            if (!options.map((e) => e.value).includes(value)) {\n                throw new Error(`\"${key}\" 字段必须是以下选项之一：${options.map((e) => e.value).join(',')}`)\n            }\n            return\n        }\n        if (item.type === 'string') {\n            if (typeof value !== 'string') {\n                throw new Error(`\"${key}\" 字段必须是字符串！`)\n            }\n            return\n        }\n        if (item.type === 'number') {\n            if (typeof value !== 'number') {\n                throw new Error(`\"${key}\" 字段必须是数字！`)\n            }\n            return\n        }\n        if (item.type === 'boolean') {\n            if (typeof value !== 'boolean') {\n                throw new Error(`\"${key}\" 字段必须是布尔值！`)\n            }\n            return\n        }\n        if (item.type === 'array') {\n            if (!Array.isArray(value)) {\n                throw new Error(`\"${key}\" 字段必须是数组！`)\n            }\n            return\n        }\n        if (item.type === 'object') {\n            if (typeof value !== 'object') {\n                throw new Error(`\"${key}\" 字段必须是对象！`)\n            }\n            return\n        }\n        throw new Error(`\"${key}\" 字段类型不支持！`)\n    })\n}\n","import { AxiosResponse } from 'axios'\nimport debug from 'debug'\nimport { Markdown } from './dingtalk/markdown'\nimport { Text } from './dingtalk/text'\nimport { Link } from './dingtalk/link'\nimport { FeedCard } from './dingtalk/feed-card'\nimport { ActionCard, IndependentJump, OverallJump } from './dingtalk/action-card'\nimport { Send } from '@/interfaces/send'\nimport { warn } from '@/utils/helper'\nimport { ajax } from '@/utils/ajax'\nimport { generateSignature } from '@/utils/crypto'\nimport { SendResponse } from '@/interfaces/response'\nimport { ConfigSchema, OptionSchema } from '@/interfaces/schema'\nimport { validate } from '@/utils/validate'\n\nconst Debugger = debug('push:dingtalk')\n\nexport type DingtalkMsgType = 'text' | 'markdown' | 'link' | 'actionCard' | 'feedCard'\n\nexport interface DingtalkConfig {\n    /**\n     * 钉钉机器人 access_token。官方文档：https://developers.dingtalk.com/document/app/custom-robot-access\n     */\n    DINGTALK_ACCESS_TOKEN: string\n    /**\n     * 加签安全秘钥（HmacSHA256）\n     */\n    DINGTALK_SECRET?: string\n}\n\nexport type DingtalkConfigSchema = ConfigSchema<DingtalkConfig>\n\nexport const dingtalkConfigSchema: DingtalkConfigSchema = {\n    DINGTALK_ACCESS_TOKEN: {\n        type: 'string',\n        title: '钉钉机器人 access_token',\n        description: '钉钉机器人 access_token',\n        required: true,\n        default: '',\n    },\n    DINGTALK_SECRET: {\n        type: 'string',\n        title: '加签安全秘钥（HmacSHA256）',\n        required: false,\n        default: '',\n    },\n} as const\n\nexport type DingtalkOption = Partial<(Text | Markdown | Link | FeedCard | ActionCard)>\n\ntype TempDingtalkOption = {\n    msgtype?: DingtalkOption['msgtype']\n    text?: Partial<Text['text']>\n    markdown?: Partial<Markdown['markdown']>\n    link?: Partial<Link['link']>\n    actionCard?: Partial<{\n        // 首屏会话透出的展示内容\n        title: string\n        // markdown 格式的消息内容\n        text: string\n        // 0：按钮竖直排列；1：按钮横向排列\n        btnOrientation?: '0' | '1'\n    }> & Partial<OverallJump> & Partial<IndependentJump>\n    feedCard?: Partial<FeedCard['feedCard']>\n\n    at?: Text['at']\n    [key: string]: any\n}\n\nexport type DingtalkOptionSchema = OptionSchema<TempDingtalkOption>\n\nexport const dingtalkOptionSchema: DingtalkOptionSchema = {\n    msgtype: {\n        type: 'select',\n        title: '消息类型',\n        description: '消息类型',\n        required: false,\n        default: 'text',\n        options: [\n            {\n                label: '文本',\n                value: 'text',\n            },\n            {\n                label: 'Markdown',\n                value: 'markdown',\n            },\n            {\n                label: '链接',\n                value: 'link',\n            },\n            {\n                label: '按钮',\n                value: 'actionCard',\n            },\n            {\n                label: 'FeedCard',\n                value: 'feedCard',\n            },\n        ],\n    },\n    text: {\n        type: 'object',\n        title: '文本',\n        description: '文本',\n        required: false,\n        default: {},\n    },\n    markdown: {\n        type: 'object',\n        title: 'Markdown',\n        description: 'Markdown',\n        required: false,\n        default: {},\n    },\n    link: {\n        type: 'object',\n        title: '链接',\n        description: '链接',\n        required: false,\n        default: {},\n    },\n    actionCard: {\n        type: 'object',\n        title: '动作卡片',\n        description: '动作卡片',\n        required: false,\n        default: {},\n    },\n    feedCard: {\n        type: 'object',\n        title: '订阅卡片',\n        description: '订阅卡片',\n        required: false,\n        default: {},\n    },\n} as const\n\nexport interface DingtalkResponse {\n    errcode: number\n    errmsg: string\n}\n\n/**\n * 钉钉机器人推送\n * 在 [dingtalk-robot-sdk](https://github.com/ineo6/dingtalk-robot-sdk) 的基础上重构了一下，用法几乎完全一致。\n * @author CaoMeiYouRen\n * @date 2021-02-27\n * @export\n * @class Dingtalk\n */\nexport class Dingtalk implements Send {\n\n    static readonly namespace = '钉钉'\n\n    static readonly configSchema = dingtalkConfigSchema\n\n    static readonly optionSchema = dingtalkOptionSchema\n\n    private ACCESS_TOKEN: string\n    /**\n     * 加签安全秘钥（HmacSHA256）\n     *\n     * @private\n     */\n    private SECRET?: string\n    private webhook: string = 'https://oapi.dingtalk.com/robot/send'\n\n    /**\n     * 参考文档 [钉钉开放平台 - 自定义机器人接入](https://developers.dingtalk.com/document/app/custom-robot-access)\n     * @author CaoMeiYouRen\n     * @date 2024-11-08\n     * @param config\n     */\n    constructor(config: DingtalkConfig) {\n        const { DINGTALK_ACCESS_TOKEN, DINGTALK_SECRET } = config\n        this.ACCESS_TOKEN = DINGTALK_ACCESS_TOKEN\n        this.SECRET = DINGTALK_SECRET\n        Debugger('DINGTALK_ACCESS_TOKEN: %s , DINGTALK_SECRET: %s', this.ACCESS_TOKEN, this.SECRET)\n        // 根据 configSchema 验证 config\n        validate(config, Dingtalk.configSchema)\n        if (!this.SECRET) {\n            warn('未提供 DINGTALK_SECRET ！')\n        }\n    }\n\n    private getSign(timeStamp: number): string {\n        let signStr = ''\n        if (this.SECRET) {\n            signStr = generateSignature(timeStamp, this.SECRET, this.SECRET)\n            Debugger('Sign string is %s, result is %s', `${timeStamp}\\n${this.SECRET}`, signStr)\n        }\n        return signStr\n    }\n\n    private async push(data: DingtalkOption): Promise<AxiosResponse<DingtalkResponse>> {\n        const timestamp = Date.now()\n        const sign = this.getSign(timestamp)\n        const result = await ajax({\n            url: this.webhook,\n            method: 'POST',\n            headers: {\n                'Content-Type': 'application/json',\n            },\n            query: {\n                timestamp,\n                sign,\n                access_token: this.ACCESS_TOKEN,\n            },\n            data,\n        })\n        Debugger('Result is %s, %s。', result.data.errcode, result.data.errmsg)\n        if (result.data.errcode === 310000) {\n            console.error('Send Failed:', result.data)\n            Debugger('Please check safe config : %O', result.data)\n        }\n        return result\n    }\n\n    /**\n     *\n     *\n     * @author CaoMeiYouRen\n     * @date 2024-11-08\n     * @param title 消息的标题\n     * @param [desp] 消息的内容，支持 Markdown\n     * @returns\n     */\n    async send(title: string, desp?: string, option?: DingtalkOption): Promise<SendResponse<DingtalkResponse>> {\n        Debugger('title: \"%s\", desp: \"%s\", option: %O', title, desp, option)\n        switch (option.msgtype) {\n            case 'text':\n                return this.push({\n                    msgtype: 'text',\n                    text: {\n                        content: `${title}${desp ? `\\n${desp}` : ''}`,\n                    },\n                    ...option,\n                })\n            case 'markdown':\n                return this.push({\n                    msgtype: 'markdown',\n                    markdown: {\n                        title,\n                        text: `# ${title}${desp ? `\\n\\n${desp}` : ''}`,\n                    },\n                    ...option,\n                })\n            case 'link':\n                return this.push({\n                    msgtype: 'link',\n                    link: {\n                        title,\n                        text: desp || '',\n                        picUrl: option?.link?.picUrl || '',\n                        messageUrl: option.link?.messageUrl || '',\n                    },\n                    ...option,\n                })\n            case 'actionCard':\n                return this.push({\n                    msgtype: 'actionCard',\n                    actionCard: {\n                        title,\n                        text: desp || '',\n                        btnOrientation: option?.actionCard?.btnOrientation || '0',\n                        btns: (option?.actionCard as any)?.btns,\n                        singleTitle: (option?.actionCard as any)?.singleTitle,\n                        singleURL: (option?.actionCard as any)?.singleURL,\n                    },\n                    ...option,\n                })\n            case 'feedCard':\n                return this.push({\n                    msgtype: 'feedCard',\n                    feedCard: {\n                        links: option?.feedCard?.links || [],\n                    },\n                    ...option,\n                })\n            default:\n                throw new Error('msgtype is required!')\n        }\n    }\n}\n","import axios, { AxiosResponse, Method, AxiosRequestHeaders } from 'axios'\nimport debug from 'debug'\nimport { HttpsProxyAgent } from 'https-proxy-agent'\nimport { SocksProxyAgent } from 'socks-proxy-agent'\nimport { isHttpURL, isSocksUrl, logger } from './helper'\n\nconst Debugger = debug('push:ajax')\n\ninterface AjaxConfig {\n    url: string\n    query?: Record<string, unknown>\n    data?: Record<string, unknown> | string | Buffer | ArrayBuffer\n    method?: Method\n    headers?: Record<string, unknown>\n    baseURL?: string\n    proxyUrl?: string\n}\n\n/**\n * axios 接口封装\n *\n * @author CaoMeiYouRen\n * @date 2021-02-27\n * @export\n * @param config\n * @returns\n */\nexport async function ajax<T = any>(config: AjaxConfig): Promise<AxiosResponse<T>> {\n    try {\n        Debugger('ajax config: %O', config)\n        const { url, query = {}, method = 'GET', baseURL = '', proxyUrl } = config\n        const headers = (config.headers || {}) as AxiosRequestHeaders\n        let { data = {} } = config\n\n        if (headers['Content-Type'] === 'application/x-www-form-urlencoded' && typeof data === 'object') {\n            data = new URLSearchParams(data as Record<string, string>).toString()\n        }\n\n        let httpAgent = null\n        Debugger('NO_PROXY: %s', process.env.NO_PROXY)\n        if (process.env.NO_PROXY !== 'true') {\n            Debugger('HTTP_PROXY: %s', process.env.HTTP_PROXY)\n            Debugger('HTTPS_PROXY: %s', process.env.HTTPS_PROXY)\n            Debugger('SOCKS_PROXY: %s', process.env.SOCKS_PROXY)\n            if (isHttpURL(proxyUrl)) {\n                httpAgent = new HttpsProxyAgent(proxyUrl)\n            } else if (isSocksUrl(proxyUrl)) {\n                httpAgent = new SocksProxyAgent(proxyUrl)\n            } else if (process.env.HTTPS_PROXY) {\n                httpAgent = new HttpsProxyAgent(process.env.HTTPS_PROXY)\n            } else if (process.env.HTTP_PROXY) {\n                httpAgent = new HttpsProxyAgent(process.env.HTTP_PROXY)\n            } else if (process.env.SOCKS_PROXY) {\n                httpAgent = new SocksProxyAgent(process.env.SOCKS_PROXY)\n            }\n        }\n        const response = await axios(url, {\n            baseURL,\n            method,\n            headers,\n            params: query,\n            data,\n            timeout: 60000,\n            httpAgent,\n            httpsAgent: httpAgent,\n            proxy: false,\n        })\n        Debugger('response data: %O', response.data)\n        return response\n    } catch (error) {\n        if (error?.response) {\n            logger.error(error.response)\n            return error.response\n        }\n        throw error\n    }\n}\n","import crypto from 'crypto'\n\n/**\n * 生成钉钉签名\n *\n * @author CaoMeiYouRen\n * @date 2024-10-30\n * @export\n * @param timestamp\n * @param suiteTicket\n * @param suiteSecret\n */\nexport function generateSignature(timestamp: string | number, suiteTicket: string, suiteSecret: crypto.BinaryLike | crypto.KeyObject): string {\n    // 创建要签名的字符串\n    const stringToSign = `${timestamp}\\n${suiteTicket}`\n\n    // 创建 HMAC 实例\n    const hmac = crypto.createHmac('sha256', suiteSecret)\n\n    // 更新 HMAC 实例的数据\n    hmac.update(stringToSign, 'utf8')\n\n    // 计算 HMAC 签名并进行 Base64 编码\n    const signature = hmac.digest('base64')\n\n    return signature\n}\n\nexport function base64Encode(str: string): string {\n    return Buffer.from(str).toString('base64')\n}\n\nexport function rfc2047Encode(str: string): string {\n    return `=?utf-8?B?${base64Encode(str)}?=`\n}\n","import debug from 'debug'\nimport { Send } from '@/interfaces/send'\nimport { ajax } from '@/utils/ajax'\nimport { SendResponse } from '@/interfaces/response'\nimport { ConfigSchema, OptionSchema } from '@/interfaces/schema'\nimport { validate } from '@/utils/validate'\n\nconst Debugger = debug('push:discord')\n\nexport interface DiscordConfig {\n    /**\n     * Webhook Url 可在服务器设置 -> 整合 -> Webhook -> 创建 Webhook 中获取\n     */\n    DISCORD_WEBHOOK: string\n\n    /**\n     * 代理地址\n     */\n    PROXY_URL?: string\n}\n\nexport type DiscordConfigSchema = ConfigSchema<DiscordConfig>\n\nexport const discordConfigSchema: DiscordConfigSchema = {\n    DISCORD_WEBHOOK: {\n        type: 'string',\n        title: 'Webhook Url',\n        description: 'Webhook Url 可在服务器设置 -> 整合 -> Webhook -> 创建 Webhook 中获取',\n        required: true,\n    },\n    PROXY_URL: {\n        type: 'string',\n        title: '代理地址',\n        description: '代理地址',\n        required: false,\n    },\n} as const\n\n/**\n * Discord 额外选项\n * 由于参数过多，因此请参考官方文档进行配置\n */\nexport type DiscordOption = {\n    /**\n     * 机器人显示的名称\n     */\n    username?: string\n    /**\n     * 机器人头像的 Url\n     */\n    avatar_url?: string\n    [key: string]: any\n}\n\nexport type DiscordOptionSchema = OptionSchema<DiscordOption>\n\nexport const discordOptionSchema: DiscordOptionSchema = {\n    username: {\n        type: 'string',\n        title: '机器人显示的名称',\n        description: '机器人显示的名称',\n        required: false,\n    },\n    avatar_url: {\n        type: 'string',\n        title: '机器人头像的 Url',\n        description: '机器人头像的 Url',\n        required: false,\n    },\n} as const\n\nexport interface DiscordResponse { }\n\n/**\n * Discord Webhook 推送\n *\n * @author CaoMeiYouRen\n * @date 2023-09-17\n * @export\n * @class Discord\n */\nexport class Discord implements Send {\n\n    static readonly namespace = 'Discord'\n    static readonly configSchema = discordConfigSchema\n    static readonly optionSchema = discordOptionSchema\n\n    /**\n     * Webhook Url 可在服务器设置 -> 整合 -> Webhook -> 创建 Webhook 中获取\n     *\n     * @author CaoMeiYouRen\n     * @date 2023-09-17\n     * @private\n     */\n    private DISCORD_WEBHOOK: string\n\n    proxyUrl: string\n\n    /**\n     * 创建 Discord 实例\n     * @author CaoMeiYouRen\n     * @date 2024-11-08\n     * @param config 配置\n     */\n    constructor(config: DiscordConfig) {\n        const { DISCORD_WEBHOOK, PROXY_URL } = config\n        Debugger('DISCORD_WEBHOOK: %s, PROXY_URL: %s', DISCORD_WEBHOOK, PROXY_URL)\n        this.DISCORD_WEBHOOK = DISCORD_WEBHOOK\n        if (PROXY_URL) {\n            this.proxyUrl = PROXY_URL\n        }\n        // 根据 configSchema 验证 config\n        validate(config, Discord.configSchema)\n    }\n\n    /**\n     * 发送消息\n     *\n     * @author CaoMeiYouRen\n     * @date 2024-11-08\n     * @param title 消息的标题\n     * @param [desp] 消息的描述。最多 2000 个字符\n     * @param [option] 额外选项\n     */\n    async send(title: string, desp?: string, option?: DiscordOption): Promise<SendResponse<DiscordResponse>> {\n        Debugger('title: \"%s\", desp: \"%s\", option: %o', title, desp, option)\n        const { username, avatar_url, ...args } = option || {}\n        const proxyUrl = this.proxyUrl\n        const content = `${title}${desp ? `\\n${desp}` : ''}`\n        return ajax({\n            url: this.DISCORD_WEBHOOK,\n            method: 'POST',\n            proxyUrl,\n            data: {\n                username,\n                content,\n                avatar_url,\n                ...args,\n            },\n        })\n    }\n}\n","import debug from 'debug'\nimport { Send } from '@/interfaces/send'\nimport { ajax } from '@/utils/ajax'\nimport { SendResponse } from '@/interfaces/response'\nimport { ConfigSchema, OptionSchema } from '@/interfaces/schema'\nimport { validate } from '@/utils/validate'\n\nconst Debugger = debug('push:feishu')\n\nexport interface FeishuConfig {\n    /**\n     * 飞书应用 ID。官方文档：https://open.feishu.cn/document/server-docs/api-call-guide/terminology#b047be0c\n     */\n    FEISHU_APP_ID: string\n    /**\n     * 飞书应用密钥。官方文档：https://open.feishu.cn/document/server-docs/api-call-guide/terminology#1b5fb6cd\n     */\n    FEISHU_APP_SECRET: string\n}\n\nexport type FeishuConfigSchema = ConfigSchema<FeishuConfig>\n\nexport const feishuConfigSchema: FeishuConfigSchema = {\n    FEISHU_APP_ID: {\n        type: 'string',\n        title: '飞书应用 ID',\n        description: '飞书应用 ID',\n        required: true,\n        default: '',\n    },\n    FEISHU_APP_SECRET: {\n        type: 'string',\n        title: '飞书应用密钥',\n        description: '飞书应用密钥',\n        required: true,\n        default: '',\n    },\n}\n\nexport type FeishuOption = {\n    // 用户 ID 类型\n    receive_id_type: 'open_id' | 'union_id' | 'user_id' | 'email' | 'chat_id'\n    // 消息接收者的 ID，ID 类型与查询参数 receive_id_type 的取值一致。\n    receive_id: string\n    // 消息类型。\n    msg_type: 'text' | 'post' | 'image' | 'file' | 'audio' | 'media' | 'sticker' | 'interactive' | 'share_chat' | 'share_user' | 'system'\n    // 消息内容，JSON 结构序列化后的字符串。该参数的取值与 msg_type 对应，例如 msg_type 取值为 text，则该参数需要传入文本类型的内容。\n    content?: string\n    // 自定义设置的唯一字符串序列，用于在发送消息时请求去重。持有相同 uuid 的请求，在 1 小时内至多成功发送一条消息。\n    uuid?: string\n}\n\nexport type FeishuOptionSchema = OptionSchema<FeishuOption>\n\nexport const feishuOptionSchema: FeishuOptionSchema = {\n    receive_id_type: {\n        type: 'select',\n        title: '用户 ID 类型',\n        description: '用户 ID 类型',\n        required: true,\n        options: [\n            {\n                label: 'open_id',\n                value: 'open_id',\n            },\n            {\n                label: 'union_id',\n                value: 'union_id',\n            },\n            {\n                label: 'user_id',\n                value: 'user_id',\n            },\n            {\n                label: 'email',\n                value: 'email',\n            },\n            {\n                label: 'chat_id',\n                value: 'chat_id',\n            },\n        ],\n    },\n    receive_id: {\n        type: 'string',\n        title: '消息接收者的 ID',\n        description: '消息接收者的 ID，ID 类型与查询参数 receive_id_type 的取值一致。',\n        required: true,\n    },\n    msg_type: {\n        type: 'select',\n        title: '消息类型',\n        description: '消息类型',\n        required: true,\n        options: [\n            {\n                label: '文本',\n                value: 'text',\n            },\n            {\n                label: '富文本',\n                value: 'post',\n            },\n            {\n                label: '图片',\n                value: 'image',\n            },\n            {\n                label: '文件',\n                value: 'file',\n            },\n            {\n                label: '语音',\n                value: 'audio',\n            },\n            {\n                label: '视频',\n                value: 'media',\n            },\n            {\n                label: '表情包',\n                value: 'sticker',\n            },\n            {\n                label: '卡片',\n                value: 'interactive',\n            },\n            {\n                label: '分享群名片',\n                value: 'share_chat',\n            },\n            {\n                label: '分享个人名片',\n                value: 'share_user',\n            },\n            {\n                label: '系统消息',\n                value: 'system',\n            },\n        ],\n    },\n    content: {\n        type: 'string',\n        title: '消息内容',\n        description: '消息内容，JSON 结构序列化后的字符串。该参数的取值与 msg_type 对应，例如 msg_type 取值为 text，则该参数需要传入文本类型的内容。',\n        required: false,\n    },\n    uuid: {\n        type: 'string',\n        title: '自定义设置的唯一字符串序列',\n        description: '自定义设置的唯一字符串序列，用于在发送消息时请求去重。持有相同 uuid 的请求，在 1 小时内至多成功发送一条消息。',\n        required: false,\n    },\n}\n\n/**\n * 飞书。官方文档：https://open.feishu.cn/document/home/index\n *\n * @author CaoMeiYouRen\n * @date 2025-02-10\n * @export\n * @class Feishu\n */\nexport class Feishu implements Send {\n\n    static readonly namespace = '飞书'\n\n    static readonly configSchema = feishuConfigSchema\n\n    static readonly optionSchema = feishuOptionSchema\n\n    private readonly config: FeishuConfig\n\n    /**\n    * accessToken 的过期时间(时间戳)\n    */\n    private expiresTime: number\n\n    private accessToken: string\n\n    constructor(config: FeishuConfig) {\n        this.config = config\n        // 根据 configSchema 验证 config\n        validate(config, Feishu.configSchema)\n    }\n\n    private async getAccessToken() {\n        const { FEISHU_APP_ID, FEISHU_APP_SECRET } = this.config\n        const url = 'https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal'\n        const data = {\n            app_id: FEISHU_APP_ID,\n            app_secret: FEISHU_APP_SECRET,\n        }\n        const result = await ajax({\n            url,\n            method: 'POST',\n            headers: {\n                'Content-Type': 'application/json; charset=utf-8',\n            },\n            data,\n        })\n        const { code, msg, tenant_access_token, expire } = result.data\n        if (code !== 0) { // 出错返回码，为0表示成功，非0表示调用失败\n            throw new Error(msg || '获取 tenant_access_token 失败！')\n        }\n        this.expiresTime = Date.now() + expire * 1000\n        Debugger('获取 tenant_access_token 成功: %s', tenant_access_token)\n        return tenant_access_token as string\n    }\n\n    async send(title: string, desp?: string, option?: FeishuOption): Promise<SendResponse> {\n        Debugger('title: \"%s\", desp: \"%s\", option: %O', title, desp, option)\n        if (!this.accessToken || Date.now() >= this.expiresTime) {\n            this.accessToken = await this.getAccessToken()\n        }\n        const { receive_id_type = 'open_id', receive_id, msg_type = 'text', content, uuid } = option\n        const data = { receive_id, msg_type, content, uuid }\n        if (!data.content) {\n            switch (msg_type) {\n                case 'text':\n                    data.content = JSON.stringify({\n                        text: `${title}${desp ? `\\n${desp}` : ''}`,\n                    })\n                    break\n                case 'post':\n                    data.content = JSON.stringify({\n                        post: {\n                            zh_cn: {\n                                title,\n                                content: [\n                                    [\n                                        {\n                                            tag: 'text',\n                                            text: desp,\n                                        },\n                                    ],\n                                ],\n                            },\n                        },\n                    })\n                    break\n                default:\n                    throw new Error('msg_type is required!')\n            }\n        }\n        const result = await ajax({\n            url: 'https://open.feishu.cn/open-apis/im/v1/messages',\n            method: 'POST',\n            headers: {\n                'Content-Type': 'application/json; charset=utf-8',\n                Authorization: `Bearer ${this.accessToken}`,\n            },\n            data,\n            query: {\n                receive_id_type: receive_id_type || 'open_id',\n            },\n        })\n        return result\n    }\n}\n","import debug from 'debug'\nimport { Send } from '@/interfaces/send'\nimport { ajax } from '@/utils/ajax'\nimport { SendResponse } from '@/interfaces/response'\nimport { ConfigSchema, OptionSchema } from '@/interfaces/schema'\nimport { validate } from '@/utils/validate'\n\nconst Debugger = debug('push:i-got')\n\nexport interface IGotConfig {\n    /**\n     * 微信搜索小程序“iGot”获取推送key\n     */\n    I_GOT_KEY: string\n}\n\nexport type IGotConfigSchema = ConfigSchema<IGotConfig>\n\nexport const iGotConfigSchema: IGotConfigSchema = {\n    I_GOT_KEY: {\n        type: 'string',\n        title: 'iGot 推送key',\n        description: 'iGot 推送key',\n        required: true,\n        default: '',\n    },\n} as const\n\nexport interface IGotOption {\n    /**\n     * 链接； 点开消息后会主动跳转至此地址\n     */\n    url?: string\n    /**\n     * 是否自动复制； 为1自动复制\n     */\n    automaticallyCopy?: number\n    /**\n     * 紧急消息，为1表示紧急。此消息将置顶在小程序内， 同时会在推送的消息内做一定的特殊标识\n     */\n    urgent?: number\n    /**\n     * 需要自动复制的文本内容\n     */\n    copy?: string\n    /**\n     * 主题； 订阅链接下有效；对推送内容分类，用户可选择性订阅\n     */\n    topic?: string\n    [key: string]: any\n}\n\nexport type IGotOptionSchema = OptionSchema<IGotOption>\n\nexport const iGotOptionSchema: IGotOptionSchema = {\n    url: {\n        type: 'string',\n        title: '链接',\n        description: '链接； 点开消息后会主动跳转至此地址',\n        required: false,\n        default: '',\n    },\n    automaticallyCopy: {\n        type: 'number',\n        title: '是否自动复制',\n        description: '是否自动复制； 为1自动复制',\n        required: false,\n        default: 0,\n    },\n    urgent: {\n        type: 'number',\n        title: '紧急消息',\n        description: '紧急消息，为1表示紧急。此消息将置顶在小程序内， 同时会在推送的消息内做一定的特殊标识',\n        required: false,\n        default: 0,\n    },\n    copy: {\n        type: 'string',\n        title: '需要自动复制的文本内容',\n        description: '需要自动复制的文本内容',\n        required: false,\n        default: '',\n    },\n    topic: {\n        type: 'string',\n        title: '主题',\n        description: '主题； 订阅链接下有效；对推送内容分类，用户可选择性订阅',\n        required: false,\n        default: '',\n    },\n} as const\n\nexport interface IGotResponse {\n    /**\n     * 状态码； 0为正常\n     */\n    ret: number\n    /**\n     * 响应结果\n     */\n    data: {\n        /**\n         * 消息记录，后期开放其他接口用\n         * */\n        id: string\n    }\n    /**\n     * 结果描述\n     */\n    errMsg: string\n}\n\n/**\n * iGot 推送，官方文档：http://hellyw.com\n *\n * @author CaoMeiYouRen\n * @date 2021-03-03\n * @export\n * @class IGot\n */\nexport class IGot implements Send {\n    static readonly namespace = 'iGot'\n    static readonly configSchema = iGotConfigSchema\n    static readonly optionSchema = iGotOptionSchema\n    /**\n     * 微信搜索小程序“iGot”获取推送key\n     *\n     * @private\n     */\n    private I_GOT_KEY: string\n    /**\n     * @author CaoMeiYouRen\n     * @date 2024-11-08\n     * @param config 微信搜索小程序“iGot”获取推送key\n     */\n    constructor(config: IGotConfig) {\n        const { I_GOT_KEY } = config\n        this.I_GOT_KEY = I_GOT_KEY\n        Debugger('set I_GOT_KEY: \"%s\"', I_GOT_KEY)\n        // 根据 configSchema 验证 config\n        validate(config, IGot.configSchema)\n    }\n    /**\n     *\n     *\n     * @author CaoMeiYouRen\n     * @date 2024-11-08\n     * @param title 消息标题\n     * @param [desp] 消息正文\n     * @param [option] 额外选项\n     * @returns\n     */\n    send(title: string, desp?: string, option?: IGotOption): Promise<SendResponse<IGotResponse>> {\n        Debugger('title: \"%s\", desp: \"%s\", option: \"%o\"', title, desp, option)\n        return ajax({\n            url: `https://push.hellyw.com/${this.I_GOT_KEY}`,\n            method: 'POST',\n            headers: {\n                'Content-Type': 'application/json',\n            },\n            data: {\n                title,\n                content: desp || title,\n                automaticallyCopy: 0, // 关闭自动复制\n                ...option,\n            },\n        })\n    }\n\n}\n","import debug from 'debug'\nimport { Send } from '@/interfaces/send'\nimport { ajax } from '@/utils/ajax'\nimport { SendResponse } from '@/interfaces/response'\nimport { ConfigSchema, OptionSchema } from '@/interfaces/schema'\nimport { validate } from '@/utils/validate'\nimport { rfc2047Encode } from '@/utils/crypto'\n\nconst Debugger = debug('push:ntfy')\n\nexport interface NtfyConfig {\n    /**\n     * 推送地址\n     */\n    NTFY_URL: string\n\n    /**\n     * 主题\n     * 用于区分不同的推送目标。\n     * 主题本质上是一个密码，所以请选择不容易猜到的东西。\n     * 例如：`my-topic`\n     */\n    NTFY_TOPIC: string\n\n    /**\n     * 认证参数。\n     * 支持 Basic Auth、Bearer Token。\n     * Basic Auth 示例：\"Basic dGVzdDpwYXNz\"\n     * Bearer Token 示例：\"Bearer tk_...\"\n     */\n    NTFY_AUTH?: string\n}\n\nexport type NtfyConfigSchema = ConfigSchema<NtfyConfig>\nexport const ntfyConfigSchema: NtfyConfigSchema = {\n    NTFY_URL: {\n        type: 'string',\n        title: '推送地址',\n        description: '推送地址',\n        required: true,\n        default: '',\n    },\n    NTFY_TOPIC: {\n        type: 'string',\n        title: '主题',\n        description: '主题',\n        required: true,\n        default: '',\n    },\n    NTFY_AUTH: {\n        type: 'string',\n        title: '认证参数',\n        description: '支持 Basic Auth、Bearer Token。\\n' +\n            'Basic Auth 示例：\"Basic dGVzdDpwYXNz\"\\n' +\n            'Bearer Token 示例：\"Bearer tk_...\"',\n        required: false,\n        default: '',\n    },\n} as const\n\nexport interface NtfyOption {\n    /**\n     * 通知中显示的标题\n     */\n    title?: string\n    /**\n     * 通知中显示的消息正文\n     */\n    message?: string\n    /**\n     * 消息正文\n     */\n    body?: string\n    /**\n     * 消息优先级（1-5，1最低，5最高）\n     */\n    priority?: number\n    /**\n     * 标签列表（逗号分隔），支持Emoji短代码\n     */\n    tags?: string\n    /**\n     * 启用Markdown格式化（设为`true`或`yes`）\n     */\n    markdown?: boolean\n    /**\n     * 延迟发送时间（支持时间戳、自然语言如`tomorrow 10am`）\n     */\n    delay?: string\n    /**\n     * 点击通知时打开的URL\n     */\n    click?: string\n    /**\n     * 附加文件的URL\n     */\n    attach?: string\n    /**\n     * 附件的显示文件名\n     */\n    filename?: string\n    /**\n     * 通知图标的URL（仅支持JPEG/PNG）\n     */\n    icon?: string\n    /**\n     * 定义通知的操作按钮（JSON或简写格式）\n     */\n    actions?: string\n    /**\n     * 设为`no`禁止服务器缓存消息\n     */\n    cache?: boolean\n    /**\n     * 设为`no`禁止转发到Firebase（仅影响Android推送）\n     */\n    firebase?: boolean\n    /**\n     * 设为`1`启用UnifiedPush模式（用于Matrix网关）\n     */\n    unifiedPush?: boolean\n    /**\n     * 将通知转发到指定邮箱\n     */\n    email?: string\n    /**\n     * 发送语音呼叫（需验证手机号，仅限认证用户）\n     */\n    call?: string\n    /**\n     * 设为`text/markdown`启用Markdown\n     */\n    contentType?: string\n    /**\n     * 直接上传文件作为附件（需设置`X-Filename`）\n     */\n    file?: File\n}\n\nexport type NtfyOptionSchema = OptionSchema<NtfyOption>\n\nexport const ntfyOptionSchema: NtfyOptionSchema = {\n    title: {\n        type: 'string',\n        title: '标题',\n        description: '标题',\n        required: false,\n        default: '',\n    },\n    body: {\n        type: 'string',\n        title: '消息正文',\n        description: '消息正文',\n        required: false,\n        default: '',\n    },\n    priority: {\n        type: 'number',\n        title: '消息优先级',\n        description: '消息优先级（1-5，1最低，5最高）',\n        required: false,\n        default: 3,\n    },\n    tags: {\n        type: 'string',\n        title: '标签列表',\n        description: '标签列表（逗号分隔），支持Emoji短代码',\n        required: false,\n        default: '',\n    },\n    markdown: {\n        type: 'boolean',\n        title: '启用Markdown格式',\n        description: '启用Markdown格式（设为`true`或`yes`）',\n        required: false,\n        default: false,\n    },\n    delay: {\n        type: 'string',\n        title: '延迟发送时间',\n        description: '延迟发送时间（支持时间戳、自然语言如`tomorrow 10am`）',\n        required: false,\n        default: '',\n    },\n    click: {\n        type: 'string',\n        title: '点击通知时打开的URL',\n        description: '点击通知时打开的URL',\n        required: false,\n        default: '',\n    },\n    attach: {\n        type: 'string',\n        title: '附加文件的URL',\n        description: '附加文件的URL',\n        required: false,\n        default: '',\n    },\n    filename: {\n        type: 'string',\n        title: '附件的显示文件名',\n        description: '附件的显示文件名',\n        required: false,\n        default: '',\n    },\n    icon: {\n        type: 'string',\n        title: '通知图标的URL',\n        description: '通知图标的URL（仅支持JPEG/PNG）',\n        required: false,\n        default: '',\n    },\n    actions: {\n        type: 'string',\n        title: '定义通知的操作按钮',\n        description: '定义通知的操作按钮（JSON或简写格式）',\n        required: false,\n        default: '',\n    },\n    cache: {\n        type: 'boolean',\n        title: '禁止服务器缓存消息',\n        description: '设为`no`禁止服务器缓存消息',\n        required: false,\n        default: false,\n    },\n    firebase: {\n        type: 'boolean',\n        title: '禁止转发到Firebase',\n        description: '设为`no`禁止转发到Firebase（仅影响Android推送）',\n        required: false,\n        default: false,\n    },\n    unifiedPush: {\n        type: 'boolean',\n        title: '启用UnifiedPush模式',\n        description: '设为`1`启用UnifiedPush模式（用于Matrix网关）',\n        required: false,\n        default: false,\n    },\n    email: {\n        type: 'string',\n        title: '邮箱',\n        description: '将通知转发到指定邮箱',\n        required: false,\n        default: '',\n    },\n    call: {\n        type: 'string',\n        title: '发送语音呼叫',\n        description: '发送语音呼叫（需验证手机号，仅限认证用户）',\n        required: false,\n        default: '',\n    },\n    contentType: {\n        type: 'string',\n        title: '编码格式',\n        description: '设为`text/markdown`启用Markdown',\n        required: false,\n        default: '',\n    },\n    file: {\n        type: 'object',\n        title: '附件',\n        description: '直接上传文件作为附件（需设置`X-Filename`）',\n        required: false,\n    },\n} as const\n\nexport interface NtfyResponse {\n    /**\n     * 消息ID\n     */\n    id: string\n    /**\n     * 消息发布时间（Unix时间戳）\n     */\n    time: number\n    /**\n     * 消息过期时间（Unix时间戳）\n     */\n    expires: number\n    /**\n     * 事件类型\n     */\n    event: string\n    /**\n     * 主题\n     */\n    topic: string\n    /**\n     * 消息内容\n     */\n    message: string\n}\n\n/**\n * ntfy推送。\n * 官方文档：https://ntfy.sh/docs/publish/\n *\n * @author CaoMeiYouRen\n * @date 2025-02-11\n * @export\n * @class Ntfy\n */\nexport class Ntfy implements Send {\n    static readonly namespace = 'ntfy'\n    static readonly configSchema = ntfyConfigSchema\n    static readonly optionSchema = ntfyOptionSchema\n    /**\n     * 推送地址\n     */\n    private NTFY_URL: string\n    /**\n     * 认证参数。\n     * 支持 Basic Auth、Bearer Token。\n     * Basic Auth 示例：\"Basic dGVzdDpwYXNz\"\n     * Bearer Token 示例：\"Bearer tk_...\"\n     */\n    private NTFY_AUTH?: string\n\n    /**\n     * 主题\n     * 用于区分不同的推送目标。\n     * 主题本质上是一个密码，所以请选择不容易猜到的东西。\n     * 例如：`my-topic`\n     */\n    private NTFY_TOPIC: string\n\n    constructor(config: NtfyConfig) {\n        const { NTFY_URL, NTFY_AUTH, NTFY_TOPIC } = config\n        this.NTFY_URL = NTFY_URL\n        this.NTFY_TOPIC = NTFY_TOPIC\n        this.NTFY_AUTH = NTFY_AUTH\n        Debugger('set NTFY_URL: \"%s\", NTFY_TOPIC: \"%s\", NTFY_AUTH: \"%s\"', NTFY_URL, NTFY_TOPIC, NTFY_AUTH)\n        // 根据 configSchema 验证 config\n        validate(config, Ntfy.configSchema)\n    }\n\n    async send(title: string, desp: string, option?: NtfyOption): Promise<SendResponse<NtfyResponse>> {\n        Debugger('option: \"%o\"', option)\n        const { message, body, priority, tags, markdown, delay, click, attach, filename, icon, actions, cache, firebase, unifiedPush, email, call, contentType, file } = option || {}\n        const headers: any = {}\n        if (this.NTFY_AUTH) {\n            headers['Authorization'] = this.NTFY_AUTH\n        }\n        if (contentType) {\n            headers['Content-Type'] = contentType\n        }\n        const xTitle = title || option.title\n        if (xTitle) {\n            headers['X-Title'] = rfc2047Encode(xTitle)\n        }\n        if (message) {\n            headers['X-Message'] = rfc2047Encode(message)\n        }\n        if (priority) {\n            headers['X-Priority'] = priority.toString()\n        }\n        if (tags) {\n            headers['X-Tags'] = tags\n        }\n        if (markdown) {\n            headers['X-Markdown'] = markdown.toString()\n        }\n        if (delay) {\n            headers['X-Delay'] = delay\n        }\n        if (click) {\n            headers['X-Click'] = click\n        }\n        if (attach) {\n            headers['X-Attach'] = attach\n        }\n        if (filename) {\n            headers['X-Filename'] = filename\n        }\n        if (icon) {\n            headers['X-Icon'] = icon\n        }\n        if (actions) {\n            headers['X-Actions'] = actions\n        }\n        if (cache) {\n            headers['X-Cache'] = cache ? 'yes' : 'no'\n        }\n        if (firebase) {\n            headers['X-Firebase'] = firebase ? 'yes' : 'no'\n        }\n        if (unifiedPush) {\n            headers['X-UnifiedPush'] = unifiedPush ? '1' : '0'\n        }\n        if (email) {\n            headers['X-Email'] = email\n        }\n        if (call) {\n            headers['X-Call'] = call\n        }\n        if (file) {\n            headers['X-Filename'] = file.name\n            headers['Content-Type'] = 'application/octet-stream'\n            headers['Content-Length'] = file.size\n            headers['Content-Disposition'] = `attachment; filename=\"${file.name}\"`\n        }\n        Debugger('headers: \"%o\"', headers)\n        const data = desp || body || message\n        Debugger('data: \"%s\"', data)\n        const url = new URL(this.NTFY_TOPIC, this.NTFY_URL).toString()\n        const response = await ajax({\n            url,\n            method: 'POST',\n            headers,\n            data,\n        })\n        return response\n    }\n}\n","import debug from 'debug'\nimport { Send } from '@/interfaces/send'\nimport { ajax } from '@/utils/ajax'\nimport { warn } from '@/utils/helper'\nimport { SendResponse } from '@/interfaces/response'\nimport { ConfigSchema, OptionSchema } from '@/interfaces/schema'\nimport { validate } from '@/utils/validate'\n\nconst Debugger = debug('push:one-bot')\n\nexport interface OneBotConfig {\n    /**\n     * OneBot HTTP 基础路径\n     */\n    ONE_BOT_BASE_URL: string\n    /**\n     * OneBot AccessToken\n     * 出于安全原因，请务必设置 AccessToken\n     */\n    ONE_BOT_ACCESS_TOKEN?: string\n}\n\nexport type OneBotConfigSchema = ConfigSchema<OneBotConfig>\nexport const oneBotConfigSchema: OneBotConfigSchema = {\n    ONE_BOT_BASE_URL: {\n        type: 'string',\n        title: 'OneBot HTTP 基础路径',\n        description: 'OneBot HTTP 基础路径',\n        required: true,\n    },\n    ONE_BOT_ACCESS_TOKEN: {\n        type: 'string',\n        title: 'OneBot AccessToken',\n        description: '出于安全原因，请务必设置 AccessToken',\n        required: false,\n    },\n} as const\n\nexport interface OneBotPrivateMsgOption {\n    /**\n     * 消息类型\n     */\n    message_type: 'private'\n    /**\n     * 对方 QQ 号\n     */\n    user_id: number\n}\n\nexport interface OneBotGroupMsgOption {\n    /**\n     * 消息类型\n     */\n    message_type: 'group'\n    /**\n     * 群号\n     */\n    group_id: number\n\n}\n\nexport type OneBotOption = (OneBotPrivateMsgOption | OneBotGroupMsgOption) & {\n    /**\n     * 消息内容是否作为纯文本发送（即不解析 CQ 码），只在 message 字段是字符串时有效\n     */\n    auto_escape?: boolean\n}\n\nexport type OneBotMsgType = OneBotOption['message_type']\n\nexport type OneBotOptionSchema = OptionSchema<{\n    // 消息类型，private 或 group\n    message_type: OneBotMsgType\n    // 如果为 private，对方 QQ 号\n    user_id?: number\n    // 如果为 group，群号\n    group_id?: number\n    // 消息内容是否作为纯文本发送（即不解析 CQ 码），只在 message 字段是字符串时有效\n    auto_escape?: boolean\n}>\n\nexport const oneBotOptionSchema: OneBotOptionSchema = {\n    message_type: {\n        type: 'select',\n        title: '消息类型',\n        description: '消息类型，private 或 group，默认为 private',\n        required: true,\n        default: 'private',\n        options: [\n            {\n                label: '私聊',\n                value: 'private',\n            },\n            {\n                label: '群聊',\n                value: 'group',\n            },\n        ],\n    },\n    user_id: {\n        type: 'number',\n        title: ' QQ 号',\n        description: '对方 QQ 号。仅私聊有效。',\n        required: false,\n    },\n    group_id: {\n        type: 'number',\n        title: '群号',\n        description: '群号。仅群聊有效。',\n        required: false,\n    },\n    auto_escape: {\n        type: 'boolean',\n        title: '消息内容是否作为纯文本发送（即不解析 CQ 码），只在 message 字段是字符串时有效',\n        description: '消息内容是否作为纯文本发送（即不解析 CQ 码），只在 message 字段是字符串时有效',\n        required: false,\n    },\n} as const\n\nexport interface OneBotData {\n    ClassType: string\n    // 消息 ID\n    message_id: number\n}\n\nexport interface OneBotResponse {\n    status: string\n    retcode: number\n    data: OneBotData\n    echo?: any\n}\n\n/**\n * OneBot。官方文档：https://github.com/botuniverse/onebot-11\n * 本项目实现的版本为 OneBot 11\n * @author CaoMeiYouRen\n * @date 2023-10-22\n * @export\n * @class OneBot\n */\nexport class OneBot implements Send {\n    static readonly namespace = 'OneBot'\n    static readonly configSchema = oneBotConfigSchema\n    static readonly optionSchema = oneBotOptionSchema\n\n    /**\n     *  OneBot 协议版本号\n     *\n     * @author CaoMeiYouRen\n     * @date 2023-10-22\n     * @static\n     */\n    static version = 11\n\n    /**\n     * OneBot HTTP 基础路径\n     *\n     * @author CaoMeiYouRen\n     * @date 2023-10-22\n     * @private\n     * @example http://127.0.0.1\n     */\n    private ONE_BOT_BASE_URL: string\n    /**\n     * OneBot AccessToken\n     * 出于安全原因，请务必设置 AccessToken\n     * @author CaoMeiYouRen\n     * @date 2023-10-22\n     * @private\n     */\n    private ONE_BOT_ACCESS_TOKEN?: string\n\n    /**\n     * 创建 OneBot 实例\n     * @author CaoMeiYouRen\n     * @date 2024-11-08\n     * @param config OneBot 配置\n     */\n    constructor(config: OneBotConfig) {\n        const { ONE_BOT_BASE_URL, ONE_BOT_ACCESS_TOKEN } = config\n        this.ONE_BOT_BASE_URL = ONE_BOT_BASE_URL\n        this.ONE_BOT_ACCESS_TOKEN = ONE_BOT_ACCESS_TOKEN\n        Debugger('set ONE_BOT_BASE_URL: \"%s\", ONE_BOT_ACCESS_TOKEN: \"%s\"', ONE_BOT_BASE_URL, ONE_BOT_ACCESS_TOKEN)\n        // 根据 configSchema 验证 config\n        validate(config, OneBot.configSchema)\n        if (!this.ONE_BOT_ACCESS_TOKEN) {\n            warn('未提供 ONE_BOT_ACCESS_TOKEN ！出于安全原因，请务必设置 AccessToken！')\n        }\n    }\n\n    /**\n     *\n     *\n     * @author CaoMeiYouRen\n     * @date 2024-11-08\n     * @param title 消息标题\n     * @param desp 消息正文\n     * @param option 额外推送选项\n     */\n    async send(title: string, desp: string, option: OneBotOption): Promise<SendResponse<OneBotResponse>> {\n        Debugger('title: \"%s\", desp: \"%s\", option: \"%o\"', title, desp, option)\n        // !由于 OneBot 的 option 中带有必填项，所以需要校验\n        // 根据 optionSchema 验证 option\n        validate(option, OneBot.optionSchema as OptionSchema<OneBotOption>)\n        if (option.message_type === 'private' && !option.user_id) {\n            throw new Error('OneBot 私聊消息类型必须提供 user_id')\n        }\n        if (option.message_type === 'group' && !option.group_id) {\n            throw new Error('OneBot 群聊消息类型必须提供 group_id')\n        }\n        const { message_type = 'private', ...args } = option || {}\n        const message = `${title}${desp ? `\\n${desp}` : ''}`\n        return ajax<OneBotResponse>({\n            baseURL: this.ONE_BOT_BASE_URL,\n            url: '/send_msg',\n            method: 'POST',\n            headers: {\n                'Content-Type': 'application/json',\n                Authorization: `Bearer ${this.ONE_BOT_ACCESS_TOKEN}`,\n            },\n            data: {\n                auto_escape: false,\n                message_type,\n                message,\n                ...args,\n            },\n        })\n    }\n\n}\n","import debug from 'debug'\nimport { Send } from '@/interfaces/send'\nimport { ajax } from '@/utils/ajax'\nimport { SendResponse } from '@/interfaces/response'\nimport { ConfigSchema, OptionSchema } from '@/interfaces/schema'\nimport { validate } from '@/utils/validate'\n\nconst Debugger = debug('push:push-deer')\n\nexport type PushDeerPushType = 'markdown' | 'text' | 'image'\n\nexport interface PushDeerConfig {\n    /**\n     * pushkey。请参考 https://github.com/easychen/pushdeer 获取\n     */\n    PUSH_DEER_PUSH_KEY: string\n\n    /**\n     * 使用自架版时的服务器端地址。例如 http://127.0.0.1:8800。默认为 https://api2.pushdeer.com\n     */\n    PUSH_DEER_ENDPOINT?: string\n}\n\nexport type PushDeerConfigSchema = ConfigSchema<PushDeerConfig>\n\nexport const pushDeerConfigSchema: PushDeerConfigSchema = {\n    PUSH_DEER_PUSH_KEY: {\n        type: 'string',\n        title: 'pushkey',\n        description: '请参考 https://github.com/easychen/pushdeer 获取',\n        required: true,\n    },\n    PUSH_DEER_ENDPOINT: {\n        type: 'string',\n        title: '使用自架版时的服务器端地址',\n        description: '例如 http://127.0..1:8800。默认为 https://api2.pushdeer.com',\n        required: false,\n        default: 'https://api2.pushdeer.com',\n    },\n} as const\n\nexport interface PushDeerOption {\n    /**\n     * 格式。文本=text，markdown，图片=image，默认为markdown。type 为 image 时，text 中为要发送图片的URL\n     */\n    type?: PushDeerPushType\n}\n\nexport type PushDeerOptionSchema = OptionSchema<PushDeerOption>\nexport const pushDeerOptionSchema: PushDeerOptionSchema = {\n    type: {\n        type: 'select',\n        title: '格式',\n        description: '文本=text，markdown，图片=image，默认为markdown。type 为 image 时，text 中为要发送图片的URL',\n        required: false,\n        default: 'markdown',\n        options: [\n            {\n                label: '文本',\n                value: 'text',\n            },\n            {\n                label: 'Markdown',\n                value: 'markdown',\n            },\n            {\n                label: '图片',\n                value: 'image',\n            },\n        ],\n    },\n} as const\n\nexport interface PushDeerResponse {\n    /**\n     * 正确为0，错误为非0\n     */\n    code: number\n    /**\n     * 错误信息。无错误时无此字段\n     */\n    error: string\n    /**\n     * 消息内容，错误时无此字段\n     */\n    content: {\n        result: string[]\n    }\n}\n\n/**\n * PushDeer 推送。 官方文档 https://github.com/easychen/pushdeer\n *\n * @author CaoMeiYouRen\n * @date 2022-02-28\n * @export\n * @class PushDeer\n */\nexport class PushDeer implements Send {\n\n    static readonly namespace = 'PushDeer'\n    static readonly configSchema = pushDeerConfigSchema\n    static readonly optionSchema = pushDeerOptionSchema\n\n    /**\n     * pushkey，请参考 https://github.com/easychen/pushdeer 获取\n     *\n     * @author CaoMeiYouRen\n     * @date 2022-02-28\n     * @private\n     */\n    private PUSH_DEER_PUSH_KEY: string\n\n    /**\n     * 使用自架版时的服务器端地址。例如 http://127.0.0.1:8800\n     *\n     * @author CaoMeiYouRen\n     * @date 2022-02-28\n     * @private\n     */\n    private PUSH_DEER_ENDPOINT: string\n\n    /**\n     * 创建 PushDeer 实例\n     * @author CaoMeiYouRen\n     * @date 2024-11-08\n     * @param config 配置\n     */\n    constructor(config: PushDeerConfig) {\n        const { PUSH_DEER_PUSH_KEY, PUSH_DEER_ENDPOINT } = config\n        this.PUSH_DEER_PUSH_KEY = PUSH_DEER_PUSH_KEY\n        this.PUSH_DEER_ENDPOINT = PUSH_DEER_ENDPOINT || 'https://api2.pushdeer.com'\n        Debugger('set PUSH_DEER_PUSH_KEY: \"%s\", PUSH_DEER_ENDPOINT: \"%s\"', PUSH_DEER_PUSH_KEY, PUSH_DEER_ENDPOINT)\n        // 根据 configSchema 验证 config\n        validate(config, PushDeer.configSchema)\n    }\n\n    /**\n     * @author CaoMeiYouRen\n     * @date 2024-11-08\n     * @param text 推送消息内容\n     * @param [desp=''] 消息内容第二部分\n     * @param [option={}] 额外推送选项\n     */\n    async send(title: string, desp: string = '', option?: PushDeerOption): Promise<SendResponse<PushDeerResponse>> {\n        Debugger('title: \"%s\", desp: \"%s\", option: \"%o\"', title, desp, option)\n        const { type = 'markdown' } = option || {}\n        return ajax({\n            baseURL: this.PUSH_DEER_ENDPOINT,\n            url: '/message/push',\n            method: 'POST',\n            headers: {\n                'Content-Type': 'application/x-www-form-urlencoded',\n            },\n            data: {\n                text: title,\n                desp,\n                pushkey: this.PUSH_DEER_PUSH_KEY,\n                type,\n            },\n        })\n    }\n\n}\n","import debug from 'debug'\nimport { Send } from '@/interfaces/send'\nimport { ajax } from '@/utils/ajax'\nimport { SendResponse } from '@/interfaces/response'\nimport { ConfigSchema, OptionSchema } from '@/interfaces/schema'\nimport { validate } from '@/utils/validate'\n\nconst Debugger = debug('push:push-plus')\n/**\nhtml\t默认模板，支持html文本\ntxt\t纯文本展示，不转义html\njson\t内容基于json格式展示\nmarkdown\t内容基于markdown格式展示\ncloudMonitor\t阿里云监控报警定制模板\njenkins\tjenkins插件定制模板\nroute\t路由器插件定制模板 */\nexport type PushPlusTemplateType = 'html' | 'txt' | 'json' | 'markdown' | 'cloudMonitor' | 'jenkins' | 'route'\n/**\nwechat\t免费\t微信公众号\nwebhook\t免费\t第三方webhook；企业微信、钉钉、飞书、server酱；webhook机器人推送\ncp\t免费\t企业微信应用；具体参考企业微信应用推送\nmail\t免费\t邮箱；具体参考邮件渠道使用说明\nsms\t收费\t短信，未开放\n */\nexport type PushPlusChannelType = 'wechat' | 'webhook' | 'cp' | 'sms' | 'mail'\n\nexport interface PushPlusConfig {\n    /**\n     *  请前往 https://www.pushplus.plus 领取\n     */\n    PUSH_PLUS_TOKEN: string\n}\n\nexport type PushPlusConfigSchema = ConfigSchema<PushPlusConfig>\n\nexport const pushPlusConfigSchema: PushPlusConfigSchema = {\n    PUSH_PLUS_TOKEN: {\n        type: 'string',\n        title: 'PushPlus Token',\n        description: '请前往 https://www.pushplus.plus/ 领取',\n        required: true,\n    },\n}\n\nexport interface PushPlusOption {\n    /**\n     * 模板类型\n     */\n    template?: PushPlusTemplateType\n    /**\n     * 渠道类型\n     */\n    channel?: PushPlusChannelType\n    /**\n     * 群组编码，不填仅发送给自己；channel为webhook时无效\n     */\n    topic?: string\n    /**\n     * webhook编码，仅在channel使用webhook渠道和CP渠道时需要填写\n     */\n    webhook?: string\n    /**\n     * 发送结果回调地址\n     */\n    callbackUrl?: string\n    /**\n     * 毫秒时间戳。格式如：1632993318000。服务器时间戳大于此时间戳，则消息不会发送\n     */\n    timestamp?: number\n}\n\nexport type PushPlusOptionSchema = OptionSchema<PushPlusOption>\n\nexport const pushPlusOptionSchema: PushPlusOptionSchema = {\n    template: {\n        type: 'select',\n        title: '模板类型',\n        description: 'html，txt，json，markdown，cloudMonitor，jenkins，route',\n        required: false,\n        default: 'html',\n        options: [\n            {\n                label: 'HTML',\n                value: 'html',\n            },\n            {\n                label: '文本',\n                value: 'txt',\n            },\n            {\n                label: 'JSON',\n                value: 'json',\n            },\n            {\n                label: 'Markdown',\n                value: 'markdown',\n            },\n            {\n                label: '阿里云监控',\n                value: 'cloudMonitor',\n            },\n            {\n                label: 'Jenkins',\n                value: 'jenkins',\n            },\n            {\n                label: '路由器',\n                value: 'route',\n            },\n        ],\n    },\n    channel: {\n        type: 'select',\n        title: '渠道类型',\n        description: 'wechat，webhook，cp，sms，mail',\n        required: false,\n        default: 'wechat',\n        options: [\n            {\n                label: '微信',\n                value: 'wechat',\n            },\n            {\n                label: 'Webhook',\n                value: 'webhook',\n            },\n            {\n                label: '企业微信',\n                value: 'cp',\n            },\n            {\n                label: '邮件',\n                value: 'mail',\n            },\n            {\n                label: '短信',\n                value: 'sms',\n            },\n        ],\n    },\n    topic: {\n        type: 'string',\n        title: '群组编码',\n        description: '不填仅发送给自己；channel为webhook时无效',\n        required: false,\n        default: '',\n    },\n    webhook: {\n        type: 'string',\n        title: 'webhook编码',\n        description: '仅在channel使用webhook渠道和CP渠道时需要填写',\n        required: false,\n        default: '',\n    },\n    callbackUrl: {\n        type: 'string',\n        title: '发送结果回调地址',\n        description: '发送结果回调地址',\n        required: false,\n        default: '',\n    },\n    timestamp: {\n        type: 'number',\n        title: '毫秒时间戳',\n        description: '格式如：1632993318000。服务器时间戳大于此时间戳，则消息不会发送',\n        required: false,\n        // default: 0,\n    },\n}\n\nexport interface PushPlusResponse {\n    // 200 为正确\n    code: number\n    msg: string\n    data: any\n}\n\n/**\n * pushplus 推送加开放平台，仅支持一对一推送。官方文档：https://www.pushplus.plus/doc/\n *\n * @author CaoMeiYouRen\n * @date 2021-03-03\n * @export\n * @class PushPlus\n */\nexport class PushPlus implements Send {\n    static readonly namespace = 'PushPlus'\n    static readonly configSchema = pushPlusConfigSchema\n    static readonly optionSchema = pushPlusOptionSchema\n    /**\n     * 请前往 https://www.pushplus.plus 领取\n     *\n     * @private\n     */\n    private PUSH_PLUS_TOKEN: string\n\n    /**\n     *\n     * @author CaoMeiYouRen\n     * @date 2024-11-08\n     * @param config 请前往 https://www.pushplus.plus 领取\n     */\n    constructor(config: PushPlusConfig) {\n        const { PUSH_PLUS_TOKEN } = config\n        this.PUSH_PLUS_TOKEN = PUSH_PLUS_TOKEN\n        Debugger('set PUSH_PLUS_TOKEN: \"%s\"', PUSH_PLUS_TOKEN)\n        // 根据 configSchema 验证 config\n        validate(config, PushPlus.configSchema)\n    }\n\n    /**\n     * 发送消息\n     *\n     * @author CaoMeiYouRen\n     * @date 2024-11-08\n     * @param title 消息标题\n     * @param [desp=''] 消息内容\n     * @param [option] 额外推送选项\n     */\n    send(title: string, desp: string = '', option?: PushPlusOption): Promise<SendResponse<PushPlusResponse>> {\n        Debugger('title: \"%s\", desp: \"%s\", option: \"%o\"', title, desp, option)\n        const { template = 'html', channel = 'wechat', ...args } = option || {}\n        const content = desp || title\n        return ajax({\n            url: 'http://www.pushplus.plus/send',\n            method: 'POST',\n            headers: {\n                'Content-Type': 'application/json',\n            },\n            data: {\n                token: this.PUSH_PLUS_TOKEN,\n                title,\n                content: content || title,\n                template,\n                channel,\n                ...args,\n            },\n        })\n    }\n\n}\n","import debug from 'debug'\nimport { Send } from '@/interfaces/send'\nimport { ajax } from '@/utils/ajax'\nimport { SendResponse } from '@/interfaces/response'\nimport { ConfigSchema, OptionSchema } from '@/interfaces/schema'\nimport { validate } from '@/utils/validate'\n\nconst Debugger = debug('push:qmsg')\n\n/**\n * 推送类型，见 [Qmsg](https://qmsg.zendee.cn/docs/api)。\n */\nexport type QmsgPushType = 'send' | 'group'\n\nexport interface QmsgConfig {\n    /**\n     * 推送的 key。在 [Qmsg 酱管理台](https://qmsg.zendee.cn/user) 查看\n     */\n    QMSG_KEY: string\n}\nexport type QmsgConfigSchema = ConfigSchema<QmsgConfig>\n\nexport const qmsgConfigSchema: QmsgConfigSchema = {\n    QMSG_KEY: {\n        type: 'string',\n        title: '推送的 key',\n        description: '在 [Qmsg 酱管理台](https://qmsg.zendee.cn/user) 查看',\n        required: true,\n    },\n} as const\n\nexport interface QmsgPrivateMsgOption {\n    /**\n     * send 表示发送消息给指定的QQ号，group 表示发送消息给指定的QQ群。默认为 send\n     */\n    type: 'send'\n    /**\n     * 指定要接收消息的QQ号或者QQ群。多个以英文逗号分割，例如：12345,12346\n     */\n    qq: string\n}\n\nexport interface QmsgGroupMsgOption {\n    /**\n     * send 表示发送消息给指定的QQ号，group 表示发送消息给指定的QQ群。默认为 send\n     */\n    type: 'group'\n    /**\n     * 指定要接收消息的QQ号或者QQ群。多个以英文逗号分割，例如：12345,12346\n     */\n    qq: string\n\n}\n\nexport type QmsgOption = (QmsgPrivateMsgOption | QmsgGroupMsgOption) & {\n    /**\n     * 机器人的QQ号。指定使用哪个机器人来发送消息，不指定则会自动随机选择一个在线的机器人发送消息。该参数仅私有云有效\n     */\n    bot?: string\n}\n\nexport type QmsgOptionSchema = OptionSchema<{\n    // 消息类型\n    type: 'send' | 'group'\n    // 指定要接收消息的QQ号或者QQ群。多个以英文逗号分割，例如：12345,12346\n    qq: string\n    // 机器人的QQ号。指定使用哪个机器人来发送消息，不指定则会自动随机选择一个在线的机器人发送消息。该参数仅私有云有效\n    bot?: string\n}>\n\nexport const qmsgOptionSchema: QmsgOptionSchema = {\n    type: {\n        type: 'select',\n        title: '消息类型',\n        description: 'send 表示发送消息给指定的QQ号，group 表示发送消息给指定的QQ群。默认为 send',\n        required: true,\n        default: 'send',\n        options: [\n            {\n                label: '私聊',\n                value: 'send',\n            },\n            {\n                label: '群聊',\n                value: 'group',\n            },\n        ],\n    },\n    qq: {\n        type: 'string',\n        title: '指定要接收消息的QQ号或者QQ群',\n        description: '多个以英文逗号分割，例如：12345,12346',\n        required: true,\n    },\n    bot: {\n        type: 'string',\n        title: '机器人的QQ号',\n        description: '指定使用哪个机器人来发送消息，不指定则会自动随机选择一个在线的机器人发送消息。该参数仅私有云有效',\n        required: false,\n    },\n} as const\n\nexport interface QmsgResponse {\n    /**\n     * 本次请求是否成功\n     */\n    success: boolean\n    /**\n     * 本次请求结果描述\n     */\n    reason: string\n    /**\n     * 错误代码。错误代码目前不可靠，如果要判断是否成功请使用success\n     */\n    code: number\n    info: any\n}\n\n/**\n * Qmsg酱。使用说明见 [Qmsg酱](https://qmsg.zendee.cn/docs)\n *\n * @author CaoMeiYouRen\n * @date 2022-02-17\n * @export\n * @class Qmsg\n */\nexport class Qmsg implements Send {\n\n    static readonly namespace = 'Qmsg酱'\n    static readonly configSchema = qmsgConfigSchema\n    static readonly optionSchema = qmsgOptionSchema\n\n    private QMSG_KEY: string\n\n    constructor(config: QmsgConfig) {\n        const { QMSG_KEY } = config\n        this.QMSG_KEY = QMSG_KEY\n        Debugger('set QMSG_KEY: \"%s\"', QMSG_KEY)\n        // 根据 configSchema 验证 config\n        validate(config, Qmsg.configSchema)\n    }\n\n    /**\n     *\n     * 发送消息\n     * @author CaoMeiYouRen\n     * @date 2024-11-08\n     * @param title 消息标题\n     * @param [desp] 消息描述\n     * @param [option] QmsgOption 选项\n     */\n    async send(title: string, desp: string, option: QmsgOption): Promise<SendResponse<QmsgResponse>> {\n        Debugger('title: \"%s\", desp: \"%s\", option: \"%o\"', title, desp, option)\n        // !由于 Qmsg 酱的 option 中带有必填项，所以需要校验\n        // 根据 optionSchema 验证 option\n        validate(option, Qmsg.optionSchema)\n        const { qq, type = 'send', bot } = option || {}\n        const msg = `${title}${desp ? `\\n${desp}` : ''}`\n        return ajax({\n            url: `https://qmsg.zendee.cn/${type}/${this.QMSG_KEY}`,\n            headers: {\n                'Content-Type': 'application/x-www-form-urlencoded',\n            },\n            method: 'POST',\n            data: { msg, qq, bot },\n        })\n    }\n\n}\n","import debug from 'debug'\nimport { Send } from '@/interfaces/send'\nimport { ajax } from '@/utils/ajax'\nimport { SendResponse } from '@/interfaces/response'\nimport { ConfigSchema, OptionSchema } from '@/interfaces/schema'\nimport { validate } from '@/utils/validate'\n\nconst Debugger = debug('push:server-chan-turbo')\n\nexport type ChannelValue = 98 | 66 | 1 | 2 | 3 | 8 | 0 | 88 | 18 | 9\n\nexport type Channel = `${ChannelValue}` | `${ChannelValue}|${ChannelValue}`\n\nexport interface ServerChanTurboConfig {\n    /**\n     * Server酱 Turbo 的 SCTKEY\n     * 请前往 https://sct.ftqq.com/sendkey 领取\n     */\n    SERVER_CHAN_TURBO_SENDKEY: string\n}\n\nexport type ServerChanTurboConfigSchema = ConfigSchema<ServerChanTurboConfig>\nexport const serverChanTurboConfigSchema: ServerChanTurboConfigSchema = {\n    SERVER_CHAN_TURBO_SENDKEY: {\n        type: 'string',\n        title: 'SCTKEY',\n        description: 'Server酱 Turbo 的 SCTKEY。请前往 https://sct.ftqq.com/sendkey 领取',\n        required: true,\n    },\n} as const\n\n/**\n * 附加参数\n */\nexport type ServerChanTurboOption = {\n    /**\n     *  消息卡片内容，选填。最大长度 64。如果不指定，将自动从 desp 中截取生成。\n     */\n    short?: string\n    /**\n     * 是否隐藏调用 IP，选填。如果不指定，则显示；为 1 则隐藏。\n     */\n    noip?: '1' | 1 | true\n    /**\n     * 动态指定本次推送使用的消息通道，选填。如不指定，则使用网站上的消息通道页面设置的通道。支持最多两个通道，多个通道值用竖线 \"|\" 隔开。\n     * 通道对应的值如下：\n     * 官方Android版·β=98\n     * 企业微信应用消息=66\n     * 企业微信群机器人=1\n     * 钉钉群机器人=2\n     * 飞书群机器人=3\n     * Bark iOS=8\n     * 测试号=0\n     * 自定义=88\n     * PushDeer=18\n     * 方糖服务号=9\n     */\n    channel?: Channel\n    /**\n     * 消息抄送的 openid，选填。只支持测试号和企业微信应用消息通道。多个 openid 用 \",\" 隔开。企业微信应用消息通道的 openid 参数，内容为接收人在企业微信中的 UID，多个人请 \"|\" 隔开。\n     */\n    openid?: string\n}\n\nexport type ServerChanTurboOptionSchema = OptionSchema<{\n    short?: string\n    openid?: string\n    channel?: string\n    noip?: boolean\n}>\nexport const serverChanTurboOptionSchema: ServerChanTurboOptionSchema = {\n    short: {\n        type: 'string',\n        title: '消息卡片内容',\n        description: '选填。最大长度 64。如果不指定，将自动从 desp 中截取生成。',\n        required: false,\n    },\n    noip: {\n        type: 'boolean',\n        title: '是否隐藏调用 IP',\n        description: '选填。如果不指定，则显示；为 1/true 则隐藏。',\n        required: false,\n    },\n    channel: {\n        type: 'string',\n        title: '消息通道',\n        description: '选填。动态指定本次推送使用的消息通道，支持最多两个通道，多个通道值用竖线 \"|\" 隔开。',\n        required: false,\n    },\n    openid: {\n        type: 'string',\n        title: '消息抄送的 openid',\n        description: '选填。只支持测试号和企业微信应用消息通道。多个 openid 用 \",\" 隔开。企业微信应用消息通道的 openid 参数，内容为接收人在企业微信中的 UID，多个人请 \"|\" 隔开。',\n        required: false,\n    },\n}\n\nexport interface ServerChanTurboResponse {\n    // 0 表示成功，其他值表示失败\n    code: number\n    message: string\n    data: {\n        // 推送消息的 ID\n        pushid: string\n        // 推送消息的阅读凭证\n        readkey: string\n        error: string\n        errno: number\n    }\n}\n\n/**\n * Server 酱·Turbo\n * 文档 https://sct.ftqq.com/\n *\n * @author CaoMeiYouRen\n * @date 2021-02-27\n * @export\n * @class ServerChanTurbo\n */\nexport class ServerChanTurbo implements Send {\n\n    static readonly namespace = 'Server酱·Turbo'\n    static readonly configSchema = serverChanTurboConfigSchema\n    static readonly optionSchema = serverChanTurboOptionSchema\n\n    /**\n     *\n     * @author CaoMeiYouRen\n     * @date 2024-11-08\n     * @param config 请前往 https://sct.ftqq.com/sendkey 领取\n     */\n    constructor(config: ServerChanTurboConfig) {\n        const { SERVER_CHAN_TURBO_SENDKEY } = config\n        this.SCTKEY = SERVER_CHAN_TURBO_SENDKEY\n        Debugger('set SCTKEY: \"%s\"', this.SCTKEY)\n        // 根据 configSchema 验证 config\n        validate(config, ServerChanTurbo.configSchema)\n    }\n    /**\n     *\n     *\n     * @private 请前往 https://sct.ftqq.com/sendkey 领取\n     */\n    private SCTKEY: string\n\n    /**\n     * 发送消息\n     *\n     * @author CaoMeiYouRen\n     * @date 2024-11-08\n     * @param title 消息的标题\n     * @param [desp=''] 消息的内容，支持 Markdown\n     * @param [option={}] 额外发送选项\n     */\n    async send(title: string, desp: string = '', option: ServerChanTurboOption = {}): Promise<SendResponse<ServerChanTurboResponse>> {\n        Debugger('title: \"%s\", desp: \"%s\", option: %O', title, desp, option)\n        if (option.noip === 1 || option.noip === true) {\n            option.noip = '1'\n        }\n        const data = {\n            text: title,\n            desp,\n            ...option,\n        }\n        return ajax({\n            url: `https://sctapi.ftqq.com/${this.SCTKEY}.send`,\n            method: 'POST',\n            headers: {\n                'Content-Type': 'application/x-www-form-urlencoded',\n            },\n            data,\n        })\n    }\n}\n","import debug from 'debug'\nimport { Send } from '@/interfaces/send'\nimport { ajax } from '@/utils/ajax'\nimport { SendResponse } from '@/interfaces/response'\nimport { ConfigSchema, OptionSchema } from '@/interfaces/schema'\nimport { validate } from '@/utils/validate'\n\nconst Debugger = debug('push:server-chan-v3')\n\nexport interface ServerChanV3Config {\n    /**\n     * 请前往 https://sc3.ft07.com/sendkey 领取\n     */\n    SERVER_CHAN_V3_SENDKEY: string\n}\n\nexport type ServerChanV3ConfigSchema = ConfigSchema<ServerChanV3Config>\nexport const serverChanV3ConfigSchema: ServerChanV3ConfigSchema = {\n    SERVER_CHAN_V3_SENDKEY: {\n        type: 'string',\n        title: 'SENDKEY',\n        description: '请前往 https://sc3.ft07.com/sendkey 领取',\n        required: true,\n    },\n} as const\n\n/**\n * 附加参数\n */\nexport type ServerChanV3Option = {\n    tags?: string | string[] // 标签列表，多个标签使用竖线分隔；也可以用数组格式，数组格式下不要加竖线\n    short?: string // 推送消息的简短描述，用于指定消息卡片的内容部分，尤其是在推送markdown的时候\n}\n\nexport type ServerChanV3OptionSchema = OptionSchema<{\n    tags?: string[]\n    short?: string\n}>\nexport const serverChanV3OptionSchema: ServerChanV3OptionSchema = {\n    tags: {\n        type: 'array',\n        title: '标签列表',\n        description: '多个标签用数组格式',\n        required: false,\n    },\n    short: {\n        type: 'string',\n        title: '推送消息的简短描述',\n        description: '用于指定消息卡片的内容部分，尤其是在推送markdown的时候',\n        required: false,\n    },\n} as const\n\nexport interface ServerChanV3Response {\n    // 0 表示成功，其他值表示失败\n    code: number\n    message: string\n    errno: number\n    data: {\n        // 推送消息的 ID\n        pushid: string\n        meta: {\n            android: any\n            devices: any[]\n        }\n    }\n}\n\n/**\n * Server酱³\n * 文档：https://sc3.ft07.com/doc\n * @author CaoMeiYouRen\n * @date 2024-10-04\n * @export\n * @class ServerChanV3\n */\nexport class ServerChanV3 implements Send {\n\n    static readonly namespace = 'Server酱³'\n    static readonly configSchema = serverChanV3ConfigSchema\n    static readonly optionSchema = serverChanV3OptionSchema\n\n    /**\n     * 请前往 https://sc3.ft07.com/sendkey 领取\n     *\n     * @author CaoMeiYouRen\n     * @date 2024-10-04\n     * @private\n     */\n    private sendkey: string\n\n    private uid: string = ''\n\n    /**\n     * 创建 ServerChanV3 实例\n     * @author CaoMeiYouRen\n     * @date 2024-11-08\n     * @param config 请前往 https://sc3.ft07.com/sendkey 领取\n     */\n    constructor(config: ServerChanV3Config) {\n        const { SERVER_CHAN_V3_SENDKEY } = config\n        const sendkey = SERVER_CHAN_V3_SENDKEY\n        this.sendkey = sendkey\n        Debugger('set sendkey: \"%s\"', sendkey)\n        // 根据 configSchema 验证 config\n        validate(config, ServerChanV3.configSchema)\n        this.uid = this.sendkey.match(/^sctp(\\d+)t/)?.[1]\n        if (!this.uid) {\n            throw new Error('SERVER_CHAN_V3_SENDKEY 不合法！')\n        }\n    }\n\n    /**\n     * 发送消息\n     *\n     * @author CaoMeiYouRen\n     * @date 2024-11-08\n     * @param title 消息的标题\n     * @param [desp=''] 消息的内容，支持 Markdown\n     * @param [option={}] 额外发送选项\n     */\n    async send(title: string, desp: string = '', option: ServerChanV3Option = {}): Promise<SendResponse<ServerChanV3Response>> {\n        Debugger('title: \"%s\", desp: \"%s\", option: %O', title, desp, option)\n        if (Array.isArray(option.tags)) {\n            option.tags = option.tags.join('|')\n        }\n        const data = {\n            text: title,\n            desp,\n            ...option,\n        }\n        return ajax({\n            url: `https://${this.uid}.push.ft07.com/send/${this.sendkey}.send`,\n            method: 'POST',\n            headers: {\n                'Content-Type': 'application/json',\n            },\n            data,\n        })\n    }\n\n}\n","import debug from 'debug'\nimport { Send } from '@/interfaces/send'\nimport { ajax } from '@/utils/ajax'\nimport { SendResponse } from '@/interfaces/response'\nimport { ConfigSchema, OptionSchema } from '@/interfaces/schema'\nimport { validate } from '@/utils/validate'\n\nconst Debugger = debug('push:telegram')\n\nexport interface TelegramConfig {\n    /**\n     * 机器人令牌\n     * 您可以从 https://t.me/BotFather 获取 Token。\n     * @author CaoMeiYouRen\n     * @date 2023-10-22\n     */\n    TELEGRAM_BOT_TOKEN: string\n    /**\n     * 支持对话/群组/频道的 Chat ID\n     * 您可以转发消息到 https://t.me/JsonDumpBot 获取 Chat ID\n     * @author CaoMeiYouRen\n     * @date 2023-10-22\n     */\n    TELEGRAM_CHAT_ID: number\n    /**\n     * 代理地址\n     */\n    PROXY_URL?: string\n}\n\nexport type TelegramConfigSchema = ConfigSchema<TelegramConfig>\nexport const telegramConfigSchema: TelegramConfigSchema = {\n    TELEGRAM_BOT_TOKEN: {\n        type: 'string',\n        title: '机器人令牌',\n        description: '您可以从 https://t.me/BotFather 获取 Token。',\n        required: true,\n    },\n    TELEGRAM_CHAT_ID: {\n        type: 'number',\n        title: '支持对话/群组/频道的 Chat ID',\n        description: '您可以转发消息到 https://t.me/JsonDumpBot 获取 Chat ID',\n        required: true,\n    },\n    PROXY_URL: {\n        type: 'string',\n        title: '代理地址',\n        description: '代理地址',\n        required: false,\n    },\n} as const\n\n/**\n * 参考 https://core.telegram.org/bots/api#sendmessage\n *\n * @author CaoMeiYouRen\n * @date 2024-11-09\n * @export\n * @interface TelegramOption\n */\nexport interface TelegramOption {\n    /**\n     * 静默发送\n     * 静默地发送消息。消息发布后用户会收到无声通知。\n     */\n    disable_notification?: boolean\n    /**\n     * 阻止转发/保存\n     * 如果启用，Telegram 中的机器人消息将受到保护，不会被转发和保存。\n     */\n    protect_content?: boolean\n    /**\n     * 话题 ID\n     * 可选的唯一标识符，用以向该标识符对应的话题发送消息，仅限启用了话题功能的超级群组可用\n     */\n    message_thread_id?: string\n    [key: string]: any\n}\n\nexport type TelegramOptionSchema = OptionSchema<TelegramOption>\n\nexport const telegramOptionSchema: TelegramOptionSchema = {\n    disable_notification: {\n        type: 'boolean',\n        title: '静默发送',\n        description: '静默地发送消息。消息发布后用户会收到无声通知。',\n        required: false,\n    },\n    protect_content: {\n        type: 'boolean',\n        title: '阻止转发/保存',\n        description: '如果启用，Telegram 中的机器人消息将受到保护，不会被转发和保存。',\n        required: false,\n    },\n    message_thread_id: {\n        type: 'string',\n        title: '话题 ID',\n        description: '可选的唯一标识符，用以向该标识符对应的话题发送消息，仅限启用了话题功能的超级群组可用',\n        required: false,\n    },\n} as const\n\ninterface From {\n    id: number\n    is_bot: boolean\n    first_name: string\n    username: string\n}\ninterface Chat {\n    id: number\n    first_name: string\n    last_name: string\n    username: string\n    type: string\n}\ninterface Result {\n    message_id: number\n    from: From\n    chat: Chat\n    date: number\n    text: string\n}\nexport interface TelegramResponse {\n    ok: boolean\n    result: Result\n}\n\n/**\n *  Telegram Bot 推送。\n *  官方文档：https://core.telegram.org/bots/api#making-requests\n *\n * @author CaoMeiYouRen\n * @date 2023-09-16\n * @export\n * @class Telegram\n */\nexport class Telegram implements Send {\n\n    static readonly namespace = 'Telegram'\n    static readonly configSchema = telegramConfigSchema\n    static readonly optionSchema = telegramOptionSchema\n\n    /**\n     * 机器人令牌\n     * 您可以从 https://t.me/BotFather 获取 Token。\n     * @author CaoMeiYouRen\n     * @date 2023-10-22\n     * @private\n     */\n    private TELEGRAM_BOT_TOKEN: string\n    /**\n     * 支持对话/群组/频道的 Chat ID\n     * 您可以转发消息到 https://t.me/JsonDumpBot 获取 Chat ID\n     * @author CaoMeiYouRen\n     * @date 2023-10-22\n     * @private\n     */\n    private TELEGRAM_CHAT_ID: number\n\n    proxyUrl?: string\n\n    constructor(config: TelegramConfig) {\n        Debugger('config: %O', config)\n        Object.assign(this, config)\n        // 根据 configSchema 验证 config\n        validate(config, Telegram.configSchema)\n        if (config.PROXY_URL) {\n            this.proxyUrl = config.PROXY_URL\n        }\n    }\n\n    /**\n     * 发送消息\n     *\n     * @author CaoMeiYouRen\n     * @date 2024-11-09\n     * @param title 消息标题\n     * @param [desp] 消息正文，和 title 相加后不超过 4096 个字符\n     * @param [option] 其他参数\n     */\n    async send(title: string, desp?: string, option?: TelegramOption): Promise<SendResponse<TelegramResponse>> {\n        const url = `https://api.telegram.org/bot${this.TELEGRAM_BOT_TOKEN}/sendMessage`\n        Debugger('title: \"%s\", desp: \"%s\", option: %O', title, desp, option)\n        const text = `${title}${desp ? `\\n${desp}` : ''}`\n        return ajax<TelegramResponse>({\n            url,\n            method: 'POST',\n            proxyUrl: this.proxyUrl,\n            data: {\n                chat_id: this.TELEGRAM_CHAT_ID,\n                text,\n            },\n        })\n    }\n}\n","import debug from 'debug'\nimport { Send } from '@/interfaces/send'\nimport { warn } from '@/utils/helper'\nimport { ajax } from '@/utils/ajax'\nimport { SendResponse } from '@/interfaces/response'\nimport { ConfigSchema, OptionSchema } from '@/interfaces/schema'\nimport { validate } from '@/utils/validate'\n\nconst Debugger = debug('push:wechat-app')\nexport type WechatAppMsgType = 'text' | 'markdown' | 'voice' | 'file' | 'image' | 'voice' | 'video' | 'textcard' | 'news' | 'mpnews' | 'miniprogram_notice' | 'template_card'\nexport interface WechatAppConfig {\n    /**\n     * 企业ID，获取方式参考：[术语说明-corpid](https://work.weixin.qq.com/api/doc/90000/90135/91039#14953/corpid)\n     *\n     */\n    WECHAT_APP_CORPID: string\n    /**\n     * 应用的凭证密钥，获取方式参考：[术语说明-secret](https://work.weixin.qq.com/api/doc/90000/90135/91039#14953/secret)\n     *\n     */\n    WECHAT_APP_SECRET: string\n    /**\n     * 企业应用的id。企业内部开发，可在应用的设置页面查看\n     *\n     */\n    WECHAT_APP_AGENTID: number\n}\n\nexport type WechatAppConfigSchema = ConfigSchema<WechatAppConfig>\n\nexport const wechatAppConfigSchema: WechatAppConfigSchema = {\n    WECHAT_APP_CORPID: {\n        type: 'string',\n        title: '企业ID',\n        description: '企业ID，获取方式参考：[术语说明-corpid](https://work.weixin.qq.com/api/doc/90000/90135/91039#14953/corpid)',\n        required: true,\n        default: '',\n    },\n    WECHAT_APP_SECRET: {\n        type: 'string',\n        title: '应用的凭证密钥',\n        description: '应用的凭证密钥，获取方式参考：[术语说明-secret](https://work.weixin.qq.com/api/doc/90000/90135/91039#14953/secret)',\n        required: true,\n        default: '',\n    },\n    WECHAT_APP_AGENTID: {\n        type: 'number',\n        title: '企业应用的id',\n        description: '企业应用的id。企业内部开发，可在应用的设置页面查看',\n        required: true,\n        default: 0,\n    },\n} as const\n\nexport type WechatAppOption = {\n    // 消息类型\n    msgtype: WechatAppMsgType\n    // 表示是否是保密消息，0表示可对外分享，1表示不能，默认0。\n    safe?: 0 | 1\n    // 表示是否开启id转译，0表示否，1表示是，默认0。\n    enable_id_trans?: 0 | 1\n    // 表示是否开启重复消息检查，0表示否，1表示是，默认0\n    enable_duplicate_check?: 0 | 1\n    // 表示是否重复消息检查的时间间隔，默认1800s，最大不超过4小时\n    duplicate_check_interval?: number\n    [key: string]: any\n    // 指定接收消息的成员，成员ID列表（多个接收者用‘|’分隔，最多支持1000个）。\n    // 特殊情况：指定为\"@all\"，则向该企业应用的全部成员发送\n    touser?: string\n} & ({\n    // 指定接收消息的部门，部门ID列表，多个接收者用‘|’分隔，最多支持100个。\n    // 当touser为\"@all\"时忽略本参数\n    toparty?: string\n} | {\n    // 指定接收消息的标签，标签ID列表，多个接收者用‘|’分隔，最多支持100个。\n    // 当touser为\"@all\"时忽略本参数\n    totag?: string\n})\n\nexport type WechatAppOptionSchema = OptionSchema<WechatAppOption>\nexport const wechatAppOptionSchema: WechatAppOptionSchema = {\n    msgtype: {\n        type: 'select',\n        title: '消息类型',\n        description: '消息类型',\n        required: true,\n        options: [\n            {\n                label: '文本',\n                value: 'text',\n            },\n            {\n                label: 'Markdown',\n                value: 'markdown',\n            },\n            {\n                label: '语音',\n                value: 'voice',\n            },\n            {\n                label: '文件',\n                value: 'file',\n            },\n            {\n                label: '图片',\n                value: 'image',\n            },\n            {\n                label: '视频',\n                value: 'video',\n            },\n            {\n                label: '图文',\n                value: 'news',\n            },\n            {\n                label: '小程序通知',\n                value: 'miniprogram_notice',\n            },\n            {\n                label: '模板卡片',\n                value: 'template_card',\n            },\n        ],\n    },\n    safe: {\n        type: 'select',\n        title: '是否是保密消息',\n        description: '表示是否是保密消息，0表示可对外分享，1表示不能',\n        required: false,\n        options: [\n            {\n                label: '否',\n                value: 0,\n            },\n            {\n                label: '是',\n                value: 1,\n            },\n        ],\n    },\n    enable_id_trans: {\n        type: 'select',\n        title: '是否开启id转译',\n        description: '表示是否开启id转译，0表示否，1表示是，默认0。',\n        required: false,\n        options: [\n            {\n                label: '否',\n                value: 0,\n            },\n            {\n                label: '是',\n                value: 1,\n            },\n        ],\n    },\n    enable_duplicate_check: {\n        type: 'select',\n        title: '是否开启重复消息检查',\n        description: '表示是否开启重复消息检查，0表示否，1表示是，默认',\n        required: false,\n        options: [\n            {\n                label: '否',\n                value: 0,\n            },\n            {\n                label: '是',\n                value: 1,\n            },\n        ],\n    },\n    duplicate_check_interval: {\n        type: 'number',\n        title: '重复消息检查的时间间隔',\n        description: '表示是否重复消息检查的时间间隔，默认1800s，最大不超过4小时',\n        required: false,\n    },\n    touser: {\n        type: 'string',\n        title: '指定接收消息的成员',\n        description: '指定接收消息的成员，成员ID列表（多个接收者用‘|’分隔，最多支持1000个）。',\n        required: false,\n    },\n    toparty: {\n        type: 'string',\n        title: '指定接收消息的部门',\n        description: '指定接收消息的部门，部门ID列表，多个接收者用‘|’分隔，最多支持100个。',\n        required: false,\n    },\n    totag: {\n        type: 'string',\n        title: '指定接收消息的标签',\n        description: '指定接收消息的标签，标签ID列表，多个接收者用‘|’分隔，最多支持100个。',\n        required: false,\n    },\n} as const\n\nexport interface WechatAppResponse {\n    // 企业微信返回的错误码，为0表示成功，非0表示调用失败\n    errcode: number\n    errmsg: string\n    invaliduser?: string\n    invalidparty?: string\n    invalidtag?: string\n    unlicenseduser?: string\n    msgid: string\n    response_code?: string\n}\n/**\n * 企业微信应用推送，文档：https://developer.work.weixin.qq.com/document/path/90664\n *\n * @author CaoMeiYouRen\n * @date 2021-02-28\n * @export\n * @class WechatApp\n */\nexport class WechatApp implements Send {\n\n    static readonly namespace = '企业微信应用'\n    static readonly configSchema = wechatAppConfigSchema\n    static readonly optionSchema = wechatAppOptionSchema\n\n    private ACCESS_TOKEN: string\n\n    private WECHAT_APP_CORPID: string\n    private WECHAT_APP_SECRET: string\n    private WECHAT_APP_AGENTID: number\n\n    /**\n     * ACCESS_TOKEN 的过期时间(时间戳)\n     *\n     * @private\n     */\n    private expiresTime: number\n\n    constructor(config: WechatAppConfig) {\n        Debugger('config: %O', config)\n        Object.assign(this, config)\n        // 根据 configSchema 验证 config\n        validate(config, WechatApp.configSchema)\n    }\n\n    private async getAccessToken(): Promise<string> {\n        const { data } = await ajax({\n            url: 'https://qyapi.weixin.qq.com/cgi-bin/gettoken',\n            query: {\n                corpid: this.WECHAT_APP_CORPID,\n                corpsecret: this.WECHAT_APP_SECRET,\n            },\n        })\n        if (data?.errcode !== 0) { // 出错返回码，为0表示成功，非0表示调用失败\n            throw new Error(data?.errmsg || '获取 access_token 失败！')\n        }\n        const { access_token, expires_in = 7200 } = data\n        Debugger('获取 access_token 成功: %s', access_token)\n        this.extendexpiresTime(expires_in)\n        return access_token\n    }\n    /**\n     * 延长过期时间\n     *\n     * @author CaoMeiYouRen\n     * @date 2021-03-03\n     * @private\n     * @param expiresIn 延长的秒数\n     */\n    private extendexpiresTime(expiresIn: number): void {\n        this.expiresTime = Date.now() + expiresIn * 1000 // 设置过期时间\n    }\n\n    /**\n     * 发送消息\n     *\n     * @author CaoMeiYouRen\n     * @date 2024-11-08\n     * @param title 消息标题\n     * @param [desp] 消息内容，最长不超过2048个字节，超过将截断（支持id转译）\n     * @param [option] 额外推送选项\n     */\n    async send(title: string, desp?: string, option?: WechatAppOption): Promise<SendResponse<WechatAppResponse>> {\n        Debugger('title: \"%s\", desp: \"%s\", option: %O', title, desp, option)\n        if (!this.ACCESS_TOKEN || Date.now() >= this.expiresTime) {\n            this.ACCESS_TOKEN = await this.getAccessToken()\n        }\n        const { msgtype = 'text', touser: _touser, ...args } = option || {}\n        if (!_touser) {\n            warn('未指定 touser，将使用 \"@all\" 向全体成员推送')\n        }\n        const sep = msgtype === 'markdown' ? '\\n\\n' : '\\n'\n        const content = `${title}${desp ? `${sep}${desp}` : ''}`\n        const touser = _touser || '@all' // 如果没有指定 touser，则使用全体成员\n        return ajax({\n            url: 'https://qyapi.weixin.qq.com/cgi-bin/message/send',\n            method: 'POST',\n            headers: {\n                'Content-Type': 'application/json',\n            },\n            query: {\n                access_token: this.ACCESS_TOKEN,\n            },\n            data: {\n                touser,\n                msgtype,\n                agentid: this.WECHAT_APP_AGENTID,\n                [msgtype]: {\n                    content,\n                },\n                ...args,\n            },\n        })\n    }\n}\n","import debug from 'debug'\nimport { Send } from '@/interfaces/send'\nimport { ajax } from '@/utils/ajax'\nimport { SendResponse } from '@/interfaces/response'\nimport { ConfigSchema, OptionSchema } from '@/interfaces/schema'\nimport { validate } from '@/utils/validate'\n\nconst Debugger = debug('push:wechat-robot')\n\nexport type WechatRobotMsgType = 'text' | 'markdown' | 'image' | 'news' | 'file' | 'voice' | 'template_card'\n\nexport interface WechatRobotConfig {\n    // 企业微信机器人的key\n    WECHAT_ROBOT_KEY: string\n}\nexport type WechatRobotConfigSchema = ConfigSchema<WechatRobotConfig>\nexport const wechatRobotConfigSchema: WechatRobotConfigSchema = {\n    WECHAT_ROBOT_KEY: {\n        type: 'string',\n        title: '企业微信机器人的key',\n        description: '企业微信机器人的key',\n        required: true,\n    },\n} as const\n\nexport interface WechatRobotOption {\n    msgtype?: WechatRobotMsgType\n    [key: string]: any\n}\nexport type WechatRobotOptionSchema = OptionSchema<WechatRobotOption>\nexport const wechatRobotOptionSchema: WechatRobotOptionSchema = {\n    msgtype: {\n        type: 'select',\n        title: '消息类型',\n        description: '消息类型',\n        options: [\n            {\n                label: '文本',\n                value: 'text',\n            },\n            {\n                label: 'Markdown',\n                value: 'markdown',\n            },\n            {\n                label: '图片',\n                value: 'image',\n            },\n            {\n                label: '图文',\n                value: 'news',\n            },\n            {\n                label: '文件',\n                value: 'file',\n            },\n            {\n                label: '语音',\n                value: 'voice',\n            },\n            {\n                label: '模板卡片',\n                value: 'template_card',\n            },\n        ],\n        required: false,\n        default: 'text',\n    },\n} as const\n\nexport interface WechatRobotResponse {\n    // 企业微信机器人返回的错误码，为0表示成功，非0表示调用失败\n    errcode: number\n    errmsg: string\n}\n\n/**\n * 企业微信群机器人。文档: [如何使用群机器人](https://developer.work.weixin.qq.com/document/path/91770)\n *\n * @author CaoMeiYouRen\n * @date 2021-02-28\n * @export\n * @class WechatRobot\n */\nexport class WechatRobot implements Send {\n\n    static readonly namespace = '企业微信群机器人'\n    static readonly configSchema = wechatRobotConfigSchema\n    static readonly optionSchema = wechatRobotOptionSchema\n\n    private WECHAT_ROBOT_KEY: string\n\n    constructor(config: WechatRobotConfig) {\n        const { WECHAT_ROBOT_KEY } = config\n        this.WECHAT_ROBOT_KEY = WECHAT_ROBOT_KEY\n        Debugger('set WECHAT_ROBOT_KEY: \"%s\"', WECHAT_ROBOT_KEY)\n        // 根据 configSchema 验证 config\n        validate(config, WechatRobot.configSchema)\n    }\n\n    /**\n     *\n     *\n     * @author CaoMeiYouRen\n     * @date 2024-11-08\n     * @param title 消息标题\n     * @param [desp] 消息内容。text内容，最长不超过2048个字节；markdown内容，最长不超过4096个字节；必须是utf8编码\n     * @param [option] 额外推送选项\n     */\n    async send(title: string, desp?: string, option?: WechatRobotOption): Promise<SendResponse<WechatRobotResponse>> {\n        Debugger('title: \"%s\", desp: \"%s\", option: %O', title, desp, option)\n        const { msgtype = 'text', ...args } = option || {}\n        const sep = msgtype === 'markdown' ? '\\n\\n' : '\\n'\n        const content = `${title}${desp ? `${sep}${desp}` : ''}`\n        return ajax({\n            url: 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send',\n            headers: {\n                'Content-Type': 'application/json',\n            },\n            method: 'POST',\n            query: { key: this.WECHAT_ROBOT_KEY },\n            data: {\n                msgtype,\n                [msgtype]: { content },\n                ...args,\n            },\n        })\n    }\n}\n","import debug from 'debug'\nimport { Send } from '@/interfaces/send'\nimport { ajax } from '@/utils/ajax'\nimport { SendResponse } from '@/interfaces/response'\nimport { ConfigSchema, OptionSchema } from '@/interfaces/schema'\nimport { validate } from '@/utils/validate'\n\nconst Debugger = debug('push:xi-zhi')\n\nexport interface XiZhiConfig {\n    // 息知的 key，前往 https://xz.qqoq.net/#/index 获取\n    XI_ZHI_KEY: string\n}\n\nexport type XiZhiConfigSchema = ConfigSchema<XiZhiConfig>\nexport const xiZhiConfigSchema: XiZhiConfigSchema = {\n    XI_ZHI_KEY: {\n        type: 'string',\n        title: '息知的 key',\n        description: '前往 https://xz.qqoq.net/#/index 获取',\n        required: true,\n    },\n} as const\n\nexport interface XiZhiOption {\n}\n\nexport type XiZhiOptionSchema = OptionSchema<XiZhiOption>\nexport const xiZhiOptionSchema: XiZhiOptionSchema = {\n} as const\n\nexport interface XiZhiResponse {\n    // 状态码，200 表示成功\n    code: number\n    msg: string\n}\n\n/**\n * 息知 推送，官方文档：https://xz.qqoq.net/#/index\n *\n * @author CaoMeiYouRen\n * @date 2022-02-18\n * @export\n * @class XiZhi\n */\nexport class XiZhi implements Send {\n\n    static readonly namespace = '息知'\n    static readonly configSchema = xiZhiConfigSchema\n    static readonly optionSchema = xiZhiOptionSchema\n\n    private XI_ZHI_KEY: string\n\n    constructor(config: XiZhiConfig) {\n        const { XI_ZHI_KEY } = config\n        this.XI_ZHI_KEY = XI_ZHI_KEY\n        Debugger('set XI_ZHI_KEY: \"%s\"', XI_ZHI_KEY)\n        // 根据 configSchema 验证 config\n        validate(config, XiZhi.configSchema)\n    }\n\n    async send(title: string, desp?: string, option?: XiZhiOption): Promise<SendResponse<XiZhiResponse>> {\n        Debugger('title: \"%s\", desp: \"%s\"', title, desp)\n        return ajax({\n            url: `https://xizhi.qqoq.net/${this.XI_ZHI_KEY}.send`,\n            method: 'POST',\n            headers: {\n                'Content-Type': 'application/json',\n            },\n            data: {\n                title,\n                content: desp,\n            },\n        })\n    }\n}\n","import debug from 'debug'\nimport { Send } from '@/interfaces/send'\nimport { ajax } from '@/utils/ajax'\nimport { SendResponse } from '@/interfaces/response'\nimport { ConfigSchema, OptionSchema } from '@/interfaces/schema'\nimport { validate } from '@/utils/validate'\nimport { uniq } from '@/utils/helper'\n\nconst Debugger = debug('push:wx-pusher')\n\nexport interface WxPusherConfig {\n    /**\n     * WxPusher 的 appToken。在 https://wxpusher.zjiecode.com/admin/main/app/appToken 申请\n     */\n    WX_PUSHER_APP_TOKEN: string\n    /**\n     * WxPusher 的 uid。在 https://wxpusher.zjiecode.com/admin/main/wxuser/list 查看\n     */\n    WX_PUSHER_UID: string\n}\n\nexport type WxPusherConfigSchema = ConfigSchema<WxPusherConfig>\n\nexport const wxPusherConfigSchema: WxPusherConfigSchema = {\n    WX_PUSHER_APP_TOKEN: {\n        type: 'string',\n        title: 'appToken',\n        description: '在 https://wxpusher.zjiecode.com/admin/main/app/appToken 申请',\n        required: true,\n    },\n    WX_PUSHER_UID: {\n        type: 'string',\n        title: 'uid',\n        description: '在 https://wxpusher.zjiecode.com/admin/main/wxuser/list 查看',\n        required: true,\n    },\n} as const\n\nexport interface WxPusherOption {\n    /**\n     * 消息摘要，显示在微信聊天页面或者模版消息卡片上，限制长度20，可以不传，不传默认截取content前面的内容。\n     */\n    summary?: string\n    /**\n     * 内容类型 1表示文字  2表示html(只发送body标签内部的数据即可，不包括body标签) 3表示markdown\n     * @default 1\n     */\n    contentType?: 1 | 2 | 3\n    /**\n     * 是否保存发送内容，1保存，0不保存\n     * @default 0\n     */\n    save?: 0 | 1\n    /**\n     * 主题ID，可以根据主题ID发送消息，可以在主题管理中查看主题ID\n     */\n    topicIds?: number[]\n    /**\n     * 发送目标的UID，是一个数组。注意uids和topicIds可以同时填写，也可以只填写一个。\n     */\n    uids?: string[]\n    /**\n     * 发送url，可以不传，如果传了，则根据url弹出通知\n     */\n    url?: string\n    /**\n     * 验证负载，仅针对text消息类型有效\n     */\n    verifyPayload?: string\n}\n\nexport type WxPusherOptionSchema = OptionSchema<WxPusherOption>\n\nexport const wxPusherOptionSchema: WxPusherOptionSchema = {\n    summary: {\n        type: 'string',\n        title: '消息摘要',\n        description: '显示在微信聊天页面或者模版消息卡片上，限制长度20，可以不传，不传默认截取content前面的内容。',\n        required: false,\n    },\n    contentType: {\n        type: 'select',\n        title: '内容类型',\n        description: '内容类型',\n        required: false,\n        default: 1,\n        options: [\n            {\n                label: '文本',\n                value: 1,\n            },\n            {\n                label: 'HTML',\n                value: 2,\n            },\n            {\n                label: 'Markdown',\n                value: 3,\n            },\n        ],\n    },\n    save: {\n        type: 'select',\n        title: '是否保存发送内容',\n        description: '是否保存发送内容，1保存，0不保存，默认0',\n        required: false,\n        default: 0,\n        options: [\n            {\n                label: '不保存',\n                value: 0,\n            },\n            {\n                label: '保存',\n                value: 1,\n            },\n        ],\n    },\n    topicIds: {\n        type: 'array',\n        title: '主题ID',\n        description: '主题ID，可以根据主题ID发送消息，可以在主题管理中查看主题ID',\n        required: false,\n    },\n    uids: {\n        type: 'array',\n        title: '用户ID',\n        description: '发送目标的UID，是一个数组。注意uids和topicIds可以同时填写，也可以只填写一个。',\n        required: false,\n    },\n    url: {\n        type: 'string',\n        title: '发送url',\n        description: '发送url，可以不传，如果传了，则根据url弹出通知',\n        required: false,\n    },\n    verifyPayload: {\n        type: 'string',\n        title: '验证负载',\n        description: '仅针对text消息类型有效',\n        required: false,\n    },\n} as const\n\nexport interface WxPusherResponse {\n    /**\n     * 请求是否成功\n     */\n    success: boolean\n    /**\n     * 请求返回码\n     */\n    code: number\n    /**\n     * 请求返回消息\n     */\n    msg: string\n    /**\n     * 请求返回数据\n     */\n    data: {\n        /**\n         * 消息ID\n         */\n        messageId: number\n        /**\n         * 消息编码\n         */\n        code: string\n    }\n}\n\n/**\n * WxPusher 推送。官方文档：https://wxpusher.zjiecode.com/docs\n *\n * @author CaoMeiYouRen\n * @date 2024-11-09\n * @export\n * @class WxPusher\n */\nexport class WxPusher implements Send {\n    static readonly namespace = 'WxPusher'\n    static readonly configSchema = wxPusherConfigSchema\n    static readonly optionSchema = wxPusherOptionSchema\n\n    private WX_PUSHER_APP_TOKEN: string\n    private WX_PUSHER_UID: string\n\n    constructor(config: WxPusherConfig) {\n        const { WX_PUSHER_APP_TOKEN, WX_PUSHER_UID } = config\n        this.WX_PUSHER_APP_TOKEN = WX_PUSHER_APP_TOKEN\n        this.WX_PUSHER_UID = WX_PUSHER_UID\n        Debugger('set WX_PUSHER_APP_TOKEN: \"%s\", WX_PUSHER_UID: \"%s\"', WX_PUSHER_APP_TOKEN, WX_PUSHER_UID)\n        // 根据 configSchema 验证 config\n        validate(config, WxPusher.configSchema)\n    }\n\n    async send(title: string, desp?: string, option?: WxPusherOption): Promise<SendResponse<WxPusherResponse>> {\n        Debugger('title: \"%s\", desp: \"%s\", option: %O', title, desp, option)\n        const { contentType = 1, ...args } = option || {}\n        const uids = uniq([...option.uids || [], this.WX_PUSHER_UID])\n        const content = `${title}${desp ? `\\n${desp}` : ''}`\n        return ajax({\n            url: 'https://wxpusher.zjiecode.com/api/send/message',\n            method: 'POST',\n            headers: {\n                'Content-Type': 'application/json',\n            },\n            data: {\n                ...args,\n                appToken: this.WX_PUSHER_APP_TOKEN,\n                content,\n                contentType,\n                uids,\n            },\n        })\n    }\n}\n","import { CustomEmail, Dingtalk, Discord, Feishu, IGot, Ntfy, OneBot, PushDeer, PushPlus, Qmsg, ServerChanTurbo, ServerChanV3, Telegram, WechatApp, WechatRobot, XiZhi, WxPusher } from './index'\nimport { SendResponse } from '@/interfaces/response'\n\nexport const PushAllInOne = {\n    CustomEmail,\n    Dingtalk,\n    Discord,\n    Feishu,\n    IGot,\n    Ntfy,\n    OneBot,\n    PushDeer,\n    PushPlus,\n    Qmsg,\n    ServerChanTurbo,\n    ServerChanV3,\n    Telegram,\n    WechatApp,\n    WechatRobot,\n    WxPusher,\n    XiZhi,\n} as const\n\nexport type IPushAllInOne = typeof PushAllInOne\n\nexport type PushType = keyof IPushAllInOne\n\nexport type MetaPushConfig<T extends PushType = PushType> = {\n    type: T\n    config: ConstructorParameters<IPushAllInOne[T]>[0]\n    option: Parameters<IPushAllInOne[T]['prototype']['send']>[2]\n}\n\n/**\n * 从传入变量中读取配置，并选择一个渠道推送\n *\n * @author CaoMeiYouRen\n * @date 2024-11-09\n * @export\n * @template T\n * @param title 推送标题\n * @param desp 推送内容\n * @param pushConfig 推送配置\n */\nexport async function runPushAllInOne<T extends PushType>(title: string, desp: string, pushConfig: MetaPushConfig<T>): Promise<SendResponse<any>> {\n    const { type, config, option } = pushConfig\n    if (PushAllInOne[type]) {\n        const push = new PushAllInOne[type](config as any)\n        return push.send(title, desp, option as any)\n    }\n    throw new Error('未匹配到任何推送方式！')\n}\n"],"mappings":"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","names":["debug","debug","Debugger","debug","error","Debugger","debug","debug","Debugger","debug","debug","Debugger","debug","debug","Debugger","debug","debug","Debugger","debug","debug","Debugger","debug","debug","Debugger","debug","debug","Debugger","debug","debug","Debugger","debug","debug","Debugger","debug","debug","Debugger","debug","debug","Debugger","debug","debug","Debugger","debug","debug","Debugger","debug","debug","Debugger","debug","debug","Debugger","debug"]}