求一个监听gitee的webhooks,bot向用户推送信息(pr信息,评论信息,push信息)的插件

飞书上有自定义的机器人可以实现这个操作,但是我想bot把信息发在qq群里,所以想用koishi来做,但是目前插件只有github的。

本来想自己写的,用ai已经弄出个大概了,但是自己发现自己用的是云服务器上的docker :skull:,没法写插件,只能各位大佬来写和发布了 :pray:

这是ai生成的,有大佬想写插件的话可以看看

import { Context } from ‘koishi’

export const name = ‘gitee-webhook’

export interface Config {
giteeSecret: string
}

export function apply(ctx: Context, config: Config) {
// 验证 Gitee webhook 签名
function verifyGiteeSignature(secret: string, timestamp: string, signature: string, payload: any) {
if (!secret) return true // 如果没有配置密钥,则跳过验证

const payloadStr = typeof payload === 'string' ? payload : JSON.stringify(payload)
const signStr = `${timestamp}\n${secret}`
const crypto = require('crypto')
const hmac = crypto.createHmac('sha256', signStr)
hmac.update(payloadStr)
const expectedSignature = hmac.digest('hex')

return signature === expectedSignature

}

// 格式化推送消息
function formatPushMessage(data: any) {
const repository = data.repository
const pusher = data.pusher
const commits = data.commits ||

let message = `📦 仓库 ${repository.name} 有新的推送\n`
message += `👤 推送者: ${pusher.name}\n`
message += `📌 分支: ${data.ref.replace('refs/heads/', '')}\n`

if (commits.length > 0) {
  message += `\n📝 提交信息:\n`
  // 最多显示最近3条提交
  const displayCommits = commits.slice(0, 3)
  displayCommits.forEach((commit: any) => {
    message += `  ${commit.id.substring(0, 7)} - ${commit.message.trim()}\n`
  })

  if (commits.length > 3) {
    message += `  ... 还有 ${commits.length - 3} 条提交\n`
  }
}

message += `\n🔗 ${data.compare}`

return message

}

// 格式化其他事件消息
function formatOtherMessage(data: any, eventName: string) {
const repository = data.repository
let message = 🔔 仓库 ${repository.name} 有新的事件\n
message += 🏷️ 事件类型: ${eventName}\n

if (data.sender) {
  message += `👤 操作者: ${data.sender.name || data.sender.login}\n`
}

// 根据不同事件类型添加额外信息
switch (eventName) {
  case 'Merge Request Hook':
    if (data.pull_request) {
      message += `📋 合并请求: #${data.pull_request.id} ${data.pull_request.title}\n`
      message += `📄 源分支: ${data.pull_request.head_ref}\n`
      message += `📁 目标分支: ${data.pull_request.base_ref}\n`
    }
    break

  case 'Issue Hook':
    if (data.issue) {
      message += `📝 问题: #${data.issue.id} ${data.issue.title}\n`
      message += `📊 状态: ${data.issue.state}\n`
    }
    break

  default:
    message += `📄 事件详情请查看Gitee\n`
}

if (repository.html_url) {
  message += `\n🔗 ${repository.html_url}`
}

return message

}

// 注册中间件处理 webhook 请求
ctx.router(‘POST’, ‘/webhook’, async (koa) => {
const eventName = koa.request.headers[‘x-gitee-event’]
const signature = koa.request.headers[‘x-gitee-signature’]
const timestamp = koa.request.headers[‘x-gitee-timestamp’]
const token = koa.request.headers[‘x-gitee-token’]

ctx.logger.info(`收到 Gitee webhook 事件: ${eventName}`)

const data = koa.request.body
const repository = data?.repository

// 验证签名(如果配置了密钥)
if (config.giteeSecret) {
  if (!verifyGiteeSignature(config.giteeSecret, timestamp, signature, data)) {
    ctx.logger.warn('Gitee webhook 签名验证失败')
    koa.status = 401
    koa.body = 'Unauthorized'
    return
  }
}

let message = ''

// 根据事件类型格式化消息
switch (eventName) {
  case 'Push Hook':
    message = formatPushMessage(data)
    break
  case 'Merge Request Hook':
  case 'Issue Hook':
    message = formatOtherMessage(data, eventName)
    break
  default:
    message = `🔔 收到未支持的 Gitee 事件: ${eventName}`
}

// 发送到所有群组
// 获取所有群组
const groups = await ctx.bots[Object.keys(ctx.bots)[0]].getGroupList?.()
if (groups) {
  // 向所有群组发送消息
  for (const group of groups) {
    await ctx.bots[Object.keys(ctx.bots)[0]].sendGroupMessage(group.id, message)
  }
}

koa.status = 200
koa.body = 'OK'

})

ctx.logger.info(‘Gitee webhook 插件加载成功’)
}

1 个赞