util_notify.lua 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. local util_notify = {}
  2. -- 在通知内容加入设备信息
  3. local is_append_more_info = true
  4. -- 消息队列
  5. local msg_queue = {}
  6. local function urlencodeTab(params)
  7. local msg = {}
  8. for k, v in pairs(params) do
  9. table.insert(msg, string.urlEncode(k) .. "=" .. string.urlEncode(v))
  10. table.insert(msg, "&")
  11. end
  12. table.remove(msg)
  13. return table.concat(msg)
  14. end
  15. -- 发送到 telegram
  16. local function notifyToTelegram(msg)
  17. if config.TELEGRAM_PROXY_API == nil or config.TELEGRAM_PROXY_API == "" then
  18. log.error("util_notify.notifyToTelegram", "未配置 `config.TELEGRAM_PROXY_API`")
  19. return
  20. end
  21. local header = {
  22. ["content-type"] = "text/plain",
  23. ["x-disable-web-page-preview"] = "1",
  24. ["x-chat-id"] = config.TELEGRAM_CHAT_ID or "",
  25. ["x-token"] = config.TELEGRAM_TOKEN or ""
  26. }
  27. log.info("util_notify.notifyToTelegram", "POST", config.TELEGRAM_PROXY_API)
  28. return util_http.fetch(nil, "POST", config.TELEGRAM_PROXY_API, header, msg)
  29. end
  30. -- 发送到 pushdeer
  31. local function notifyToPushDeer(msg)
  32. if config.PUSHDEER_API == nil or config.PUSHDEER_API == "" then
  33. log.error("util_notify.notifyToPushDeer", "未配置 `config.PUSHDEER_API`")
  34. return
  35. end
  36. if config.PUSHDEER_KEY == nil or config.PUSHDEER_KEY == "" then
  37. log.error("util_notify.notifyToPushDeer", "未配置 `config.PUSHDEER_KEY`")
  38. return
  39. end
  40. local header = {
  41. ["Content-Type"] = "application/x-www-form-urlencoded"
  42. }
  43. local body = {
  44. pushkey = config.PUSHDEER_KEY or "",
  45. type = "text",
  46. text = msg
  47. }
  48. log.info("util_notify.notifyToPushDeer", "POST", config.PUSHDEER_API)
  49. return util_http.fetch(nil, "POST", config.PUSHDEER_API, header, urlencodeTab(body))
  50. end
  51. -- 发送到 bark
  52. local function notifyToBark(msg)
  53. if config.BARK_API == nil or config.BARK_API == "" then
  54. log.error("util_notify.notifyToBark", "未配置 `config.BARK_API`")
  55. return
  56. end
  57. if config.BARK_KEY == nil or config.BARK_KEY == "" then
  58. log.error("util_notify.notifyToBark", "未配置 `config.BARK_KEY`")
  59. return
  60. end
  61. local header = {
  62. ["Content-Type"] = "application/x-www-form-urlencoded"
  63. }
  64. local body = {
  65. body = msg
  66. }
  67. local url = config.BARK_API .. "/" .. config.BARK_KEY
  68. log.info("util_notify.notifyToBark", "POST", url)
  69. return util_http.fetch(nil, "POST", url, header, urlencodeTab(body))
  70. end
  71. -- 发送到 dingtalk
  72. local function notifyToDingTalk(msg)
  73. if config.DINGTALK_WEBHOOK == nil or config.DINGTALK_WEBHOOK == "" then
  74. log.error("util_notify.notifyToDingTalk", "未配置 `config.DINGTALK_WEBHOOK`")
  75. return
  76. end
  77. local header = {
  78. ["Content-Type"] = "application/json; charset=utf-8"
  79. }
  80. local body = {
  81. msgtype = "text",
  82. text = {
  83. content = msg
  84. }
  85. }
  86. local json_data = json.encode(body)
  87. -- LuatOS Bug, json.encode 会将 \n 转换为 \b
  88. json_data = string.gsub(json_data, "\\b", "\\n")
  89. log.info("util_notify.notifyToDingTalk", "POST", config.DINGTALK_WEBHOOK)
  90. return util_http.fetch(nil, "POST", config.DINGTALK_WEBHOOK, header, json_data)
  91. end
  92. -- 发送到 feishu
  93. local function notifyToFeishu(msg)
  94. if config.FEISHU_WEBHOOK == nil or config.FEISHU_WEBHOOK == "" then
  95. log.error("util_notify.notifyToFeishu", "未配置 `config.FEISHU_WEBHOOK`")
  96. return
  97. end
  98. local header = {
  99. ["Content-Type"] = "application/json; charset=utf-8"
  100. }
  101. local body = {
  102. msg_type = "text",
  103. content = {
  104. text = msg
  105. }
  106. }
  107. local json_data = json.encode(body)
  108. -- LuatOS Bug, json.encode 会将 \n 转换为 \b
  109. json_data = string.gsub(json_data, "\\b", "\\n")
  110. log.info("util_notify.notifyToFeishu", "POST", config.FEISHU_WEBHOOK)
  111. return util_http.fetch(nil, "POST", config.FEISHU_WEBHOOK, header, json_data)
  112. end
  113. -- 发送到 wecom
  114. local function notifyToWeCom(msg)
  115. if config.WECOM_WEBHOOK == nil or config.WECOM_WEBHOOK == "" then
  116. log.error("util_notify.notifyToWeCom", "未配置 `config.WECOM_WEBHOOK`")
  117. return
  118. end
  119. local header = {
  120. ["Content-Type"] = "application/json; charset=utf-8"
  121. }
  122. local body = {
  123. msgtype = "text",
  124. text = {
  125. content = msg
  126. }
  127. }
  128. local json_data = json.encode(body)
  129. -- LuatOS Bug, json.encode 会将 \n 转换为 \b
  130. json_data = string.gsub(json_data, "\\b", "\\n")
  131. log.info("util_notify.notifyToWeCom", "POST", config.WECOM_WEBHOOK)
  132. return util_http.fetch(nil, "POST", config.WECOM_WEBHOOK, header, json_data)
  133. end
  134. -- 发送到 next-smtp-proxy
  135. local function notifyToNextSmtpProxy(msg)
  136. if config.NEXT_SMTP_PROXY_API == nil or config.NEXT_SMTP_PROXY_API == "" then
  137. log.error("util_notify.notifyToNextSmtpProxy", "未配置 `config.NEXT_SMTP_PROXY_API`")
  138. return
  139. end
  140. if config.NEXT_SMTP_PROXY_USER == nil or config.NEXT_SMTP_PROXY_USER == "" then
  141. log.error("util_notify.notifyToNextSmtpProxy", "未配置 `config.NEXT_SMTP_PROXY_USER`")
  142. return
  143. end
  144. if config.NEXT_SMTP_PROXY_PASSWORD == nil or config.NEXT_SMTP_PROXY_PASSWORD == "" then
  145. log.error("util_notify.notifyToNextSmtpProxy", "未配置 `config.NEXT_SMTP_PROXY_PASSWORD`")
  146. return
  147. end
  148. if config.NEXT_SMTP_PROXY_HOST == nil or config.NEXT_SMTP_PROXY_HOST == "" then
  149. log.error("util_notify.notifyToNextSmtpProxy", "未配置 `config.NEXT_SMTP_PROXY_HOST`")
  150. return
  151. end
  152. if config.NEXT_SMTP_PROXY_PORT == nil or config.NEXT_SMTP_PROXY_PORT == "" then
  153. log.error("util_notify.notifyToNextSmtpProxy", "未配置 `config.NEXT_SMTP_PROXY_PORT`")
  154. return
  155. end
  156. if config.NEXT_SMTP_PROXY_TO_EMAIL == nil or config.NEXT_SMTP_PROXY_TO_EMAIL == "" then
  157. log.error("util_notify.notifyToNextSmtpProxy", "未配置 `config.NEXT_SMTP_PROXY_TO_EMAIL`")
  158. return
  159. end
  160. local header = {
  161. ["Content-Type"] = "application/x-www-form-urlencoded"
  162. }
  163. local body = {
  164. user = config.NEXT_SMTP_PROXY_USER,
  165. password = config.NEXT_SMTP_PROXY_PASSWORD,
  166. host = config.NEXT_SMTP_PROXY_HOST,
  167. port = config.NEXT_SMTP_PROXY_PORT,
  168. form_name = config.NEXT_SMTP_PROXY_FORM_NAME,
  169. to_email = config.NEXT_SMTP_PROXY_TO_EMAIL,
  170. subject = config.NEXT_SMTP_PROXY_SUBJECT,
  171. text = msg
  172. }
  173. log.info("util_notify.notifyToNextSmtpProxy", "POST", config.NEXT_SMTP_PROXY_API)
  174. return util_http.fetch(nil, "POST", config.NEXT_SMTP_PROXY_API, header, urlencodeTab(body))
  175. end
  176. local function append()
  177. local msg = "\n"
  178. -- 运营商
  179. local oper = util_mobile.getOper(true)
  180. if oper ~= "" then
  181. msg = msg .. "\n运营商: " .. oper
  182. end
  183. -- 信号
  184. local rsrp = mobile.rsrp()
  185. if rsrp ~= 0 then
  186. msg = msg .. "\n信号: " .. rsrp .. "dBm"
  187. end
  188. -- 频段
  189. local band = util_mobile.getBand()
  190. if band >= 0 then
  191. msg = msg .. "\n频段: B" .. band
  192. end
  193. -- 位置
  194. local _, _, map_link = util_location.get()
  195. if map_link ~= "" then
  196. msg = msg .. "\n位置: " .. map_link -- 这里使用 U+00a0 防止换行
  197. end
  198. return msg
  199. end
  200. --- 发送通知
  201. -- @param msg 消息内容
  202. -- @return true: 发送成功 or 出错但无需重试, false: 发送失败, 需要重发
  203. function util_notify.send(msg)
  204. log.info("util_notify.send", "发送通知", config.NOTIFY_TYPE)
  205. if type(msg) == "table" then
  206. msg = table.concat(msg, "\n")
  207. end
  208. if type(msg) ~= "string" then
  209. log.error("util_notify.send", "发送通知失败", "参数类型错误", type(msg))
  210. return true
  211. end
  212. if msg == "" then
  213. log.error("util_notify.send", "发送通知失败", "消息为空")
  214. return true
  215. end
  216. if is_append_more_info then
  217. msg = msg .. append()
  218. end
  219. -- 判断通知类型
  220. local notify
  221. if config.NOTIFY_TYPE == "telegram" then
  222. notify = notifyToTelegram
  223. elseif config.NOTIFY_TYPE == "pushdeer" then
  224. notify = notifyToPushDeer
  225. elseif config.NOTIFY_TYPE == "bark" then
  226. notify = notifyToBark
  227. elseif config.NOTIFY_TYPE == "dingtalk" then
  228. notify = notifyToDingTalk
  229. elseif config.NOTIFY_TYPE == "feishu" then
  230. notify = notifyToFeishu
  231. elseif config.NOTIFY_TYPE == "wecom" then
  232. notify = notifyToWeCom
  233. elseif config.NOTIFY_TYPE == "next-smtp-proxy" then
  234. notify = notifyToNextSmtpProxy
  235. else
  236. log.error("util_notify.send", "发送通知失败", "未配置 `config.NOTIFY_TYPE`")
  237. return true
  238. end
  239. local code, headers, body = notify(msg)
  240. if code == nil then
  241. return true
  242. end
  243. if code == 200 then
  244. log.info("util_notify.send", "发送通知成功", "code:", code, "body:", body)
  245. return true
  246. else
  247. log.error("util_notify.send", "发送通知失败", "code:", code, "body:", body)
  248. return false
  249. end
  250. end
  251. --- 添加到消息队列
  252. -- @param msg 消息内容
  253. function util_notify.add(msg)
  254. table.insert(msg_queue, msg)
  255. log.debug("util_notify.add", "添加到消息队列, 当前队列长度:", #msg_queue)
  256. end
  257. -- 轮询消息队列
  258. -- 发送成功则从消息队列中删除
  259. -- 发送失败则等待下次轮询
  260. local function poll()
  261. local msg
  262. while true do
  263. -- 消息队列非空, 且网络已注册
  264. if #msg_queue > 0 and mobile.status() == 1 then
  265. log.debug("util_notify.poll", "轮询消息队列中...", "当前队列长度:", #msg_queue)
  266. msg = msg_queue[1]
  267. if util_notify.send(msg) then
  268. table.remove(msg_queue, 1)
  269. sys.wait(100)
  270. else
  271. sys.wait(2000)
  272. end
  273. else
  274. sys.wait(350)
  275. end
  276. end
  277. end
  278. sys.taskInit(poll)
  279. return util_notify