需要用到的环境

能运行电脑版钉钉的Windows或者Mac用于获取机器人地址
能长期稳定运行node.js环境的电脑或者服务器(需要网络连接),可以是你自己的电脑,服务器,软路由,群晖,你们公司闲置的电脑或者docker一个node
【可选】,如果需要天气预报,需要自行申请百度开发者api密钥,百度天气API开发文档, 以及申请密钥

获取钉钉机器人地址

  • 下载电脑版钉钉,下载地址
  • 新建一个群,加入你想通知的人,如果你想只发送给自己,踢掉其他人即可。
  • 群设置 => 群智能助手 => 添加自定义机器人(webhook) => 安全设置勾选加签
  • 最后复制好webhook地址和加签密钥

服务端部署

  • 在你的服务器(或电脑)上安装好node.js环境,官方下载,Linux和mac请自行查阅安装教程安装,Linux推荐使用docker安装
  • 检查安装,windows下打开Node.js command prompt程序,输入node -v,出现版本号即为正常,检测PATH环境变量是否配置了Node.js,点击开始=>运行=>输入cmd => 输入命令path,显示中有node.js即为正常。Linux同理。
  • 在你喜欢的位置新建一个项目文件夹,命名随意,打开文件夹,新建一个index.js
  • 安装依赖
    安装yarn
    npm i -g yarn
    安装定时模块
    yarn add node-schedule
    安装加密
    yarn add crypto
    安装node-fetch // 用于获取天气预报
    yarn add node-fetch
    编辑package.json,增加"type": "module",(放在json第一级)

加入功能

import schedule from 'node-schedule'
import fetch from 'node-fetch'
import crypto from 'crypto';

