生成 API Token

VirtFusion 的面板长下面这样,如果你的 VPS 后台是这样的,那就是 VirtFusion

部分 VPS 商会把这部分内容内嵌在网页里,这样展示出来的页面会砍掉最顶上那条 Dashboard,像这样:

但是大同小异,对于这种被砍掉顶部条的,可以用浏览器的「查看框架源代码」功能跳转到新页面后,删去 URL 中的 view-source: 后就是实际后台面板的路径。路径中 /server/ 后的内容即为 service_id

现在,我们得到了完整的后台面板页面,依次点击「Account」→「API」即可进入到生成 API Token(词元) 页面,点击「Generate Token」即可生成 Token(词元) ,只会展示一次,请及时备份或者复制

首先点击上图中的「API Documentation」,确认好实际的 API 调用端点,一般为 https://面板域名/api

配置 Gotify

Gotify 如何部署就不赘述了,Docker Compose 一把梭!

在 Apps 中新建应用,获取 Gotify Token

计划任务

把下面的内容添加到 sh 文件里,自行使用 crontab 等定时触发调用

#!/bin/bash

# ==========================================
# 1. 配置区域 (请在此处填入你的实际信息)
# ==========================================

# VirtFusion 配置
VF_API_URL="https://面板域名/api/server"
SERVER_ID="你的服务器ID,参考上文"
VF_TOKEN="替换为你的 VirtFusion API Token"

# Gotify 配置
GOTIFY_URL="https://你的Gotify服务器地址,不要加结尾的 /" 
GOTIFY_TOKEN="你的 Gotify 应用 Token"
GOTIFY_PRIORITY=5                       # 消息优先级 (默认 5)

# 数据存储配置 (用于记录上次的流量,以此计算增量)
# 默认存储在当前用户的家目录下,以 serverId 命名防止多台机器冲突
STATE_FILE="$HOME/.vf_traffic_${SERVER_ID}_last.txt"

# ==========================================
# 2. 字节转换函数 (将 Bytes 转换为 KB/MB/GB)
# ==========================================
convert_bytes() {
    local bytes=$1
    if [[ -z "$bytes" || "$bytes" == "null" ]]; then
        echo "0 B"
        return
    fi
    
    echo "$bytes" | awk '
    function human(x) {
        s="B KB MB GB TB PB"
        split(s, v, " ")
        i=1
        while (x >= 1024 && i < 6) {
            x /= 1024
            i++
        }
        return sprintf("%.2f %s", x, v[i])
    }
    {print human($1)}'
}

# ==========================================
# 3. 获取并解析 VirtFusion 数据
# ==========================================
echo "正在获取服务器数据..."

RESPONSE=$(curl -s -X GET "${VF_API_URL}/${SERVER_ID}?state=true" \
  -H "Accept: application/json" \
  -H "Authorization: Bearer ${VF_TOKEN}")

if ! echo "$RESPONSE" | jq -e . >/dev/null 2>&1; then
    echo "错误: VirtFusion API 返回了无效的 JSON 或请求失败。"
    exit 1
fi

SERVER_NAME=$(echo "$RESPONSE" | jq -r '.data.name')
STATE_STATUS=$(echo "$RESPONSE" | jq -r '.data.state')

if [[ "$STATE_STATUS" == "null" ]]; then
    MESSAGE="⚠️ 服务器 $SERVER_NAME 当前未运行 (State 为 null),无法获取实时流量数据。"
    TITLE="VirtFusion 流量报告 - $SERVER_NAME (离线)"
else
    # 提取当前流量字节数
    RX_BYTES=$(echo "$RESPONSE" | jq -r '.data.state.network.primary.traffic.rx')
    TX_BYTES=$(echo "$RESPONSE" | jq -r '.data.state.network.primary.traffic.tx')
    TOTAL_BYTES=$(echo "$RESPONSE" | jq -r '.data.state.network.primary.traffic.total')

    # ==========================================
    # 4. 计算自上次以来的增量流量
    # ==========================================
    DIFF_BYTES=0
    DIFF_HUMAN=""

    if [[ -f "$STATE_FILE" ]]; then
        # 读取上次记录的总流量
        PREV_TOTAL=$(cat "$STATE_FILE")
        
        # 判断是否发生了流量重置 (当前流量 < 上次流量)
        if (( TOTAL_BYTES >= PREV_TOTAL )); then
            DIFF_BYTES=$(( TOTAL_BYTES - PREV_TOTAL ))
            DIFF_HUMAN=$(convert_bytes "$DIFF_BYTES")
        else
            # 流量被重置了,增量就是当前的全部流量
            DIFF_BYTES=$TOTAL_BYTES
            DIFF_HUMAN="$(convert_bytes "$DIFF_BYTES") (流量周期已重置)"
        fi
    else
        # 第一次运行,没有历史数据
        DIFF_HUMAN="首次记录,无历史对比数据"
    fi

    # 将当前的最新总流量写入文件,供下次运行使用
    echo "$TOTAL_BYTES" > "$STATE_FILE"

    # ==========================================
    # 5. 格式化数据并构建消息
    # ==========================================
    RX_HUMAN=$(convert_bytes "$RX_BYTES")
    TX_HUMAN=$(convert_bytes "$TX_BYTES")
    TOTAL_HUMAN=$(convert_bytes "$TOTAL_BYTES")

    TITLE="📊 流量报告: $SERVER_NAME"
    MESSAGE="昨日已用:$DIFF_HUMAN
本月已用:$TX_HUMAN
出入站总消耗: $TOTAL_HUMAN
---
详细明细:
⬇️ 入站 (下载): $RX_HUMAN
⬆️ 出站 (上传): $TX_HUMAN"
fi

# ==========================================
# 6. 发送 Gotify 通知
# ==========================================
echo "正在发送 Gotify 通知..."

HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" -X POST "${GOTIFY_URL}/message?token=${GOTIFY_TOKEN}" \
  -F "title=${TITLE}" \
  -F "message=${MESSAGE}" \
  -F "priority=${GOTIFY_PRIORITY}" \
  -F "extras={\"client::display\": {\"contentType\": \"text/markdown\"}}")

if [[ "$HTTP_STATUS" -eq 200 ]]; then
    echo "✅ 通知发送成功!"
    echo "--- 消息预览 ---"
    echo -e "$MESSAGE"
else
    echo "❌ 发送失败,Gotify HTTP 状态码: $HTTP_STATUS"
fi

如果你在使用 1Panel 等面板,那直接把这部分代码添加到后台,执行和记录上会更方便点, 「1Panel后台」→「计划任务」→「脚本库」,并添加计划任务指定好触发时间

效果

我自己设置的是每天 0点0分 自动触发一次,这样就会把数据推送到我所有安装了 Gotify 的设备上

注⚠️:脚本默认统计的「昨日已用」数据是基于上一次调用这个脚本时候的流量用量计算的,也就是说如果你不是让他自动在每天固定时间触发,而是手动触发的话,那「昨日已用」仅代表你上次执行到这次执行之间消耗的流量情况