hookbot 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +178 -0
- package/index.js +11 -0
- package/package.json +56 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
> HookBot 仍在开发中,我们会在开发完毕后发布 Release.
|
|
2
|
+
|
|
3
|
+
# HookBot
|
|
4
|
+
|
|
5
|
+
<!-- [](https://badge.fury.io/js/hookbot) -->
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
|
|
8
|
+
**HookBot** 是一个可扩展的、为 Webhook 而做的 TypeScript 机器人流程框架,旨在轻松实现不同聊天平台、服务或 API 之间的消息同步。
|
|
9
|
+
|
|
10
|
+
不仅如此,您可以轻松编写插件系统,来编写自己的信息处理逻辑。
|
|
11
|
+
|
|
12
|
+
我们在初期准备支持 Telegram(收/发),Discord(发),您也可以自己编写自己的适配器,一次编写就可以支持本机器人。
|
|
13
|
+
|
|
14
|
+
同时我们支持 Node.js 服务器和 Serverless 环境,具体请看「快速开始」部分。
|
|
15
|
+
|
|
16
|
+
## ✨ 特性
|
|
17
|
+
|
|
18
|
+
- **🔌 统一的适配器接口**: 只需编写适配器,轻松集成任何消息源或目标。
|
|
19
|
+
- **🚀 插件化架构**: 使用插件方法,可以轻松地为您的机器人添加新功能或集成第三方服务。
|
|
20
|
+
- **⚙️ 中间件支持**: 通过添加处理方法,可以在消息处理流程的任何阶段添加处理器,以实现日志记录、权限控制、消息修改等功能。
|
|
21
|
+
- **🔒 类型安全**: 完全使用 TypeScript 编写,提供强大的类型推断和编译时检查。
|
|
22
|
+
- **🌐 灵活部署**: 同时支持在传统的 Node.js 服务器 (`listen()`) 和 Serverless 环境 (`fire()`) 中运行。
|
|
23
|
+
- **💬 提供 utils**: 内置便捷方法,轻松处理 Markdown、HTML 的转换,并且提供了不支持富文本的后备处理。
|
|
24
|
+
|
|
25
|
+
## 📦 安装
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
bun add hookbot
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## 🚀 快速开始
|
|
32
|
+
|
|
33
|
+
下面是一个简单的例子,演示了如何创建一个在同步消息的机器人。
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
import HookBot from 'hookbot';
|
|
37
|
+
|
|
38
|
+
// 1. 创建 Bot
|
|
39
|
+
// 2. 订阅/发布一个消息源
|
|
40
|
+
|
|
41
|
+
// 3. 采用 Node.js Server 或 Serverless
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## 核心概念
|
|
45
|
+
|
|
46
|
+
Webhook 是一种事件驱动的、基于 HTTP 的回调机制,它允许一个应用程序在特定事件发生时,自动将数据推送给另一个应用程序。
|
|
47
|
+
|
|
48
|
+
我们在传入 Webhook 请求时,会通过适配器的 `id` 来识别需要哪一种适配器处理,然后解析请求为一个消息数组,接下来我们对于消息,拦截器->同步消息给其他适配器->处理器。
|
|
49
|
+
|
|
50
|
+
```mermaid
|
|
51
|
+
flowchart TB
|
|
52
|
+
Start([HookBot])
|
|
53
|
+
A0[注册路由]
|
|
54
|
+
|
|
55
|
+
subgraph "Listen (Server Mode)"
|
|
56
|
+
direction TB
|
|
57
|
+
A1[启动服务]
|
|
58
|
+
A3[持续接收请求]
|
|
59
|
+
A1 --> A3
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
subgraph "Fire (Serverless Mode)"
|
|
63
|
+
direction TB
|
|
64
|
+
B2[接收 webhook 请求]
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
C1[路由交给对应的 Subscriber]
|
|
68
|
+
C2[解析为消息数组]
|
|
69
|
+
|
|
70
|
+
subgraph "处理消息数组"
|
|
71
|
+
direction TB
|
|
72
|
+
|
|
73
|
+
C3[全局拦截器 Interceptor]
|
|
74
|
+
|
|
75
|
+
subgraph "与其他 Publishers 同步"
|
|
76
|
+
direction TB
|
|
77
|
+
D1[拦截器 Interceptor]
|
|
78
|
+
D2[同步消息 sendMessage]
|
|
79
|
+
D3[处理器 Handler]
|
|
80
|
+
D1 --> D2 --> D3
|
|
81
|
+
end
|
|
82
|
+
C4[全局处理器 Handler]
|
|
83
|
+
|
|
84
|
+
end
|
|
85
|
+
Start --> A0
|
|
86
|
+
A0 --> A1
|
|
87
|
+
A0 --> B2
|
|
88
|
+
|
|
89
|
+
A3 --> C1
|
|
90
|
+
B2 --> C1
|
|
91
|
+
|
|
92
|
+
C1 --> C2 --> C3 --> D1
|
|
93
|
+
D3 --> C4
|
|
94
|
+
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### 适配器
|
|
98
|
+
|
|
99
|
+
适配器是 HookBot 与第三方消息源沟通的桥梁,他们通过 `id` 建立的来建立路由。
|
|
100
|
+
|
|
101
|
+
如果你要编写自己的适配器,请继承以下接口。
|
|
102
|
+
|
|
103
|
+
- **`SubscribableAdaptor`**: 只接收消息。它必须实现一个 `id` 和一个 `receive` 方法。HookBot 会为每个订阅者创建一个 webhook 端点 (`POST /<adaptor_id>`)。
|
|
104
|
+
- **`PublishableAdaptor`**: 只发送消息。它必须实现一个 `id` 和至少一个 `sendText` 方法。
|
|
105
|
+
- **`SyncableAdaptor`**: 既能接收也能发送消息,是 `Subscribable` 和 `Publishable` 的结合。
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### 消息
|
|
112
|
+
|
|
113
|
+
所有通过 HookBot 流转的数据都被封装成 `Message` 对象。它有一个 `type` 字段(如 `'text'`, `'media', 'location'`)来区分不同类型的消息。
|
|
114
|
+
|
|
115
|
+
```json
|
|
116
|
+
{
|
|
117
|
+
"type": "text"
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
某些适配器可能无法处理复杂类型的媒体,你需要在编写适配器时添加 `alt: string` 参数作为 fallback,我们会转换为文字消息处理。
|
|
122
|
+
|
|
123
|
+
```json
|
|
124
|
+
{
|
|
125
|
+
type: 'location',
|
|
126
|
+
//...
|
|
127
|
+
|
|
128
|
+
alt: '${content.longitude}, ${content.latitude}',
|
|
129
|
+
//...
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### 处理器
|
|
134
|
+
|
|
135
|
+
处理器是可以在消息生命周期的特定节点执行的函数,类似于中间件。
|
|
136
|
+
|
|
137
|
+
HookBot 有自己的全局处理器,分配到每个适配器时也有自己的处理器。
|
|
138
|
+
|
|
139
|
+
#### 拦截器
|
|
140
|
+
|
|
141
|
+
**`Interceptor`**: 在消息被同步给其他发布者 **之前** 执行。可以用于消息验证、修改或过滤。
|
|
142
|
+
|
|
143
|
+
#### 处理器
|
|
144
|
+
|
|
145
|
+
**`Handler`**: 在消息被同步给所有发布者 **之后** 执行。可以用于日志记录、分析或收尾工作。
|
|
146
|
+
|
|
147
|
+
您可以通过 `.intercept()` 和 `.handle()` 方法注册,他根据 `priority` 属性(数字越小,优先级越高)的顺序执行。
|
|
148
|
+
|
|
149
|
+
```typescript
|
|
150
|
+
bot.intercept({
|
|
151
|
+
name: 'process before syncing',
|
|
152
|
+
priority: 1,
|
|
153
|
+
process: processor1,
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
bot.handle({
|
|
157
|
+
name: 'process after syncing',
|
|
158
|
+
priority: 1,
|
|
159
|
+
process: processor2,
|
|
160
|
+
});
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### 插件
|
|
164
|
+
|
|
165
|
+
您可以通过 `.use()` 方法来添加插件。
|
|
166
|
+
|
|
167
|
+
## 🤝 贡献
|
|
168
|
+
|
|
169
|
+
欢迎提交 Pull Requests 和 Issues!
|
|
170
|
+
|
|
171
|
+
## TODO
|
|
172
|
+
1. 便捷添加命令/便捷筛选
|
|
173
|
+
2. 状态管理/持久化存储插件
|
|
174
|
+
3. i18n
|
|
175
|
+
|
|
176
|
+
## 📄 许可证
|
|
177
|
+
|
|
178
|
+
[MIT](./LICENSE)
|
package/index.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export class HookBotPlaceholderError extends Error {
|
|
2
|
+
constructor() {
|
|
3
|
+
super("hookbot is a placeholder package. The public SDK has not been released yet.");
|
|
4
|
+
this.name = "HookBotPlaceholderError";
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export default function HookBot() {
|
|
9
|
+
// Keep the reserved npm package intentionally non-functional until the SDK is ready.
|
|
10
|
+
throw new HookBotPlaceholderError();
|
|
11
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "hookbot",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"description": "Placeholder package for HookBot.",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"exports": "./index.js",
|
|
7
|
+
"files": [
|
|
8
|
+
"index.js",
|
|
9
|
+
"README.md",
|
|
10
|
+
"LICENSE"
|
|
11
|
+
],
|
|
12
|
+
"publishConfig": {
|
|
13
|
+
"access": "public"
|
|
14
|
+
},
|
|
15
|
+
"type": "module",
|
|
16
|
+
"scripts": {
|
|
17
|
+
"dev": "bun run src/index.ts",
|
|
18
|
+
"build": "tsc",
|
|
19
|
+
"build:clean": "rm -rf dist && bun run build",
|
|
20
|
+
"test": "bun test",
|
|
21
|
+
"test:run": "bun test",
|
|
22
|
+
"lint": "biome lint .",
|
|
23
|
+
"lint:fix": "biome lint --write .",
|
|
24
|
+
"format": "biome format --write .",
|
|
25
|
+
"format:check": "biome format .",
|
|
26
|
+
"check": "biome check .",
|
|
27
|
+
"check:fix": "biome check --write .",
|
|
28
|
+
"typecheck": "tsc --noEmit",
|
|
29
|
+
"clean": "rm -rf dist build node_modules/.cache"
|
|
30
|
+
},
|
|
31
|
+
"keywords": [
|
|
32
|
+
"webhook",
|
|
33
|
+
"bot",
|
|
34
|
+
"hookbot",
|
|
35
|
+
"typescript"
|
|
36
|
+
],
|
|
37
|
+
"license": "MIT",
|
|
38
|
+
"engines": {
|
|
39
|
+
"node": ">=18.0.0"
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"@biomejs/biome": "^2.2.4",
|
|
43
|
+
"@types/bun": "^1.2.0",
|
|
44
|
+
"@types/marked": "^5.0.2",
|
|
45
|
+
"@types/turndown": "^5.0.5",
|
|
46
|
+
"typescript": "^5.8.3"
|
|
47
|
+
},
|
|
48
|
+
"dependencies": {
|
|
49
|
+
"@hono/node-server": "^1.17.1",
|
|
50
|
+
"hono": "^4.8.5",
|
|
51
|
+
"marked": "^16.1.1",
|
|
52
|
+
"node-html-parser": "^7.0.1",
|
|
53
|
+
"ofetch": "^1.4.1",
|
|
54
|
+
"turndown": "^7.2.0"
|
|
55
|
+
}
|
|
56
|
+
}
|