钉钉机器人接入方法

目录

一、准备工作

二、代码接入

三、钉钉消息接收

四、机器人发消息


一、准备工作

        1.进入钉钉开发者后台

        2.点击应用开发,创建一个新应用。

        3.创建完成后会得到一个appKeyappSecret,接下来在机器人应用会用到。

        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<OapiRobotSendRequest.Btns> 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<OapiRobotSendRequest.Links> 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<T extends BaseDingResponse> {

    public abstract Class<T> getResponseClass();

}

@SuppressWarnings("ALL")
@EqualsAndHashCode(callSuper = true)
@Data
public class DingRobotSendRequest extends BaseDingRequest<DingRobotSendResponse> {

    @ApiModelProperty("机器人发送url地址")
    private String webHook;

    @ApiModelProperty("@用户id")
    private List<String> atUserIds;

    @ApiModelProperty("@手机号")
    private List<String> 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> 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> 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<DingRobotSendResponse> getResponseClass() {
        return DingRobotSendResponse.class;
    }
}

  • 23
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值