哪吒面板V1 + CF配置

# TG通知

  1. 找到BotFather创建bot,拿到API (TG_TOKEN),找到@userinfobot 获得user ID(CHAT_ID)
  2. 进入cloud flare workers,创建一个新worker
    1. 脚本信息如下
       export default {
        async fetch(req, env) {
          // 健康检查
          if (req.method === "GET") return new Response("OK", { status: 200 });
      
          const ct = req.headers.get("content-type") || "";
          let b = {};
          try {
            if (ct.includes("application/json")) {
              b = await req.json();
            } else if (ct.includes("application/x-www-form-urlencoded")) {
              const f = await req.formData();
              b = Object.fromEntries(f.entries());
            } else {
              return new Response("Unsupported Content-Type", { status: 415 });
            }
          } catch (e) {
            return new Response("Bad Request: invalid body", { status: 400 });
          }
      
          // ------- helpers -------
          const esc = s => String(s ?? "")
            .replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
          const num = x => Number(x || 0);
          const fmtBps = (Bps) => {
            const bit = num(Bps) * 8;
            if (bit >= 1e9) return (bit/1e9).toFixed(2) + " Gbps";
            if (bit >= 1e6) return (bit/1e6).toFixed(2) + " Mbps";
            if (bit >= 1e3) return (bit/1e3).toFixed(2) + " Kbps";
            return bit.toFixed(0) + " bps";
          };
          const fmtBytesBin = (bytes) => {
            const v = num(bytes), KiB = 1024, MiB = KiB**2, GiB = KiB**3, TiB = KiB**4;
            if (v >= TiB) return (v/TiB).toFixed(2) + " TiB";
            if (v >= GiB) return (v/GiB).toFixed(2) + " GiB";
            if (v >= MiB) return (v/MiB).toFixed(2) + " MiB";
            if (v >= KiB) return (v/KiB).toFixed(2) + " KiB";
            return v + " B";
          };
          const fmtPct = v => Number(v || 0).toFixed(2) + "%";
          const fmtLoad = v => isFinite(num(v)) ? num(v).toFixed(2) : "—";
      
          // 兼容 msg / event
          const eventStr = String(b.msg ?? b.event ?? "");
          const isRecovery = eventStr.includes("恢复");
          const icon = isRecovery ? "✅" : "🚨";
          const title = isRecovery ? "恢复" : "告警";
      
          // ------- build message -------
          const lines = [];
          lines.push(`${icon} ${title}${esc(b.name)} (${esc(b.ip)})`); if (b.datetime) lines.push(`时间:${esc(b.datetime)}`); lines.push(`IN ${fmtBps(b.net_in)} | OUT ${fmtBps(b.net_out)}`); lines.push(`Load 1/5/15: ${fmtLoad(b.load1)} / ${fmtLoad(b.load5)} / ${fmtLoad(b.load15)}`); lines.push(`CPU ${fmtPct(b.cpu)} | MEM ${fmtBytesBin(b.mem)} | DISK ${fmtBytesBin(b.disk)}`); if (eventStr) lines.push(`${esc(eventStr)}`); let text = lines.join("\n"); if (text.length > 4000) text = text.slice(0, 4000) + "\n…"; // ------- send to Telegram ------- if (!env.TG_TOKEN || !env.CHAT_ID) { return new Response("Missing TG_TOKEN/CHAT_ID", { status: 500 }); } try { const tg = await fetch(`https://api.telegram.org/bot${env.TG_TOKEN}/sendMessage`, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ chat_id: env.CHAT_ID, text, parse_mode: "HTML", disable_web_page_preview: true }) }); const body = await tg.text(); return new Response(body, { status: tg.status }); } catch (e) { return new Response("Upstream error: " + (e && e.message || String(e)), { status: 502 }); } } }
    2. 返回在设置 –> 域和路由 –> 变量和机密中创建环境变量
      类型 名称
      纯文本 CHAT_ID 你的User ID

       

       

      密钥 TG_TOKEN 你的Bot token
    3. 部署,并记录你的worker url
  3. 进入哪吒面板后台,创建新通知
    1. URL 填写之前获得的woker url
    2. 请求方式:POST
    3. 类型:JSON
    4. 请求头:不填也可以
    5. 请求体:
       {"datetime":"#DATETIME#","name":"#SERVER.NAME#","ip":"#SERVER.IP#","cpu":"#SERVER.CPU#","mem":"#SERVER.MEM#","disk":"#SERVER.DISK#","net_in":"#SERVER.NETINSPEED#","net_out":"#SERVER.NETOUTSPEED#","load1":"#SERVER.LOAD1#","load5":"#SERVER.LOAD5#","load15":"#SERVER.LOAD15#","msg":"#NEZHA#"}
    6. 确认
  4. 通知同一tab中分组 –>通知,创建一个通知分组,取个名字,加入刚刚woker进入该通知组
  5. 通知 –>警报规则
    1. 示例规则: [{“type”:”cpu”,”min”:90,”duration”:900,”cover”:0}], [{“type”:”disk”,”min”:95,”duration”:900,”cover”:0}], [{“type”:”net_in_speed”,”min”:12500000,”duration”:900,”cover”:0}]
    2. 通知组,选刚刚创建的通知分组
    3. 选择触发模式
    4. 启用,确认
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