目标效果:
钉钉群里发: create php file User.php
↓
服务器收到消息 ↓
调用 AI 生成代码 ↓
写入文件 + git commit
↓
钉钉返回执行结果
|
下面给你一个 Node.js 可直接跑的版本。
一、在钉钉创建机器人
1️⃣ 打开钉钉群
2️⃣ 群设置 → 机器人 → 添加机器人
3️⃣ 选择 自定义机器人
你会得到:
保存这两个。
二、Mac mini 上创建项目
mkdir ding-ai-bot cd ding-ai-bot npm init -y npm install express axios crypto body-parser simple-git
|
三、完整服务器代码(server.js)
这个版本包含:
- 接收钉钉消息
- 校验签名
- 调用 AI(示例用 Claude API)
- 写文件
- git commit
- 回复钉钉
const express = require('express') const crypto = require('crypto') const axios = require('axios') const bodyParser = require('body-parser') const fs = require('fs') const simpleGit = require('simple-git')
const app = express() app.use(bodyParser.json())
const PORT = 3000
const DING_SECRET = '你的加签secret' const DING_WEBHOOK = '你的Webhook地址'
const CLAUDE_API_KEY = process.env.ANTHROPIC_API_KEY
const git = simpleGit()
function verifySign(timestamp, sign) { const stringToSign = `${timestamp}\n${DING_SECRET}` const hmac = crypto.createHmac('sha256', DING_SECRET) hmac.update(stringToSign) const calcSign = hmac.digest('base64') return calcSign === sign }
async function callClaude(prompt) { const res = await axios.post( 'https://api.anthropic.com/v1/messages', { model: "claude-3-sonnet-20240229", max_tokens: 800, messages: [ { role: "user", content: prompt } ] }, { headers: { 'x-api-key': CLAUDE_API_KEY, 'anthropic-version': '2023-06-01', 'Content-Type': 'application/json' } } )
return res.data.content[0].text }
async function replyDingTalk(text) { await axios.post(DING_WEBHOOK, { msgtype: "text", text: { content: text } }) }
app.post('/ding', async (req, res) => {
const { timestamp, sign } = req.query
if (!verifySign(timestamp, sign)) { return res.status(403).send('sign error') }
const msg = req.body.text?.content
if (!msg) { return res.send('ok') }
try {
if (msg.startsWith('create php file')) {
const fileName = msg.split(' ')[3]
const prompt = `生成一个 ${fileName} PHP 类,包含基础CRUD结构`
const code = await callClaude(prompt)
fs.writeFileSync(`./workspace/${fileName}`, code)
await git.add(`./workspace/${fileName}`) await git.commit(`feat: add ${fileName}`)
await replyDingTalk(`✅ 已生成 ${fileName} 并提交 Git`) }
else { await replyDingTalk('未知命令') }
res.send('ok')
} catch (err) { console.error(err) await replyDingTalk('❌ 执行失败') res.send('error') } })
app.listen(PORT, () => { console.log(`Server running at http://localhost:${PORT}`) })
|
四、创建 workspace 目录
并初始化 git:
五、启动服务
export ANTHROPIC_API_KEY=你的key node server.js
|
建议用 pm2:
npm install -g pm2 pm2 start server.js --name ding-ai pm2 save
|
六、让钉钉访问到你的 Mac mini
如果在内网,需要:
钉钉 webhook 地址要能公网访问:
七、测试流程
在钉钉群发:
如果成功:
- workspace/User.php 被创建
- git commit 自动完成
- 群里收到成功消息
八、安全优化(必须做)
1️⃣ 限制只处理 @机器人 消息
2️⃣ 限制用户ID
3️⃣ 限制可操作目录
4️⃣ 禁止执行任意 shell
5️⃣ 限制 token 消耗
否则可能被恶意触发大量 API 费用。
九、如何接入 OpenClaw
如果你想用 OpenClaw 做执行层:
把:
替换成:
即可。
架构变为:
钉钉 → 你的服务器 → OpenClaw → Claude → 执行 → 返回
|
十、成本控制建议
推荐模型:
- claude-3-haiku(省钱)
- claude-3-sonnet(平衡)
不要默认用 Opus。
最终效果
你现在拥有:
一个国内可用的远程 AI 程序员
通过钉钉控制:
全部远程完成。