// 第一个参数为[秒 分 时 ]
// * * * * * *
// ┬ ┬ ┬ ┬ ┬ ┬
// │ │ │ │ │ │
// │ │ │ │ │ └ day of week (0 - 7) (0 or 7 is Sun)
// │ │ │ │ └───── month (1 - 12)
// │ │ │ └────────── day of month (1 - 31)
// │ │ └─────────────── hour (0 - 23)
// │ └──────────────────── minute (0 - 59)
// └───────────────────────── second (0 - 59, OPTIONAL)
// 6个占位符从左到右分别代表:秒、分、时、日、月、周几
// '*'表示通配符,匹配任意,当秒是'*'时,表示任意秒数都触发,其它类推
// 下面可以看看以下传入参数分别代表的意思
// 每分钟的第30秒触发: '30 * * * * *'
// 每小时的1分30秒触发 :'30 1 * * * *'
// 每天的凌晨1点1分30秒触发 :'30 1 1 * * *'
// 每月的1日1点1分30秒触发 :'30 1 1 1 * *'
// 2016年的1月1日1点1分30秒触发 :'30 1 1 1 2016 *'
// 每周1的1点1分30秒触发 :'30 1 1 * * 1'
const job = schedule.scheduleJob('* 00 * * * *', async() => {
  //机器人地址
  let url = `你的钉钉webhook地址`
  //签名验证
  let secret = '加签密钥'
  let time = Date.now(); //当前时间戳
  let stringToSign = time + "\n" + secret; 
  let base = crypto.createHmac('sha256', secret).update(stringToSign).digest('base64'); //encode
  let sign = encodeURIComponent(base) //二次encode
  url = url+`&timestamp=${time}&sign=${sign}`; //拼串得到最终的URL
  let location = '110100' //设置城市编码查询 https://mapopen-website-wiki.cdn.bcebos.com/cityList/weather_district_id.csv,可以自行洗成json等
  // 下面时可选的天气预报服务
  let ak = '你的百度密钥'
  let bdurl = `https://api.map.baidu.com/weather/v1/?district_id=${district}&data_type=all&ak=${ak}  //GET请求`
  // 获取天气
  let res = await fetch(bdurl)
  let data = await res.json()
  // 根据钉钉文档构建json格式的数据, 
  let body = {
    "msgtype": "markdown",
    "markdown": {
        "title": `${data.result.location.city}${data.result.location.name}`,
        "text": `${data.result.now.text}
        现在是${new Date().toLocaleTimeString()}
        起来活动,喝杯水
        `
    },
  }
  let response = await fetch(url, {
    method: 'post',
    body: JSON.stringify(body),
    headers: {'Content-Type': 'application/json'}
  });
  let msg = await response.json();
  console.log(msg);
})
百度天气返回json示例代码
请求类型为all的响应示例(部分字段需开通高级权限,具体请参考文档说明)
{
    "status":0,
    "result":{
        "location":{
            "country":"中国",
            "province":"北京市",
            "city":"北京市",
            "name":"东城",
            "id":"110101"
        },
        "now":{
            "temp":4,
            "feels_like":1,
            "rh":73,
            "wind_class":"2级",
            "wind_dir":"东风",
            "text":"多云",
            "prec_1h":0,
            "clouds":999999,
            "vis":3471,
            "aqi":140,
            "pm25":107,
            "pm10":0,
            "no2":23,
            "so2":22,
            "o3":70,
            "co":1.7,
            "uptime":"20200220143500"
        },
        "indexes":[
            {
                "name":"晨练指数",
                "brief":"较适宜",
                "detail":"天气阴沉,请避免在林中晨练。"
            },
            {
                "name":"洗车指数",
                "brief":"适宜",
                "detail":"天气较好,适合擦洗汽车。"
            },
            {
                "name":"感冒指数",
                "brief":"易发",
                "detail":"天凉,昼夜温差大,易感冒"
            },
            {
                "name":"紫外线指数",
                "brief":"最弱",
                "detail":"辐射弱,涂擦SPF8-12防晒护肤品。"
            },
            {
                "name":"穿衣指数",
                "brief":"较冷",
                "detail":"建议着厚外套加毛衣等服装。"
            },
            {
                "name":"运动指数",
                "brief":"较适宜",
                "detail":"气温较低,在户外运动请注意增减衣物。"
            }
        ],
        "alerts":[
            {
                "type": "道路冰雪",
                "level": "蓝色预警",
                "title": "市气象局发布道路冰雪蓝色预警[IV级/一般]", 
                "desc": "市气象局发布道路冰雪蓝色预警信号:受降雪天气影响,
                        预计未来 24 小时我市将出现对交通有影响的道路结冰或积雪, 
                        请有关部门及广大群众做好防范工作。"
            }

        ],
        "forecasts":[
            {
                "date":"2020-02-20",
                "week":"星期四",
                "high":7,
                "low":-2,
                "wc_day":"<3级",
                "wc_night":"<3级",
                "wd_day":"东南风",
                "wd_night":"北风",
                "text_day":"多云",
                "text_night":"阴",
                "aqi":93
            },
            {
                "date":"2020-02-21",
                "week":"星期五",
                "high":11,
                "low":1,
                "wc_day":"4~5级",
                "wc_night":"<3级",
                "wd_day":"西北风",
                "wd_night":"西北风",
                "text_day":"多云",
                "text_night":"晴",
                "aqi":44
            },
            {
                "date":"2020-02-22",
                "week":"星期六",
                "high":10,
                "low":-2,
                "wc_day":"<3级",
                "wc_night":"<3级",
                "wd_day":"西风",
                "wd_night":"南风",
                "text_day":"晴",
                "text_night":"晴",
                "aqi":39
            },
            {
                "date":"2020-02-23",
                "week":"星期日",
                "high":11,
                "low":0,
                "wc_day":"<3级",
                "wc_night":"<3级",
                "wd_day":"北风",
                "wd_night":"北风",
                "text_day":"晴",
                "text_night":"晴",
                "aqi":65
            },
            {
                "date":"2020-02-24",
                "week":"星期一",
                "high":9,
                "low":-1,
                "wc_day":"<3级",
                "wc_night":"<3级",
                "wd_day":"东风",
                "wd_night":"东北风",
                "text_day":"多云",
                "text_night":"多云",
                "aqi":38
            },
            {
                "date":"2020-02-25",
                "week":"星期二",
                "high":9,
                "low":-3,
                "wc_day":"<3级",
                "wc_night":"<3级",
                "wd_day":"东南风",
                "wd_night":"西南风",
                "text_day":"晴",
                "text_night":"晴",
                "aqi":27
            },
            {
                "date":"2020-02-26",
                "week":"星期三",
                "high":9,
                "low":-3,
                "wc_day":"<3级",
                "wc_night":"<3级",
                "wd_day":"西南风",
                "wd_night":"西南风",
                "text_day":"晴",
                "text_night":"晴",
                "aqi":26
            }
        ],
        "forecast_hours":[
            {
                "text":"晴",
                "temp_fc":14,
                "wind_class":"3~4级",
                "wind_dir":"西南风",
                "rh":15,
                "prec_1h":0,
                "clouds":10,
                "data_time":"2020-04-01 16:00:00"
            },
            {
                "text":"晴",
                "temp_fc":14,
                "wind_class":"3~4级",
                "wind_dir":"西南风",
                "rh":13,
                "prec_1h":0,
                "clouds":10,
                "data_time":"2020-04-01 17:00:00"
            },
            {
                "text":"晴",
                "temp_fc":13,
                "wind_class":"<3级",
                "wind_dir":"西南风",
                "rh":14,
                "prec_1h":0,
                "clouds":10,
                "data_time":"2020-04-01 18:00:00"
            },
            {
                "text":"晴",
                "temp_fc":11,
                "wind_class":"<3级",
                "wind_dir":"西南风",
                "rh":15,
                "prec_1h":0,
                "clouds":10,
                "data_time":"2020-04-01 19:00:00"
            },
            {
                "text":"晴",
                "temp_fc":10,
                "wind_class":"<3级",
                "wind_dir":"西南风",
                "rh":16,
                "prec_1h":0,
                "clouds":10,
                "data_time":"2020-04-01 20:00:00"
            },
            {
                "text":"晴",
                "temp_fc":9,
                "wind_class":"<3级",
                "wind_dir":"西风",
                "rh":18,
                "prec_1h":0,
                "clouds":6,
                "data_time":"2020-04-01 21:00:00"
            },
            {
                "text":"晴",
                "temp_fc":9,
                "wind_class":"<3级",
                "wind_dir":"西风",
                "rh":20,
                "prec_1h":0,
                "clouds":3,
                "data_time":"2020-04-01 22:00:00"
            },
            {
                "text":"晴",
                "temp_fc":8,
                "wind_class":"<3级",
                "wind_dir":"西风",
                "rh":21,
                "prec_1h":0,
                "clouds":0,
                "data_time":"2020-04-01 23:00:00"
            },
            {
                "text":"晴",
                "temp_fc":7,
                "wind_class":"<3级",
                "wind_dir":"西北风",
                "rh":26,
                "prec_1h":0,
                "clouds":0,
                "data_time":"2020-04-02 00:00:00"
            },
            {
                "text":"晴",
                "temp_fc":6,
                "wind_class":"<3级",
                "wind_dir":"西北风",
                "rh":31,
                "prec_1h":0,
                "clouds":0,
                "data_time":"2020-04-02 01:00:00"
            },
            {
                "text":"晴",
                "temp_fc":6,
                "wind_class":"<3级",
                "wind_dir":"西北风",
                "rh":36,
                "prec_1h":0,
                "clouds":0,
                "data_time":"2020-04-02 02:00:00"
            },
            {
                "text":"晴",
                "temp_fc":5,
                "wind_class":"<3级",
                "wind_dir":"西北风",
                "rh":39,
                "prec_1h":0,
                "clouds":0,
                "data_time":"2020-04-02 03:00:00"
            },
            {
                "text":"晴",
                "temp_fc":4,
                "wind_class":"<3级",
                "wind_dir":"西北风",
                "rh":42,
                "prec_1h":0,
                "clouds":0,
                "data_time":"2020-04-02 04:00:00"
            },
            {
                "text":"晴",
                "temp_fc":4,
                "wind_class":"<3级",
                "wind_dir":"西北风",
                "rh":45,
                "prec_1h":0,
                "clouds":0,
                "data_time":"2020-04-02 05:00:00"
            },
            {
                "text":"晴",
                "temp_fc":5,
                "wind_class":"<3级",
                "wind_dir":"西北风",
                "rh":40,
                "prec_1h":0,
                "clouds":0,
                "data_time":"2020-04-02 06:00:00"
            },
            {
                "text":"晴",
                "temp_fc":7,
                "wind_class":"<3级",
                "wind_dir":"西北风",
                "rh":34,
                "prec_1h":0,
                "clouds":0,
                "data_time":"2020-04-02 07:00:00"
            },
            {
                "text":"晴",
                "temp_fc":8,
                "wind_class":"<3级",
                "wind_dir":"西北风",
                "rh":29,
                "prec_1h":0,
                "clouds":0,
                "data_time":"2020-04-02 08:00:00"
            },
            {
                "text":"晴",
                "temp_fc":11,
                "wind_class":"<3级",
                "wind_dir":"西北风",
                "rh":29,
                "prec_1h":0,
                "clouds":0,
                "data_time":"2020-04-02 09:00:00"
            },
            {
                "text":"晴",
                "temp_fc":13,
                "wind_class":"<3级",
                "wind_dir":"西北风",
                "rh":29,
                "prec_1h":0,
                "clouds":0,
                "data_time":"2020-04-02 10:00:00"
            },
            {
                "text":"晴",
                "temp_fc":16,
                "wind_class":"<3级",
                "wind_dir":"西北风",
                "rh":29,
                "prec_1h":0,
                "clouds":0,
                "data_time":"2020-04-02 11:00:00"
            },
            {
                "text":"晴",
                "temp_fc":17,
                "wind_class":"3~4级",
                "wind_dir":"西北风",
                "rh":24,
                "prec_1h":0,
                "clouds":0,
                "data_time":"2020-04-02 12:00:00"
            },
            {
                "text":"晴",
                "temp_fc":18,
                "wind_class":"3~4级",
                "wind_dir":"西北风",
                "rh":19,
                "prec_1h":0,
                "clouds":0,
                "data_time":"2020-04-02 13:00:00"
            },
            {
                "text":"晴",
                "temp_fc":19,
                "wind_class":"3~4级",
                "wind_dir":"西北风",
                "rh":14,
                "prec_1h":0,
                "clouds":0,
                "data_time":"2020-04-02 14:00:00"
            },
            {
                "text":"晴",
                "temp_fc":19,
                "wind_class":"<3级",
                "wind_dir":"西风",
                "rh":17,
                "prec_1h":0,
                "clouds":0,
                "data_time":"2020-04-02 15:00:00"
            }
        ]
    },
    "message":"success"
}