用Apps Script+Slack incoming webhook实现表格入职前一周自动发消息
Slack的formatted_date仅用于消息内的本地化日期渲染,本身不提供定时触发能力,要实现提前一周固定时间推送新员工信息,你需要按以下步骤搭建完整逻辑:
实现步骤
1. 统一时间计算基准
所有时间计算统一以KST(韩国标准时间,UTC+9)为基准,避免跨时区、夏令时导致的时间错误:
- 先把表格第3列的入职首日日期,全部解析为KST时区的日期对象,统一忽略时分秒精度
- 推送触发规则固定为:入职日期往前推算7天,当天KST上午10点推送对应人员信息,这个逻辑天然匹配你提到的「周一入职提前一周周一推送」的要求,不需要额外计算周序。
2. 配置定时筛选逻辑
选适配你表格存储方式的定时方案,固定在每天KST上午10点运行筛选脚本:
- 如果表格存储在Google Sheets:直接用内置Apps Script配置时间驱动触发器即可,不需要额外部署服务
- 如果是本地表格/其他平台存储的表格:用Linux crontab、Windows任务计划或者云函数定时触发器都可以
筛选逻辑核心是遍历所有新员工条目,匹配「入职日减7天等于当前KST日期」的条目,JavaScript参考实现如下:
// 时区处理建议用dayjs简化计算,原生JS手动算UTC+9偏移也可实现 const dayjs = require('dayjs'); const utc = require('dayjs/plugin/utc'); const timezone = require('dayjs/plugin/timezone'); dayjs.extend(utc); dayjs.extend(timezone); const KST_TIMEZONE = 'Asia/Seoul'; const PUSH_HOUR = 10; const ADVANCE_DAYS = 7; /** * 从表格数据中筛选出本次需要推送的新员工 * @param {Array} tableData 表格读取到的二维数组 */ function getNeedPushEmployees(tableData) { const nowKst = dayjs().tz(KST_TIMEZONE); // 非上午10点直接返回空,避免非推送时段误触发 if (nowKst.hour() !== PUSH_HOUR) return []; const todayKst = nowKst.startOf('day'); return tableData.filter(row => { // 第3列索引为2,解析为KST时区的入职日期 const onboardDate = dayjs(row[2]).tz(KST_TIMEZONE).startOf('day'); return onboardDate.subtract(ADVANCE_DAYS, 'day').isSame(todayKst, 'day'); }); }
3. 组装Slack消息推送
筛选到待推送的新员工后,组装符合Incoming Webhook要求的请求体即可。如果需要在消息里展示适配用户本地时区的入职时间,可以用Slack的formatted_date语法渲染:
<!date^秒级时间戳^显示格式^兜底显示文本>
比如要显示「8月12日 周一」格式,对应写法为<!date^1723388400^{date_short} {weekday}|8月12日 周一>,其中时间戳为入职日期KST 0点对应的Unix秒级时间戳,竖线后为客户端无法解析日期时的兜底文本。
Webhook推送参考代码:
/** * 推送新员工信息到Slack * @param {Array} employees 待推送的新员工列表 * @param {string} webhookUrl Slack Incoming Webhook地址 */ async function pushMessageToSlack(employees, webhookUrl) { if (employees.length === 0) return; let content = `*下周新员工入职提醒(共${employees.length}人)*\n`; employees.forEach((emp, index) => { // 假设第1列是姓名,第2列是所属部门,第3列是入职日期 const empName = emp[0]; const empDept = emp[1]; const onboardUnix = dayjs(emp[2]).tz(KST_TIMEZONE).unix(); const onboardText = `<!date^${onboardUnix}^{date_short} {weekday}|入职日期解析失败>`; content += `${index + 1}. ${empName} - ${empDept},入职时间:${onboardText}\n`; }); await fetch(webhookUrl, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ text: content }) }); }
注意事项
- 定时任务建议配置5分钟左右的容错窗口,同时加推送去重逻辑,避免服务延迟导致漏推、重复推送
- 所有日期计算不要用服务器本地时区,必须强制指定KST时区,避免跨时区部署时出现时间计算错误
- 如果用Google Sheets方案,直接把上述逻辑贴到Apps Script编辑器,设置每日上午10点(KST)的时间驱动触发器即可,不需要额外服务器
内容的提问来源于stack exchange,提问作者Seokjin Kang
相关产品推荐
相关产品推荐

