目录
一、准备工作
二、代码接入
三、钉钉消息接收
四、机器人发消息
一、准备工作
1.进入钉钉开发者后台
2.点击应用开发,创建一个新应用。
3.创建完成后会得到一个appKey、appSecret,接下来在机器人应用会用到。
4.点击添加应用能力,选择机器人应用,点击配置,填入自定义信息配置。
5.选择消息接收模式,有HTTP和Stream模式两种,我们选择传统HTTP模式,如果选择Stream模式可以参考官方文档服务端Stream模式。配置好后最终点击发布即可。(特别注意点:如果想要在本地进行调试钉钉消息回调接收,需要配置本地内网穿透,然后将穿透地址配置到这里的回调地址即可进行在本地的功能调试)
6.还有在权限管理这里需要赋予应用对应的功能权限,比如获取群信息等相关功能的权限,那么你创建的应用才能正常获取到这些信息,需要针对自己需要用到的功能进行赋权。
7.最终在版本管理与发布这里进行版本发布,创建的应用功能才能最终生效。
8.来到钉钉应用中,创建一个钉钉群组,打开群设置,点击机器人,选择刚才我们自己创建的机器人加入到这个群组中。添加后机器人会生成一个webHook地址,这个地址是为后来我们主动调用钉钉接口,去控制这个机器人在顶顶群中发消息用的。
二、代码接入
我们是java代码应用,使用的也是最为常用的springBoot搭建的Maven应用,而钉钉官方也提供了java的sdk包:新版本sdk、老版本sdk,我们可以直接使用官方封装好的接口进行调用使用很方便。
三、钉钉消息接收
我们手写一个controller进行钉钉 消息回调的接收,那么我们在群中发消息并且@机器人,我们就会在这个回调接口中收到相关信息。具体消息体信息可以参考文档机器人接收消息。
@Api(value = "钉钉回调", tags = "钉钉回调")
@Slf4j
@RestController
@RequestMapping("V1/third/ding")
public class GroupDingBackController {
@Resource
private GroupDingBackService groupDingBackService;
@ApiOperation("钉钉群消息回调接收")
@PostMapping("/robots/msgCallBack")
public ResponseEntity> msgCallBack(@RequestBody(required = false) JSONObject backBody) {
groupDingBackService.msgCallBack(backBody);
return ResponseEntity.ok(HttpStatus.OK);
}
}
我们拿到回调消息体后就可以通过自身业务需要,进行自扩展开发了,使我们的机器人拥有更丰富的业务功能。
四、机器人发消息
官方文档机器人发消息,下边也有我自己简单封装的一个机器人发消息类工具,可以做下参考。
public DingRobotSendResponse sendMsgToDingGroup(DingRobotSendRequest sendRequest) {
try {
DingTalkClient client = new DefaultDingTalkClient(sendRequest.getWebHook());
OapiRobotSendRequest request = fillMsgData(sendRequest, new OapiRobotSendRequest());
OapiRobotSendRequest.At at = new OapiRobotSendRequest.At();
at.setAtUserIds(sendRequest.getAtUserIds());
at.setAtMobiles(sendRequest.getAtMobiles());
at.setIsAtAll(sendRequest.getIsAtAll());
request.setAt(at);
log.info("请求钉钉发送机器人消息请求参数:{}", JSON.toJSONString(request));
OapiRobotSendResponse response = client.execute(request);
log.info("请求钉钉发送机器人消息原始返回信息:{}", JSON.toJSONString(response));
DingRobotSendResponse sendResponse = new DingRobotSendResponse();
if (response.isSuccess()) {
ModelMapperUtils.map(response, sendResponse);
}
sendResponse.setErrcode(response.getErrcode());
sendResponse.setErrmsg(response.getErrmsg());
return sendResponse;
} catch (ApiException e) {
log.info("请求钉钉发送机器人消息异常:{}", e.getErrMsg(), e);
return new DingRobotSendResponse();
}
}
private static OapiRobotSendRequest fillMsgData(DingRobotSendRequest sendRequest, OapiRobotSendRequest request) {
DingMsgTypeEnum msgType = sendRequest.getMsgType();
switch (msgType) {
case TEXT:
request.setMsgtype(msgType.getType());
OapiRobotSendRequest.Text text = ModelMapperUtils.map(sendRequest.getText(), OapiRobotSendRequest.Text.class);
request.setText(text);
return request;
case LINK:
request.setMsgtype(msgType.getType());
OapiRobotSendRequest.Link link = ModelMapperUtils.map(sendRequest.getLink(), OapiRobotSendRequest.Link.class);
request.setLink(link);
return request;
case MARKDOWN:
request.setMsgtype(msgType.getType());
OapiRobotSendRequest.Markdown markdown = ModelMapperUtils.map(sendRequest.getMarkdown(), OapiRobotSendRequest.Markdown.class);
request.setMarkdown(markdown);
return request;
case ACTIONCARD:
request.setMsgtype(msgType.getType());
OapiRobotSendRequest.Actioncard actionCard = ModelMapperUtils.map(sendRequest.getActioncard(), OapiRobotSendRequest.Actioncard.class);
List btns = ModelMapperUtils.mapList(sendRequest.getActioncard().getBtns(), OapiRobotSendRequest.Btns.class);
actionCard.setBtns(btns);
request.setActionCard(actionCard);
return request;
case FEEDCARD:
request.setMsgtype(msgType.getType());
OapiRobotSendRequest.Feedcard feedCard = new OapiRobotSendRequest.Feedcard();
List links = ModelMapperUtils.mapList(sendRequest.getFeedCard().getLinks(), OapiRobotSendRequest.Links.class);
feedCard.setLinks(links);
request.setFeedCard(feedCard);
return request;
case UNKNOW:
log.info("发送钉钉机器人发现未知消息类型");
break;
default:
log.info("发送钉钉机器人没有匹配到对应的消息类型");
break;
}
return request;
}
@AllArgsConstructor
@Getter
public enum DingMsgTypeEnum {
TEXT(0, "text"),
LINK(1, "link"),
MARKDOWN(2, "markdown"),
ACTIONCARD(3, "actionCard"),
FEEDCARD(4, "feedCard"),
UNKNOW(99, "unknow");
private final Integer value;
private final String type;
public static DingMsgTypeEnum getEnum(Integer value) {
for (DingMsgTypeEnum enumValue : DingMsgTypeEnum.values()) {
if (Objects.equals(enumValue.getValue(), value)) {
return enumValue;
}
}
return UNKNOW;
}
public static String getType(Integer value) {
for (DingMsgTypeEnum enumValue : DingMsgTypeEnum.values()) {
if (Objects.equals(enumValue.getValue(), value)) {
return enumValue.getType();
}
}
return null;
}
}
@Data
public abstract class BaseDingResponse {
/**
* errcode
*/
private Long errcode;
/**
* errmsg
*/
private String errmsg;
public boolean isSuccess() {
return getErrcode() == null || getErrcode().equals(0L);
}
}
@Data
public abstract class BaseDingRequest {
public abstract Class getResponseClass();
}
@SuppressWarnings("ALL")
@EqualsAndHashCode(callSuper = true)
@Data
public class DingRobotSendRequest extends BaseDingRequest {
@ApiModelProperty("机器人发送url地址")
private String webHook;
@ApiModelProperty("@用户id")
private List atUserIds;
@ApiModelProperty("@手机号")
private List atMobiles;
@ApiModelProperty("是否@所有人")
private Boolean isAtAll;
/**
* {@link DingMsgTypeEnum}
*/
@ApiModelProperty("钉钉消息类型")
private DingMsgTypeEnum msgType;
@ApiModelProperty("文本消息内容")
private Text text;
@ApiModelProperty("link消息内容")
private Link link;
@ApiModelProperty("markdown消息内容")
private Markdown markdown;
@ApiModelProperty("actioncard消息内容")
private Actioncard actioncard;
@ApiModelProperty("feedcard消息内容")
private Feedcard feedCard;
@ApiModel("文本消息内容")
@Data
public static class Text {
/**
* text内容
*/
private String content;
}
@ApiModel("link消息内容")
@Data
public static class Link {
/**
* text内容
*/
private String text;
/**
* 标题
*/
private String title;
/**
* 图片url
*/
private String picUrl;
/**
* 消息url
*/
private String messageUrl;
}
@ApiModel("markdown消息内容")
@Data
public static class Markdown {
/**
* markdown格式的消息 此格式若想@成员需要在内容中拼接字符 ‘@150********’/'@userid'
*/
private String text;
/**
* 首屏会话透出的展示内容
*/
private String title;
}
@ApiModel("actioncard消息内容")
@Data
public static class Actioncard {
/**
* 0-按钮竖直排列,1-按钮横向排列
*/
private String btnOrientation;
/**
* 按钮的信息
*/
private List btns;
/**
* 0-正常发消息者头像,1-隐藏发消息者头像
*/
private String hideAvatar;
/**
* 单个按钮的方案。(设置此项和singleURL后btns无效。)
*/
private String singleTitle;
/**
* 点击singleTitle按钮触发的URL
*/
private String singleURL;
/**
* markdown格式的消息
*/
private String text;
/**
* 首屏会话透出的展示内容
*/
private String title;
}
@ApiModel("feedcard消息内容")
@Data
public static class Feedcard {
/**
* links
*/
private List links;
}
@ApiModel("Links消息内容")
@Data
public static class Links {
/**
* 点击单条信息到跳转链接
*/
private String messageURL;
/**
* 单条信息文本
*/
private String picURL;
/**
* 单条信息后面图片的URL
*/
private String title;
}
@ApiModel("按钮信息")
@Data
public static class Btns {
/**
* 按钮方案,
*/
private String actionURL;
/**
* 点击按钮触发的URL此消息类型为固定feedCard
*/
private String title;
}
@Override
public Class getResponseClass() {
return DingRobotSendResponse.class;
}
}