钉钉自定义机器人的一种用法

文章的主要内容是介绍怎么利用钉钉的自定义机器人来自动通知技术部的今日分享。目的是想给大家提供一种『利用钉钉的「自定义机器人」实现「定时」通知「固定格式消息」的实现思路』。

需求来源

背景

  • 公司使用钉钉作为聊天软件
  • 钉钉存在对外开放的接口,例如『自定义机器人』
  • 技术部一直有分享的氛围

起因

有分享者自然也要有听众,这样分享者才有动力。那么分享者采用什么方式通知到听众今天要分享的内容呢?目前我们都是提前把分享内容告知给郭大侠,然后由郭大侠统一在分享开始之前,『手动』在技术部的钉钉群里通知即将要分享的相关内容。但这样做存在两个问题:

  • 当你提前告知郭大侠分享内容之后,必须再一次通知郭大侠才能修改之前定的分享日期,不能实现自主修改
  • 郭大侠有时候会忘记在群里发通知

由于通过『郭大侠手动通知分享内容』的现行方式存在以上两个问题,于是就有了想写一个程序来实现自动通知分享内容的想法。Let’s do it.

实现思路

  • 先写一个 python 脚本。将公司内部专门用来记录分享内容的 wiki 页面 爬下来,然后进行解析,得到分享内容。然后利用钉钉提供的 自定义机器人 将分享内容通知到技术部聊天群
  • 再写一个定时任务。用来每天定时跑上面写好的 python 脚本

先写一个 python 脚本

工欲善其事,必先利其器。

下面介绍几个能节省几周工作时间的 python 类库。

BeautifulSoup

Beautiful Soup 是一个可以从 HTML 或 XML 文件中提取数据的 Python 库。它能够通过你喜欢的转换器实现惯用的文档导航、查找、修改文档的方式。Beautiful Soup 会帮你节省数小时甚至数天的工作时间。

Requests

Requests is the only Non-GMO HTTP library for Python, safe for human consumption.

代码
注意,代码采用 python3 实现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#!/usr/bin/env python3

import re #正则包
import requests #封装了 http 请求的包
from bs4 import BeautifulSoup #html 解析包
from datetime import datetime #时间包

#1. 将 wiki 上记录分享的网页下载下来,并进行解析
#注意点 1: 这里需要换成你自己想要解析的相应网页的 url(更换的网页地址之后记得重新定义网页的解析规则,即第 2、3、4 步的代码)
doc_url='你要解析的网页 url'
html_doc = requests.get(doc_url)
soup = BeautifulSoup(html_doc.content, 'html.parser')

#2. 利用正则找出所有的分享日期,并判断今日有无分享
date_list=soup.find_all(string=re.compile("分享日期"))
today = datetime.now().strftime("%Y-%m-%d")
#这里需要初始化一个不存在的分享日期,例如 1995-02-14
#todo 这里有一个 bug,就是如果同一天有多个分享,只会查出排在前面的那条记录。2018-03-11 21:16
next_share_date='1995-02-14'
for ele in date_list:
ele=ele[5:]
if ele==today:
next_share_date=ele
break

#3. 利用 BeautifulSoup 找出所有的分享内容
share_record=soup.find_all(string=re.compile("分享日期\s.*|分享时长\s.*|分享地点\s.*|分享简介\s.*|分享范围\s.*|分享人\s.*|《.*》"))

#4. 因为分享记录的格式固定,所以从分享日期开始往后的 7 个元素就包括了一次分享的所有记录
next_share_content=[]
for index in range(len(share_record)):
if next_share_date in share_record[index]:
for i in range(7):
next_share_content.append(share_record[index])
index+=1
else:
continue

#5. if 今日无分享,do nothing;else 通过钉钉的自定义机器人推送消息
if next_share_content == []:
print('next_share_content is null')
else:
print('next_share_content ',next_share_content)
date=''
time=''
place=''
title=''
summary=''
scope=''
author=''
href=''
for index in range(len(next_share_content)):
if '分享日期' in next_share_content[index]:
date=next_share_content[index]
if '分享时长' in next_share_content[index]:
time=next_share_content[index]
if '分享地点' in next_share_content[index]:
place=next_share_content[index]
if '《' in next_share_content[index]:
title=next_share_content[index]
#将 '分享主题' 四个字替换成 '' 空串,这样就能去除重复的 '分享主题'四个字。
p = re.compile('分享主题')
title=p.sub('',title)
#取出分享主题的链接
href_list=soup.find_all('a')
for i in range(len(href_list)):
if title in href_list[i]:
href=href_list[i].get('href')
break
if '分享简介' in next_share_content[index]:
summary=next_share_content[index]
if '分享范围' in next_share_content[index]:
scope=next_share_content[index]
if '分享人' in next_share_content[index]:
author=next_share_content[index]
#如果分享主题没有链接,则正常发主题;否则,把链接也加上。
if href=='':
str_list=['{"msgtype":"markdown","markdown":{"title":"今日分享","text":"### **分享主题** **',title,'** \n','###### **',summary[2:],'** \n','##### **',date[2:],'** \n','##### **',time[2:],'** \n','##### **',place[2:],'** \n','##### **',scope[2:],'** \n','##### ',author,' "','}',',"at":{"atMobiles":[],"isAtAll":true}','}']
else:
str_list=['{"msgtype":"markdown","markdown":{"title":"今日分享","text":"### **分享主题** [',title,'](',href,')', '\n','###### **',summary[2:],'** \n','##### **',date[2:],'** \n','##### **',time[2:],'** \n','##### **',place[2:],'** \n','##### **',scope[2:],'** \n','##### ',author,' "','}',',"at":{"atMobiles":[],"isAtAll":true}','}']
message=''.join(str_list)
print('message', message)
#注意点 2:dingding_url 需要替换成你自己钉钉机器人的 webhook 地址
dingding_url='webhook 地址'
headers={"Content-Type": "application/json"}
r = requests.post(dingding_url, data=message.encode('utf-8'), headers=headers)

复用上面这段代码需要注意两点:

  • doc_url 需要替换成自己要解析的网页地址

  • dingding_url 需要替换成自己的钉钉机器人的 webhook 地址

再写一个定时任务

linux 机器有一个 crontab 命令,这个是 linux 系统提供的实现自定义系统计划的命令。

编辑系统计划

crontab -e

查看系统计划

crontab -l

自定义一个系统计划

crontab 格式说明

crontab 命令示例
40 8 * * * /home/hufei/parse-all.py >> /home/hufei/out-all.file 2>&1

  • 40 8 * * * 每天的 8 点 40 分
  • > 表示覆盖
  • >> 表示追加
  • 1 表示 stdout 标准输出,系统默认值是 1
  • 2 表示 stderr 标准错误
  • & 表示等同于的意思
  • 2>&1 表示 2 的输出重定向等同于 1

实现效果

分享内容的格式

钉钉通知消息的格式

引用