[0.0.4迭代]活动期限/周本通知器 (#2604)

* feat(notice): 添加WebSocket独立通知功能并重构通知系统

- 实现WebSocket通知功能,支持私聊和群聊模式
- 添加通知类型配置选项,支持BGI通知、独立通知或两者同时使用
- 新增WebSocket相关配置项包括代理URL、连接地址和认证令牌
- 重构通知发送逻辑,支持多种通知类型的消息格式
- 添加@用户功能和多种消息类型支持
- 更新manifest.json添加网络请求权限配置
- 优化代码结构,使用异步初始化加载工具模块

* feat(ActivitySwitchNotice): 添加独立通知功能支持WebSocket推送

- 新增独立通知配置功能,支持通过WebSocket发送通知
- 新增ws.js模块实现WebSocket通知功能
- 新增noticeType配置选项用于选择通知模式
- 新增ws_proxy_url、ws_url、ws_token配置选项
- 新增action、send_id、at_list配置选项用于发送设置
- 更新README文档添加独立通知配置说明和使用要求
- 修复OCR识别函数名称从OcrRemainingTime改为OcrKey

* fix(ActivitySwitchNotice): 修复设置选项数组格式

- 修复了通知模式选项数组中缺少逗号的问题
- 确保JSON格式正确性以避免解析错误

* refactor(notice): 重构通知工具类并修复配置引用问题

- 将 noticeUtil.send 方法重命名为 sendText 以明确功能
- 修复配置对象引用问题,将 config 重命名为 configNotice 避免冲突
- 为 sendNotice 函数添加默认参数和调试日志
- 更新条件判断逻辑,使用 map.size 检查空值
- 修复 ws 模块中的配置对象引用,将 config 重命名为 configWs
- 重构 ws 模块初始化逻辑,确保配置正确加载
- 修复变量命名冲突,将 token 参数重命名为 wsToken
- 更新模块初始化顺序,调整 activity 工具的加载位置

* docs(ActivitySwitchNotice): 更新文档说明独立通知配置和WsProxy部署

- 更新独立通知功能说明,添加WsProxy依赖提示
- 简化settings.json文件路径引用
- 移除多余的配置示例分隔符
- 添加WsProxy部署指南和Docker镜像使用说明
- 整理文档结构,优化内容排版

* docs(ActivitySwitchNotice): 更新 README 文档完善功能说明和配置选项

- 添加了独立通知功能的详细配置说明
- 更新了设置表格格式和内容描述
- 增加了 WsProxy 部署指南和 Docker 配置示例
- 完善了核心模块和配置选项文档
- 修正了文档格式和链接引用问题

* docs(ActivitySwitchNotice): 更新 README 文档中的链接和函数名

- 修复 settings.json 链接格式
- 将 send 函数名更正为 sendText

* chore(ActivitySwitchNotice): 更新版本号

- 将版本号从 0.0.3 更新到 0.4
- 保持其他配置项不变

* docs(ActivitySwitchNotice): 更新版本历史文档

- 将版本 0.0.4 的发布状态更新为具体发布日期 2026-01-01
- 保持独立通知配置功能说明
- 保留 WebSocket 通知功能描述
- 维护版本历史记录的准确性
This commit is contained in:
云端客
2026-01-01 20:20:44 +08:00
committed by GitHub
parent 7bf8fe86fd
commit a3de5b65d6
7 changed files with 428 additions and 60 deletions

View File

@@ -4,6 +4,8 @@
这是一个用于《原神》游戏的自动化脚本工具,主要功能是自动检测游戏内活动的剩余时间,并在活动即将结束时/每周指定日期自动提醒征讨领域减半剩余次数发送通知提醒玩家。
---
## 功能特性
- ✅ 自动返回游戏主界面并打开活动页面
@@ -16,6 +18,8 @@
- ✅ 防重复检测机制
- ✅ 异常处理和错误恢复
- ✅ 自动提醒征讨领域减半剩余次数(默认`周日`提醒可配置)
- ✅ 支持独立通知功能(`0.0.4`版本新增 因BGI不支持WebSocket,需搭配WsProxy+开启JS HTTP
权限使用)[前往WsProxy部署](https://github.com/Kirito520Asuna/WsProxy)
---
@@ -31,30 +35,39 @@
#### 2. 基础设置
`settings.json` 中可以配置以下参数:
[settings.json]() 中可以配置以下参数:
| 设置项 | 说明 | 默认值 | 开放 |
|:---------------------------|:-----------------------------------------------|:------------|:--:|
| `toMainUi` | 执行前是否自动返回游戏主界面 | true | v |
| `relationship` | 剩余时间与白名单启用`和`关系(默认`或`关系) | false | v |
| `whiteActivityNameList` | 白名单活动名称(用\|分隔 | 空(监控所有活动) | v |
| `blackActivityNameList` | 名单活动名称(用\|分隔) | 空(无黑名单活动) | v |
| `notifyHoursThreshold` | 通知时间阈值(小时) | 8760365天 | v |
| `activityKey` | 打开活动页面的快捷键 | F5 | v |
| `toTopCount` | 滑动到顶最大尝试次数 | 10 | x |
| `scrollPageCount` | 滑动次数/页 | 4 | x |
| `campaignAreaKey` | 打开征讨领域页面的快捷键 | F1 | v |
| `campaignAreaReminderDay` | 周本提醒日(0-6,0=周日,1=周一,2=周二,3=周三,4=周四,5=周五,6=周六) | 0 | v |
| 设置项 | 说明 | 默认值 | 开放 |
|:--------------------------|:----------------------------------------------|:------|:--:|
| `toMainUi` | 执行前是否自动返回游戏主界面 | true | v |
| `noticeType` | 通知模式默认BGI通知-使用独立通知需要开启JS HTTP权限 | BGI通知 | v |
| `relationship` | 剩余时间与白名单启用`和`关系(默认`或`关系 | false | v |
| `whiteActivityNameList` | 名单活动名称(用\|分隔) | 空(监控所有活动) | v |
| `blackActivityNameList` | 黑名单活动名称(用\|分隔) | 空(无黑名单活动) | v |
| `notifyHoursThreshold` | 通知时间阈值(小时) | 8760365天 | v |
| `activityKey` | 打开活动页面的快捷键 | F5 | v |
| `toTopCount` | 滑动到顶最大尝试次数 | 10 | x |
| `scrollPageCount` | 滑动次数/页 | 4 | x |
| `campaignAreaKey` | 打开征讨领域页面的快捷键 | F1 | v |
| `campaignAreaReminderDay` | 周本提醒日(0-6,0=周日,1=周一,2=周二,3=周三,4=周四,5=周五,6=周六) | 0 | v |
| `ws_proxy_url` | WebSocket代理URL独立通知配置 | http://127.0.0.1:8081/ws-proxy/message/send | v |
| `ws_url` | WebSocket客户端 URL独立通知配置 | ws://127.0.0.1:8080/ | v |
| `ws_token` | WebSocket客户端 token独立通知配置 | 空 | v |
| `action` | 发送类型(私聊/群聊) (独立通知配置) | 私聊 | v |
| `send_id` | 发送ID群号或QQ号对应发送类型 (独立通知配置) | 空 | v |
| `at_list` | @某人列表使用,隔开QQ号 (独立通知配置) | 空 | v |
---
### 使用流程
#### 自动模式(推荐)
1. 启动脚本后,程序会自动:
- 检测当前是否在游戏主界面
- 如未在主界面,自动返回主界面
- 按设定的快捷键打开活动页面
- 开始扫描所有活动
- 检测当前是否在游戏主界面
- 如未在主界面,自动返回主界面
- 按设定的快捷键打开活动页面
- 开始扫描所有活动
#### 手动模式
@@ -62,6 +75,8 @@
2. 确保游戏处于主界面状态
3. 启动脚本开始扫描
---
### 功能详解
#### 活动筛选
@@ -87,6 +102,57 @@
- 防止因页面滚动不准确造成的重复识别
- 自动判断是否已滚动到页面底部
---
### 独立通知配置0.0.4版本新增)
#### 配置项说明
- **`noticeType`**:
- `BGI通知`: 使用 BetterGI 内置通知
- `独立通知`: 通过 WebSocket 发送通知
- `独立通知和BGI通知`: 同时使用两种方式
- **WebSocket 配置**:
- `ws_proxy_url`: WebSocket 代理 URL默认为 `http://127.0.0.1:8081/ws-proxy/message/send`
- `ws_url`: WebSocket 客户端 URL默认为 `ws://127.0.0.1:8080/`
- `ws_token`: WebSocket 客户端认证令牌(可选)
- **发送配置**:
- `action`: 发送类型,可选 `私聊``群聊`
- `send_id`: 根据 `action` 类型填写群号或 QQ 号
- `at_list`: @ 某人列表,使用逗号分隔多个 QQ 号
#### 使用要求
1. **开启权限**: 需要开启 JS HTTP 权限才能使用独立通知功能
2. **配置服务**: 需要搭建相应的 WebSocket 服务和代理服务器
3. **网络连接**: 确保能够连接到配置的 WebSocket 服务器
#### 配置示例
```json
{
"noticeType": "独立通知",
"ws_proxy_url": "http://127.0.0.1:8081/ws-proxy/message/send",
"ws_url": "ws://127.0.0.1:8080/",
"action": "群聊",
"send_id": "123456789",
"at_list": "987654321,111222333"
}
```
#### 部署 [WsProxy](https://github.com/Kirito520Asuna/WsProxy)
提供docker镜像方便用户快速搭建WebSocket代理服务
```shell
docker pull ghcr.io/kirito520asuna/wsproxy:latest
docker run -d -p 8081:8081 -v /path/to/application-prod.yml:/app/application-prod.yml --name wsproxy ghcr.io/kirito520asuna/wsproxy:latest
```
---
### 注意事项
#### 使用环境要求
@@ -101,11 +167,13 @@
- 🚫 避免切换窗口或最小化游戏
- ⚠️ 如遇异常可重新启动脚本
---
### 高级配置
#### 自定义快捷键
如活动页面不是F5打开可在 `activityKey` 中修改为对应按键。
如活动页面不是F5打开可在 `activityKey` 中修改为对应按键。
如冒险之书页面不是F1打开可在 `campaignAreaKey` 中修改为对应按键。
#### 时间阈值设置
@@ -116,6 +184,16 @@
- 168关注一周内结束的活动
- 720关注一个月内结束的活动
#### 独立通知配置
如果需要使用独立通知功能如发送到QQ群聊需要
1. 开启JS HTTP权限
2. 配置WebSocket相关参数
3. 设置发送类型和ID
---
### 输出示例
通知消息格式如下:
@@ -126,10 +204,6 @@
> 风花节活动 剩余时间1天5小时<还剩 29 小时><即将结束>
```
**`以上为用户使用指南全部内容`**
---
## 文件结构
@@ -139,15 +213,15 @@ ActivitySwitchNotice/
├── utils/
│ ├── activity.js # 核心活动处理逻辑
│ ├── campaignArea.js # 征讨领域提醒功能
── notice.js # 通知发送功能
── notice.js # 通知发送功能
│ └── ws.js # WebSocket通知功能
├── main.js # 主入口文件
├── manifest.json # 插件配置文件
├── settings.json # 用户设置界面定义
└── README.md # 说明文档
```
---
## 核心模块
@@ -159,13 +233,13 @@ ActivitySwitchNotice/
- `scrollPagesByActivity()` - 按页滚动活动列表
- `scrollPagesByActivityToTop()` - 滚动到活动列表顶部
- `parseRemainingTimeToHours()` - 解析剩余时间文本为小时数
- `OcrRemainingTime()` - OCR识别剩余时间
- `OcrKey()` - OCR识别剩余时间
- `activityMain()` - 主流程控制函数
### `notice.js` - 通知模块
- `sendNotice()` - 发送活动提醒通知,按剩余时间排序
- `send()` - 发送普通通知
- `sendText()` - 发送普通通知
### `campaignArea.js` - 征讨领域模块
@@ -173,22 +247,38 @@ ActivitySwitchNotice/
- `getDayOfWeek()` - 获取当前星期信息
- `campaignAreaMain()` - 征讨领域提醒主函数
### `ws.js` - WebSocket通知模块
- `send()` - 发送WebSocket消息
- `sendText()` - 发送文本消息
---
## 配置选项
`settings.json` 中可配置以下参数:
| 配置项 | 类型 | 说明 |
|:---------------------------|:-------:|:--|
| `toMainUi` | Boolean | 是否先返回主界面再执行 |
| `relationship` | Boolean | 剩余时间与白名单启用`和`关系(默认`或`关系) |
| `whiteActivityNameList` | String | 白名单活动名称(用\|分隔) |
| `blackActivityNameList` | String | 名单活动名称(用\|分隔) |
| `notifyHoursThreshold` | Number | 通知阈值(小时) |
| `activityKey` | String | 打开活动页面的快捷键 |
| `toTopCount` | Number | 滑动到顶最大尝试次数 |
| `scrollPageCount` | Number | 滑动次数/页 |
| `campaignAreaKey` | String | 打开冒险之书页面的快捷键 |
| `campaignAreaReminderDay` | Number | 周本提醒日(0-6,0=周日,1=周一,2=周二,3=周三,4=周四,5=周五,6=周六) |
| 配置项 | 类型 | 说明 |
|:--------------------------|:-------:|:----------------------------------------------|
| `toMainUi` | Boolean | 是否先返回主界面再执行 |
| `noticeType` | String | 通知模式BGI通知/独立通知/两者都发送) |
| `relationship` | Boolean | 剩余时间与白名单启用`和`关系(默认`或`关系) |
| `whiteActivityNameList` | String | 名单活动名称(用\|分隔) |
| `blackActivityNameList` | String | 黑名单活动名称(用\|分隔) |
| `notifyHoursThreshold` | Number | 通知阈值(小时) |
| `activityKey` | String | 打开活动页面的快捷键 |
| `toTopCount` | Number | 滑动到顶最大尝试次数 |
| `scrollPageCount` | Number | 滑动次数/页 |
| `campaignAreaKey` | String | 打开冒险之书页面的快捷键 |
| `campaignAreaReminderDay` | Number | 周本提醒日(0-6,0=周日,1=周一,2=周二,3=周三,4=周四,5=周五,6=周六) |
| `ws_proxy_url` | String | WebSocket代理URL独立通知配置 |
| `ws_url` | String | WebSocket客户端 URL独立通知配置 |
| `ws_token` | String | WebSocket客户端 token独立通知配置 |
| `action` | String | 发送类型(私聊/群聊)(独立通知配置) |
| `send_id` | String | 发送ID群号或QQ号对应发送类型 (独立通知配置) |
| `at_list` | String | @某人列表使用,隔开QQ号 (独立通知配置) |
---
## 工作原理
@@ -201,6 +291,8 @@ ActivitySwitchNotice/
7. 解析时间为小时数并过滤(包括黑名单过滤)
8. 发送符合条件的活动提醒
---
## 注意事项
- 请确保游戏分辨率为1920×1080以获得最佳效果
@@ -212,18 +304,26 @@ ActivitySwitchNotice/
## 版本历史
### 0.0.4 (2026-01-01)
- 新增 独立通知配置功能,支持通过 WebSocket 发送通知
- 新增 `ws.js` 模块,实现 WebSocket 通知功能
- 新增 `noticeType` 配置选项,用于选择通知模式
- 新增 `ws_proxy_url``ws_url``ws_token` 配置选项
- 新增 `action``send_id``at_list` 配置选项用于发送设置
### 0.0.3 (2025-12-29)
- 修复 修复了活动过滤逻辑问题,将`activityNameList`更改为`whiteActivityNameList`以保持一致
- 新增 黑名单与白名单的互斥过滤机制,黑名单中剔除白名单
- 新增 在配置中增加了`relationship`参数,用于控制剩余时间与白名单活动的逻辑关系
- 新增 支持剩余时间和白名单的"与"关系和"或"关系配置
- 新增 标记界面显示 `已完成` 的活动
- 新增 标记界面显示 `已完成` 的活动
### 0.0.2 (2025-12-22)
- 新增 征讨领域周次数提醒功能
- 新增 `campaignArea.js` 模块,包含征讨领域相关功能
- 新增 [campaignArea.js]() 模块,包含征讨领域相关功能
- 新增 `campaignAreaKey` 配置选项,用于自定义冒险之书页面快捷键
- 新增 `campaignAreaReminderDay` 配置选项,用于配置提醒日
- 改进 增强滚动到顶部功能的稳定性
@@ -249,5 +349,5 @@ ActivitySwitchNotice/
## 其它
作者:云端客
作者:云端客
脚本反馈邮箱doutianmianxia@qq.com

View File

@@ -1,7 +1,15 @@
eval(file.readTextSync(`utils/activity.js`));
eval(file.readTextSync(`utils/notice.js`));
eval(file.readTextSync(`utils/campaignArea.js`));
async function init() {
let utils=[
"ws",
"notice",
"campaignArea",
"activity",
]
for (let util of utils) {
eval(file.readTextSync(`utils/${util}.js`));
}
log.info("main 初始化完成");
}
// 判断是否在主界面的函数
const isInMainUI = () => {
let captureRegion = captureGameRegion();
@@ -32,6 +40,7 @@ async function toMainUi() {
}
(async function () {
await init();
if (settings.toMainUi){
await toMainUi();
}

View File

@@ -1,6 +1,6 @@
{
"name": "活动期限/周本通知器",
"version": "0.0.3",
"version": "0.0.4",
"description": "",
"settings_ui": "settings.json",
"main": "main.js",
@@ -10,5 +10,9 @@
"links": "https://github.com/Kirito520Asuna"
}
],
"dependencies": []
"dependencies": [],
"http_allowed_urls": [
"https://*",
"http://*",
]
}

View File

@@ -5,6 +5,17 @@
"label": "启用先返回主界面后执行切换",
"default": true
},
{
"name": "noticeType",
"type": "select",
"label": "通知模式(默认BGI通知-使用独立通知需要开启JS HTTP权限)",
"options": [
"BGI通知",
"独立通知",
"独立通知和BGI通知",
],
"default": "BGI通知"
},
{
"name": "relationship",
"type": "checkbox",
@@ -48,5 +59,44 @@
"label": "打开冒险之证按键(不填默认F1)",
"default": "F1"
},
{
"name": "ws_proxy_url",
"type": "input-text",
"label": "独立通知配置:\n==============================\nWebSocketProxyUrl(列:http://127.0.0.1:8081/ws-proxy/message/send)",
"default": "http://127.0.0.1:8081/ws-proxy/message/send"
},
{
"name": "ws_url",
"type": "input-text",
"label": "WebSocket客户端 Url(列:ws://127.0.0.1:8080)",
"default": "ws://127.0.0.1:8080/"
},
{
"name": "ws_token",
"type": "input-text",
"label": "WebSocket客户端 token(没有可不填)",
"default": ""
},
{
"name": "action",
"type": "select",
"label": "发送类型",
"options": [
"私聊",
"群聊"
],
"default": "私聊",
},
{
"name": "send_id",
"type": "input-text",
"label": "(发送id 群号|QQ号 对应发送类型)",
"default": ""
},
{
"name": "at_list",
"type": "input-text",
"label": "@某人列表使用,隔开(QQ号)",
"default": ""
},
]

View File

@@ -111,7 +111,7 @@ async function campaignAreaMain() {
// 如果有剩余次数,则记录日志并发送通知
if (weekJson.count > 0) {
log.info(`本周剩余消耗减半次数:${weekJson.count}`)
await noticeUtil.send(`>|本周剩余消耗减半次数:${weekJson.count}`, '秘境征讨')
await noticeUtil.sendText(`>|本周剩余消耗减半次数:${weekJson.count}`, '秘境征讨')
}
}

View File

@@ -1,13 +1,32 @@
const NoticeType = Object.freeze({
bgi: 'bgi',//BGI通知
independence: 'independence',//独立通知
fromValue(value) {
return Object.keys(this).find(key => this[key] === value);
}
})
const NoticeMap = new Map([
['BGI通知', [{type: NoticeType.bgi}]],
['独立通知', [{type: NoticeType.independence}]],
['独立通知和BGI通知', [{type: NoticeType.independence}, {type: NoticeType.bgi}]],
])
const configNotice = {
noticeList: NoticeMap.get(settings.noticeType),
}
/**
* 发送通知的异步函数
* @param {Map} map - 包含通知内容键值对的Map对象
* @param {string} title - 通知的标题
* @param {boolean} noNotice - 是否不发送通知的标志
*/
async function sendNotice(map, title, noNotice) {
async function sendNotice(map = new Map(), title, noNotice = false) {
log.debug(`sendNotice: map.size=${map.size}, noNotice=${noNotice}`);
// 如果设置了不发送通知且map为空则记录日志并返回
if (noNotice && !map) {
log.info(`无通知内容`)
if ((map.size <= 0) || noNotice) {
log.debug(`if sendNotice: map.size=${map.size}, noNotice=${noNotice}`);
log.info(`[sendNotice]无通知内容`)
return
}
// 按剩余小时升序排序(即将结束的在前)
@@ -20,8 +39,20 @@ async function sendNotice(map, title, noNotice) {
common = common ? `(${common})` : ''
noticeText += `> ${common} ${name} ${info.text} (还剩 ${info.hours} 小时) ${info.desc}\n----\n`;
}
log.debug(`sendNotice: noticeText:{noticeText}`,noticeText);
// 发送通知
notification.send(noticeText)
for (let noticeElement of configNotice.noticeList) {
switch (noticeElement.type) {
case NoticeType.independence:
await wsUtil.sendText(noticeText)
break
case NoticeType.bgi:
notification.send(noticeText)
break
}
}
log.debug(`sendNotice: --end`);
return
}
/**
@@ -30,10 +61,10 @@ async function sendNotice(map, title, noNotice) {
* @param {string} title - 通知标题
* @param {boolean} noNotice - 是否不发送通知的标志
*/
async function send(noticeText, title, noNotice) {
async function sendText(noticeText, title, noNotice) {
// 检查是否有通知内容且设置了不发送通知的标志
if (noticeText && noNotice) {
log.info(`无通知内容`) // 记录日志信息
if ((!noticeText) || noNotice) {
log.info(`sendText 无通知内容`) // 记录日志信息
return // 直接返回,不执行后续操作
}
// 构建通知文本,如果有标题则先添加标题
@@ -41,11 +72,20 @@ async function send(noticeText, title, noNotice) {
// 添加通知内容
text += noticeText
// 发送通知
notification.send(text)
for (let noticeElement of configNotice.noticeList) {
switch (noticeElement.type) {
case NoticeType.independence:
await wsUtil.sendText(text)
break
case NoticeType.bgi:
notification.send(text)
break
}
}
return
}
this.noticeUtil = {
sendNotice,
send,
sendText,
}

View File

@@ -0,0 +1,165 @@
const actionType = Object.freeze({
send_private_msg: 'send_private_msg',//私聊
send_group_msg: 'send_group_msg',//群聊
fromValue(value) {
return Object.keys(this).find(key => this[key] === value);
}
})
const textType = Object.freeze({
text: 'text',//文本
at: 'at',//@某人
image: 'image',//图片
face: 'face',//表情
json: 'json',//卡片消息
record: 'record',//语音
video: 'video',//视频
dice: 'dice',//骰子
rps: 'rps',//猜拳
file: 'file',//文件
node: 'node',//节点
// 添加反向映射(可选)
fromValue(value) {
return Object.keys(this).find(key => this[key] === value);
}
});
const actionMap = new Map([
["私聊", actionType.send_private_msg],
["群聊", actionType.send_group_msg]
]);
// const templateMap = new Map([
// [textType.text, {type: textType.text, data: {text: ""}}],
// [textType.at, {type: textType.at, data: {qq: ""}}],
// ]);
let configWs = {
action: actionMap.get(settings.action),
group_id: settings.send_id,
user_id: settings.send_id,
ws_proxy_url: settings.ws_proxy_url,
ws_url: settings.ws_url,
ws_token: settings.ws_token,
at_list: settings.at_list ? settings.at_list.split(",") : []
}
/**
*
*
* 初始化函数
* 该函数是一个异步函数,用于执行程序的初始化操作
* 目前函数体为空,可以根据实际需求添加初始化逻辑
*/
async function init() {
configWs = {
action: actionMap.get(settings.action),
group_id: settings.send_id,
user_id: settings.send_id,
ws_proxy_url: settings.ws_proxy_url,
ws_url: settings.ws_url,
ws_token: settings.ws_token,
at_list: settings.at_list ? settings.at_list.split(",") : []
}
log.debug(`configWs:{configWs}`, JSON.stringify(configWs))
log.info('ws init success')
}
/**
* 发送消息的异步函数
* @param {string} wsProxyUrl - WebSocket代理URL
* @param {string} wsUrl - WebSocket URL
* @param {string} wsToken - WebSocket令牌
* @param {string} action - 动作类型(群发或私聊)
* @param {number} group_id - 群号
* @param {number} user_id - 用户QQ号
* @param {Array} textList - 文本消息列表
* @param {Array} atList - @用户列表
* @returns {Promise<void>} 无返回值
*/
async function send(wsProxyUrl, wsUrl, wsToken, action, group_id, user_id, textList, atList) {
// 构建基础JSON对象
let json = {
action: action,//send_group_msg群发、send_private_msg私聊
// params: {
// group_id: group_id,//群号
// user_id: user_id,//QQ号
// message: []
// }
}
// 根据动作类型设置不同的参数
switch (action) {
case actionType.send_group_msg:
json.params = {
group_id: group_id,//群号
message: []
};
break;
case actionType.send_private_msg:
json.params = {
user_id: user_id,//QQ号
message: []
}
break;
default:
break;
}
// 添加文本消息到消息列表
for (let text of textList) {
json.params.message.push({
type: textType.text,
data: {
text: `${text}`
}
})
}
// 添加@消息到消息列表
for (let at of atList) {
//@qq
json.params.message.push({
type: textType.at,
data: {
qq: `${at}`
}
})
}
// 构建请求体
let body = {
url: wsUrl,
token: wsToken,
bodyJson: JSON.stringify(json)
}
// 调试日志输出请求体
log.debug(`body:{key}`, JSON.stringify(body))
// 信息日志记录HTTP请求开始
log.info('http request start')
// 发送HTTP请求
const httpResponse = await http.request("POST", wsProxyUrl, JSON.stringify(body), JSON.stringify({
"Content-Type": "application/json"
}));
// 检查响应状态码
if (httpResponse.status_code != 200) {
// 错误日志输出服务器响应
log.error(`服务器返回状态${httpResponse.headers} ${httpResponse.body}`);
return;
}
}
async function sendText(text) {
await init();
let action = configWs.action;
let group_id = configWs.group_id;
let user_id = configWs.user_id;
let wsUrl = configWs.ws_url
let wsProxyUrl = configWs.ws_proxy_url;
let ws_token = configWs.ws_token;
let textList = [text]
let atList = configWs.at_list
await send(wsProxyUrl, wsUrl, ws_token, action, group_id, user_id, textList, atList)
}
this.wsUtil = {
send,
sendText
}