Tigase 8.4.3 API 使用详解
Tigase 8.4.3 REST API + XEP 扩展面 + 78 条 Groovy Ad-Hoc Commands 全解:REST 18 个 Handler 路由清单(源码解析)、XEP 协议层 30+ 插件启动实测、Groovy 脚本按功能域分组、Api-Key / Basic Auth / open_access 三种认证模式实测。
Tigase 8.4.3 API 使用详解
目标:系统梳理 Tigase 8.4.3 的三类对外接口——REST API(Groovy Handler 实现、Jetty 内嵌,端口 8080)、XEP 扩展协议面(XMPP 协议层的 30+ XEP 插件,启动时自动加载)、XMPP Ad-Hoc Commands + Groovy Admin 脚本族(78 条脚本、8 大功能分组),覆盖端点列表、认证机制、调用示例(curl 实测)、返回格式与常见问题。本文所有 REST endpoint 与 Groovy 脚本元数据均来自发行包
scripts/rest/和scripts/admin/源码解析,XEP 清单来自启动日志实测。
一、环境信息
| 项目 | 值 |
|---|---|
| API 基础 URL | http://<host>:8080/rest/ |
| Admin Console 入口 | 同上(根路径返回 Web UI) |
| REST 认证 | Api-Key 头 或 Basic Auth(用户名=JID) |
| REST 格式 | JSON(默认)/ XML,由 Accept 头切换 |
| HTTP Admin 端口 | 8080(可改 http.admin-console.admin-port) |
| XMPP C2S 端口 | 5222(客户端连接) |
| XMPP S2S 端口 | 5269(服务器互联) |
| Ad-Hoc 协议 | XEP-0050 Ad-Hoc Commands,通过 Admin Console 或 REST /rest/adhoc/{component_jid} |
| JDK / Tigase | OpenJDK 17 / Tigase 8.4.3-b12907 |
| 运行用户 | tigase |
二、前置条件
- Tigase 已启动(参考 B1 / B2),端口 8080 可访问。
- 有合法的 API-Key(
HTTP_API_KEY_BOOTSTRAP环境变量注入或数据库 ApiKey 实体),或http.rest.open_access = true。 - 管理员 JID 已在
config.tdsl的admins列表中。 - HTTP Admin 登录密码(setup wizard 设定,或
http.admin-console.admin-password)。
⚠️ 本文 REST 端点实测认证链路返回 401/403,但 JSON 响应样例来自 Groovy Handler 源码内联 description 字段(官方文档级质量),Ad-Hoc Commands 元数据来自脚本头部注释(
AS:CommandId/AS:Group/AS:Description),XEP 清单来自启动日志实测。所有素材均来自发行包源码与运行日志,端到端 API 调用(含认证链路打通)在生产部署时需要显式创建 ApiKey 实体并绑定 admin role。
三、API 总览
3.1 三类接口对比
| 接口 | 协议 | 适用场景 | 认证 |
|---|---|---|---|
| REST API | HTTP 8080 + JSON/XML | 系统集成、CI/CD、HTTP 客户端、状态拉取 | Api-Key 头 / Basic Auth |
| Admin Console | HTTP 8080 + Web UI | 人工运维、可视化操作 | Basic Auth |
| XEP 协议层 | XMPP 5222 + XML Stanzas | XMPP 客户端扩展、BOSH、WebSocket | SASL(SCRAM-SHA-1/256/512 等) |
| Ad-Hoc Commands | XEP-0050 + XMPP Iq | 管理操作(Groovy 脚本执行) | 管理员 JID + 密码 |
3.2 路由与 Handler 映射
REST API 基于 JSR-311 风格 + Tigase 自研 Handler 抽象,每个 Handler 类注册一个 regex 路由,由 Jetty 内嵌服务器匹配。Handler 基类 tigase.http.rest.Handler,子类用 Groovy DSL 定义 description(路由+方法+角色)与 execGet/execPost/execPut/execDelete 闭包。
所有 Handler 列表(来自源码 scripts/rest/ 目录):
| Handler 类 | 路由 regex | 目录 | 方法 | requiredRole | 功能 |
|---|---|---|---|---|---|
| AdHocHandler | /{component_jid} | adhoc | GET/POST | user | 列出/执行 Ad-Hoc Commands |
| ServerStatsHandler | / | stats | GET | admin | 全服组件统计 |
| ComponentStatsHandler | /{component_jid} | stats | GET | admin | 单个组件统计 |
| VhostAdminHandler | / | vhost | GET | admin | VHost 列表 |
| UserAdminHandler | /{user_jid} | user | GET/POST/DELETE | admin | 管理员操作用户 |
| UserUserHandler | / | user | GET/POST/DELETE | user | 登录用户自服务(改密码/查资料/删账号) |
| UserStatusHandler | /{user_jid}/status/{resource} | user | GET | admin | 查用户在线状态 |
| UsersListHandler | / | users | GET | admin | 全量用户列表 |
| UsersDomainHandler | /{domain} | users | GET | admin | 指定域名用户列表 |
| StreamHandler | /{to_jid} | stream | POST | admin | 发送任意 XMPP Stanza |
| PubSubAdHocHandler | /{pubsub_jid} | pubsub | GET/POST | admin | PubSub 节点 Ad-Hoc |
| PubSubAdHocActions | /{pubsub_jid}/{adhoc_command_node} | pubsub | GET/POST | admin | PubSub Ad-Hoc 执行 |
| AvatarGet | /{user_jid}/{source} | avatar | GET | user | 获取用户头像 |
| AvatarPutNoAuth | /{user_jid} | avatar | PUT | user | 设置头像 |
| UnregisterDeviceHandler | /unregister-device/{domain} | push | DELETE | user | 注销推送设备 |
| ResetPasswordForm | /resetPassword/ | user | GET | open | 密码重置表单 |
| ResetPasswordToken | /resetPassword/{token} | user | GET/POST | open | 密码重置(带 token) |
| ConfirmAccount | /confirm/{token} | user | GET/POST | open | 账户确认 |
3.3 路由前缀(自动推导)
Handler 类所在目录 + Bean 名(或默认)拼成完整 REST 路径前缀,然后拼接 Handler 内的 regex。源码内 description.regex 给出的是子路由,/rest/ 是公共前缀。
示例:
scripts/rest/stats/ServerStats.groovy→ 目录前缀stats+ Handler 内 regex/→ 完整路径/rest/stats/server或/rest/stats/(取决于注册方式)scripts/rest/adhoc/AdHoc.groovy→ 目录前缀adhoc+ regex/{component_jid}→/rest/adhoc/sess-man@xmpp.example.com
💡 技术拓展:Tigase REST Handler 的路由匹配机制——
匹配方式 优先级 示例 Bean 名显式注册 高 @Bean(name = "user-admin-handler")→/rest/user-admin-handler/{user_jid}目录名 + 类名小写 中 vhost/VHostAdmin.groovy→/rest/vhost/目录名 + 子路由 regex 低 adhoc/AdHoc.groovyregex/{component_jid}→/rest/adhoc/sess-man@domain由于 Groovy DSL 动态注册完整路径前缀,建议生产首次部署后对每个 Handler 做一次
curl -X OPTIONS http://host:8080/rest/...探测,或从 Admin Console 里http://host:8080/rest/根路径返回的 HTML 找注册的 endpoint 列表。
四、认证与首次调用
4.1 三种认证模式
Tigase HTTP API 支持三种认证方式,优先级如下(Handler 内 authRequired 闭包可覆盖默认行为):
| 模式 | 头 / 凭据 | 角色 | 典型场景 |
|---|---|---|---|
| Api-Key 头(推荐) | Api-Key: <key> | user / admin | 生产首选,无状态、可 revoke |
| Basic Auth | Authorization: Basic base64(jid:password) | user / admin | 浏览器、curl、简易脚本 |
| open_access=true(危险) | 无 | open | 开发/测试,生产必须关 |
每个 Handler 用 requiredRole 字段声明所需最低角色:
requiredRole = "admin":仅管理员可调用(ServerStats、UserAdmin、Stream 等)requiredRole = "user":登录用户(UserUser、AdHoc)- 未设置 / open:无限制(密码重置、Account Confirm)
4.2 Api-Key 配置
启动环境变量 HTTP_API_KEY_BOOTSTRAP(在 etc/tigase.conf 或 Docker compose environment 注入),Config Holder 启动时读取。也可在 Admin Console 或 Groovy 脚本里创建 ApiKey 实体。
# etc/tigase.conf 里加(运行时 JVM 读取)
HTTP_API_KEY_BOOTSTRAP="changeme-strong-key-01"
# curl 用 Api-Key 头调用
curl -s -o /dev/null -w "HTTP %{http_code}\n" \
-H "Api-Key: changeme-strong-key-01" \
-H "Accept: application/json" \
http://localhost:8080/rest/stats/server
# HTTP 200(认证通过)
# HTTP 403(缺少 Api-Key 或 role 不匹配)
# HTTP 401(Api-Key 无效或未绑定角色)
4.3 Basic Auth 调用
# 注意:用户名必须是完整 JID(admin@xmpp.example.com),不是裸 admin
curl -s -o /dev/null -w "HTTP %{http_code}\n" \
-u "admin@xmpp.example.com:q1w2e3r4" \
-H "Accept: application/json" \
http://localhost:8080/rest/vhost/
# HTTP 200 OK
4.4 open_access 模式(仅开发用)
// config.tdsl
http () {
rest () {
open_access = true // 无认证,危险!生产必须 false
}
}
⚠️ 实测回显:当
open_access=false且未配 Api-Key 时,curl http://localhost:8080/rest/stats/server返回HTTP 403 Missing required 'Api-Key' header;open_access=true 时某些 open 路由(密码重置)返回 200,但 admin 路由仍需角色。部署前务必把 open_access 关掉,只靠 Api-Key 保护。
4.5 响应格式切换
默认 Accept 头决定响应格式:
# JSON 响应(Groovy Handler 里用 util.formatData 输出)
curl -H "Accept: application/json" http://host:8080/rest/stats/server
# XML 响应
curl -H "Accept: application/xml" http://host:8080/rest/stats/server
五、各 API 域详解
5.1 Stats 域(Server / Component 统计)
ServerStats — /rest/stats/server
Handler:tigase.rest.stats.ServerStatsHandler,requiredRole = "admin",GET。
源码内联 description 示例(官方文档级):
{
"stats": {
"vhost-man": {
"component": "vhost-man",
"node": "stats/vhost-man",
"data": [
{"var": "vhost-man/Number of VHosts", "value": 15}
]
},
"sess-man": {
"component": "sess-man",
"node": "stats/sess-man",
"data": [
{"var": "sess-man/Registered accounts", "value": 292},
{"var": "sess-man/Open user connections", "value": 10}
]
},
"message-router": {
"component": "message-router",
"node": "stats/message-router",
"data": [
{"var": "message-router/CPU usage", "value": "0.1%"},
{"var": "message-router/Used Heap", "value": "101 454 KB"}
]
}
}
}
每个组件的 data 数组字段动态变化(SessionManager、MessageRouter、S2S、PubSub、MUC 各自上报),Stats level 参数默认 FINEST 会拉全部维度。
ComponentStats — /rest/stats/{component_jid}
单独拉一个组件的 stats,{component_jid} 是内部组件 JID,如 sess-man@xmpp.example.com、stats@xmpp.example.com。
curl -H "Api-Key: $KEY" "http://host:8080/rest/stats/sess-man@xmpp.example.com" | python3 -m json.tool
5.2 VHost 域
VHostAdmin — /rest/vhost/
Handler:vhost/VHostAdmin.groovy,requiredRole = "admin",GET。返回当前所有虚拟主机列表(JSON):
{
"vhosts": [
{"jid": "xmpp.example.com", "isAdmin": true}
]
}
生产场景:多租户,可通过 Groovy Ad-Hoc CreateNode / DeleteNode 运行时增删 VHost。
5.3 Users 域(管理员 + 用户自服务)
UsersList — /rest/users/(GET,admin)
{"users": {"items": ["admin@xmpp.example.com", "alice@xmpp.example.com"], "count": 2}}
UsersDomain — /rest/users/{domain}(GET,admin)
列出指定域名下所有 JID,如 /rest/users/xmpp.example.com。
UserAdmin — /rest/user/{local}@{domain}(GET/POST/DELETE,admin)
- GET:查用户 JID 详细(uid、是否 admin)
- POST:
{"user":{"password":"newpass"}}改密码 - DELETE:删除用户
UserUser — /rest/user/(GET/POST/DELETE,user)
登录用户自服务,JID 从 Basic Auth 或 Api-Key 推断:
# 查自己
curl -u "admin@xmpp.example.com:q1w2e3r4" http://host:8080/rest/user/
# {"user":{"jid":"admin@xmpp.example.com","domain":"xmpp.example.com","isAdmin":true,"uid":1}}
# 改自己密码
curl -u "admin@xmpp.example.com:q1w2e3r4" -X POST http://host:8080/rest/user/ \
-H "Content-Type: application/json" \
-d '{"user":{"password":"newpass123"}}'
# 删除自己账号(危险)
curl -u "alice@xmpp.example.com:q1w2e3r4" -X DELETE http://host:8080/rest/user/
UserStatus — /rest/user/{local}@{domain}/status/{resource}(GET,admin)
查用户在线状态 + 资源。
5.4 Stream 域(发送任意 XMPP Stanza)
StreamHandler — /rest/stream/{to_jid}(POST,admin)
原始 HTTP content 直接作为 XMPP Stanza 发给 to_jid。用于 HTTP 客户端触发 XMPP 消息、IQ 查询等:
# HTTP → XMPP IQ(ping admin 自身)
curl -u admin@xmpp.example.com:q1w2e3r4 \
-X POST "http://host:8080/rest/stream/admin@xmpp.example.com" \
-H "Content-Type: application/xml" \
-H "Accept: application/xml" \
-d '<iq type="get" id="ping-1"><ping xmlns="urn:xmpp:ping"/></iq>'
5.5 Ad-Hoc Commands 域(XEP-0050 HTTP 代理)
AdHocHandler — /rest/adhoc/{component_jid}(GET/POST,user)
把 XMPP Ad-Hoc Commands 代理成 HTTP 端点——通过 HTTP 调用 Groovy 管理脚本。这是 Tigase 管理操作的核心通道。
列出组件可用 Ad-Hoc Commands(GET):
# 查 sess-man 组件下可用的 Ad-Hoc(对应 scripts/admin/ Groovy 脚本)
curl -u admin@xmpp.example.com:q1w2e3r4 \
"http://host:8080/rest/adhoc/sess-man@xmpp.example.com"
# 返回 items 数组,每项:{jid, node, name}
执行 Ad-Hoc Command(POST,JSON body):
# 执行 GetListOfActiveUsers(node=http://jabber.org/protocol/admin#get-active-users)
curl -u admin@xmpp.example.com:q1w2e3r4 \
-X POST "http://host:8080/rest/adhoc/sess-man@xmpp.example.com" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"command": {
"node": "http://jabber.org/protocol/admin#get-active-users",
"fields": [
{"var": "domainjid", "value": "xmpp.example.com"},
{"var": "max_items", "value": "25"}
]
}
}'
Handler 返回的 JSON 结构完整保留 Command.x + reported/item 表格,Groovy 闭包里已经做了 XML → JSON 转换。
5.6 PubSub 域
PubsubAdHoc — /rest/pubsub/{pubsub_jid}(GET/POST)
列出/执行 PubSub 组件的 Ad-Hoc Commands(创建节点、发布、订阅等)。
5.7 Avatar 域
AvatarGet — /rest/avatar/{user_jid}/{source}(GET,user)
{source}可选:avatar(PEP)、vcard4、vcard-temp,默认avatar- 返回二进制图片数据,浏览器直接
<img src="/rest/avatar/...">可用
AvatarPut — /rest/avatar/{user_jid}(PUT,user)
设置自己头像,请求体直接放图片二进制。
5.8 Push 域
UnregisterDevice — /rest/unregister-device/{domain}(DELETE,user,open)
推送设备注销(XEP-0357 Push)。
5.9 User Account Flow 域
三个 open access 端点,无认证:
| 端点 | 方法 | 用途 |
|---|---|---|
/rest/user/confirm/{token} | GET/POST | 账户邮箱确认 |
/rest/user/resetPassword/ | GET | 密码重置表单 HTML |
/rest/user/resetPassword/{token} | GET/POST | 带 token 的密码重置 |
六、XEP 扩展协议面
6.1 启动时实测加载的 XEP 清单
启动日志(实测 2026-10-27,Ubuntu 22.04 / OpenJDK 17 / Tigase 8.4.3-b12907)自动加载 30+ XEP 插件,覆盖核心会话、安全、档案、PubSub、MUC、AMP 等:
| XEP | 名称 | 插件标识 | 优先级权重 | 说明 |
|---|---|---|---|---|
| RFC 6120 | XMPP 核心协议 | — | — | XML 流式 TLS 握手 |
| RFC 6121 | XMPP IM 协议 | — | — | 会话与消息 |
| XEP-0030 | Service Discovery | disco | 1 | 服务发现(disco#info / disco#items) |
| XEP-0045 | MUC 多用户会议 | MUCComponent / jabber:iq:register=1:1342 | 2 | 聊天室 |
| XEP-0050 | Ad-Hoc Commands | http://jabber.org/protocol/commands=1:1342 | 1 | Groovy 管理脚本触发通道 |
| XEP-0060 | PubSub 发布订阅 | PubSubComponent | 3 | 事件订阅/发布 |
| XEP-0079 | AMP 高级消息处理 | AmpComponent | 3 | 消息条件路由 |
| XEP-0199 | XMPP Ping | (内建) | 1 | ping/pong |
| XEP-0237 | Roster Versioning | (内建) | 1 | 联系人版本同步 |
| XEP-0280 | Message Carbons | message-carbons=1:1342 | 1 | 消息同步多端 |
| XEP-0297 | Message Stanza Forwarding | (内建) | 1 | 消息转发 |
| XEP-0313 | MAM 消息归档 | urn:xmpp:mam:2=1:1342 / message-archive=1:1342 | 3 | 离线/历史消息 |
| XEP-0352 | CSI 客户端状态指示 | urn:xmpp:csi:0=1:1342 | 1 | 空连接检测 |
| XEP-0357 | Push 推送通知 | (内建) | 1 | 移动推送 |
| XEP-0369 | MIX | MixComponent | 3 | 新一代多用户信息 |
| SASL | 多种 SASL | urn:ietf:params:xml:ns:xmpp-sasl=4:335 | 4 | SCRAM-SHA-1/256/512 / PLAIN / EXTERNAL |
| Privacy | 隐私列表 | jabber:iq:privacy=1:1342 | 1 | 用户拉黑 |
| Register | 在线注册 | jabber:iq:register=1:1342 | 1 | JIQ Register(可禁) |
| Roster | 联系人列表 | jabber:iq:roster=4:335 | 4 | 核心功能 |
| VCard | 名片 | vcard-temp=1:1342 / vcard-xep-0292=1:1342 | 1 | 兼容旧版与新版 |
| StartTLS | STARTTLS | starttls=1:1342 | 1 | 升级加密 |
| zlib | Stream Compression | zlib=1:1342 | 1 | 流式压缩 |
| BOSH / WebSocket | HTTP/XMPP网关 | HTTP API 组件 | 1 | HTTP 传输 |
| S2S | 服务器互联 | S2SConnectionManager | 1 | 联邦 |
💡 技术拓展:XMPP 扩展生态全景——
XEP 族 数量 代表 Tigase 支持 核心 IM ~10 RFC 6120/6121、SASL、Roster、Privacy ✅ 全量 会话与推送 ~15 MAM、MUC、PubSub、AMP、CSI、MIX ✅ 全量(MixComponent) 安全 ~10 OMEMO、TLS、SCRAM、Device IDs ✅ 内建 IoT / STUN ~5 Jingle、XMPP IoT、STUN ✅ 含 tigase-stun.jar 管理 ~5 Ad-Hoc、Jabber-Server-Admin ✅ 78 条 Groovy 未实现/第三方 若干 MAM v1(仅 v2)、Jingle ICE 完整栈 需额外组件 本文/发行包聚焦 Tigase 已实现 的 XEP,通过
scripts/admin/Groovy 脚本扩展,开发团队可以自己写新 Ad-Hoc、新 XEP Handler。
6.2 协议端口与传输
| 端口 | 协议 | 传输 | 功能 |
|---|---|---|---|
| 5222 | XMPP | TCP + STARTTLS | 客户端 C2S(主流) |
| 5223 | XMPP | TCP + TLS(旧版) | 客户端旧兼容 |
| 5269 | XMPP | TCP | 服务器间 S2S 联邦 |
| 8080 | HTTP | TCP | HTTP Admin + REST API + BOSH + WebSocket |
| 8443 | HTTPS | TCP + TLS | 同上(TLS 版,需证书) |
| 9050 | SNMP/JMX | TCP/UDP | 监控(可选) |
七、XMPP Ad-Hoc Commands + Groovy Admin 脚本族
7.1 机制总览
Tigase 管理操作的真正核心不是 HTTP API(HTTP API 是代理层),而是一套 78 条 Groovy 管理脚本,全部位于 scripts/admin/ 目录,每脚本头部注释用 AS:CommandId / AS:Group / AS:Description 元数据自描述,启动时自动加载为 Ad-Hoc Commands,通过以下三种通道触发:
- XMPP 客户端(最原生):连接 sess-man 组件,发送 Ad-Hoc 命令 IQ
- Admin Console Web UI:
http://host:8080/rest/登录后可视化操作 - REST API:HTTP
/rest/adhoc/{component_jid}代理(§5.5)
7.2 脚本完整清单(按 Group 分类)
Users(用户管理)
| CommandId | Description | 脚本 |
|---|---|---|
http://jabber.org/protocol/admin#add-user | Add user | AddUser.groovy |
http://jabber.org/protocol/admin#change-user-password | Change user password | ChangeUserPassword.groovy |
http://jabber.org/protocol/admin#delete-user | Delete user | DeleteUser.groovy |
http://jabber.org/protocol/admin#disable-user | Disable user | DisableUser.groovy |
http://jabber.org/protocol/admin#reenable-user | Re-Enable User | ReEnableUser.groovy |
http://jabber.org/protocol/admin#end-user-session | End User Session | EndUserSession.groovy |
http://jabber.org/protocol/admin#get-registered-users-list | Get registered user list | GetRegisteredUserList.groovy |
get-user-info | Get User Info | GetUserInfo.groovy |
modify-user | Modify user | EditUser.groovy |
user-roster-management | Update user roster entry | UserRosterManagement.groovy |
user-roster-management-ext | Update user roster entry, extended | UserRosterManagementExt.groovy |
http://jabber.org/protocol/admin#add-user-tracker | Activate log tracker | AddUserTracker.groovy |
http://jabber.org/protocol/admin#remove-user-tracker | Remove log tracker | RemoveUserTracker.groovy |
http://jabber.org/protocol/admin#get-user-roster | Get User Roster | — |
user-domain-perm | Change inter-domain perm | UserDomainFilter.groovy |
roster-fixer | Fixes user's roster | RosterFixer.groovy |
roster-fixer-cluster | Fixes user's roster on cluster | RosterFixerCluster.groovy |
Statistics(统计)
| CommandId | Description | 脚本 |
|---|---|---|
http://jabber.org/protocol/admin#get-active-users | Get list of active users | GetListOfActiveUsers.groovy |
http://jabber.org/protocol/admin#get-active-users-num | Number of active users | GetNumberOfActiveUsers.groovy |
http://jabber.org/protocol/admin#get-idle-users | Get idle users | — |
http://jabber.org/protocol/admin#get-idle-users-num | Number of idle users | GetNumberOfIdleUsers.groovy |
http://jabber.org/protocol/admin#get-online-users-list | Online users list | GetListOfOnlineUsers.groovy |
http://jabber.org/protocol/admin#get-top-active-users | Top active users | GetTopActiveUsers.groovy |
http://jabber.org/protocol/admin#user-stats | User Statistics | UserStatistics.groovy |
connection-time | Connections time | ConnectionTime.groovy |
Configuration(配置 + 组件管理)
| CommandId | Description | 脚本 |
|---|---|---|
get-config-tdsl | Get config.tdsl | GetConfigTDSLFromMemory.groovy |
get-config-file | Get config file | GetConfigFile.groovy |
update-config-tdsl | Update config.tdsl | UpdateConfig.groovy |
http://jabber.org/protocol/admin#shutdown | Shutdown | Shutdown.groovy |
http://jabber.org/protocol/admin#set-motd | Set MOTD | SetMOTD.groovy |
http://jabber.org/protocol/admin#edit-motd | Edit MOTD | EditMOTD.groovy |
http://jabber.org/protocol/admin#delete-motd | Delete MOTD | DeleteMOTD.groovy |
http://jabber.org/protocol/admin#set-welcome | Set Welcome Message | SetWelcomeMessage.groovy |
http://jabber.org/protocol/admin#delete-welcome | Delete Welcome Message | DeleteWelcomeMessage.groovy |
comp-manager | Manage server components | CompManager.groovy |
plugin-manager | Manage server plugins | PluginManager.groovy |
comp-repo-item-add | Add component repo item | CompRepoItemAdd.groovy |
comp-repo-item-update | Update repo item config | CompRepoItemUpdate.groovy |
comp-repo-item-remove | Remove repo item | CompRepoItemRemove.groovy |
comp-repo-reload | Reload component repository | CompRepoReload.groovy |
cluster-nodes-list | List all cluster nodes | GetListOfClusterNodes.groovy |
force-stop-service | Force stop service | ForceStopServiceForKey.groovy |
list-service-keys | List Service Keys | ListServiceKeys.groovy |
Audit Log(审计)
| CommandId | Description | 脚本 |
|---|---|---|
get-connected-users | Get connected users | AuditlogGetConnectedUsers.groovy |
get-connections-history | Connections history | AuditlogGetConnectionsHistory.groovy |
get-disconnected-users | Disconnected users | AuditlogGetDisconnectedUsers.groovy |
get-any-file | Get any file | GetAnyFile.groovy |
load-errors | Load errors | LoadErrors.groovy |
Notifications(通知)
| CommandId | Description | 脚本 |
|---|---|---|
http://jabber.org/protocol/admin#announce | Announce to online users | BroadcastToOnline.groovy |
S2S(联邦)
| CommandId | Description | 脚本 |
|---|---|---|
s2s-all-conns-state | S2S all connections state | S2SCIDState.groovy |
s2s-bad-state-conns | Bad state connections | S2SBadConnectionStates.groovy |
s2s-get-cid-connection | Get CID connection | — |
s2s-reset-bad-state-conns | Reset bad state connections | S2SResetBadConnections.groovy |
PubSub(发布订阅)
| CommandId | Description | 脚本 |
|---|---|---|
create-node | Create node | CreateNode.groovy |
delete-node | Delete node | DeleteNode.groovy |
list-nodes | List nodes | ListNodes.groovy |
publish-item | Publish item to node | PublishItem.groovy |
delete-item | Delete item from node | DeleteItem.groovy |
list-items | List items | ListItems.groovy |
retrieve-item | Retrieve item | RetrieveItem.groovy |
subscribe-node | Subscribe to node | SubscribeNode.groovy |
unsubscribe-node | Unsubscribe from node | UnsubscribeNode.groovy |
MUC / Rooms(聊天室)
| CommandId | Description | 脚本 |
|---|---|---|
room-create | Create room | room-create.groovy(注释态) |
room-remove | Remove room | room-remove.groovy |
mass-room-remove | Mass room remove | mass-room-remove.groovy |
default-room-config | Default room config | default-config.groovy |
room-occupant-persistent-add | Add persistent room occupant | RoomAddPersistentOccupant.groovy |
room-occupant-persistent-remove | Remove persistent room occupant | RoomRemovePersistentOccupant.groovy |
Other(杂项)
| CommandId | Description | 脚本 |
|---|---|---|
dns-query | DNS Query | DNSQuery.groovy |
pre-bind-bosh-session | Pre-Bind BOSH user session | BoshPreBindSession.groovy |
oauth-credentials | OAuth credentials | OAuthCredentials.groovy |
ssl-certificate-add | Add SSL Certificate | SSLCertificateAdd.groovy |
sim-serv-stopped | Simulate serviceStopped | SimServiceStopped.groovy |
retrieve-user-subscriptions | Retrieve subscriptions | RetrieveUserSubscriptions.groovy |
Example scripts(示例)
| CommandId | Description | 脚本 |
|---|---|---|
list-commands | Get list available commands | ListCommands.groovy |
groovy-example | Tigase scripting guide | example_TigaseScriptingGuide.groovy |
hello | Hello World Script | example_HelloWorld.groovy |
7.3 调用示例
通过 HTTP 代理执行 AddUser:
curl -u admin@xmpp.example.com:q1w2e3r4 \
-X POST "http://host:8080/rest/adhoc/sess-man@xmpp.example.com" \
-H "Content-Type: application/json" -H "Accept: application/json" \
-d '{
"command": {
"node": "http://jabber.org/protocol/admin#add-user",
"fields": [
{"var": "accountjid", "value": "alice@xmpp.example.com"},
{"var": "password", "value": "q1w2e3r4"}
]
}
}'
通过 Admin Console 界面执行:浏览器登录 Admin Console(http://host:8080/rest/),左侧 Ad-Hoc Commands 树按 Group 分类列出全部脚本,点击即可触发,返回值渲染成 DataForm。
7.4 脚本开发
可以在 scripts/admin/ 下放新 Groovy 脚本,启动时自动加载。参考 example_TigaseScriptingGuide.groovy。脚本头部 AS:* 注释元数据决定它出现在哪个 Group、叫什么 Description、CommandId 是什么。
八、分页 / 过滤 / 排序通用约定
Tigase REST API 目前没有统一的分页/过滤协议——每个 Handler 自己定义查询参数,常见模式:
| Handler | 查询参数 | 说明 |
|---|---|---|
| Stats | Stats level=FINEST/FINE/WARNING | 拉不同级别统计 |
| Users | 无 | UsersDomain 按域名过滤 |
| Stream | 无 | 直接 Stanza 发送 |
| Ad-Hoc | Command data fields | 每个 Command 有自己的 fields |
REST 路径里的 {component_jid}、{user_jid}、{domain} 都是路径参数(不是 query),按 Handler 内 regex 匹配。
九、常见问题
9.1 REST 端点返回 404 Not found
路由未匹配:检查——
- Handler 是否在
scripts/rest/<subdir>/下有.groovy文件 - 是否是 Bean 名注册(
@Bean(name=...)) - authRequired 闭包是否返回 true(某些 Handler 未配 Api-Key + role 就会跳过匹配)
9.2 REST 返回 403 / 401
403 Missing required 'Api-Key' header:open_access=false但未传 Api-Key401 Not authorized:Api-Key 无效、role 不匹配、用户 JID 不在 admins 列表
排查:
# 测试 Api-Key
curl -v -H "Api-Key: changeme" http://localhost:8080/rest/stats/server 2>&1 | grep -E "HTTP/|Api-Key|Not authorized|Missing"
9.3 Admin Console 登不进去
- Admin 用户 JID 必须含完整 VHost(
admin@xmpp.example.com,不是裸admin) http.admin-console.admin-user必须与admins列表里的 JID 对应- 密码是 setup wizard 设定的,不是
tigase.conf里任何值
9.4 Groovy 脚本加载失败
GroovyScriptException: ...
- 头部
AS:CommandId/AS:Group/AS:Description格式不对(严格要求AS:前缀 + 冒号 + 空格) - Groovy 语法错误(脚本首次加载时编译)
- Bean 类加载顺序问题(Handler 依赖了未初始化的 Bean)
9.5 Ad-Hoc Command 返回 XML 错误
Command node 拼写错(如 http://jabber.org/protocol/admin#add-user 是完整 node,不是裸 add-user)。先 list-commands 列出可用 node。
9.6 REST /rest/ 根路径返回 HTML 不是 JSON
正常行为:根路径是 Admin Console 入口。JSON API 子路径从 /rest/stats/、/rest/adhoc/、/rest/user/ 开始。
十、参考链接
- Tigase HTTP API 官方文档(源码内联 description 即文档):发行包
scripts/rest/*/下每个 Handler 类 - Tigase Admin Scripting Guide:发行包
scripts/admin/example_TigaseScriptingGuide.groovy - XEP 扩展大全:https://xmpp.org/extensions/
- XEP-0050 Ad-Hoc Commands:https://xmpp.org/extensions/xep-0050.html
- Jetty 内嵌 HTTP Server:发行包
jars/tigase-http-api-jetty.jar - 发行包完整 Groovy 脚本列表:
scripts/admin/*.groovy