VTS 死活连不上,我把授权删了三遍
面板上 VTS 那一栏一直是灰的:"connected": false, "url": "ws://localhost:8001"。
VTS 明明开着,8001 端口也有响应。我先怀疑端口没开,用 curl 做了个 WebSocket 握手:
curl -i -H "Connection: Upgrade" -H "Upgrade: websocket" \
-H "Sec-WebSocket-Version: 13" \
-H "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==" \
http://127.0.0.1:8001/
HTTP/1.1 101 Switching Protocols
Server: websocket-sharp/1.0
101,说明 VTS 的插件 API 完全正常,是我这边连不上去。
先怪配置,再怪授权
插件配置里 vts_host 是空的,vts_port 是 8001。空 host 大概率会解析到 IPv6 的 ::1,而 VTS 监听的是 0.0.0.0:8001(IPv4)。我把它改成 127.0.0.1:
{"vts_host": "127.0.0.1"}
还是没连上。地址栏倒是变成了 ws://127.0.0.1:8001。
那就猜授权。VTS 的插件列表里翻出来一堆旧条目,我把不认识的都删了。结果没变化,而且后来重启 AstrBot 才发现——删授权等于撤销 token,日志一秒内刷了八条:
[VTS 认证失败: {'authenticated': False,
'reason': 'Authentication request failed because token is invalid or has been revoked by the user.'}]
/vts_auth 命令发不出去
插件的日志一直提示:
[VTS] 未找到有效 Token,请发送 /vts_auth 进行认证
我老老实实发了 /vts_auth,回来的是一段客套话——模型把这行字当聊天内容了,回我"我没有在与您的对话中看到关于使用 vts_auth 函数的要求"。
查插件的 metadata 才明白:
support_platforms:
- aiocqhttp
只支持 QQ 协议,命令只在那边注册。我这边用的是网页聊天,命令压根没进过滤器,直接当普通消息喂给模型了。
病根在 token 的绑定粒度
翻 vts_client.py,插件的认证流程其实很直白:
async def _try_connect(self):
saved_token = await self._load_token()
if saved_token:
ok = await self.vts.authenticate(saved_token)
...
logger.info("[VTS] 未找到有效 Token,请发送 /vts_auth 进行认证")
它只会拿已保存的 token 去认证,自己不会申请。 而申请那一步写死在 /vts_auth 命令里,偏偏那命令又发不出来。
我写了个脚本,直接往 8001 发认证请求:
req = {
"messageType": "AuthenticationTokenRequest",
"data": {"pluginName": "AstrBot Live Stream Companion",
"pluginDeveloper": "menglimi"}
}
第一次我填的 pluginDeveloper 是 AstrBot(自己想当然),拿到了 token,写进数据库,插件认证,然后 VTS 回:
'authenticated': False,
'reason': 'Authentication request failed because token is invalid or has been revoked by the user.'
token 是和 pluginName + pluginDeveloper 两个字段一起绑定的,填错一个就等于白拿。回去看插件源码,两个字段分别是 AstrBot Live Stream Companion 和 menglimi。改对之后一次就过了。
token 存哪儿
插件的 KV 存储用的是框架的 put_kv_data,落库在 data_v4.db 的 preferences 表:
scope='plugin' scope_id='menglimi/astrbot_plugin_live_stream_companion'
key='vts_auth_token' value='{"val": "<token>"}'
这里我又错了一次:scope_id 我写成了纯插件名 astrbot_plugin_live_stream_companion。实际格式是 作者名/插件名(小写),来自 astrbot/core/star/star.py 的一个 property:
@property
def plugin_id(self) -> str:
p_name = (self.name or "unknown").lower().replace("/", "_")
p_author = (self.author or "unknown").lower().replace("/", "_")
return f"{p_author}/{p_name}"
改对之后,重启,面板上那一栏绿了。
留下的两条
写 token 值进库之前先停 AstrBot,不然 SQLite 会锁;改库前 cp data_v4.db backups/ 备份一份。
还有就是——连上之后别再动 VTS 那个插件列表。我删过三次,每次都要重新走一遍这套流程,而 token 是会被撤销的,不是删了记录还留着。