一、前言

服务器上有时 定时任务、重要接口 等出现异常,导致数据不正常,不能及时通知到服务负责人,及时处理问题。所以引入“钉钉”作为通知工具,当服务出现异常便可立即收到通知,及时处理!
二、使用方式
1、客户端配置机器人
1.1首先需要有阿里巴巴的“钉钉”客户端

使用shell脚本连接钉钉机器人发送消息_java

1.2、建立群聊(如果只想通知给自己,不想通知其他人,也可以与他们创建群聊之后再将他们踢出)

使用shell脚本连接钉钉机器人发送消息_json_02

 

 

1.3、点击“群设置”里面的“智能群助手”

使用shell脚本连接钉钉机器人发送消息_java_03

1.4、“添加机器人

使用shell脚本连接钉钉机器人发送消息_java_04

 

 

 1.5、自定义

使用shell脚本连接钉钉机器人发送消息_apache_05

 

 

注意:后续的消息体中必须要包含设置的“自定义关键词”,消息才能发送成功。

使用shell脚本连接钉钉机器人发送消息_java_06

 

 

 1.7、点击“完成”后会得到一个webhook,把这个webhook复制出来,一会儿代码中要用,


类似这样的:https://oapi.dingtalk.com/robot/send?access_token=880e6b7********************************************97d5e

使用shell脚本连接钉钉机器人发送消息_json_07

 

 

 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
}
}

使用shell脚本连接钉钉机器人发送消息_java_08

 

 

 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"
}
}

使用shell脚本连接钉钉机器人发送消息_json_09

 

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
}
}

使用shell脚本连接钉钉机器人发送消息_apache_10

 

 

 

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