guanghulab/dingtalk-api.js
2026-05-10 13:12:44 +08:00

199 lines
5.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* dingtalk-api.js
* 钉钉Bot消息发送 + 多维表格读写
* 秋秋说:这个文件就像邮递员,负责送消息和更新表格
*/
const axios = require('axios');
const config = require('./config.json');
/**
* 发送钉钉消息
* @param {String} message - 要发送的广播内容
* @param {String} webhook - 钉钉机器人webhook地址可选默认用config里的
* @returns {Promise<Object>} 发送结果
*/
async function sendDingTalkMessage(message, webhook = null) {
try {
const targetWebhook = webhook || config.dingtalk.webhook;
// 如果配置的是占位符,则模拟发送成功(用于测试)
if (targetWebhook.includes('YOUR_BOT_TOKEN')) {
console.log('【测试模式】钉钉消息发送模拟:', message);
return {
success: true,
simulated: true,
message: '测试模式,未实际发送'
};
}
const response = await axios.post(targetWebhook, {
msgtype: 'text',
text: {
content: message
}
});
return {
success: true,
data: response.data
};
} catch (error) {
console.error('钉钉消息发送失败:', error.message);
return {
success: false,
error: error.message
};
}
}
/**
* 更新多维表格(任务状态)
* @param {Object} parsedLog - 解析后的SYSLOG
* @param {String} newBroadcast - 生成的新广播
* @returns {Promise<Object>} 更新结果
*/
async function updateBitable(parsedLog, newBroadcast) {
try {
const { appId, tableId } = config.bitable;
// 如果配置的是占位符,则模拟更新成功(用于测试)
if (appId.includes('YOUR_BITABLE_APP_ID')) {
console.log('【测试模式】多维表格更新模拟:', { parsedLog, newBroadcast });
return {
success: true,
simulated: true,
message: '测试模式,未实际更新表格',
oldTask: {
status: '已完成',
bcNumber: parsedLog.bcNumber
},
newTask: {
status: '待执行',
broadcast: newBroadcast
}
};
}
// 这里需要根据钉钉多维表格API实际文档实现
// 以下是示例结构妈妈后面有真实appId时秋秋再给完整代码
// 1. 获取access_token需要appKey和appSecret
const token = await getDingTalkToken();
// 2. 查询旧任务
const oldTask = await findTaskByBCNumber(token, appId, tableId, parsedLog.bcNumber);
// 3. 更新旧任务状态为「已完成」
if (oldTask && oldTask.recordId) {
await updateTaskStatus(token, appId, tableId, oldTask.recordId, '已完成');
}
// 4. 添加新任务(待执行)
const newTaskData = {
bcNumber: extractNextBCNumber(parsedLog.bcNumber, parsedLog.phaseNum),
devId: parsedLog.devId,
phase: parsedLog.phaseNum ? parseInt(parsedLog.phaseNum, 10) + 1 : 1,
status: '待执行',
broadcast: newBroadcast,
createdAt: new Date().toISOString()
};
await addNewTask(token, appId, tableId, newTaskData);
// 5. 更新连胜记录(如果有)
if (parsedLog.status === 'completed') {
await updateStreak(token, appId, tableId, parsedLog.devId);
}
return {
success: true,
oldTaskUpdated: true,
newTaskAdded: true
};
} catch (error) {
console.error('多维表格更新失败:', error.message);
return {
success: false,
error: error.message
};
}
}
/**
* 获取钉钉access_token辅助函数
*/
async function getDingTalkToken() {
const { appKey, appSecret } = config.dingtalk;
if (appKey.includes('YOUR_APP_KEY')) {
return 'test_token';
}
// 实际获取token的逻辑
const response = await axios.post('https://api.dingtalk.com/v1.0/oauth2/accessToken', {
appKey,
appSecret
});
return response.data.accessToken;
}
/**
* 根据BC编号查找任务辅助函数
*/
async function findTaskByBCNumber(token, appId, tableId, bcNumber) {
// 这里需要根据钉钉多维表格API实际实现
// 返回 { recordId: 'xxx', fields: {...} }
return null;
}
/**
* 更新任务状态(辅助函数)
*/
async function updateTaskStatus(token, appId, tableId, recordId, status) {
// 这里需要根据钉钉多维表格API实际实现
return true;
}
/**
* 添加新任务(辅助函数)
*/
async function addNewTask(token, appId, tableId, taskData) {
// 这里需要根据钉钉多维表格API实际实现
return true;
}
/**
* 更新连胜记录(辅助函数)
*/
async function updateStreak(token, appId, tableId, devId) {
// 这里需要根据钉钉多维表格API实际实现
return true;
}
/**
* 提取下一个BC编号
*/
function extractNextBCNumber(currentBC, currentPhase) {
if (!currentBC) return 'BC-M17-001-ZZ';
// 尝试解析当前BC编号生成下一个
// 格式BC-XXX-YYY-ZZYYY是环节号部分
const match = currentBC.match(/BC-([A-Z0-9]+)-([0-9]+)-ZZ/i);
if (match) {
const module = match[1];
const phase = parseInt(match[2], 10);
const nextPhase = currentPhase ? parseInt(currentPhase, 10) + 1 : phase + 1;
return `BC-${module}-${nextPhase.toString().padStart(3, '0')}-ZZ`;
}
return 'BC-M17-001-ZZ';
}
module.exports = {
sendDingTalkMessage,
updateBitable
};