# Web Data Monitor User Guide

## Introduction

Web Data Monitor： [Chrome 商店链接](https://chrome.google.com/webstore/detail/web-data-monitor/jicncdodkpdlndbppohjljcggoemckjp)\
这是一个自定义可编程的网络数据监控框架。\
扩展提供了基于 Javascript 编程语言以及 jQuery 工具库的支持让用户可以编程自定义监控及提醒逻辑，\
通过它用户可以监控任意网页或接口数据变更，实现如股价提醒，商品打折提醒，剧漫更新提醒，RSS更新提醒，直播通知，新邮件提，网站签到等等功能。

## Simple Document​​​

![添加任务界面](/files/-M4AAcp0Zi6f5Hd-CiAL)

1. ​任务名称：用于任务说明以及唯一标记
2. 相关页面：点击提醒时默认打开页面的url
3. 监测周期：调用网络请求周期
4. 允许弹窗提醒：弹窗提醒控制（优先级高于代码逻辑）
5. 请求参数：基础参数已列出，具体可参考 jQuery ajax请求参数 API 文档（如遇网站复杂请求参数可以通过Chrome浏览器开发者工具拿到curl再通过[工具网站](https://curlconverter.com/javascript-jquery/)转换获取）
6. 数据处理：相关代码说明如下

```javascript
//以下是几个预置变量说明
//queryResult  调用jQuery ajax请求返回的结果，格式根据请求参数可以是JSON或者HTML文本或者XML
//presetPageUrl 配置中的相关页面url
//isRefresh 是否是主动点击刷新标志位
//lastReturn 上一次处理的返回，具体可看最下return返回代码
 
var highlight = lastReturn.highlight;//是否高亮显示
var popup = lastReturn.popup;//是否弹框提醒
var url = presetPageUrl;//点击打开页面url
var content = lastReturn.content;//条目显示文本
var extra = lastReturn.extra;//额外数据
//以上部分为默认设置一般无需修改
 
//此处添加处理代码，根据queryResult和isRefresh确定highlight,popup,url,content,extra
//此处还可以添加额外的操作，如调用其他API实现邮件微信提醒等
 
//返回处理结果一般无需修改
//扩展根据返回结果进行高亮，弹窗，显示说明等操作
return {'highlight':highlight,'popup':popup,'url':url,'content':content,'extra':extra};
```

## Basic Usage​

### 各种更新提醒

```javascript
//queryResult
//presetPageUrl  isRefresh  lastReturn
var highlight = lastReturn.highlight;
var popup = lastReturn.popup;
var url = presetPageUrl;
var content = lastReturn.content;
var extra = lastReturn.extra;
 
//此处可以通过CSS选择器，正则或者读取JSON对象来定位获取更新后不相同的部分
//此示例基本可以实现类似Chrome扩展的所有功能
queryResult = $(queryResult).find('#video_list_li a:last').text();//1 
 
content = '更新到了 ' + queryResult;
if (content != lastReturn.content) {
    highlight = true;
    popup = true;
}
 
 
return {'highlight':highlight,'popup':popup,'url':url,'content':content,'extra':extra};
```

{% file src="/files/-M4EOcjlVu7aYnSDMVtw" %}

{% file src="/files/-M4AQzv\_cIbe9mZufmPd" %}

{% file src="/files/-M4AQrMxFw764KhiS4\_9" %}

### 邮件提醒示例

```javascript
//queryResult
//presetPageUrl  isRefresh  lastReturn
var highlight = lastReturn.highlight;
var popup = lastReturn.popup;
var url = presetPageUrl;
var content = lastReturn.content;
var extra = lastReturn.extra;
 

if (queryResult.indexOf('unreadMessageCount') == -1) {//1 此处为判断登陆的代码，不同邮箱不同
    highlight = true;
    popup = content != '登录失效，请重新登录！';
    content = '登录失效，请重新登录！';
} else {
    //2 此处为用于获取邮件数量的代码
    var count = Number(new RegExp('folderStats.*?\'unreadMessageCount\':(.*?),', 'ig').exec(queryResult)[1]); 
    extra = count;
    var lastCount = lastReturn.extra;
 
    content = count == 0 ? '暂无新邮件' : '收到 ' + count + ' 封新邮件';
    if (count == 0) {
        highlight = false;
        popup = false;
    }
    else if (count > lastCount) {
        highlight = true;
        popup = true;
    } else if (count > 0 && isRefresh) {
        highlight = true;
        popup = false;
    } else if (count < lastCount) {
        popup = false;
    }
}
 
 
return {'highlight':highlight,'popup':popup,'url':url,'content':content,'extra':extra};
```

{% file src="/files/-M4AQrMv-Z2ghKd8qQvd" %}

{% file src="/files/-M4E\_PeTpRP8wQk2VrQB" %}

### 直播提醒示例

```javascript
//queryResult
//presetPageUrl  isRefresh  lastReturn
var highlight = lastReturn.highlight;
var popup = lastReturn.popup;
var url = presetPageUrl;
var content = lastReturn.content;
var extra = lastReturn.extra;


if (queryResult.error == -1) {//1 判断登陆状态
    highlight = true;
    popup = content != '登录失效，请重新登录！';
    content = '登陆失效，请重新登录！';
} else {
    var onLiveInfoList = extra ? JSON.parse(extra) : [];
    var nowOnLiveInfoList = [];
    var newOnline = false;
    var newOffline = false;
    var baseUrl = 'https://www.douyu.com';//2 用于拼接完整直播间网址，一般直播网站都会需要

    queryResult = queryResult.data.list;//3 从JSON数据中获取到直播间列表
    for (let i = 0; i < queryResult.length; i++) {
        if (queryResult[i].show_status == 1) {//4 判断是否在线
            onLiveInfo = {
                'name': queryResult[i].nickname,//5 直播间名
                'subUrl': queryResult[i].url,//6 直播间子网址
            };
            nowOnLiveInfoList.push(onLiveInfo);
        }
    }

    //维护onLiveInfoList
    //移除已下线
    var newOnlineNameMap = {};
    for (let i = 0; i < nowOnLiveInfoList.length; i++) {
        newOnlineNameMap[nowOnLiveInfoList[i].name] = i;
    }
    for (let i = onLiveInfoList.length - 1; i >= 0; i--) {
        if (newOnlineNameMap[onLiveInfoList[i].name] == undefined) {
            newOffline = true;
            onLiveInfoList.splice(i, 1);
        }
    }
    //添加新上线
    var onLiveNameMap = {};
    for (let i = 0; i < onLiveInfoList.length; i++) {
        onLiveNameMap[onLiveInfoList[i].name] = i;
    }
    for (let i = 0; i < nowOnLiveInfoList.length; i++) {
        if (onLiveNameMap[nowOnLiveInfoList[i].name] == undefined) {
            newOnline = true;
            onLiveInfoList.unshift(nowOnLiveInfoList[i]);
        }
    }
    extra = JSON.stringify(onLiveInfoList);

    for (let i = 0; i < onLiveInfoList.length; i++) {
        if (i == 0) {
            content = '当前有' + onLiveInfoList.length + '人正在直播：\n';
            content += onLiveInfoList[i].name + '(最新) ';
            url = baseUrl + onLiveInfoList[i].subUrl;
        } else {
            content += ', ' + onLiveInfoList[i].name;
        }
    }
    if (onLiveInfoList.length == 0) {
        content = '暂无人直播';
        highlight = false;
        popup = false;
    } else if (newOnline) {
        highlight = true;
        popup = true;
    } else if (onLiveInfoList.length > 0 && isRefresh) {
        highlight = true;
        popup = false;
    } else if (onLiveInfoList.length > 0 && newOffline) {
        popup = false;
    }
}


return {'highlight': highlight, 'popup': popup, 'url': url, 'content': content, 'extra': extra};
```

{% file src="/files/-M4AQrMndpVG5bph1ULc" %}

### 站点签到示例

```javascript
//queryResult
//presetPageUrl  isRefresh  lastReturn
var highlight = lastReturn.highlight;
var popup = lastReturn.popup;
var url = presetPageUrl;
var content = lastReturn.content;
var extra = lastReturn.extra;
 
 
if ($(queryResult).find('.inner').length == 0) {//1
    highlight = true;
    popup = content != '登录失效，请重新登录！';
    content = '登录失效，请重新登录！';
} else {
    if (queryResult.indexOf('领取今日的登录奖励') != -1) {//2
        var once = new RegExp(/\?once=(\d*?)\';/, 'ig').exec(queryResult)[1];
        $.ajax({
            "type": "get",
            "async": false,
            "url": "https://www.v2ex.com/mission/daily/redeem?once=" + once,
            "dataType": "html",
            "timeout": 7000,
            success: function (res) {
                highlight = true;
                content = '签到成功';
            }
        });
    } else {
        highlight = false;
        content = '已签到';
    }
}
 
 
return {'highlight': highlight, 'popup': popup, 'url': url, 'content': content, 'extra': extra};
```

{% file src="/files/-M8v33PP8leCkfQEvii-" %}

{% file src="/files/-M8v37wPV1FzNvgfg70Y" %}

## Other Extensions

最后附上本人开发的另外几个实用的 Chrome 扩展

Tab Freezer： [Chrome 商店链接](https://chrome.google.com/webstore/detail/tab-freezer/opmcmbcmkbobnbloaanbgminfokciinp)\
这个扩展是提供给海量标签页综合症 TMTS (Too Many Tabs Syndrome) 患者的（比如我自己），冻结页面节省内存（然后打开更多的标签，，？？？），相比于其他 OneTab 等扩展，有两个优点，1. 标签页不会关闭；2. 点击即可生效，不会再弹出扩展弹框

Volume Manager： [Chrome 商店链接](https://chrome.google.com/webstore/detail/volume-manager/ogpbjlhpdjmcbkocjibemdmblffnfkmm)\
这个扩展是用来控制页面内音频视频的音量的，应该是 Chrome 市场里最完善的一款音量控制扩展了。\
不仅支持 HTML5 标准的音频视频同时也支持 Flash，最关键的是可以记忆每个页面或者网站的音量修改配置。

Regex Extractor： [Chrome 商店链接](https://chrome.google.com/webstore/detail/regex-extracter/hhnkaciopdblfpomobniofiiecfiibph)\
这个扩展的功能简单来说就是用正则表达式查询当前网页内的文本，默认如果正则中有捕获就返回捕获部分的文本，\
支持文本、节点和源码三种模式，常用的场景比如：批量获取邮箱，批量获取图片链接，批量获取动漫电视剧每集的下载链接等。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://zhangbohun.gitbook.io/web-data-monitor/master.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
