local util_notify = {} -- 在通知内容加入设备信息 local is_append_more_info = true -- 消息队列 local msg_queue = {} local function urlencodeTab(params) local msg = {} for k, v in pairs(params) do table.insert(msg, string.urlEncode(k) .. "=" .. string.urlEncode(v)) table.insert(msg, "&") end table.remove(msg) return table.concat(msg) end -- 发送到 telegram local function notifyToTelegram(msg) if config.TELEGRAM_PROXY_API == nil or config.TELEGRAM_PROXY_API == "" then log.error("util_notify.notifyToTelegram", "未配置 `config.TELEGRAM_PROXY_API`") return end local header = { ["content-type"] = "text/plain", ["x-disable-web-page-preview"] = "1", ["x-chat-id"] = config.TELEGRAM_CHAT_ID or "", ["x-token"] = config.TELEGRAM_TOKEN or "" } log.info("util_notify.notifyToTelegram", "POST", config.TELEGRAM_PROXY_API) return util_http.fetch(nil, "POST", config.TELEGRAM_PROXY_API, header, msg) end -- 发送到 pushdeer local function notifyToPushDeer(msg) if config.PUSHDEER_API == nil or config.PUSHDEER_API == "" then log.error("util_notify.notifyToPushDeer", "未配置 `config.PUSHDEER_API`") return end if config.PUSHDEER_KEY == nil or config.PUSHDEER_KEY == "" then log.error("util_notify.notifyToPushDeer", "未配置 `config.PUSHDEER_KEY`") return end local header = { ["Content-Type"] = "application/x-www-form-urlencoded" } local body = { pushkey = config.PUSHDEER_KEY or "", type = "text", text = msg } log.info("util_notify.notifyToPushDeer", "POST", config.PUSHDEER_API) return util_http.fetch(nil, "POST", config.PUSHDEER_API, header, urlencodeTab(body)) end -- 发送到 bark local function notifyToBark(msg) if config.BARK_API == nil or config.BARK_API == "" then log.error("util_notify.notifyToBark", "未配置 `config.BARK_API`") return end if config.BARK_KEY == nil or config.BARK_KEY == "" then log.error("util_notify.notifyToBark", "未配置 `config.BARK_KEY`") return end local header = { ["Content-Type"] = "application/x-www-form-urlencoded" } local body = { body = msg } local url = config.BARK_API .. "/" .. config.BARK_KEY log.info("util_notify.notifyToBark", "POST", url) return util_http.fetch(nil, "POST", url, header, urlencodeTab(body)) end -- 发送到 dingtalk local function notifyToDingTalk(msg) if config.DINGTALK_WEBHOOK == nil or config.DINGTALK_WEBHOOK == "" then log.error("util_notify.notifyToDingTalk", "未配置 `config.DINGTALK_WEBHOOK`") return end local header = { ["Content-Type"] = "application/json; charset=utf-8" } local body = { msgtype = "text", text = { content = msg } } local json_data = json.encode(body) -- LuatOS Bug, json.encode 会将 \n 转换为 \b json_data = string.gsub(json_data, "\\b", "\\n") log.info("util_notify.notifyToDingTalk", "POST", config.DINGTALK_WEBHOOK) return util_http.fetch(nil, "POST", config.DINGTALK_WEBHOOK, header, json_data) end -- 发送到 feishu local function notifyToFeishu(msg) if config.FEISHU_WEBHOOK == nil or config.FEISHU_WEBHOOK == "" then log.error("util_notify.notifyToFeishu", "未配置 `config.FEISHU_WEBHOOK`") return end local header = { ["Content-Type"] = "application/json; charset=utf-8" } local body = { msg_type = "text", content = { text = msg } } local json_data = json.encode(body) -- LuatOS Bug, json.encode 会将 \n 转换为 \b json_data = string.gsub(json_data, "\\b", "\\n") log.info("util_notify.notifyToFeishu", "POST", config.FEISHU_WEBHOOK) return util_http.fetch(nil, "POST", config.FEISHU_WEBHOOK, header, json_data) end -- 发送到 wecom local function notifyToWeCom(msg) if config.WECOM_WEBHOOK == nil or config.WECOM_WEBHOOK == "" then log.error("util_notify.notifyToWeCom", "未配置 `config.WECOM_WEBHOOK`") return end local header = { ["Content-Type"] = "application/json; charset=utf-8" } local body = { msgtype = "text", text = { content = msg } } local json_data = json.encode(body) -- LuatOS Bug, json.encode 会将 \n 转换为 \b json_data = string.gsub(json_data, "\\b", "\\n") log.info("util_notify.notifyToWeCom", "POST", config.WECOM_WEBHOOK) return util_http.fetch(nil, "POST", config.WECOM_WEBHOOK, header, json_data) end -- 发送到 next-smtp-proxy local function notifyToNextSmtpProxy(msg) if config.NEXT_SMTP_PROXY_API == nil or config.NEXT_SMTP_PROXY_API == "" then log.error("util_notify.notifyToNextSmtpProxy", "未配置 `config.NEXT_SMTP_PROXY_API`") return end if config.NEXT_SMTP_PROXY_USER == nil or config.NEXT_SMTP_PROXY_USER == "" then log.error("util_notify.notifyToNextSmtpProxy", "未配置 `config.NEXT_SMTP_PROXY_USER`") return end if config.NEXT_SMTP_PROXY_PASSWORD == nil or config.NEXT_SMTP_PROXY_PASSWORD == "" then log.error("util_notify.notifyToNextSmtpProxy", "未配置 `config.NEXT_SMTP_PROXY_PASSWORD`") return end if config.NEXT_SMTP_PROXY_HOST == nil or config.NEXT_SMTP_PROXY_HOST == "" then log.error("util_notify.notifyToNextSmtpProxy", "未配置 `config.NEXT_SMTP_PROXY_HOST`") return end if config.NEXT_SMTP_PROXY_PORT == nil or config.NEXT_SMTP_PROXY_PORT == "" then log.error("util_notify.notifyToNextSmtpProxy", "未配置 `config.NEXT_SMTP_PROXY_PORT`") return end if config.NEXT_SMTP_PROXY_TO_EMAIL == nil or config.NEXT_SMTP_PROXY_TO_EMAIL == "" then log.error("util_notify.notifyToNextSmtpProxy", "未配置 `config.NEXT_SMTP_PROXY_TO_EMAIL`") return end local header = { ["Content-Type"] = "application/x-www-form-urlencoded" } local body = { user = config.NEXT_SMTP_PROXY_USER, password = config.NEXT_SMTP_PROXY_PASSWORD, host = config.NEXT_SMTP_PROXY_HOST, port = config.NEXT_SMTP_PROXY_PORT, form_name = config.NEXT_SMTP_PROXY_FORM_NAME, to_email = config.NEXT_SMTP_PROXY_TO_EMAIL, subject = config.NEXT_SMTP_PROXY_SUBJECT, text = msg } log.info("util_notify.notifyToNextSmtpProxy", "POST", config.NEXT_SMTP_PROXY_API) return util_http.fetch(nil, "POST", config.NEXT_SMTP_PROXY_API, header, urlencodeTab(body)) end local function append() local msg = "\n" -- 运营商 local oper = util_mobile.getOper(true) if oper ~= "" then msg = msg .. "\n运营商: " .. oper end -- 信号 local rsrp = mobile.rsrp() if rsrp ~= 0 then msg = msg .. "\n信号: " .. rsrp .. "dBm" end -- 频段 local band = util_mobile.getBand() if band >= 0 then msg = msg .. "\n频段: B" .. band end -- 位置 local _, _, map_link = util_location.get() if map_link ~= "" then msg = msg .. "\n位置: " .. map_link -- 这里使用 U+00a0 防止换行 end return msg end --- 发送通知 -- @param msg 消息内容 -- @return true: 发送成功 or 出错但无需重试, false: 发送失败, 需要重发 function util_notify.send(msg) log.info("util_notify.send", "发送通知", config.NOTIFY_TYPE) if type(msg) == "table" then msg = table.concat(msg, "\n") end if type(msg) ~= "string" then log.error("util_notify.send", "发送通知失败", "参数类型错误", type(msg)) return true end if msg == "" then log.error("util_notify.send", "发送通知失败", "消息为空") return true end if is_append_more_info then msg = msg .. append() end -- 判断通知类型 local notify if config.NOTIFY_TYPE == "telegram" then notify = notifyToTelegram elseif config.NOTIFY_TYPE == "pushdeer" then notify = notifyToPushDeer elseif config.NOTIFY_TYPE == "bark" then notify = notifyToBark elseif config.NOTIFY_TYPE == "dingtalk" then notify = notifyToDingTalk elseif config.NOTIFY_TYPE == "feishu" then notify = notifyToFeishu elseif config.NOTIFY_TYPE == "wecom" then notify = notifyToWeCom elseif config.NOTIFY_TYPE == "next-smtp-proxy" then notify = notifyToNextSmtpProxy else log.error("util_notify.send", "发送通知失败", "未配置 `config.NOTIFY_TYPE`") return true end local code, headers, body = notify(msg) if code == nil then return true end if code == 200 then log.info("util_notify.send", "发送通知成功", "code:", code, "body:", body) return true else log.error("util_notify.send", "发送通知失败", "code:", code, "body:", body) return false end end --- 添加到消息队列 -- @param msg 消息内容 function util_notify.add(msg) table.insert(msg_queue, msg) log.debug("util_notify.add", "添加到消息队列, 当前队列长度:", #msg_queue) end -- 轮询消息队列 -- 发送成功则从消息队列中删除 -- 发送失败则等待下次轮询 local function poll() local msg while true do -- 消息队列非空, 且网络已注册 if #msg_queue > 0 and mobile.status() == 1 then log.debug("util_notify.poll", "轮询消息队列中...", "当前队列长度:", #msg_queue) msg = msg_queue[1] if util_notify.send(msg) then table.remove(msg_queue, 1) sys.wait(100) else sys.wait(2000) end else sys.wait(350) end end end sys.taskInit(poll) return util_notify