Skip to content

Commit 456e21b

Browse files
committed
chore: update deps
1 parent 94448f8 commit 456e21b

12 files changed

Lines changed: 1418 additions & 10 deletions

File tree

cmd/config-ui/README.md

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# Webhook Config UI
2+
3+
在网页中快速生成可调用的 webhook 配置(YAML/JSON 片段)及调用 URL、curl 示例,便于复制到 `hooks.yaml` / `hooks.json` 或直接调用。
4+
5+
## 运行方式
6+
7+
```bash
8+
# 使用默认端口 9080
9+
go run ./cmd/config-ui
10+
11+
# 指定端口
12+
go run ./cmd/config-ui -port 9080
13+
14+
# 或通过环境变量
15+
PORT=9080 go run ./cmd/config-ui
16+
```
17+
18+
编译为独立二进制后:
19+
20+
```bash
21+
go build -o webhook-config-ui ./cmd/config-ui
22+
./webhook-config-ui -port 9080
23+
```
24+
25+
## 使用说明
26+
27+
1. 浏览器打开 `http://localhost:9080`(或你指定的端口)。
28+
2. 填写表单:
29+
- **必填**:Hook ID、执行命令
30+
- **可选**:工作目录、响应消息、**Webhook 服务地址**(如 `http://localhost:9000`,用于生成正确的调用 URL)、HTTP 方法、成功状态码、是否返回命令输出等
31+
- **可选(高级)**:响应头、传递参数/环境变量、触发规则、请求 Content-Type(均为 JSON 格式;若填写则需为合法 JSON,否则生成接口会返回 400 及错误说明)
32+
3. 可点击「加载示例」快速填充一份示例(id、执行命令、Webhook 地址等),再点「生成」试跑。
33+
4. 点击「生成」后,页面会展示:
34+
- 调用 URL(如 `http://localhost:9000/hooks/my-hook`
35+
- curl 示例
36+
- YAML 与 JSON 配置片段
37+
5. 可复制或下载 YAML/JSON 片段,粘贴到 webhook 的 `hooks.yaml` / `hooks.json` 中使用。可选区块(响应头、传递参数、触发规则等)默认折叠,点击「可选」展开。YAML/JSON 结果块可折叠以节省空间。成功生成后会记住 Hook ID 与 Webhook 服务地址(localStorage),下次打开页面时自动回填(若为空)。
38+
39+
## 与 webhook 同机部署
40+
41+
config-ui 为独立服务,与 webhook 主程序分开运行。若需同机部署:
42+
43+
- webhook 主服务:例如 `:9000`(hooks 端点 `/hooks/:id`
44+
- config-ui:例如 `:9080`(仅提供配置生成页)
45+
46+
可编写 `docker-compose.yml` 或 systemd 单元,分别启动两个进程;生成结果中的「调用 URL」需与 webhook 实际监听地址一致(可在生成后手动替换 host/port)。
47+
48+
## 技术说明
49+
50+
- 静态资源与页面配置通过 `embed` 嵌入,单二进制即可运行。
51+
- 页面配置来自 `config/page.yaml`(i18n 与表单结构)。
52+
- 生成 API:`POST /api/generate`,请求体为表单对应 JSON,响应为 `{ "yaml", "json", "callUrl", "curlExample" }`;错误时返回 `{ "error": "..." }` 及 4xx 状态码。
53+
54+
## 故障排查
55+
56+
- **页面空白**:若仅见白屏,多为模板字段与结构体不一致(如模板用了 `{{.Id}}` 而结构体为 `ID`)。当前模板已使用 `{{.ID}}`,重新构建并运行即可。
57+
- **表单无法提交 / 复制无效**:确认浏览器控制台无 JS 报错;检查 `/static/js/app.js` 是否正常加载(Network 面板)。
58+
- **生成接口 400**:查看响应体中的 `error` 字段,多为「id / execute-command 未填」或「可选 JSON 格式错误」。

cmd/config-ui/config/page.yaml

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
# Page data for webhook config generator UI.
2+
# i18n: zh/en; configSections: basic + optional form fields.
3+
4+
i18n:
5+
zh:
6+
title: "Webhook - 配置生成"
7+
subtitle: "填写 Hook 基础信息与可选项,点击生成后复制或下载 YAML/JSON 配置及调用示例。"
8+
basicSection: "基础"
9+
optionalSection: "可选"
10+
idLabel: "Hook ID"
11+
idDesc: "用于生成调用地址,如 my-hook。必填。"
12+
executeCommandLabel: "执行命令"
13+
executeCommandDesc: "触发时执行的命令路径。必填。"
14+
commandWorkingDirectoryLabel: "工作目录"
15+
commandWorkingDirectoryDesc: "命令执行时的工作目录,留空使用默认。"
16+
responseMessageLabel: "响应消息"
17+
responseMessageDesc: "成功时返回给调用方的消息文本。"
18+
webhookBaseUrlLabel: "Webhook 服务地址"
19+
webhookBaseUrlDesc: "生成调用 URL 时使用,如 http://localhost:9000;留空则使用当前页面的 host 与端口。"
20+
httpMethodsLabel: "HTTP 方法"
21+
httpMethodsDesc: "允许的请求方法,如 POST;留空表示不限制。"
22+
successHttpResponseCodeLabel: "成功状态码"
23+
successHttpResponseCodeDesc: "成功时返回的 HTTP 状态码,默认 200。"
24+
includeCommandOutputLabel: "返回命令输出"
25+
includeCommandOutputDesc: "是否将命令 stdout/stderr 作为响应体返回。"
26+
responseHeadersLabel: "响应头"
27+
responseHeadersDesc: "JSON 数组,如 [{\"name\":\"X-Custom\",\"value\":\"ok\"}]。"
28+
passArgumentsLabel: "传递参数给命令"
29+
passArgumentsDesc: "JSON 数组,如 [{\"source\":\"payload\",\"name\":\"repo\"}]。"
30+
passEnvironmentLabel: "传递环境变量"
31+
passEnvironmentDesc: "JSON 数组,如 [{\"source\":\"payload\",\"envname\":\"REPO\",\"name\":\"repo\"}]。"
32+
triggerRuleLabel: "触发规则"
33+
triggerRuleDesc: "JSON 对象,如 {\"match\":{\"type\":\"value\",\"parameter\":{\"source\":\"header\",\"name\":\"X-Key\"},\"value\":\"secret\"}}。"
34+
incomingPayloadContentTypeLabel: "请求 Content-Type"
35+
incomingPayloadContentTypeDesc: "期望的请求体类型,如 application/json。"
36+
btnGenerate: "生成"
37+
generating: "生成中..."
38+
resultSuccess: "生成成功。可复制或下载:"
39+
resultErrorId: "请填写 Hook ID。"
40+
resultErrorCommand: "请填写执行命令。"
41+
requestFailed: "请求失败: "
42+
copyYaml: "复制 YAML"
43+
copyJson: "复制 JSON"
44+
copyCurl: "复制 curl"
45+
copySuccess: "已复制"
46+
copyFailed: "复制失败"
47+
copyAll: "复制全部"
48+
outputCallUrl: "调用 URL"
49+
outputCurl: "curl"
50+
outputYaml: "YAML"
51+
outputJson: "JSON"
52+
downloadYaml: "下载 hooks.yaml 片段"
53+
downloadJson: "下载 hooks.json 片段"
54+
btnLoadExample: "加载示例"
55+
en:
56+
title: "Webhook - Config Generator"
57+
subtitle: "Fill in hook basics and options, then click Generate to copy or download YAML/JSON config and call example."
58+
basicSection: "Basic"
59+
optionalSection: "Optional"
60+
idLabel: "Hook ID"
61+
idDesc: "Used for the call URL, e.g. my-hook. Required."
62+
executeCommandLabel: "Execute command"
63+
executeCommandDesc: "Command path to run when triggered. Required."
64+
commandWorkingDirectoryLabel: "Working directory"
65+
commandWorkingDirectoryDesc: "Working directory for the command; leave empty for default."
66+
responseMessageLabel: "Response message"
67+
responseMessageDesc: "Message returned to the caller on success."
68+
webhookBaseUrlLabel: "Webhook base URL"
69+
webhookBaseUrlDesc: "Base URL for generated call URL, e.g. http://localhost:9000; leave empty to use current host and port."
70+
httpMethodsLabel: "HTTP methods"
71+
httpMethodsDesc: "Allowed methods, e.g. POST; empty means no restriction."
72+
successHttpResponseCodeLabel: "Success status code"
73+
successHttpResponseCodeDesc: "HTTP status code on success, default 200."
74+
includeCommandOutputLabel: "Include command output"
75+
includeCommandOutputDesc: "Whether to return command stdout/stderr as response body."
76+
responseHeadersLabel: "Response headers"
77+
responseHeadersDesc: "JSON array, e.g. [{\"name\":\"X-Custom\",\"value\":\"ok\"}]."
78+
passArgumentsLabel: "Pass arguments to command"
79+
passArgumentsDesc: "JSON array, e.g. [{\"source\":\"payload\",\"name\":\"repo\"}]."
80+
passEnvironmentLabel: "Pass environment to command"
81+
passEnvironmentDesc: "JSON array, e.g. [{\"source\":\"payload\",\"envname\":\"REPO\",\"name\":\"repo\"}]."
82+
triggerRuleLabel: "Trigger rule"
83+
triggerRuleDesc: "JSON object, e.g. {\"match\":{\"type\":\"value\",\"parameter\":{\"source\":\"header\",\"name\":\"X-Key\"},\"value\":\"secret\"}}."
84+
incomingPayloadContentTypeLabel: "Incoming Content-Type"
85+
incomingPayloadContentTypeDesc: "Expected request body type, e.g. application/json."
86+
btnGenerate: "Generate"
87+
generating: "Generating..."
88+
resultSuccess: "Done. Copy or download:"
89+
resultErrorId: "Please fill in Hook ID."
90+
resultErrorCommand: "Please fill in execute command."
91+
requestFailed: "Request failed: "
92+
copyYaml: "Copy YAML"
93+
copyJson: "Copy JSON"
94+
copyCurl: "Copy curl"
95+
copySuccess: "Copied"
96+
copyFailed: "Copy failed"
97+
copyAll: "Copy all"
98+
outputCallUrl: "Call URL"
99+
outputCurl: "curl"
100+
outputYaml: "YAML"
101+
outputJson: "JSON"
102+
downloadYaml: "Download hooks.yaml snippet"
103+
downloadJson: "Download hooks.json snippet"
104+
btnLoadExample: "Load example"
105+
106+
configSections:
107+
- titleKey: basicSection
108+
options:
109+
- type: text
110+
id: id
111+
name: id
112+
labelKey: idLabel
113+
descKey: idDesc
114+
placeholder: "my-hook"
115+
- type: text
116+
id: execute-command
117+
name: execute-command
118+
labelKey: executeCommandLabel
119+
descKey: executeCommandDesc
120+
placeholder: "/path/to/script.sh"
121+
- type: text
122+
id: command-working-directory
123+
name: command-working-directory
124+
labelKey: commandWorkingDirectoryLabel
125+
descKey: commandWorkingDirectoryDesc
126+
placeholder: "/home/app"
127+
- type: text
128+
id: response-message
129+
name: response-message
130+
labelKey: responseMessageLabel
131+
descKey: responseMessageDesc
132+
placeholder: "OK"
133+
- type: text
134+
id: webhook_base_url
135+
name: webhook_base_url
136+
labelKey: webhookBaseUrlLabel
137+
descKey: webhookBaseUrlDesc
138+
placeholder: "http://localhost:9000"
139+
- type: text
140+
id: http-methods
141+
name: http-methods
142+
labelKey: httpMethodsLabel
143+
descKey: httpMethodsDesc
144+
placeholder: "POST"
145+
- type: number
146+
id: success-http-response-code
147+
name: success-http-response-code
148+
labelKey: successHttpResponseCodeLabel
149+
descKey: successHttpResponseCodeDesc
150+
default: "200"
151+
- type: checkbox
152+
id: include-command-output-in-response
153+
name: include-command-output-in-response
154+
labelKey: includeCommandOutputLabel
155+
descKey: includeCommandOutputDesc
156+
- titleKey: optionalSection
157+
collapsible: true
158+
options:
159+
- type: textarea
160+
id: response-headers
161+
name: response-headers
162+
labelKey: responseHeadersLabel
163+
descKey: responseHeadersDesc
164+
placeholder: "[{\"name\":\"X-Custom\",\"value\":\"ok\"}]"
165+
- type: textarea
166+
id: pass-arguments-to-command
167+
name: pass-arguments-to-command
168+
labelKey: passArgumentsLabel
169+
descKey: passArgumentsDesc
170+
placeholder: "[{\"source\":\"payload\",\"name\":\"repo\"}]"
171+
- type: textarea
172+
id: pass-environment-to-command
173+
name: pass-environment-to-command
174+
labelKey: passEnvironmentLabel
175+
descKey: passEnvironmentDesc
176+
placeholder: ""
177+
- type: textarea
178+
id: trigger-rule
179+
name: trigger-rule
180+
labelKey: triggerRuleLabel
181+
descKey: triggerRuleDesc
182+
placeholder: "{}"
183+
- type: text
184+
id: incoming-payload-content-type
185+
name: incoming-payload-content-type
186+
labelKey: incomingPayloadContentTypeLabel
187+
descKey: incomingPayloadContentTypeDesc
188+
placeholder: "application/json"

0 commit comments

Comments
 (0)