引言
此前经历了一次 JMS 暂停服务,原因是流量用完了,还是一小时内就被人用光了。想到他有一个流量查询的接口迟迟没用上,这就把它对接到 CFW 上去。
原理
我们会看到有一些机场到订阅连接在导入 CFW 后会显示总流量、剩余流量、到期时间,而有一些又没有。其原因是在响应头中含有Subscription-Userinfo
属性(规范参考此处),CFW 会在 Profiles 模块中显示对应的流量及到期信息,响应头常见例子如下:
subscription-userinfo: upload=455727941; download=6174315083; total=1073741824000; expire=1671815872
此外,而 CFW 还支持识别添加在配置文件首行的subscription-userinfo
,格式以#
开头,以;
结尾。示例:
# upload=455727941; download=6174315083; total=1073741824000; expire=1671815872;
其中
upload
或者download
属性允许只有一个。
由此,我们可以利用CFW的预处理脚本功能实现在 Profiles 模块中显示对应的流量及到期信息
实现步骤
在此篇文章中实现步骤已经非常清晰,可以直接一步一步跟着做。
其中需要注意的是脚本替换为如下脚本(其中 url 替换为自己 JMS 服务中的 API 链接):
parsers: # array
- reg: "myprofile.yml"
code: |
module.exports.parse = async (raw, { axios, yaml, notify, console }) => {
// 移除特定注释行
raw = raw.replace(/# upload=\d*; download=\d*; total=\d*; expire=\d*;*\n/gm,'')
// Justmysocks的流量查询API
const url = '(justmysocks带宽统计的API)'
// 解析返回值
const response = await axios.get(url)
const { data, status } = response
if(status === 200 && data){
// 从返回的JSON中提取信息
const { monthly_bw_limit_b, bw_counter_b, bw_reset_day_of_month } = data;
// 获取本月重置日期的时间戳
let currentDate = new Date();
const currentMonth = currentDate.getMonth();
currentDate.setDate(bw_reset_day_of_month);
// 如果月份发生了变化,说明当月没有这一天
if (currentDate.getMonth() !== currentMonth) {
// 设置为当月最后一天
currentDate = new Date(currentDate.getFullYear(), currentMonth + 1, 0);
}
const timestamp = Math.floor(currentDate.getTime() / 1000);
const info = `upload=${bw_counter_b}; total=${monthly_bw_limit_b}; expire=${timestamp};`;
// 将提取的信息添加到原始数据的顶部
return `# ${info}\n${raw}`
}
return raw
}