使用shell脚本连接钉钉机器人发送消息
一、前言
服务器上有时 定时任务、重要接口 等出现异常,导致数据不正常,不能及时通知到服务负责人,及时处理问题。所以引入“钉钉”作为通知工具,当服务出现异常便可立即收到通知,及时处理!
二、使用方式
1、客户端配置机器人
1.1首先需要有阿里巴巴的“钉钉”客户端
1.2、建立群聊(如果只想通知给自己,不想通知其他人,也可以与他们创建群聊之后再将他们踢出)
1.3、点击“群设置”里面的“智能群助手”
1.4、“添加机器人”
1.5、自定义
1.6、给机器人取个名字,注意:后续的消息体中必须要包含设置的“自定义关键词”,消息才能发送成功。
1.7、点击“完成”后会得到一个webhook,把这个webhook复制出来,一会儿代码中要用,
类似这样的:https://oapi.dingtalk.com/robot/send?access_token=880e6b7********************************************97d5e
1.8、点击“完成”之后会收到这样一条消息,说明机器人配置完成了,接下来就是代码了
2.消息类型及数据格式
2.1 文本类型(text)
参数 | 必选 | 类型 | 说明 |
---|---|---|---|
msgtype | true | string | 此消息类型为固定text |
content | true | string | 内容消息 |
atMobiles | false | string | 被@人手机号 |
isAtall | false | bool | @所有人时为ture,否则为false |
{ "msgtype": "text", "text": { "content": "我是陈十六,请多指教@156****16**" }, "at": { "atMobiles": [ "1825718XXXX" ], "isAtAll": false } }
2.2 link类型
参数 | 必选 | 类型 | 说明 |
---|---|---|---|
msgtype | true | string | 此消息类型为固定link |
title | true | string | 消息标题 |
text | true | string | 内容消息,如果太长只会显示一部分 |
messageUrl | true | string | 点击消息跳转的url |
picUrl | false | string | 图片url |
{ "msgtype": "link", "link": { "text":"link是以连接的形式发送消息。", "title": "连接的主题", "picUrl": "", "messageUrl": "复制的机器人的Webhoot" } }
2.3、markdown类型
{ "msgtype": "markdown", "markdown": {"title":"杭州天气", "text":"#### 杭州天气 \n > 9度,@1825718XXXX 西北风1级,空气良89,相对温度73%\n\n > ![screenshot](http://i01.lw.aliimg.com/media/lALPBbCc1ZhJGIvNAkzNBLA_1200_588.png)\n > ###### 10点20分发布 [天气](http://www.thinkpage.cn/) " }, "at": { "atMobiles": [ "1825718XXXX" ], "isAtAll": false } }
3、通过代码使用机器人发送钉钉消息
a、通过java代码实现
package com.common.util; import com.alibaba.fastjson.JSON; import lombok.extern.slf4j.Slf4j; import org.springframework.util.CollectionUtils; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; /** * 钉钉-工具类 */ @Slf4j public class DingTalkUtil { /** * 钉钉机器人发消息地址(配置机器人的webhook) * 此处大家可以配置到配置文件等等方式 */ private static final String MSG_URL = "https://oapi.dingtalk.com/robot/send?access_token=880e6b7********************************************97d5e"; /** * 通知具体人 * * @param content 通知内容 * @param mobileList 通知具体人的手机号码列表 */ public static void sendDingTalkMsg(List<String> mobileList, String content) { sendDingTalkMsg(false, mobileList, content); } /** * 通知所有人 * * @param content 通知内容 */ public static void sendDingTalkMsg(String content) { sendDingTalkMsg(true, null, content); } /** * 发送消息 * * @param content 通知内容 * @param isAtAll 是否@所有人 * @param mobileList 通知具体人的手机号码列表 */ private static void sendDingTalkMsg(boolean isAtAll, List<String> mobileList, String content) { try { if (!CollectionUtils.isEmpty(mobileList)) { isAtAll = false; } //消息内容 Map<String, String> contentMap = new HashMap<>(); contentMap.put("content", content); //通知人 Map<String, Object> atMap = new HashMap<>(); //1.是否通知所有人 atMap.put("isAtAll", isAtAll); //2.通知具体人的手机号码列表 atMap.put("atMobiles", mobileList); Map<String, Object> parameter = new HashMap<>(); parameter.put("msgtype", "text"); parameter.put("at", atMap); parameter.put("text", contentMap); //推送消息(http请求) String result = HttpUtils.post(MSG_URL, JSON.toJSONString(parameter)); log.info("发送钉钉消息-result:{}", result); } catch (Exception e) { log.error("发送钉钉消息异常", e); } } public static void main(String[] args) { // sendDingTalkMsg("服务通知:测试消息"); sendDingTalkMsg(Collections.singletonList("189********"), "服务通知:测试消息"); } }
另附代码中使用到的HttpUtils
package com.common.util; import com.alibaba.fastjson.JSON; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.apache.http.HttpStatus; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.message.BasicHeader; import org.apache.http.util.EntityUtils; import java.io.Closeable; import java.nio.charset.Charset; import java.util.Map; /** * http请求-工具类 * * @author xiehongwei * @date 2020/11/03 */ @Slf4j public class HttpUtils { private static final String UTF_8 = "utf-8"; private static RequestConfig requestConfig; static { requestConfig = RequestConfig.custom() .setConnectTimeout(1000)//连接超时时间 .setSocketTimeout(3000)//读超时时间 .build(); } /** * post请求(无参/参数在url上) */ public static String post(String url) throws Exception { return post(url, ""); } /** * post请求 */ public static String post(String url, String body) throws Exception { CloseableHttpClient httpClient = null; CloseableHttpResponse httpResponse = null; try { httpClient = HttpClients.createDefault(); HttpPost httpPost = new HttpPost(url); if (StringUtils.isNotBlank(body)) { StringEntity se = new StringEntity(body, Charset.forName(UTF_8)); se.setContentType("text/json"); se.setContentEncoding(new BasicHeader("Content-Type", "application/json")); httpPost.setEntity(se); } httpPost.setConfig(requestConfig); httpPost.setHeader("Content-Type", "application/json;charset=utf-8"); httpResponse = httpClient.execute(httpPost); if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { return EntityUtils.toString(httpResponse.getEntity(), UTF_8); } else { log.error("post请求其它服务失败,statusCode:{}", httpResponse.getStatusLine().getStatusCode()); } } catch (Exception e) { log.error("post请求其它服务异常", e); throw e; } finally { close(httpClient); close(httpResponse); } return null; } /** * post请求 */ public static String post(String url, Map<String, String> parameter) throws Exception { return post(url, JSON.toJSONString(parameter)); } /** * 关闭流 */ private static <T extends Closeable> void close(T io) { if (io == null) { return; } try { io.close(); } catch (Exception e) { log.error(e.getMessage(), e); } } }
shell脚本实现
#!/bin/bash webhook='https://oapi.dingtalk.com/robot/send?access_token=34XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' cluster='QQOrder_ERP' host=`hostname -I | awk '{print $1}'` vip=$1 function SendMsgToDingding() { curl $webhook -H 'Content-Type: application/json' -d " { 'msgtype': 'text', 'text': { 'content': '集群名称:$cluster\n告警信息:虚拟IP<$vip>已漂移至节点<$host>,请注意\n' }, 'at': { 'isAtAll': true } }" } SendMsgToDingding