37 lines
1000 B
TypeScript
37 lines
1000 B
TypeScript
|
|
import crypto from 'crypto'
|
||
|
|
|
||
|
|
/**
|
||
|
|
* HMAC-SHA256 签名工具
|
||
|
|
* 与乐读派 Demo 的签名逻辑对齐
|
||
|
|
*/
|
||
|
|
|
||
|
|
/** 计算 HMAC-SHA256 并返回 hex 字符串 */
|
||
|
|
export function hmacSha256(data: string, secret: string): string {
|
||
|
|
return crypto.createHmac('sha256', secret).update(data).digest('hex')
|
||
|
|
}
|
||
|
|
|
||
|
|
/** 构造 Webhook 请求头(含签名) */
|
||
|
|
export function buildWebhookHeaders(
|
||
|
|
webhookId: string,
|
||
|
|
body: string,
|
||
|
|
appSecret: string,
|
||
|
|
eventType = 'work.status_changed',
|
||
|
|
) {
|
||
|
|
const timestamp = Date.now().toString()
|
||
|
|
const signData = `${webhookId}.${timestamp}.${body}`
|
||
|
|
const signature = `HMAC-SHA256=${hmacSha256(signData, appSecret)}`
|
||
|
|
|
||
|
|
return {
|
||
|
|
'X-Webhook-Id': webhookId,
|
||
|
|
'X-Webhook-Event': eventType,
|
||
|
|
'X-Webhook-Timestamp': timestamp,
|
||
|
|
'X-Webhook-Signature': signature,
|
||
|
|
'Content-Type': 'application/json',
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/** 生成随机事件 ID */
|
||
|
|
export function randomEventId(): string {
|
||
|
|
return `evt_test_${Date.now()}_${Math.random().toString(36).slice(2, 10)}`
|
||
|
|
}
|