npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

koishi-plugin-super-event-message-push

v0.1.13

Published

super-event-message-push

Readme

koishi-plugin-super-event-message-push

npm

用于接收后端推送的消息并通过 OneBot 协议转发到 QQ 群的 Koishi 插件。

功能

  • 接收来自后端的 webhook 请求
  • 使用 HMAC-SHA256 + 时间戳验证请求签名
  • 通过 OneBot 协议将消息转发到指定 QQ 群
  • 防重放攻击(5 秒时间窗口)

配置

插件配置

在 Koishi 控制台中配置以下参数:

| 参数 | 类型 | 默认值 | 说明 | |------|------|--------|------| | endpoint | string | /super-event/webhook | 接收 webhook 的路径 | | secret | string | change-me | 用于验证签名的密钥(需与后端配置一致) | | apiBaseUrl | string | http://localhost:4000/api | 后端 API 地址(保留用于未来功能) |

依赖

需要安装以下插件:

  • @koishijs/plugin-server - HTTP 服务器支持
  • @koishijs/plugin-adapter-onebot - OneBot 协议适配器

使用方法

1. 配置后端

在后端的 .env 文件中配置:

KOISHI_WEBHOOK_URL=http://your-koishi-server:5140/super-event/webhook
KOISHI_WEBHOOK_SECRET=your-secret-key

2. 后端调用示例

方式一:通过公共 Webhook 接口(推荐)

import crypto from 'crypto';
import axios from 'axios';

/**
 * 推送消息到 Koishi
 */
async function pushToKoishi(channel: number, message: string) {
  const secret = process.env.KOISHI_WEBHOOK_SECRET || 'change-me';
  const url = 'http://localhost:4000/api/push/webhook';
  
  const body = JSON.stringify({ channel, message });
  const timestamp = Math.floor(Date.now() / 1000);
  const signature = crypto
    .createHmac('sha256', secret)
    .update(timestamp + body)
    .digest('hex');

  const response = await axios.post(url, { channel, message }, {
    headers: {
      'x-super-event-signature': signature,
      'x-super-event-timestamp': String(timestamp),
      'content-type': 'application/json',
    },
  });

  return response.data;
}

// 使用示例
await pushToKoishi(123456789, '这是一条测试消息');

方式二:直接调用后端服务(需要权限)

import axios from 'axios';

async function pushToKoishiWithAuth(channel: number, message: string, token: string) {
  const response = await axios.post(
    'http://localhost:4000/api/push',
    { channel, message },
    {
      headers: {
        'Authorization': `Bearer ${token}`,
        'content-type': 'application/json',
      },
    }
  );

  return response.data;
}

3. 前端调用示例

import crypto from 'crypto-js';

/**
 * 前端推送消息到 Koishi(通过后端中转)
 */
async function sendMessageToGroup(channel: number, message: string) {
  const secret = 'your-secret-key'; // 注意:实际项目中不要在前端硬编码密钥
  const body = JSON.stringify({ channel, message });
  const timestamp = Math.floor(Date.now() / 1000);
  
  // 使用 crypto-js 计算签名
  const signature = crypto.HmacSHA256(timestamp + body, secret).toString();

  const response = await fetch('http://localhost:4000/api/push/webhook', {
    method: 'POST',
    headers: {
      'x-super-event-signature': signature,
      'x-super-event-timestamp': String(timestamp),
      'content-type': 'application/json',
    },
    body,
  });

  return response.json();
}

API 规范

请求格式

URL: POST {koishi-url}{endpoint}

Headers:

  • x-super-event-signature: HMAC-SHA256(secret, timestamp + body)
  • x-super-event-timestamp: Unix 时间戳(秒)
  • content-type: application/json

Body:

{
  "channel": 123456789,
  "message": "要发送的消息内容"
}

响应格式

成功响应 (200)

{
  "success": true,
  "message": "Message sent successfully"
}

错误响应

  • 400 Bad Request: 缺少签名/时间戳,或请求体格式错误
{
  "error": "Missing signature or timestamp"
}
  • 401 Unauthorized: 签名验证失败
{
  "error": "Invalid signature"
}
  • 404 Not Found: 请求已过期(超过 5 秒)
{
  "error": "Request expired"
}
  • 500 Internal Server Error: 发送消息失败或没有可用的 OneBot 适配器
{
  "error": "Failed to send message",
  "details": "错误详情"
}

安全性

签名验证

使用 HMAC-SHA256 算法生成签名,确保消息来自可信来源:

signature = HMAC_SHA256(secret, timestamp + body)

防重放攻击

  • 每个请求必须包含时间戳
  • 服务器只接受 5 秒内的请求
  • 超过时间窗口的请求返回 404

最佳实践

  1. 使用强密钥: KOISHI_WEBHOOK_SECRET 应使用随机生成的强密钥
  2. HTTPS 传输: 生产环境中使用 HTTPS 保护传输过程
  3. 密钥管理: 不要在前端代码中硬编码密钥,通过后端中转
  4. 访问控制: 配置防火墙规则,限制只有后端服务器可以访问 Koishi webhook

故障排查

消息发送失败

  1. 检查 OneBot 适配器是否已启动并连接
  2. 查看 Koishi 日志确认是否收到请求
  3. 确认群号是否正确,机器人是否在该群内

签名验证失败

  1. 确认后端和 Koishi 的 secret 配置一致
  2. 检查时间戳是否在 5 秒内
  3. 确认请求体格式是否正确(JSON 字符串)

请求过期

  1. 检查服务器时间是否同步(使用 NTP)
  2. 网络延迟过大时适当调整时间窗口

开发

构建

pnpm install
pnpm build

测试

pnpm test

许可证

MIT