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 三种认证模式实测。

TigaseTigaseJabberRESTXEPMUCPubSub即时通讯2026/10/27

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 基础 URLhttp://<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 / TigaseOpenJDK 17 / Tigase 8.4.3-b12907
运行用户tigase

二、前置条件

  1. Tigase 已启动(参考 B1 / B2),端口 8080 可访问。
  2. 有合法的 API-Key(HTTP_API_KEY_BOOTSTRAP 环境变量注入或数据库 ApiKey 实体),或 http.rest.open_access = true。
  3. 管理员 JID 已在 config.tdsl 的 admins 列表中。
  4. 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 APIHTTP 8080 + JSON/XML系统集成、CI/CD、HTTP 客户端、状态拉取Api-Key 头 / Basic Auth
Admin ConsoleHTTP 8080 + Web UI人工运维、可视化操作Basic Auth
XEP 协议层XMPP 5222 + XML StanzasXMPP 客户端扩展、BOSH、WebSocketSASL(SCRAM-SHA-1/256/512 等)
Ad-Hoc CommandsXEP-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}adhocGET/POSTuser列出/执行 Ad-Hoc Commands
ServerStatsHandler/statsGETadmin全服组件统计
ComponentStatsHandler/{component_jid}statsGETadmin单个组件统计
VhostAdminHandler/vhostGETadminVHost 列表
UserAdminHandler/{user_jid}userGET/POST/DELETEadmin管理员操作用户
UserUserHandler/userGET/POST/DELETEuser登录用户自服务(改密码/查资料/删账号)
UserStatusHandler/{user_jid}/status/{resource}userGETadmin查用户在线状态
UsersListHandler/usersGETadmin全量用户列表
UsersDomainHandler/{domain}usersGETadmin指定域名用户列表
StreamHandler/{to_jid}streamPOSTadmin发送任意 XMPP Stanza
PubSubAdHocHandler/{pubsub_jid}pubsubGET/POSTadminPubSub 节点 Ad-Hoc
PubSubAdHocActions/{pubsub_jid}/{adhoc_command_node}pubsubGET/POSTadminPubSub Ad-Hoc 执行
AvatarGet/{user_jid}/{source}avatarGETuser获取用户头像
AvatarPutNoAuth/{user_jid}avatarPUTuser设置头像
UnregisterDeviceHandler/unregister-device/{domain}pushDELETEuser注销推送设备
ResetPasswordForm/resetPassword/userGETopen密码重置表单
ResetPasswordToken/resetPassword/{token}userGET/POSTopen密码重置(带 token)
ConfirmAccount/confirm/{token}userGET/POSTopen账户确认

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.groovy regex /{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 AuthAuthorization: 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 6120XMPP 核心协议——XML 流式 TLS 握手
RFC 6121XMPP IM 协议——会话与消息
XEP-0030Service Discoverydisco1服务发现(disco#info / disco#items)
XEP-0045MUC 多用户会议MUCComponent / jabber:iq:register=1:13422聊天室
XEP-0050Ad-Hoc Commandshttp://jabber.org/protocol/commands=1:13421Groovy 管理脚本触发通道
XEP-0060PubSub 发布订阅PubSubComponent3事件订阅/发布
XEP-0079AMP 高级消息处理AmpComponent3消息条件路由
XEP-0199XMPP Ping(内建)1ping/pong
XEP-0237Roster Versioning(内建)1联系人版本同步
XEP-0280Message Carbonsmessage-carbons=1:13421消息同步多端
XEP-0297Message Stanza Forwarding(内建)1消息转发
XEP-0313MAM 消息归档urn:xmpp:mam:2=1:1342 / message-archive=1:13423离线/历史消息
XEP-0352CSI 客户端状态指示urn:xmpp:csi:0=1:13421空连接检测
XEP-0357Push 推送通知(内建)1移动推送
XEP-0369MIXMixComponent3新一代多用户信息
SASL多种 SASLurn:ietf:params:xml:ns:xmpp-sasl=4:3354SCRAM-SHA-1/256/512 / PLAIN / EXTERNAL
Privacy隐私列表jabber:iq:privacy=1:13421用户拉黑
Register在线注册jabber:iq:register=1:13421JIQ Register(可禁)
Roster联系人列表jabber:iq:roster=4:3354核心功能
VCard名片vcard-temp=1:1342 / vcard-xep-0292=1:13421兼容旧版与新版
StartTLSSTARTTLSstarttls=1:13421升级加密
zlibStream Compressionzlib=1:13421流式压缩
BOSH / WebSocketHTTP/XMPP网关HTTP API 组件1HTTP 传输
S2S服务器互联S2SConnectionManager1联邦

💡 技术拓展:XMPP 扩展生态全景——

XEP 族数量代表Tigase 支持
核心 IM~10RFC 6120/6121、SASL、Roster、Privacy✅ 全量
会话与推送~15MAM、MUC、PubSub、AMP、CSI、MIX✅ 全量(MixComponent)
安全~10OMEMO、TLS、SCRAM、Device IDs✅ 内建
IoT / STUN~5Jingle、XMPP IoT、STUN✅ 含 tigase-stun.jar
管理~5Ad-Hoc、Jabber-Server-Admin✅ 78 条 Groovy
未实现/第三方若干MAM v1(仅 v2)、Jingle ICE 完整栈需额外组件

本文/发行包聚焦 Tigase 已实现 的 XEP,通过 scripts/admin/ Groovy 脚本扩展,开发团队可以自己写新 Ad-Hoc、新 XEP Handler。

6.2 协议端口与传输

端口协议传输功能
5222XMPPTCP + STARTTLS客户端 C2S(主流)
5223XMPPTCP + TLS(旧版)客户端旧兼容
5269XMPPTCP服务器间 S2S 联邦
8080HTTPTCPHTTP Admin + REST API + BOSH + WebSocket
8443HTTPSTCP + TLS同上(TLS 版,需证书)
9050SNMP/JMXTCP/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,通过以下三种通道触发:

  1. XMPP 客户端(最原生):连接 sess-man 组件,发送 Ad-Hoc 命令 IQ
  2. Admin Console Web UI:http://host:8080/rest/ 登录后可视化操作
  3. REST API:HTTP /rest/adhoc/{component_jid} 代理(§5.5)

7.2 脚本完整清单(按 Group 分类)

Users(用户管理)

CommandIdDescription脚本
http://jabber.org/protocol/admin#add-userAdd userAddUser.groovy
http://jabber.org/protocol/admin#change-user-passwordChange user passwordChangeUserPassword.groovy
http://jabber.org/protocol/admin#delete-userDelete userDeleteUser.groovy
http://jabber.org/protocol/admin#disable-userDisable userDisableUser.groovy
http://jabber.org/protocol/admin#reenable-userRe-Enable UserReEnableUser.groovy
http://jabber.org/protocol/admin#end-user-sessionEnd User SessionEndUserSession.groovy
http://jabber.org/protocol/admin#get-registered-users-listGet registered user listGetRegisteredUserList.groovy
get-user-infoGet User InfoGetUserInfo.groovy
modify-userModify userEditUser.groovy
user-roster-managementUpdate user roster entryUserRosterManagement.groovy
user-roster-management-extUpdate user roster entry, extendedUserRosterManagementExt.groovy
http://jabber.org/protocol/admin#add-user-trackerActivate log trackerAddUserTracker.groovy
http://jabber.org/protocol/admin#remove-user-trackerRemove log trackerRemoveUserTracker.groovy
http://jabber.org/protocol/admin#get-user-rosterGet User Roster—
user-domain-permChange inter-domain permUserDomainFilter.groovy
roster-fixerFixes user's rosterRosterFixer.groovy
roster-fixer-clusterFixes user's roster on clusterRosterFixerCluster.groovy

Statistics(统计)

CommandIdDescription脚本
http://jabber.org/protocol/admin#get-active-usersGet list of active usersGetListOfActiveUsers.groovy
http://jabber.org/protocol/admin#get-active-users-numNumber of active usersGetNumberOfActiveUsers.groovy
http://jabber.org/protocol/admin#get-idle-usersGet idle users—
http://jabber.org/protocol/admin#get-idle-users-numNumber of idle usersGetNumberOfIdleUsers.groovy
http://jabber.org/protocol/admin#get-online-users-listOnline users listGetListOfOnlineUsers.groovy
http://jabber.org/protocol/admin#get-top-active-usersTop active usersGetTopActiveUsers.groovy
http://jabber.org/protocol/admin#user-statsUser StatisticsUserStatistics.groovy
connection-timeConnections timeConnectionTime.groovy

Configuration(配置 + 组件管理)

CommandIdDescription脚本
get-config-tdslGet config.tdslGetConfigTDSLFromMemory.groovy
get-config-fileGet config fileGetConfigFile.groovy
update-config-tdslUpdate config.tdslUpdateConfig.groovy
http://jabber.org/protocol/admin#shutdownShutdownShutdown.groovy
http://jabber.org/protocol/admin#set-motdSet MOTDSetMOTD.groovy
http://jabber.org/protocol/admin#edit-motdEdit MOTDEditMOTD.groovy
http://jabber.org/protocol/admin#delete-motdDelete MOTDDeleteMOTD.groovy
http://jabber.org/protocol/admin#set-welcomeSet Welcome MessageSetWelcomeMessage.groovy
http://jabber.org/protocol/admin#delete-welcomeDelete Welcome MessageDeleteWelcomeMessage.groovy
comp-managerManage server componentsCompManager.groovy
plugin-managerManage server pluginsPluginManager.groovy
comp-repo-item-addAdd component repo itemCompRepoItemAdd.groovy
comp-repo-item-updateUpdate repo item configCompRepoItemUpdate.groovy
comp-repo-item-removeRemove repo itemCompRepoItemRemove.groovy
comp-repo-reloadReload component repositoryCompRepoReload.groovy
cluster-nodes-listList all cluster nodesGetListOfClusterNodes.groovy
force-stop-serviceForce stop serviceForceStopServiceForKey.groovy
list-service-keysList Service KeysListServiceKeys.groovy

Audit Log(审计)

CommandIdDescription脚本
get-connected-usersGet connected usersAuditlogGetConnectedUsers.groovy
get-connections-historyConnections historyAuditlogGetConnectionsHistory.groovy
get-disconnected-usersDisconnected usersAuditlogGetDisconnectedUsers.groovy
get-any-fileGet any fileGetAnyFile.groovy
load-errorsLoad errorsLoadErrors.groovy

Notifications(通知)

CommandIdDescription脚本
http://jabber.org/protocol/admin#announceAnnounce to online usersBroadcastToOnline.groovy

S2S(联邦)

CommandIdDescription脚本
s2s-all-conns-stateS2S all connections stateS2SCIDState.groovy
s2s-bad-state-connsBad state connectionsS2SBadConnectionStates.groovy
s2s-get-cid-connectionGet CID connection—
s2s-reset-bad-state-connsReset bad state connectionsS2SResetBadConnections.groovy

PubSub(发布订阅)

CommandIdDescription脚本
create-nodeCreate nodeCreateNode.groovy
delete-nodeDelete nodeDeleteNode.groovy
list-nodesList nodesListNodes.groovy
publish-itemPublish item to nodePublishItem.groovy
delete-itemDelete item from nodeDeleteItem.groovy
list-itemsList itemsListItems.groovy
retrieve-itemRetrieve itemRetrieveItem.groovy
subscribe-nodeSubscribe to nodeSubscribeNode.groovy
unsubscribe-nodeUnsubscribe from nodeUnsubscribeNode.groovy

MUC / Rooms(聊天室)

CommandIdDescription脚本
room-createCreate roomroom-create.groovy(注释态)
room-removeRemove roomroom-remove.groovy
mass-room-removeMass room removemass-room-remove.groovy
default-room-configDefault room configdefault-config.groovy
room-occupant-persistent-addAdd persistent room occupantRoomAddPersistentOccupant.groovy
room-occupant-persistent-removeRemove persistent room occupantRoomRemovePersistentOccupant.groovy

Other(杂项)

CommandIdDescription脚本
dns-queryDNS QueryDNSQuery.groovy
pre-bind-bosh-sessionPre-Bind BOSH user sessionBoshPreBindSession.groovy
oauth-credentialsOAuth credentialsOAuthCredentials.groovy
ssl-certificate-addAdd SSL CertificateSSLCertificateAdd.groovy
sim-serv-stoppedSimulate serviceStoppedSimServiceStopped.groovy
retrieve-user-subscriptionsRetrieve subscriptionsRetrieveUserSubscriptions.groovy

Example scripts(示例)

CommandIdDescription脚本
list-commandsGet list available commandsListCommands.groovy
groovy-exampleTigase scripting guideexample_TigaseScriptingGuide.groovy
helloHello World Scriptexample_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查询参数说明
StatsStats level=FINEST/FINE/WARNING拉不同级别统计
Users无UsersDomain 按域名过滤
Stream无直接 Stanza 发送
Ad-HocCommand data fields每个 Command 有自己的 fields

REST 路径里的 {component_jid}、{user_jid}、{domain} 都是路径参数(不是 query),按 Handler 内 regex 匹配。

九、常见问题

9.1 REST 端点返回 404 Not found

路由未匹配:检查——

  1. Handler 是否在 scripts/rest/<subdir>/ 下有 .groovy 文件
  2. 是否是 Bean 名注册(@Bean(name=...))
  3. authRequired 闭包是否返回 true(某些 Handler 未配 Api-Key + role 就会跳过匹配)

9.2 REST 返回 403 / 401

  • 403 Missing required 'Api-Key' header:open_access=false 但未传 Api-Key
  • 401 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