From 712e2702c0011639a85a63a08faeabb86add3c55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A6=AC=E5=89=83=20=E5=A4=A9=E6=84=9B=E6=98=9F?= <131457234+TiaraBasori@users.noreply.github.com> Date: Wed, 24 Dec 2025 14:47:46 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B0=8F=E6=9B=B4=E6=96=B0:=E5=B0=86=E4=B8=80?= =?UTF-8?q?=E8=A8=80=E6=8F=92=E4=BB=B6=E7=9A=84=E6=8F=92=E4=BB=B6=E5=90=8D?= =?UTF-8?q?=E6=94=B9=E4=B8=BAhitokoto?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 如上. --- hitokoto/hitokoto.ts | 157 +++++++++++++++++++++++++++++++++++++++++++ plugins.json | 4 +- yiyan/yiyan.ts | 110 ------------------------------ 3 files changed, 159 insertions(+), 112 deletions(-) create mode 100644 hitokoto/hitokoto.ts delete mode 100644 yiyan/yiyan.ts diff --git a/hitokoto/hitokoto.ts b/hitokoto/hitokoto.ts new file mode 100644 index 00000000..67b97a37 --- /dev/null +++ b/hitokoto/hitokoto.ts @@ -0,0 +1,157 @@ +import { Plugin } from "@utils/pluginBase"; +import { Api } from "telegram"; +import axios from "axios"; + +// 类型定义 +interface HitokotoResponse { + hitokoto: string; + from?: string; + from_who?: string; + type: string; +} + +// 一言类型映射 +const hitokotoTypeMap: Record = { + "a": "动画", + "b": "漫画", + "c": "游戏", + "d": "文学", + "e": "原创", + "f": "网络", + "g": "其他", + "h": "影视", + "i": "诗词", + "j": "网易云", + "k": "哲学", + "l": "抖机灵" +}; + +// 帮助文本(符合开发规范格式) +const help_text = `⚙️ Hitokoto 插件 + +📝 功能描述: +• 从 hitokoto.cn API 获取随机一言 +• 支持多种类型(动画、漫画、文学、哲学等) +• 包含详细的来源信息 + +🔧 使用方法: +• .hitokoto - 获取随机一言 +• .hitokoto help - 显示帮助信息`; + +// HTML转义函数(符合开发规范) +const htmlEscape = (text: string): string => + text.replace(/[&<>"']/g, m => ({ + '&': '&', '<': '<', '>': '>', + '"': '"', "'": ''' + }[m] || m)); + +class HitokotoPlugin extends Plugin { + // 插件描述(符合开发规范) + description = help_text; + + // 命令处理器(主命令改为 hitokoto) + cmdHandlers = { + hitokoto: this.handleHitokotoCommand.bind(this) + }; + + /** + * 处理 hitokoto 命令 + * 符合开发规范:支持 help/h 子指令和无参数时显示帮助 + */ + private async handleHitokotoCommand(msg: Api.Message): Promise { + try { + // 解析参数 + const parts = msg.text?.trim().split(/\s+/) || []; + const subCommand = parts[1]?.toLowerCase() || ""; + + // 处理 help/h 子指令或无参数情况 + if (!subCommand || subCommand === "help" || subCommand === "h") { + await msg.edit({ + text: help_text, + parseMode: "html" + }); + return; + } + + // 如果不是 help/h,则执行获取一言功能 + await this.fetchAndSendHitokoto(msg); + + } catch (error: any) { + await this.handleError(msg, error); + } + } + + /** + * 获取并发送一言 + */ + private async fetchAndSendHitokoto(msg: Api.Message): Promise { + // 发送等待消息 + const processingMsg = await msg.edit({ + text: "🔄 正在获取一言...", + parseMode: "html" + }); + + let hitokotoData: HitokotoResponse | null = null; + let retryCount = 0; + const maxRetries = 10; + + // 重试机制 + while (retryCount < maxRetries && !hitokotoData) { + try { + const response = await axios.get( + "https://v1.hitokoto.cn/?charset=utf-8", + { timeout: 10000 } + ); + hitokotoData = response.data; + break; + } catch (error) { + retryCount++; + if (retryCount >= maxRetries) { + throw new Error("获取一言失败,请稍后重试"); + } + // 等待一段时间后重试 + await new Promise(resolve => setTimeout(resolve, 1000)); + } + } + + if (!hitokotoData) { + throw new Error("无法获取一言数据"); + } + + // 构建来源信息 + let sourceInfo = ""; + if (hitokotoData.from) { + sourceInfo += `《${htmlEscape(hitokotoData.from)}》`; + } + if (hitokotoData.type && hitokotoTypeMap[hitokotoData.type]) { + sourceInfo += `(${hitokotoTypeMap[hitokotoData.type]})`; + } + if (hitokotoData.from_who) { + sourceInfo += ` - ${htmlEscape(hitokotoData.from_who)}`; + } + + // 构建最终消息 + const finalText = sourceInfo + ? `💬 ${htmlEscape(hitokotoData.hitokoto)}\n\n📚 ${sourceInfo}` + : `💬 ${htmlEscape(hitokotoData.hitokoto)}`; + + // 编辑消息显示结果 + await processingMsg.edit({ + text: finalText, + parseMode: "html" + }); + } + + /** + * 错误处理 + */ + private async handleError(msg: Api.Message, error: any): Promise { + const errorMsg = error.message || "未知错误"; + await msg.edit({ + text: `❌ 获取一言失败:${htmlEscape(errorMsg)}`, + parseMode: "html" + }); + } +} + +export default new HitokotoPlugin(); \ No newline at end of file diff --git a/plugins.json b/plugins.json index f735e43d..ef023cca 100644 --- a/plugins.json +++ b/plugins.json @@ -311,8 +311,8 @@ "url": "https://github.com/TeleBoxDev/TeleBox_Plugins/blob/main/xmsl/xmsl.ts?raw=true", "desc": "全自动羡慕" }, - "yiyan": { - "url": "https://github.com/TeleBoxOrg/TeleBox_Plugins/blob/main/yiyan/yiyan.ts?raw=true", + "hitokoto": { + "url": "https://github.com/TeleBoxOrg/TeleBox_Plugins/blob/main/hitokoto/hitokoto.ts?raw=true", "desc": "获取随机一言" }, "teletype": { diff --git a/yiyan/yiyan.ts b/yiyan/yiyan.ts deleted file mode 100644 index 647fab28..00000000 --- a/yiyan/yiyan.ts +++ /dev/null @@ -1,110 +0,0 @@ -import { Plugin } from "@utils/pluginBase"; -import { Api } from "telegram"; -import axios from "axios"; - -// 类型定义 -interface HitokotoResponse { - hitokoto: string; - from?: string; - from_who?: string; - type: string; -} - -// 一言类型映射 -const hitokotoTypeMap: Record = { - "a": "动画", - "b": "漫画", - "c": "游戏", - "d": "文学", - "e": "原创", - "f": "网络", - "g": "其他", - "h": "影视", - "i": "诗词", - "j": "网易云", - "k": "哲学", - "l": "抖机灵" -}; - -class YiyanPlugin extends Plugin { - // 插件描述 - description = "📝 获取随机一言\n\n使用命令:.yiyan"; - - // 命令处理器 - cmdHandlers = { - yiyan: this.getHitokoto.bind(this) - }; - - /** - * 获取一言 - */ - private async getHitokoto(msg: Api.Message): Promise { - try { - // 发送等待消息 - const processingMsg = await msg.edit({ - text: "🔄 正在获取一言...", - parseMode: "html" - }); - - let hitokotoData: HitokotoResponse | null = null; - let retryCount = 0; - const maxRetries = 10; - - // 重试机制 - while (retryCount < maxRetries && !hitokotoData) { - try { - const response = await axios.get( - "https://v1.hitokoto.cn/?charset=utf-8", - { timeout: 10000 } - ); - hitokotoData = response.data; - break; - } catch (error) { - retryCount++; - if (retryCount >= maxRetries) { - throw new Error("获取一言失败,请稍后重试"); - } - // 等待一段时间后重试 - await new Promise(resolve => setTimeout(resolve, 1000)); - } - } - - if (!hitokotoData) { - throw new Error("无法获取一言数据"); - } - - // 构建来源信息 - let sourceInfo = ""; - if (hitokotoData.from) { - sourceInfo += `《${hitokotoData.from}》`; - } - if (hitokotoData.type && hitokotoTypeMap[hitokotoData.type]) { - sourceInfo += `(${hitokotoTypeMap[hitokotoData.type]})`; - } - if (hitokotoData.from_who) { - sourceInfo += ` - ${hitokotoData.from_who}`; - } - - // 构建最终消息 - const finalText = sourceInfo - ? `💬 ${hitokotoData.hitokoto}\n\n📚 ${sourceInfo}` - : `💬 ${hitokotoData.hitokoto}`; - - // 编辑消息显示结果 - await processingMsg.edit({ - text: finalText, - parseMode: "html" - }); - - } catch (error: any) { - // 错误处理 - const errorMsg = error.message || "未知错误"; - await msg.edit({ - text: `❌ 获取一言失败:${errorMsg}`, - parseMode: "html" - }); - } - } -} - -export default new YiyanPlugin();