最近团队同学提到一个痛点:每次发完新的 npm 包后,大家都没办法第一时间知道更新,往往需要手动在群里吼一声,不仅繁琐还容易遗漏。于是就有了个想法,npm自动发包后,通过钉钉机器人自动群发通知。
这套方案不仅能提高团队协同效率,还能让每一次版本迭代都有迹可循。接下来,我将一步步带你实现这个自动化流程。
利用 npm 的 postpublish 钩子
首先我们写包要执行脚本都会在script中写自动化脚本,那么通过在 package.json 中配置 postpublish 钩子,我们可以确保只有在 npm publish 成功执行并完成包上传后 ,才会触发通知脚本。
js
"scripts": {
"build": "rollup -c",
"prepublishOnly": "yarn build",
"test": "jest",
"dev": "rollup -w -c",
"postpublish": "node scripts/notify.js"
}
在 npm 的生命周期钩子中,只要执行了 publish 命令(无论是否带有 --access public 参数),系统都会在包成功上传到 npm 仓库后,自动顺序执行名为 postpublish 的脚本。
配置钉钉群机器人(加签安全模式)
-
进入群设置在里面可以看到机器人,点击进入

-
进去之后添加机器人,点击后可以看到机器人类型弹窗,我们添加自定义机器人

-
添加机器人 并且安全设置选择 加签,复制号密钥留着备用
钉钉加签验证规则:将时间戳 timestamp 和密钥 secret 当做签名字符串,使用HmacSHA256算法计算签名,然后进行Base64 encode,最后再把签名参数再进行urlEncode,得到最终的签名(需要使用UTF-8字符集)。 -
获取 Webhook: 完成添加后,你会得到一个 Webhook 地址,里面包含了一个
access_token,同样复制备用。
编写通知脚本(scripts/notify.js)
在项目根目录下创建 scripts/notify.js 文件。我们将在这里完成加签计算、数据拼装以及发送 HTTP 请求。(注意:在实际生产环境中,出于安全考虑,强烈建议将 Secret 和 Token 存放在环境变量中,而不是直接硬编码在脚本里。)
js
const https = require('https');
const crypto = require('crypto');
const pkg = require('../package.json');
// ==========================================
// 1. 基础配置
// ==========================================
// ⚠️ 建议:实际项目中请将密钥放入系统环境变量 process.env 中
const secret = '你的SEC开头的密钥';
const accessToken = '你的TOKEN';
const timestamp = Date.now();
// 模拟获取更新日志(你可以编写逻辑从 CHANGELOG.md 或 git commit 中提取)
const changes = '常规问题修复与性能优化';
// ==========================================
// 2. 严谨构造签名
// ==========================================
// [钉钉官方要求:把timestamp + "\n" + secret 当做签名字符串]
const stringToSign = timestamp + "\n" + secret;
const sign = crypto.createHmac('sha256', secret)
.update(stringToSign)
.digest('base64');
const encodedSign = encodeURIComponent(sign);
// ==========================================
// 3. 构造带签名和时间戳的 URL
// ==========================================
const url = `https://oapi.dingtalk.com/robot/send?access_token=${accessToken}×tamp=${timestamp}&sign=${encodedSign}`;
// ==========================================
// 4. 构造消息体 (Markdown 格式)
// ==========================================
const data = JSON.stringify({
msgtype: 'markdown',
markdown: {
title: 'NPM 包发布通知',
text: `### 📦 新版本发布通知\n\n` +
`**包名:** \`${pkg.name}\`\n\n` +
`**版本:** \`v${pkg.version}\`\n\n` +
`**更新:** ${changes || '暂无更新描述'}\n\n` +
`**时间:** ${new Date().toLocaleString()}\n\n` +
`> [👉 查看 NPM 详情](https://www.npmjs.com/package/${pkg.name})`
},
at: {
isAtAll: false // 是否 @ 所有人
}
});
// ==========================================
// 5. 发送请求
// ==========================================
const req = https.request(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
}
}, (res) => {
let responseData = '';
res.on('data', (chunk) => responseData += chunk);
res.on('end', () => {
try {
const result = JSON.parse(responseData);
if (result.errcode === 0) {
console.log('✅ 钉钉消息同步成功!团队成员已收到发包通知。');
} else {
console.error('❌ 钉钉返回错误:', result.errmsg);
}
} catch (err) {
console.error('❌ 解析钉钉响应失败:', err.message);
}
});
});
req.on('error', (e) => console.error('❌ 请求失败:', e));
req.write(data);
req.end();
总结
到这里我们的自动化改造就完成了!现在,只要运行 npm publish,打包上传成功后,钉钉群内就会自动弹出版式精美的 Markdown 更新通知。这不仅省去了人工通知的麻烦,也为团队沉淀了一份可视化的版本更新时间线。赶快在你们的团队项目中用起来吧!