博客上的评论系统是用的Twikoo的,它是有评论邮件提醒功能的,我尝试了但是没有成功,所以就想用之前的自己搭的
Server酱
来实现新评论提醒功能。
0.抓包分析
整个分析下来,主要的是请求的内容不一样,请求的URL地址都是一样的。https://tcb-api.tencentcloudapi.com/web?env=XXXXX,我是基于腾讯云函数搭建的,具体的教程之前的文章中也有写过,这边就不啰嗦了,这里主要用到两个函数。一个是刷新Token的,一个是获得评论的。内容如下:
// 刷新Token
{
"action": "auth.fetchAccessTokenWithRefreshToken",
"dataVersion": "2020-01-10",
"env": "$env",
"refresh_token": "$refresh_token",
"seqId": "$seqId"
}
// 获得评论
{
"action": "functions.invokeFunction",
"dataVersion": "2020-01-10",
"env": "$env",
"function_name": "twikoo",
"request_data": "{\"event\":\"COMMENT_GET_FOR_ADMIN\",\"per\":5,\"page\":1}",
"access_token": "$access_token",
"seqId": "$seqId"
};
这边有个小坑,就是用Node-RED
的时候一直报如下的错误:
{
"code": "INVALID_APP_SIGN",
"message": "jwt must be provided",
"requestId": "bf131bb336c26"
}
我用PostMan
和ApiPost
发送请求都能够成功,但是一到Node-RED
上就报错,百思不解,最后把头全部搞过去,一个个排除,最后发现是头要加上origin这个头才行。加上这个之后,报错就变成了:
{
"code": "ACCESS_TOKEN_EXPIRED",
"message": "Access_token expired",
"requestId": "0e3de4a761649"
}
这个错误很明显了,Token过期了,所以只要刷新下Token一下就行了。
1.开始写流
有了上面的铺垫,写起来就很简单了,有两种做法,一种是上来直接调用刷新token然后再调用获取评论,还有一种做法是先用缓存的token请求调用获取评论,如果返回token过期,则再刷新token再去请求。这边图省事就直接用第一种。
JSON信息如下:
[
{
"id": "4b5ebb669cd0e232",
"type": "comment",
"z": "0217ee1fba23525d",
"name": "网站评论数更新通知",
"info": "",
"x": 90,
"y": 1280,
"wires": []
},
{
"id": "2eb6253b6231925f",
"type": "inject",
"z": "0217ee1fba23525d",
"name": "",
"props": [],
"repeat": "3600",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"x": 70,
"y": 1320,
"wires": [
[
"de4ca953468e4720"
]
]
},
{
"id": "de4ca953468e4720",
"type": "function",
"z": "0217ee1fba23525d",
"name": "刷新token",
"func": "var headers = {\n \"content-type\": \"application/json;charset=UTF-8\",\n \"origin\": \"https://www.wangxingyang.com\"\n};\n\nvar data = {\"action\":\"auth.fetchAccessTokenWithRefreshToken\",\"dataVersion\":\"2020-01-10\",\"env\":\"EEEEEE\",\"refresh_token\":\"EEEEE\",\"seqId\":\"437ef9ewde67\"};\n\nmsg.headers = headers;\n\nmsg.payload = JSON.stringify(data);\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 200,
"y": 1320,
"wires": [
[
"439f033b91296d4d"
]
]
},
{
"id": "439f033b91296d4d",
"type": "http request",
"z": "0217ee1fba23525d",
"name": "",
"method": "POST",
"ret": "obj",
"paytoqs": "ignore",
"url": "https://tcb-api.tencentcloudapi.com/web?env=EEEEE",
"tls": "",
"persist": true,
"proxy": "",
"authType": "",
"senderr": false,
"x": 340,
"y": 1320,
"wires": [
[
"1093b292b44df7cf"
]
]
},
{
"id": "1093b292b44df7cf",
"type": "function",
"z": "0217ee1fba23525d",
"name": "请求获取评论",
"func": "var headers = {\n \"content-type\": \"application/json;charset=UTF-8\",\n \"origin\": \"https://www.wangxingyang.com\"\n};\n\nvar data = {\n\t\"action\": \"functions.invokeFunction\",\n\t\"dataVersion\": \"2020-01-10\",\n\t\"env\": \"EEEEE\",\n\t\"function_name\": \"twikoo\",\n\t\"request_data\": \"{\\\"event\\\":\\\"COMMENT_GET_FOR_ADMIN\\\",\\\"per\\\":5,\\\"page\\\":1}\",\n\t\"access_token\": msg.payload.access_token,\n\t\"seqId\": \"c854eedewsc6\"\n};\n\nmsg.headers = headers;\n\nmsg.payload = JSON.stringify(data);\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 500,
"y": 1320,
"wires": [
[
"f7ce907edcd55bcb"
]
]
},
{
"id": "f7ce907edcd55bcb",
"type": "http request",
"z": "0217ee1fba23525d",
"name": "",
"method": "POST",
"ret": "obj",
"paytoqs": "ignore",
"url": "https://tcb-api.tencentcloudapi.com/web?env=EEEEEE",
"tls": "",
"persist": true,
"proxy": "",
"authType": "",
"senderr": false,
"x": 660,
"y": 1320,
"wires": [
[
"9898c4f905717a13"
]
]
},
{
"id": "9898c4f905717a13",
"type": "json",
"z": "0217ee1fba23525d",
"name": "",
"property": "payload.data.response_data",
"action": "",
"pretty": false,
"x": 790,
"y": 1320,
"wires": [
[
"7c1a5eb76c9ab46a",
"d64dd8d502b22cff"
]
]
},
{
"id": "7c1a5eb76c9ab46a",
"type": "rbe",
"z": "0217ee1fba23525d",
"name": "",
"func": "rbei",
"gap": "",
"start": "",
"inout": "out",
"septopics": true,
"property": "payload.data.response_data.count",
"topi": "topic",
"x": 910,
"y": 1320,
"wires": [
[
"9119b6c2921a0102"
]
]
},
{
"id": "d48e19601ad7ae9f",
"type": "http request",
"z": "0217ee1fba23525d",
"name": "发送通知",
"method": "GET",
"ret": "txt",
"paytoqs": "ignore",
"url": "https://EEEEEEE.tencentcs.com/release/wecomchan?sendkey=EEEEE&msg_type=text&msg={{msgText}}&to_user=EEEEE",
"tls": "",
"persist": false,
"proxy": "",
"authType": "",
"senderr": false,
"x": 1220,
"y": 1320,
"wires": [
[]
]
},
{
"id": "9119b6c2921a0102",
"type": "function",
"z": "0217ee1fba23525d",
"name": "评论变动赋值",
"func": "let nick = msg.payload.data.response_data.data[0].nick;\nlet url = msg.payload.data.response_data.data[0].link;\nlet commentText = msg.payload.data.response_data.data[0].commentText;\n\nmsg.msgText = \"📢|[\" + nick + \"] 在博客中评论道: [ \" + commentText + \" ];\"\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 1060,
"y": 1320,
"wires": [
[
"d48e19601ad7ae9f"
]
]
},
{
"id": "d64dd8d502b22cff",
"type": "debug",
"z": "0217ee1fba23525d",
"name": "",
"active": true,
"tosidebar": true,
"console": true,
"tostatus": false,
"complete": "true",
"targetType": "full",
"statusVal": "",
"statusType": "auto",
"x": 910,
"y": 1280,
"wires": []
}
]
最后的通知结果如下:
这样就搞定了。因为没有什么实时性要求,所以这边是每个小时获取一次。如果获取时间间隔比较短,建议把Token缓存起来。
2.写在最后
很多时候想做一些事情,但是如果你没有沉下心来做,很多时候你只会停留在想象的阶段,所以做事还是得动手。