var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.ts var src_exports = {}; __export(src_exports, { CustomEmail: () => CustomEmail, Dingtalk: () => Dingtalk, Discord: () => Discord, IGot: () => IGot, OneBot: () => OneBot, PushAllInOne: () => PushAllInOne, PushDeer: () => PushDeer, PushPlus: () => PushPlus, Qmsg: () => Qmsg, ServerChanTurbo: () => ServerChanTurbo, ServerChanV3: () => ServerChanV3, Telegram: () => Telegram, WechatApp: () => WechatApp, WechatRobot: () => WechatRobot, XiZhi: () => XiZhi, customEmailConfigSchema: () => customEmailConfigSchema, customEmailOptionSchema: () => customEmailOptionSchema, dingtalkConfigSchema: () => dingtalkConfigSchema, dingtalkOptionSchema: () => dingtalkOptionSchema, discordConfigSchema: () => discordConfigSchema, discordOptionSchema: () => discordOptionSchema, iGotConfigSchema: () => iGotConfigSchema, iGotOptionSchema: () => iGotOptionSchema, oneBotConfigSchema: () => oneBotConfigSchema, oneBotOptionSchema: () => oneBotOptionSchema, pushDeerConfigSchema: () => pushDeerConfigSchema, pushDeerOptionSchema: () => pushDeerOptionSchema, pushPlusConfigSchema: () => pushPlusConfigSchema, pushPlusOptionSchema: () => pushPlusOptionSchema, qmsgConfigSchema: () => qmsgConfigSchema, qmsgOptionSchema: () => qmsgOptionSchema, runPushAllInOne: () => runPushAllInOne, serverChanTurboConfigSchema: () => serverChanTurboConfigSchema, serverChanTurboOptionSchema: () => serverChanTurboOptionSchema, serverChanV3ConfigSchema: () => serverChanV3ConfigSchema, serverChanV3OptionSchema: () => serverChanV3OptionSchema, telegramConfigSchema: () => telegramConfigSchema, telegramOptionSchema: () => telegramOptionSchema, wechatAppConfigSchema: () => wechatAppConfigSchema, wechatAppOptionSchema: () => wechatAppOptionSchema, wechatRobotConfigSchema: () => wechatRobotConfigSchema, wechatRobotOptionSchema: () => wechatRobotOptionSchema, xiZhiConfigSchema: () => xiZhiConfigSchema, xiZhiOptionSchema: () => xiZhiOptionSchema }); module.exports = __toCommonJS(src_exports); // src/push/custom-email.ts var import_debug = __toESM(require("debug"), 1); var import_nodemailer = __toESM(require("nodemailer"), 1); // src/utils/helper.ts var colors; if (globalThis.process && typeof globalThis.process.on === "function") { import("@colors/colors").then((value) => { colors = value.default; }).catch(console.error); } function warn(text) { if (colors) { text = colors.yellow(text); } console.warn(text); } function error(text) { if (colors) { text = colors.red(text); } console.error(text); } var logger = { warn, error }; var isHttpURL = (url) => /^(https?:\/\/)/.test(url); var isSocksUrl = (url) => /^(socks5?:\/\/)/.test(url); function isEmpty(value) { return value === null || value === void 0 || value === ""; } // src/utils/validate.ts function validate(config, schema) { Object.keys(schema).forEach((key) => { const item = schema[key]; const value = config[key]; if (!item.required && isEmpty(value)) { return; } if (item.required && isEmpty(value)) { throw new Error(`"${key}" 字段是必须的!`); } if (item.type === "select") { const { options } = item; if (!options.map((e) => e.value).includes(value)) { throw new Error(`"${key}" 字段必须是以下选项之一:${options.map((e) => e.value).join(",")}`); } return; } if (item.type === "string") { if (typeof value !== "string") { throw new Error(`"${key}" 字段必须是字符串!`); } return; } if (item.type === "number") { if (typeof value !== "number") { throw new Error(`"${key}" 字段必须是数字!`); } return; } if (item.type === "boolean") { if (typeof value !== "boolean") { throw new Error(`"${key}" 字段必须是布尔值!`); } return; } if (item.type === "array") { if (!Array.isArray(value)) { throw new Error(`"${key}" 字段必须是数组!`); } return; } if (item.type === "object") { if (typeof value !== "object") { throw new Error(`"${key}" 字段必须是对象!`); } return; } throw new Error(`"${key}" 字段类型不支持!`); }); } // src/push/custom-email.ts var Debugger = (0, import_debug.default)("push:custom-email"); var customEmailConfigSchema = { EMAIL_TYPE: { type: "select", title: "邮件类型", description: "邮件类型", required: true, default: "text", options: [ { label: "文本", value: "text" }, { label: "HTML", value: "html" } ] }, EMAIL_TO_ADDRESS: { type: "string", title: "收件邮箱", description: "收件邮箱", required: true, default: "" }, EMAIL_AUTH_USER: { type: "string", title: "发件邮箱", description: "发件邮箱", required: true, default: "" }, EMAIL_AUTH_PASS: { type: "string", title: "发件授权码(或密码)", description: "发件授权码(或密码)", required: true, default: "" }, EMAIL_HOST: { type: "string", title: "发件域名", description: "发件域名", required: true, default: "" }, EMAIL_PORT: { type: "number", title: "发件端口", description: "发件端口", required: true, default: 465 } }; var customEmailOptionSchema = { to: { type: "string", title: "收件邮箱", description: "收件邮箱", required: false, default: "" }, from: { type: "string", title: "发件邮箱", description: "发件邮箱", required: false, default: "" }, subject: { type: "string", title: "邮件主题", description: "邮件主题", required: false, default: "" }, text: { type: "string", title: "邮件内容", description: "邮件内容", required: false, default: "" }, html: { type: "string", title: "邮件内容", description: "邮件内容", required: false, default: "" } }; var _CustomEmail = class _CustomEmail { constructor(config) { this.config = config; Debugger("CustomEmailConfig: %o", config); validate(config, _CustomEmail.configSchema); const { EMAIL_AUTH_USER, EMAIL_AUTH_PASS, EMAIL_HOST, EMAIL_PORT } = this.config; this.transporter = import_nodemailer.default.createTransport({ host: EMAIL_HOST, port: Number(EMAIL_PORT), auth: { user: EMAIL_AUTH_USER, pass: EMAIL_AUTH_PASS } }); } /** * 释放资源(需要支持 Symbol.dispose) * * @author CaoMeiYouRen * @date 2024-11-08 */ [Symbol.dispose]() { if (this.transporter) { this.transporter.close(); } } /** * * @author CaoMeiYouRen * @date 2024-11-08 * @param title 消息的标题 * @param [desp] 消息的内容,支持 html * @param [option] 额外选项 */ async send(title, desp, option) { var _a; Debugger('title: "%s", desp: "%s", option: %o', title, desp, option); const { EMAIL_TYPE, EMAIL_TO_ADDRESS, EMAIL_AUTH_USER } = this.config; if (!await this.transporter.verify()) { throw new Error("自定义邮件的发件配置无效"); } const { to: _to, ...args } = option || {}; const from = EMAIL_AUTH_USER; const to = _to || EMAIL_TO_ADDRESS; const type = EMAIL_TYPE; const response = await this.transporter.sendMail({ from, to, subject: title, [type]: desp, ...args }); if (typeof Symbol.dispose === "undefined") { this.transporter.close(); } Debugger("CustomEmail Response: %o", response); if ((_a = response.response) == null ? void 0 : _a.includes("250 OK")) { return { status: 200, statusText: "OK", data: response, headers: {} }; } return { status: 500, statusText: "Internal Server Error", data: response, headers: {} }; } }; // 命名空间 _CustomEmail.namespace = "自定义邮件"; _CustomEmail.configSchema = customEmailConfigSchema; _CustomEmail.optionSchema = customEmailOptionSchema; var CustomEmail = _CustomEmail; // src/push/dingtalk.ts var import_debug3 = __toESM(require("debug"), 1); // src/utils/ajax.ts var import_axios = __toESM(require("axios"), 1); var import_debug2 = __toESM(require("debug"), 1); var import_https_proxy_agent = require("https-proxy-agent"); var import_socks_proxy_agent = require("socks-proxy-agent"); var Debugger2 = (0, import_debug2.default)("push:ajax"); async function ajax(config) { try { Debugger2("ajax config: %O", config); const { url, query = {}, method = "GET", baseURL = "", proxyUrl } = config; const headers = config.headers || {}; let { data = {} } = config; if (headers["Content-Type"] === "application/x-www-form-urlencoded" && typeof data === "object") { data = new URLSearchParams(data).toString(); } let httpAgent = null; Debugger2("NO_PROXY: %s", process.env.NO_PROXY); if (process.env.NO_PROXY !== "true") { Debugger2("HTTP_PROXY: %s", process.env.HTTP_PROXY); Debugger2("HTTPS_PROXY: %s", process.env.HTTPS_PROXY); Debugger2("SOCKS_PROXY: %s", process.env.SOCKS_PROXY); if (isHttpURL(proxyUrl)) { httpAgent = new import_https_proxy_agent.HttpsProxyAgent(proxyUrl); } else if (isSocksUrl(proxyUrl)) { httpAgent = new import_socks_proxy_agent.SocksProxyAgent(proxyUrl); } else if (process.env.HTTPS_PROXY) { httpAgent = new import_https_proxy_agent.HttpsProxyAgent(process.env.HTTPS_PROXY); } else if (process.env.HTTP_PROXY) { httpAgent = new import_https_proxy_agent.HttpsProxyAgent(process.env.HTTP_PROXY); } else if (process.env.SOCKS_PROXY) { httpAgent = new import_socks_proxy_agent.SocksProxyAgent(process.env.SOCKS_PROXY); } } const response = await (0, import_axios.default)(url, { baseURL, method, headers, params: query, data, timeout: 6e4, httpAgent, httpsAgent: httpAgent, proxy: false }); Debugger2("response data: %O", response.data); return response; } catch (error2) { if (error2 == null ? void 0 : error2.response) { logger.error(error2.response); return error2.response; } throw error2; } } // src/utils/crypto.ts var import_crypto = __toESM(require("crypto"), 1); function generateSignature(timestamp, suiteTicket, suiteSecret) { const stringToSign = `${timestamp} ${suiteTicket}`; const hmac = import_crypto.default.createHmac("sha256", suiteSecret); hmac.update(stringToSign, "utf8"); const signature = hmac.digest("base64"); return signature; } // src/push/dingtalk.ts var Debugger3 = (0, import_debug3.default)("push:dingtalk"); var dingtalkConfigSchema = { DINGTALK_ACCESS_TOKEN: { type: "string", title: "钉钉机器人 access_token", description: "钉钉机器人 access_token", required: true, default: "" }, DINGTALK_SECRET: { type: "string", title: "加签安全秘钥(HmacSHA256)", required: false, default: "" } }; var dingtalkOptionSchema = { msgtype: { type: "select", title: "消息类型", description: "消息类型", required: false, default: "text", options: [ { label: "文本", value: "text" }, { label: "Markdown", value: "markdown" }, { label: "链接", value: "link" }, { label: "按钮", value: "actionCard" }, { label: "FeedCard", value: "feedCard" } ] }, text: { type: "object", title: "文本", description: "文本", required: false, default: {} }, markdown: { type: "object", title: "Markdown", description: "Markdown", required: false, default: {} }, link: { type: "object", title: "链接", description: "链接", required: false, default: {} }, actionCard: { type: "object", title: "动作卡片", description: "动作卡片", required: false, default: {} }, feedCard: { type: "object", title: "订阅卡片", description: "订阅卡片", required: false, default: {} } }; var _Dingtalk = class _Dingtalk { /** * 参考文档 [钉钉开放平台 - 自定义机器人接入](https://developers.dingtalk.com/document/app/custom-robot-access) * @author CaoMeiYouRen * @date 2024-11-08 * @param config */ constructor(config) { this.webhook = "https://oapi.dingtalk.com/robot/send"; const { DINGTALK_ACCESS_TOKEN, DINGTALK_SECRET } = config; this.ACCESS_TOKEN = DINGTALK_ACCESS_TOKEN; this.SECRET = DINGTALK_SECRET; Debugger3("DINGTALK_ACCESS_TOKEN: %s , DINGTALK_SECRET: %s", this.ACCESS_TOKEN, this.SECRET); validate(config, _Dingtalk.configSchema); if (!this.SECRET) { warn("未提供 DINGTALK_SECRET !"); } } getSign(timeStamp) { let signStr = ""; if (this.SECRET) { signStr = generateSignature(timeStamp, this.SECRET, this.SECRET); Debugger3("Sign string is %s, result is %s", `${timeStamp} ${this.SECRET}`, signStr); } return signStr; } async push(data) { const timestamp = Date.now(); const sign = this.getSign(timestamp); const result = await ajax({ url: this.webhook, method: "POST", headers: { "Content-Type": "application/json" }, query: { timestamp, sign, access_token: this.ACCESS_TOKEN }, data }); Debugger3("Result is %s, %s。", result.data.errcode, result.data.errmsg); if (result.data.errcode === 31e4) { console.error("Send Failed:", result.data); Debugger3("Please check safe config : %O", result.data); } return result; } /** * * * @author CaoMeiYouRen * @date 2024-11-08 * @param title 消息的标题 * @param [desp] 消息的内容,支持 Markdown * @returns */ async send(title, desp, option) { var _a, _b, _c, _d, _e, _f, _g; Debugger3('title: "%s", desp: "%s", option: %O', title, desp, option); switch (option.msgtype) { case "text": return this.push({ msgtype: "text", text: { content: `${title}${desp ? ` ${desp}` : ""}` }, ...option }); case "markdown": return this.push({ msgtype: "markdown", markdown: { title, text: `# ${title}${desp ? ` ${desp}` : ""}` }, ...option }); case "link": return this.push({ msgtype: "link", link: { title, text: desp || "", picUrl: ((_a = option == null ? void 0 : option.link) == null ? void 0 : _a.picUrl) || "", messageUrl: ((_b = option.link) == null ? void 0 : _b.messageUrl) || "" }, ...option }); case "actionCard": return this.push({ msgtype: "actionCard", actionCard: { title, text: desp || "", btnOrientation: ((_c = option == null ? void 0 : option.actionCard) == null ? void 0 : _c.btnOrientation) || "0", btns: (_d = option == null ? void 0 : option.actionCard) == null ? void 0 : _d.btns, singleTitle: (_e = option == null ? void 0 : option.actionCard) == null ? void 0 : _e.singleTitle, singleURL: (_f = option == null ? void 0 : option.actionCard) == null ? void 0 : _f.singleURL }, ...option }); case "feedCard": return this.push({ msgtype: "feedCard", feedCard: { links: ((_g = option == null ? void 0 : option.feedCard) == null ? void 0 : _g.links) || [] }, ...option }); default: throw new Error("msgtype is required!"); } } }; _Dingtalk.namespace = "钉钉"; _Dingtalk.configSchema = dingtalkConfigSchema; _Dingtalk.optionSchema = dingtalkOptionSchema; var Dingtalk = _Dingtalk; // src/push/discord.ts var import_debug4 = __toESM(require("debug"), 1); var Debugger4 = (0, import_debug4.default)("push:discord"); var discordConfigSchema = { DISCORD_WEBHOOK: { type: "string", title: "Webhook Url", description: "Webhook Url 可在服务器设置 -> 整合 -> Webhook -> 创建 Webhook 中获取", required: true }, PROXY_URL: { type: "string", title: "代理地址", description: "代理地址", required: false } }; var discordOptionSchema = { username: { type: "string", title: "机器人显示的名称", description: "机器人显示的名称", required: false }, avatar_url: { type: "string", title: "机器人头像的 Url", description: "机器人头像的 Url", required: false } }; var _Discord = class _Discord { /** * 创建 Discord 实例 * @author CaoMeiYouRen * @date 2024-11-08 * @param config 配置 */ constructor(config) { const { DISCORD_WEBHOOK, PROXY_URL } = config; Debugger4("DISCORD_WEBHOOK: %s, PROXY_URL: %s", DISCORD_WEBHOOK, PROXY_URL); this.DISCORD_WEBHOOK = DISCORD_WEBHOOK; if (PROXY_URL) { this.proxyUrl = PROXY_URL; } validate(config, _Discord.configSchema); } /** * 发送消息 * * @author CaoMeiYouRen * @date 2024-11-08 * @param title 消息的标题 * @param [desp] 消息的描述。最多 2000 个字符 * @param [option] 额外选项 */ async send(title, desp, option) { Debugger4('title: "%s", desp: "%s", option: %o', title, desp, option); const { username, avatar_url, ...args } = option || {}; const proxyUrl = this.proxyUrl; const content = `${title}${desp ? ` ${desp}` : ""}`; return ajax({ url: this.DISCORD_WEBHOOK, method: "POST", proxyUrl, data: { username, content, avatar_url, ...args } }); } }; _Discord.namespace = "Discord"; _Discord.configSchema = discordConfigSchema; _Discord.optionSchema = discordOptionSchema; var Discord = _Discord; // src/push/i-got.ts var import_debug5 = __toESM(require("debug"), 1); var Debugger5 = (0, import_debug5.default)("push:i-got"); var iGotConfigSchema = { I_GOT_KEY: { type: "string", title: "iGot 推送key", description: "iGot 推送key", required: true, default: "" } }; var iGotOptionSchema = { url: { type: "string", title: "链接", description: "链接; 点开消息后会主动跳转至此地址", required: false, default: "" }, automaticallyCopy: { type: "number", title: "是否自动复制", description: "是否自动复制; 为1自动复制", required: false, default: 0 }, urgent: { type: "number", title: "紧急消息", description: "紧急消息,为1表示紧急。此消息将置顶在小程序内, 同时会在推送的消息内做一定的特殊标识", required: false, default: 0 }, copy: { type: "string", title: "需要自动复制的文本内容", description: "需要自动复制的文本内容", required: false, default: "" }, topic: { type: "string", title: "主题", description: "主题; 订阅链接下有效;对推送内容分类,用户可选择性订阅", required: false, default: "" } }; var _IGot = class _IGot { /** * @author CaoMeiYouRen * @date 2024-11-08 * @param config 微信搜索小程序“iGot”获取推送key */ constructor(config) { const { I_GOT_KEY } = config; this.I_GOT_KEY = I_GOT_KEY; Debugger5('set I_GOT_KEY: "%s"', I_GOT_KEY); validate(config, _IGot.configSchema); } /** * * * @author CaoMeiYouRen * @date 2024-11-08 * @param title 消息标题 * @param [desp] 消息正文 * @param [option] 额外选项 * @returns */ send(title, desp, option) { Debugger5('title: "%s", desp: "%s", option: "%o"', title, desp, option); return ajax({ url: `https://push.hellyw.com/${this.I_GOT_KEY}`, method: "POST", headers: { "Content-Type": "application/json" }, data: { title, content: desp || title, automaticallyCopy: 0, // 关闭自动复制 ...option } }); } }; _IGot.namespace = "iGot"; _IGot.configSchema = iGotConfigSchema; _IGot.optionSchema = iGotOptionSchema; var IGot = _IGot; // src/push/one-bot.ts var import_debug6 = __toESM(require("debug"), 1); var Debugger6 = (0, import_debug6.default)("push:one-bot"); var oneBotConfigSchema = { ONE_BOT_BASE_URL: { type: "string", title: "OneBot HTTP 基础路径", description: "OneBot HTTP 基础路径", required: true }, ONE_BOT_ACCESS_TOKEN: { type: "string", title: "OneBot AccessToken", description: "出于安全原因,请务必设置 AccessToken", required: false } }; var oneBotOptionSchema = { message_type: { type: "select", title: "消息类型", description: "消息类型,private 或 group,默认为 private", required: true, default: "private", options: [ { label: "私聊", value: "private" }, { label: "群聊", value: "group" } ] }, user_id: { type: "number", title: " QQ 号", description: "对方 QQ 号。仅私聊有效。", required: false }, group_id: { type: "number", title: "群号", description: "群号。仅群聊有效。", required: false }, auto_escape: { type: "boolean", title: "消息内容是否作为纯文本发送(即不解析 CQ 码),只在 message 字段是字符串时有效", description: "消息内容是否作为纯文本发送(即不解析 CQ 码),只在 message 字段是字符串时有效", required: false } }; var _OneBot = class _OneBot { /** * 创建 OneBot 实例 * @author CaoMeiYouRen * @date 2024-11-08 * @param config OneBot 配置 */ constructor(config) { const { ONE_BOT_BASE_URL, ONE_BOT_ACCESS_TOKEN } = config; this.ONE_BOT_BASE_URL = ONE_BOT_BASE_URL; this.ONE_BOT_ACCESS_TOKEN = ONE_BOT_ACCESS_TOKEN; Debugger6('set ONE_BOT_BASE_URL: "%s", ONE_BOT_ACCESS_TOKEN: "%s"', ONE_BOT_BASE_URL, ONE_BOT_ACCESS_TOKEN); validate(config, _OneBot.configSchema); if (!this.ONE_BOT_ACCESS_TOKEN) { warn("未提供 ONE_BOT_ACCESS_TOKEN !出于安全原因,请务必设置 AccessToken!"); } } /** * * * @author CaoMeiYouRen * @date 2024-11-08 * @param title 消息标题 * @param desp 消息正文 * @param option 额外推送选项 */ async send(title, desp, option) { Debugger6('title: "%s", desp: "%s", option: "%o"', title, desp, option); validate(option, _OneBot.optionSchema); if (option.message_type === "private" && !option.user_id) { throw new Error("OneBot 私聊消息类型必须提供 user_id"); } if (option.message_type === "group" && !option.group_id) { throw new Error("OneBot 群聊消息类型必须提供 group_id"); } const { message_type = "private", ...args } = option || {}; const message = `${title}${desp ? ` ${desp}` : ""}`; return ajax({ baseURL: this.ONE_BOT_BASE_URL, url: "/send_msg", method: "POST", headers: { "Content-Type": "application/json", Authorization: `Bearer ${this.ONE_BOT_ACCESS_TOKEN}` }, data: { auto_escape: false, message_type, message, ...args } }); } }; _OneBot.namespace = "OneBot"; _OneBot.configSchema = oneBotConfigSchema; _OneBot.optionSchema = oneBotOptionSchema; /** * OneBot 协议版本号 * * @author CaoMeiYouRen * @date 2023-10-22 * @static */ _OneBot.version = 11; var OneBot = _OneBot; // src/push/push-deer.ts var import_debug7 = __toESM(require("debug"), 1); var Debugger7 = (0, import_debug7.default)("push:push-deer"); var pushDeerConfigSchema = { PUSH_DEER_PUSH_KEY: { type: "string", title: "pushkey", description: "请参考 https://github.com/easychen/pushdeer 获取", required: true }, PUSH_DEER_ENDPOINT: { type: "string", title: "使用自架版时的服务器端地址", description: "例如 http://127.0..1:8800。默认为 https://api2.pushdeer.com", required: false, default: "https://api2.pushdeer.com" } }; var pushDeerOptionSchema = { type: { type: "select", title: "格式", description: "文本=text,markdown,图片=image,默认为markdown。type 为 image 时,text 中为要发送图片的URL", required: false, default: "markdown", options: [ { label: "文本", value: "text" }, { label: "Markdown", value: "markdown" }, { label: "图片", value: "image" } ] } }; var _PushDeer = class _PushDeer { /** * 创建 PushDeer 实例 * @author CaoMeiYouRen * @date 2024-11-08 * @param config 配置 */ constructor(config) { const { PUSH_DEER_PUSH_KEY, PUSH_DEER_ENDPOINT } = config; this.PUSH_DEER_PUSH_KEY = PUSH_DEER_PUSH_KEY; this.PUSH_DEER_ENDPOINT = PUSH_DEER_ENDPOINT || "https://api2.pushdeer.com"; Debugger7('set PUSH_DEER_PUSH_KEY: "%s", PUSH_DEER_ENDPOINT: "%s"', PUSH_DEER_PUSH_KEY, PUSH_DEER_ENDPOINT); validate(config, _PushDeer.configSchema); } /** * @author CaoMeiYouRen * @date 2024-11-08 * @param text 推送消息内容 * @param [desp=''] 消息内容第二部分 * @param [option={}] 额外推送选项 */ async send(title, desp = "", option) { Debugger7('title: "%s", desp: "%s", option: "%o"', title, desp, option); const { type = "markdown" } = option || {}; return ajax({ baseURL: this.PUSH_DEER_ENDPOINT, url: "/message/push", method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded" }, data: { text: title, desp, pushkey: this.PUSH_DEER_PUSH_KEY, type } }); } }; _PushDeer.namespace = "PushDeer"; _PushDeer.configSchema = pushDeerConfigSchema; _PushDeer.optionSchema = pushDeerOptionSchema; var PushDeer = _PushDeer; // src/push/push-plus.ts var import_debug8 = __toESM(require("debug"), 1); var Debugger8 = (0, import_debug8.default)("push:push-plus"); var pushPlusConfigSchema = { PUSH_PLUS_TOKEN: { type: "string", title: "PushPlus Token", description: "请前往 https://www.pushplus.plus/ 领取", required: true } }; var pushPlusOptionSchema = { template: { type: "select", title: "模板类型", description: "html,txt,json,markdown,cloudMonitor,jenkins,route", required: false, default: "html", options: [ { label: "HTML", value: "html" }, { label: "文本", value: "txt" }, { label: "JSON", value: "json" }, { label: "Markdown", value: "markdown" }, { label: "阿里云监控", value: "cloudMonitor" }, { label: "Jenkins", value: "jenkins" }, { label: "路由器", value: "route" } ] }, channel: { type: "select", title: "渠道类型", description: "wechat,webhook,cp,sms,mail", required: false, default: "wechat", options: [ { label: "微信", value: "wechat" }, { label: "Webhook", value: "webhook" }, { label: "企业微信", value: "cp" }, { label: "邮件", value: "mail" }, { label: "短信", value: "sms" } ] }, topic: { type: "string", title: "群组编码", description: "不填仅发送给自己;channel为webhook时无效", required: false, default: "" }, webhook: { type: "string", title: "webhook编码", description: "仅在channel使用webhook渠道和CP渠道时需要填写", required: false, default: "" }, callbackUrl: { type: "string", title: "发送结果回调地址", description: "发送结果回调地址", required: false, default: "" }, timestamp: { type: "number", title: "毫秒时间戳", description: "格式如:1632993318000。服务器时间戳大于此时间戳,则消息不会发送", required: false // default: 0, } }; var _PushPlus = class _PushPlus { /** * * @author CaoMeiYouRen * @date 2024-11-08 * @param config 请前往 https://www.pushplus.plus 领取 */ constructor(config) { const { PUSH_PLUS_TOKEN } = config; this.PUSH_PLUS_TOKEN = PUSH_PLUS_TOKEN; Debugger8('set PUSH_PLUS_TOKEN: "%s"', PUSH_PLUS_TOKEN); validate(config, _PushPlus.configSchema); } /** * 发送消息 * * @author CaoMeiYouRen * @date 2024-11-08 * @param title 消息标题 * @param [desp=''] 消息内容 * @param [option] 额外推送选项 */ send(title, desp = "", option) { Debugger8('title: "%s", desp: "%s", option: "%o"', title, desp, option); const { template = "html", channel = "wechat", ...args } = option || {}; const content = desp || title; return ajax({ url: "http://www.pushplus.plus/send", method: "POST", headers: { "Content-Type": "application/json" }, data: { token: this.PUSH_PLUS_TOKEN, title, content: content || title, template, channel, ...args } }); } }; _PushPlus.namespace = "PushPlus"; _PushPlus.configSchema = pushPlusConfigSchema; _PushPlus.optionSchema = pushPlusOptionSchema; var PushPlus = _PushPlus; // src/push/qmsg.ts var import_debug9 = __toESM(require("debug"), 1); var Debugger9 = (0, import_debug9.default)("push:qmsg"); var qmsgConfigSchema = { QMSG_KEY: { type: "string", title: "推送的 key", description: "在 [Qmsg 酱管理台](https://qmsg.zendee.cn/user) 查看", required: true } }; var qmsgOptionSchema = { type: { type: "select", title: "消息类型", description: "send 表示发送消息给指定的QQ号,group 表示发送消息给指定的QQ群。默认为 send", required: true, default: "send", options: [ { label: "私聊", value: "send" }, { label: "群聊", value: "group" } ] }, qq: { type: "string", title: "指定要接收消息的QQ号或者QQ群", description: "多个以英文逗号分割,例如:12345,12346", required: true }, bot: { type: "string", title: "机器人的QQ号", description: "指定使用哪个机器人来发送消息,不指定则会自动随机选择一个在线的机器人发送消息。该参数仅私有云有效", required: false } }; var _Qmsg = class _Qmsg { constructor(config) { const { QMSG_KEY } = config; this.QMSG_KEY = QMSG_KEY; Debugger9('set QMSG_KEY: "%s"', QMSG_KEY); validate(config, _Qmsg.configSchema); } /** * * 发送消息 * @author CaoMeiYouRen * @date 2024-11-08 * @param title 消息标题 * @param [desp] 消息描述 * @param [option] QmsgOption 选项 */ async send(title, desp, option) { Debugger9('title: "%s", desp: "%s", option: "%o"', title, desp, option); validate(option, _Qmsg.optionSchema); const { qq, type = "send", bot } = option || {}; const msg = `${title}${desp ? ` ${desp}` : ""}`; return ajax({ url: `https://qmsg.zendee.cn/${type}/${this.QMSG_KEY}`, headers: { "Content-Type": "application/x-www-form-urlencoded" }, method: "POST", data: { msg, qq, bot } }); } }; _Qmsg.namespace = "Qmsg酱"; _Qmsg.configSchema = qmsgConfigSchema; _Qmsg.optionSchema = qmsgOptionSchema; var Qmsg = _Qmsg; // src/push/server-chan-turbo.ts var import_debug10 = __toESM(require("debug"), 1); var Debugger10 = (0, import_debug10.default)("push:server-chan-turbo"); var serverChanTurboConfigSchema = { SERVER_CHAN_TURBO_SENDKEY: { type: "string", title: "SCTKEY", description: "Server酱 Turbo 的 SCTKEY。请前往 https://sct.ftqq.com/sendkey 领取", required: true } }; var serverChanTurboOptionSchema = { short: { type: "string", title: "消息卡片内容", description: "选填。最大长度 64。如果不指定,将自动从 desp 中截取生成。", required: false }, noip: { type: "boolean", title: "是否隐藏调用 IP", description: "选填。如果不指定,则显示;为 1/true 则隐藏。", required: false }, channel: { type: "string", title: "消息通道", description: '选填。动态指定本次推送使用的消息通道,支持最多两个通道,多个通道值用竖线 "|" 隔开。', required: false }, openid: { type: "string", title: "消息抄送的 openid", description: '选填。只支持测试号和企业微信应用消息通道。多个 openid 用 "," 隔开。企业微信应用消息通道的 openid 参数,内容为接收人在企业微信中的 UID,多个人请 "|" 隔开。', required: false } }; var _ServerChanTurbo = class _ServerChanTurbo { /** * * @author CaoMeiYouRen * @date 2024-11-08 * @param config 请前往 https://sct.ftqq.com/sendkey 领取 */ constructor(config) { const { SERVER_CHAN_TURBO_SENDKEY } = config; this.SCTKEY = SERVER_CHAN_TURBO_SENDKEY; Debugger10('set SCTKEY: "%s"', this.SCTKEY); validate(config, _ServerChanTurbo.configSchema); } /** * 发送消息 * * @author CaoMeiYouRen * @date 2024-11-08 * @param title 消息的标题 * @param [desp=''] 消息的内容,支持 Markdown * @param [option={}] 额外发送选项 */ async send(title, desp = "", option = {}) { Debugger10('title: "%s", desp: "%s", option: %O', title, desp, option); if (option.noip === 1 || option.noip === true) { option.noip = "1"; } const data = { text: title, desp, ...option }; return ajax({ url: `https://sctapi.ftqq.com/${this.SCTKEY}.send`, method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded" }, data }); } }; _ServerChanTurbo.namespace = "Server酱·Turbo"; _ServerChanTurbo.configSchema = serverChanTurboConfigSchema; _ServerChanTurbo.optionSchema = serverChanTurboOptionSchema; var ServerChanTurbo = _ServerChanTurbo; // src/push/server-chan-v3.ts var import_debug11 = __toESM(require("debug"), 1); var Debugger11 = (0, import_debug11.default)("push:server-chan-v3"); var serverChanV3ConfigSchema = { SERVER_CHAN_V3_SENDKEY: { type: "string", title: "SENDKEY", description: "请前往 https://sc3.ft07.com/sendkey 领取", required: true } }; var serverChanV3OptionSchema = { tags: { type: "array", title: "标签列表", description: "多个标签用数组格式", required: false }, short: { type: "string", title: "推送消息的简短描述", description: "用于指定消息卡片的内容部分,尤其是在推送markdown的时候", required: false } }; var _ServerChanV3 = class _ServerChanV3 { /** * 创建 ServerChanV3 实例 * @author CaoMeiYouRen * @date 2024-11-08 * @param config 请前往 https://sc3.ft07.com/sendkey 领取 */ constructor(config) { this.uid = ""; var _a; const { SERVER_CHAN_V3_SENDKEY } = config; const sendkey = SERVER_CHAN_V3_SENDKEY; this.sendkey = sendkey; Debugger11('set sendkey: "%s"', sendkey); validate(config, _ServerChanV3.configSchema); this.uid = (_a = this.sendkey.match(/^sctp(\d+)t/)) == null ? void 0 : _a[1]; if (!this.uid) { throw new Error("SERVER_CHAN_V3_SENDKEY 不合法!"); } } /** * 发送消息 * * @author CaoMeiYouRen * @date 2024-11-08 * @param title 消息的标题 * @param [desp=''] 消息的内容,支持 Markdown * @param [option={}] 额外发送选项 */ async send(title, desp = "", option = {}) { Debugger11('title: "%s", desp: "%s", option: %O', title, desp, option); if (Array.isArray(option.tags)) { option.tags = option.tags.join("|"); } const data = { text: title, desp, ...option }; return ajax({ url: `https://${this.uid}.push.ft07.com/send/${this.sendkey}.send`, method: "POST", headers: { "Content-Type": "application/json" }, data }); } }; _ServerChanV3.namespace = "Server酱³"; _ServerChanV3.configSchema = serverChanV3ConfigSchema; _ServerChanV3.optionSchema = serverChanV3OptionSchema; var ServerChanV3 = _ServerChanV3; // src/push/telegram.ts var import_debug12 = __toESM(require("debug"), 1); var Debugger12 = (0, import_debug12.default)("push:telegram"); var telegramConfigSchema = { TELEGRAM_BOT_TOKEN: { type: "string", title: "机器人令牌", description: "您可以从 https://t.me/BotFather 获取 Token。", required: true }, TELEGRAM_CHAT_ID: { type: "number", title: "支持对话/群组/频道的 Chat ID", description: "您可以转发消息到 https://t.me/JsonDumpBot 获取 Chat ID", required: true }, PROXY_URL: { type: "string", title: "代理地址", description: "代理地址", required: false } }; var telegramOptionSchema = { disable_notification: { type: "boolean", title: "静默发送", description: "静默地发送消息。消息发布后用户会收到无声通知。", required: false }, protect_content: { type: "boolean", title: "阻止转发/保存", description: "如果启用,Telegram 中的机器人消息将受到保护,不会被转发和保存。", required: false }, message_thread_id: { type: "string", title: "话题 ID", description: "可选的唯一标识符,用以向该标识符对应的话题发送消息,仅限启用了话题功能的超级群组可用", required: false } }; var _Telegram = class _Telegram { constructor(config) { Debugger12("config: %O", config); Object.assign(this, config); validate(config, _Telegram.configSchema); if (config.PROXY_URL) { this.proxyUrl = config.PROXY_URL; } } /** * 发送消息 * * @author CaoMeiYouRen * @date 2024-11-09 * @param title 消息标题 * @param [desp] 消息正文,和 title 相加后不超过 4096 个字符 * @param [option] 其他参数 */ async send(title, desp, option) { const url = `https://api.telegram.org/bot${this.TELEGRAM_BOT_TOKEN}/sendMessage`; Debugger12('title: "%s", desp: "%s", option: %O', title, desp, option); const text = `${title}${desp ? ` ${desp}` : ""}`; return ajax({ url, method: "POST", proxyUrl: this.proxyUrl, data: { chat_id: this.TELEGRAM_CHAT_ID, text } }); } }; _Telegram.namespace = "Telegram"; _Telegram.configSchema = telegramConfigSchema; _Telegram.optionSchema = telegramOptionSchema; var Telegram = _Telegram; // src/push/wechat-app.ts var import_debug13 = __toESM(require("debug"), 1); var Debugger13 = (0, import_debug13.default)("push:wechat-app"); var wechatAppConfigSchema = { WECHAT_APP_CORPID: { type: "string", title: "企业ID", description: "企业ID,获取方式参考:[术语说明-corpid](https://work.weixin.qq.com/api/doc/90000/90135/91039#14953/corpid)", required: true, default: "" }, WECHAT_APP_SECRET: { type: "string", title: "应用的凭证密钥", description: "应用的凭证密钥,获取方式参考:[术语说明-secret](https://work.weixin.qq.com/api/doc/90000/90135/91039#14953/secret)", required: true, default: "" }, WECHAT_APP_AGENTID: { type: "number", title: "企业应用的id", description: "企业应用的id。企业内部开发,可在应用的设置页面查看", required: true, default: 0 } }; var wechatAppOptionSchema = { msgtype: { type: "select", title: "消息类型", description: "消息类型", required: true, options: [ { label: "文本", value: "text" }, { label: "Markdown", value: "markdown" }, { label: "语音", value: "voice" }, { label: "文件", value: "file" }, { label: "图片", value: "image" }, { label: "视频", value: "video" }, { label: "图文", value: "news" }, { label: "小程序通知", value: "miniprogram_notice" }, { label: "模板卡片", value: "template_card" } ] }, safe: { type: "select", title: "是否是保密消息", description: "表示是否是保密消息,0表示可对外分享,1表示不能", required: false, options: [ { label: "否", value: 0 }, { label: "是", value: 1 } ] }, enable_id_trans: { type: "select", title: "是否开启id转译", description: "表示是否开启id转译,0表示否,1表示是,默认0。", required: false, options: [ { label: "否", value: 0 }, { label: "是", value: 1 } ] }, enable_duplicate_check: { type: "select", title: "是否开启重复消息检查", description: "表示是否开启重复消息检查,0表示否,1表示是,默认", required: false, options: [ { label: "否", value: 0 }, { label: "是", value: 1 } ] }, duplicate_check_interval: { type: "number", title: "重复消息检查的时间间隔", description: "表示是否重复消息检查的时间间隔,默认1800s,最大不超过4小时", required: false }, touser: { type: "string", title: "指定接收消息的成员", description: "指定接收消息的成员,成员ID列表(多个接收者用‘|’分隔,最多支持1000个)。", required: false }, toparty: { type: "string", title: "指定接收消息的部门", description: "指定接收消息的部门,部门ID列表,多个接收者用‘|’分隔,最多支持100个。", required: false }, totag: { type: "string", title: "指定接收消息的标签", description: "指定接收消息的标签,标签ID列表,多个接收者用‘|’分隔,最多支持100个。", required: false } }; var _WechatApp = class _WechatApp { constructor(config) { Debugger13("config: %O", config); Object.assign(this, config); validate(config, _WechatApp.configSchema); } async getAccessToken() { const { data } = await ajax({ url: "https://qyapi.weixin.qq.com/cgi-bin/gettoken", query: { corpid: this.WECHAT_APP_CORPID, corpsecret: this.WECHAT_APP_SECRET } }); if ((data == null ? void 0 : data.errcode) !== 0) { throw new Error((data == null ? void 0 : data.errmsg) || "获取 access_token 失败!"); } const { access_token, expires_in = 7200 } = data; Debugger13("获取 access_token 成功: %s", access_token); this.extendexpiresTime(expires_in); return access_token; } /** * 延长过期时间 * * @author CaoMeiYouRen * @date 2021-03-03 * @private * @param expiresIn 延长的秒数 */ extendexpiresTime(expiresIn) { this.expiresTime = Date.now() + expiresIn * 1e3; } /** * 发送消息 * * @author CaoMeiYouRen * @date 2024-11-08 * @param title 消息标题 * @param [desp] 消息内容,最长不超过2048个字节,超过将截断(支持id转译) * @param [option] 额外推送选项 */ async send(title, desp, option) { Debugger13('title: "%s", desp: "%s", option: %O', title, desp, option); if (!this.ACCESS_TOKEN || Date.now() >= this.expiresTime) { this.ACCESS_TOKEN = await this.getAccessToken(); } const { msgtype = "text", touser: _touser, ...args } = option || {}; if (!_touser) { warn('未指定 touser,将使用 "@all" 向全体成员推送'); } const sep = msgtype === "markdown" ? "\n\n" : "\n"; const content = `${title}${desp ? `${sep}${desp}` : ""}`; const touser = _touser || "@all"; return ajax({ url: "https://qyapi.weixin.qq.com/cgi-bin/message/send", method: "POST", headers: { "Content-Type": "application/json" }, query: { access_token: this.ACCESS_TOKEN }, data: { touser, msgtype, agentid: this.WECHAT_APP_AGENTID, [msgtype]: { content }, ...args } }); } }; _WechatApp.namespace = "企业微信应用"; _WechatApp.configSchema = wechatAppConfigSchema; _WechatApp.optionSchema = wechatAppOptionSchema; var WechatApp = _WechatApp; // src/push/wechat-robot.ts var import_debug14 = __toESM(require("debug"), 1); var Debugger14 = (0, import_debug14.default)("push:wechat-robot"); var wechatRobotConfigSchema = { WECHAT_ROBOT_KEY: { type: "string", title: "企业微信机器人的key", description: "企业微信机器人的key", required: true } }; var wechatRobotOptionSchema = { msgtype: { type: "select", title: "消息类型", description: "消息类型", options: [ { label: "文本", value: "text" }, { label: "Markdown", value: "markdown" }, { label: "图片", value: "image" }, { label: "图文", value: "news" }, { label: "文件", value: "file" }, { label: "语音", value: "voice" }, { label: "模板卡片", value: "template_card" } ], required: false, default: "text" } }; var _WechatRobot = class _WechatRobot { constructor(config) { const { WECHAT_ROBOT_KEY } = config; this.WECHAT_ROBOT_KEY = WECHAT_ROBOT_KEY; Debugger14('set WECHAT_ROBOT_KEY: "%s"', WECHAT_ROBOT_KEY); validate(config, _WechatRobot.configSchema); } /** * * * @author CaoMeiYouRen * @date 2024-11-08 * @param title 消息标题 * @param [desp] 消息内容。text内容,最长不超过2048个字节;markdown内容,最长不超过4096个字节;必须是utf8编码 * @param [option] 额外推送选项 */ async send(title, desp, option) { Debugger14('title: "%s", desp: "%s", option: %O', title, desp, option); const { msgtype = "text", ...args } = option || {}; const sep = msgtype === "markdown" ? "\n\n" : "\n"; const content = `${title}${desp ? `${sep}${desp}` : ""}`; return ajax({ url: "https://qyapi.weixin.qq.com/cgi-bin/webhook/send", headers: { "Content-Type": "application/json" }, method: "POST", query: { key: this.WECHAT_ROBOT_KEY }, data: { msgtype, [msgtype]: { content }, ...args } }); } }; _WechatRobot.namespace = "企业微信群机器人"; _WechatRobot.configSchema = wechatRobotConfigSchema; _WechatRobot.optionSchema = wechatRobotOptionSchema; var WechatRobot = _WechatRobot; // src/push/xi-zhi.ts var import_debug15 = __toESM(require("debug"), 1); var Debugger15 = (0, import_debug15.default)("push:xi-zhi"); var xiZhiConfigSchema = { XI_ZHI_KEY: { type: "string", title: "息知的 key", description: "前往 https://xz.qqoq.net/#/index 获取", required: true } }; var xiZhiOptionSchema = {}; var _XiZhi = class _XiZhi { constructor(config) { const { XI_ZHI_KEY } = config; this.XI_ZHI_KEY = XI_ZHI_KEY; Debugger15('set XI_ZHI_KEY: "%s"', XI_ZHI_KEY); validate(config, _XiZhi.configSchema); } async send(title, desp, option) { Debugger15('title: "%s", desp: "%s"', title, desp); return ajax({ url: `https://xizhi.qqoq.net/${this.XI_ZHI_KEY}.send`, method: "POST", headers: { "Content-Type": "application/json" }, data: { title, content: desp } }); } }; _XiZhi.namespace = "息知"; _XiZhi.configSchema = xiZhiConfigSchema; _XiZhi.optionSchema = xiZhiOptionSchema; var XiZhi = _XiZhi; // src/one.ts var PushAllInOne = { CustomEmail, Dingtalk, Discord, IGot, OneBot, PushDeer, PushPlus, Qmsg, ServerChanTurbo, ServerChanV3, Telegram, WechatApp, WechatRobot, XiZhi }; async function runPushAllInOne(title, desp, pushConfig) { const { type, config, option } = pushConfig; if (PushAllInOne[type]) { const push = new PushAllInOne[type](config); return push.send(title, desp, option); } throw new Error("未匹配到任何推送方式!"); } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { CustomEmail, Dingtalk, Discord, IGot, OneBot, PushAllInOne, PushDeer, PushPlus, Qmsg, ServerChanTurbo, ServerChanV3, Telegram, WechatApp, WechatRobot, XiZhi, customEmailConfigSchema, customEmailOptionSchema, dingtalkConfigSchema, dingtalkOptionSchema, discordConfigSchema, discordOptionSchema, iGotConfigSchema, iGotOptionSchema, oneBotConfigSchema, oneBotOptionSchema, pushDeerConfigSchema, pushDeerOptionSchema, pushPlusConfigSchema, pushPlusOptionSchema, qmsgConfigSchema, qmsgOptionSchema, runPushAllInOne, serverChanTurboConfigSchema, serverChanTurboOptionSchema, serverChanV3ConfigSchema, serverChanV3OptionSchema, telegramConfigSchema, telegramOptionSchema, wechatAppConfigSchema, wechatAppOptionSchema, wechatRobotConfigSchema, wechatRobotOptionSchema, xiZhiConfigSchema, xiZhiOptionSchema }); //# sourceMappingURL=index.cjs.map