From a3de5b65d619bd99f758d0178cbe71f2ac59dce8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BA=91=E7=AB=AF=E5=AE=A2?= <107686912+Kirito520Asuna@users.noreply.github.com> Date: Thu, 1 Jan 2026 20:20:44 +0800 Subject: [PATCH] =?UTF-8?q?[0.0.4=E8=BF=AD=E4=BB=A3]=E6=B4=BB=E5=8A=A8?= =?UTF-8?q?=E6=9C=9F=E9=99=90/=E5=91=A8=E6=9C=AC=E9=80=9A=E7=9F=A5?= =?UTF-8?q?=E5=99=A8=20(#2604)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 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 通知功能描述 - 维护版本历史记录的准确性 --- repo/js/ActivitySwitchNotice/README.md | 184 ++++++++++++++---- repo/js/ActivitySwitchNotice/main.js | 17 +- repo/js/ActivitySwitchNotice/manifest.json | 8 +- repo/js/ActivitySwitchNotice/settings.json | 52 ++++- .../utils/campaignArea.js | 2 +- repo/js/ActivitySwitchNotice/utils/notice.js | 60 +++++- repo/js/ActivitySwitchNotice/utils/ws.js | 165 ++++++++++++++++ 7 files changed, 428 insertions(+), 60 deletions(-) create mode 100644 repo/js/ActivitySwitchNotice/utils/ws.js diff --git a/repo/js/ActivitySwitchNotice/README.md b/repo/js/ActivitySwitchNotice/README.md index 8ce01e507..cb9610c1e 100644 --- a/repo/js/ActivitySwitchNotice/README.md +++ b/repo/js/ActivitySwitchNotice/README.md @@ -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` | 通知时间阈值(小时) | 8760(365天) | 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` | 通知时间阈值(小时) | 8760(365天) | 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 \ No newline at end of file diff --git a/repo/js/ActivitySwitchNotice/main.js b/repo/js/ActivitySwitchNotice/main.js index 5a647dd23..a3e5ec4ee 100644 --- a/repo/js/ActivitySwitchNotice/main.js +++ b/repo/js/ActivitySwitchNotice/main.js @@ -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(); } diff --git a/repo/js/ActivitySwitchNotice/manifest.json b/repo/js/ActivitySwitchNotice/manifest.json index 1d1985840..2bc28b1f7 100644 --- a/repo/js/ActivitySwitchNotice/manifest.json +++ b/repo/js/ActivitySwitchNotice/manifest.json @@ -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://*", + ] } \ No newline at end of file diff --git a/repo/js/ActivitySwitchNotice/settings.json b/repo/js/ActivitySwitchNotice/settings.json index c8fd7ce9d..a7cd12d0d 100644 --- a/repo/js/ActivitySwitchNotice/settings.json +++ b/repo/js/ActivitySwitchNotice/settings.json @@ -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": "" + }, ] diff --git a/repo/js/ActivitySwitchNotice/utils/campaignArea.js b/repo/js/ActivitySwitchNotice/utils/campaignArea.js index 541d30667..841391a22 100644 --- a/repo/js/ActivitySwitchNotice/utils/campaignArea.js +++ b/repo/js/ActivitySwitchNotice/utils/campaignArea.js @@ -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}`, '秘境征讨') } } diff --git a/repo/js/ActivitySwitchNotice/utils/notice.js b/repo/js/ActivitySwitchNotice/utils/notice.js index a6cc277aa..807821a2a 100644 --- a/repo/js/ActivitySwitchNotice/utils/notice.js +++ b/repo/js/ActivitySwitchNotice/utils/notice.js @@ -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, } \ No newline at end of file diff --git a/repo/js/ActivitySwitchNotice/utils/ws.js b/repo/js/ActivitySwitchNotice/utils/ws.js new file mode 100644 index 000000000..455ba4c31 --- /dev/null +++ b/repo/js/ActivitySwitchNotice/utils/ws.js @@ -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} 无返回值 + */ +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 +} \ No newline at end of file