koishi-plugin-tx-cos
v0.0.1
Published
来用腾讯cos作为assets服务吧
Readme
koishi-plugin-tx-cos
使用腾讯云对象存储(COS)作为 Koishi 的 assets 服务。插件会将消息中的图片、音频和视频上传到指定存储桶,并把资源地址替换为可公开访问的 COS 或 CDN URL。
功能特点
- 实现 Koishi
assets服务,可直接配合各类图片、音频和视频消息使用 - 支持 HTTP URL、Data URL 等 Koishi HTTP 服务能够读取的资源
- 使用文件内容的 SHA-1 摘要生成对象名,相同内容会得到稳定的存储路径
- 支持自定义对象路径前缀、COS 公网域名或 CDN 域名
- 支持 URL 白名单,指定资源可跳过上传
- 自动跳过已经指向当前
baseUrl的资源,避免重复处理
使用要求
- Koishi 4.18
- 腾讯云 COS 存储桶
- 对目标存储桶具有对象写入权限的腾讯云 API 密钥
- 可公开读取对象的 COS 访问地址,或已正确配置回源的 CDN 域名
- 已启用 Koishi
http服务
插件返回的是不带临时签名的公开 URL,因此存储桶或 CDN 必须允许客户端读取对应对象。建议为插件使用权限最小化的独立密钥,不要将密钥提交到代码仓库。
安装
在 Koishi 插件市场搜索 tx-cos,或通过包管理器安装:
yarn add koishi-plugin-tx-cos启用插件并填写 COS 配置后,它会注册为当前 Koishi 实例的 assets 服务。一个 Koishi 实例通常只应启用一个 assets 服务实现,以免服务冲突。
腾讯云 COS 准备
- 创建 COS 存储桶,并记下完整存储桶名称和地域。
- 创建具有目标存储桶对象写入权限的 API 密钥,获取
SecretId和SecretKey。 - 配置存储桶公开读取,或配置能够公开访问对象的 CDN 域名。
- 将公网访问根地址填写到
baseUrl,不要包含对象路径前缀。
例如:
bucket: example-1250000000
region: ap-guangzhou
baseUrl: https://example-1250000000.cos.ap-guangzhou.myqcloud.com
prefix: koishi-assets上传后的资源地址类似:
https://example-1250000000.cos.ap-guangzhou.myqcloud.com/koishi-assets/6c6f0e...a1.png使用自定义 CDN 域名时,baseUrl 也可以填写为 https://static.example.com,但该域名必须正确回源到配置的存储桶和路径。
配置项
| 配置项 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- |
| secretId | string | 必填 | 腾讯云 API 密钥的 SecretId |
| secretKey | string | 必填 | 腾讯云 API 密钥的 SecretKey,控制台中会按敏感字段显示 |
| bucket | string | 必填 | 完整存储桶名称,格式为 bucket-appid |
| region | string | 必填 | 存储桶地域,例如 ap-guangzhou |
| baseUrl | string | 必填 | COS 公网访问或 CDN 根地址 |
| prefix | string | koishi-assets | 上传对象的路径前缀 |
| whitelist | string[] | [] | 不进行上传和地址替换的 URL 前缀列表 |
baseUrl 末尾的 / 会被自动处理。prefix 中不安全的字符会替换为 -,多级路径可以使用 / 分隔。
配置示例
推荐通过环境变量保存密钥:
plugins:
tx-cos:
secretId: ${{env.COS_SECRET_ID}}
secretKey: ${{env.COS_SECRET_KEY}}
bucket: ${{env.COS_BUCKET}}
region: ${{env.COS_REGION}}
baseUrl: ${{env.COS_BASE_URL}}
prefix: koishi-assets
whitelist:
- https://trusted.example.com/static/对应的环境变量示例:
COS_SECRET_ID=AKIDxxxxxxxxxxxxxxxx
COS_SECRET_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
COS_BUCKET=example-1250000000
COS_REGION=ap-guangzhou
COS_BASE_URL=https://static.example.com请根据实际 Koishi 配置结构放置插件配置;控制台安装时可直接在插件配置页面填写这些字段。
工作方式
当 Koishi 处理消息中的 <img>、<audio> 或 <video> 元素时,插件会:
- 检查资源 URL 是否命中
whitelist,或是否已经使用当前baseUrl。 - 通过 Koishi
http服务读取资源内容。 - 根据内容计算 SHA-1 摘要,并结合传入的文件名或检测到的扩展名生成对象名。
- 将对象上传到
bucket的prefix路径下,同时保留资源的 Content-Type。 - 返回公开 URL,替换消息中的原始资源地址。
同一进程内成功上传过的对象会记录在内存中,再次遇到同一对象时直接返回公开 URL。Bot 重启后这份记录会清空;由于对象名由内容生成,重复上传仍会写入同一个对象键。
白名单
whitelist 使用 URL 前缀匹配。命中白名单的资源会保留原地址,不会下载或上传到 COS。
whitelist:
- https://q.qlogo.cn/
- https://third-party.example.com/public/只有确认目标平台可以直接访问这些 URL 时才应加入白名单。
常见问题
上传成功但消息中的资源无法访问
检查以下项目:
baseUrl是否能公开访问,而不是腾讯云控制台内部地址。- 存储桶是否允许读取对象,或 CDN 是否已正确配置回源和访问权限。
- CDN 回源路径是否与
prefix一致。 bucket是否包含 AppId,region是否与存储桶实际地域一致。
出现 AccessDenied 或签名错误
检查 secretId、secretKey 是否正确,以及密钥是否拥有向目标存储桶执行对象写入操作的权限。还应确认服务器时间准确,且 bucket 和 region 没有填错。
为什么统计数量与存储桶中的对象数不一致
插件的 stats() 只统计当前进程启动后成功执行的上传次数和字节数,不会读取 COS 中已有对象,也不会在 Bot 重启后保留统计结果。
是否会自动删除 COS 中的旧文件
不会。插件只负责上传和返回资源地址,不会清理对象。需要自动清理时,请在腾讯云 COS 中配置生命周期规则,并确认生命周期策略不会误删仍在使用的资源。
许可证
MIT
