钉钉机器人-自定义卡片推送快速入门

首先来个简单的案例


Webhook-钉钉机器人快速启动案例

url

复制代码
package com.example.kiratest.Test;

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.util.EntityUtils;
import com.alibaba.fastjson.JSONObject;
 
public class DingTalkCardMessageSender {
 
    // 钉钉机器人Webhook URL
    private static final String WEBHOOK_URL = "https://oapi.dingtalk.com/robot/send?access_token=9abd4ead51a7b12d84e5906c3be67ed7aff75ad21f9aacedc316e9f0ff75616e";
 
    public static void main(String[] args) throws Exception {
        // 构建卡片消息
        JSONObject cardMessage = new JSONObject();
        cardMessage.put("msgtype", "markdown");
        
        JSONObject markdown = new JSONObject();
        markdown.put("title", "我的卡片消息标题");
        markdown.put("text", "```markdown\n我的基本测试\n```");

        cardMessage.put("markdown", markdown);
 
        // 发送HTTP POST请求
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpPost httpPost = new HttpPost(WEBHOOK_URL);
            httpPost.setHeader("Content-Type", "application/json");
            
            StringEntity entity = new StringEntity(cardMessage.toJSONString(), "UTF-8");
            httpPost.setEntity(entity);
 
            try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
                String responseBody = EntityUtils.toString(response.getEntity(), "UTF-8");
                System.out.println("Response: " + responseBody);
            }
        }
    }
}

这个是发送我们定义好的模板卡片,不需要我们传数据


Notify方法类

Notify接口

复制代码
package com.example.kiratest.Notify;

public interface Notifier<T> {
    T notify(String message,Integer msgType);
}

DingTalkNotify实现类

我们的流程就是通过getToken()来拿到tingtalk平台的token

然后用notify()向https://api.dingtalk.com/v1.0/card/instances/createAndDeliver 链接来发起请求,把卡片模板推送到群

复制代码
package com.example.kiratest.Notify;

import com.alibaba.fastjson.JSON;
import com.example.kiratest.Notify.Util.SmartHttpUtil;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.stereotype.Component;
import org.springframework.web.util.UriComponentsBuilder;

import java.util.Map;

@Slf4j
@Setter
@Component
/**
 * 获取Token然后发起请求
 */
//我们首先通过getToken()来获取我们的Token,然后调用SmartHttpUtil里的postWithHeade()方法来发起请求
public class DingtalkNotifier implements Notifier {


    private String appkey="dingzrr5q24mlutd6knl";
    private String appsecret="C2vkXuTegyUNsmftSKRgO4zq0lRuLBbw2oxxB_A_vzc0T0LHcsR2FxH3atMLDrlT";

    private String dingTalkTokenUrl = "https://oapi.dingtalk.com/gettoken";
    private String dingTalkSendUrl = "https://api.dingtalk.com/v1.0/card/instances/createAndDeliver";

    @Override
    public T notify(String message,Integer msgType) {

        try {
            Map<String, String> headers = Map.of("x-acs-dingtalk-access-token", getToken());
            log.info("开始发送请求");
            String s = SmartHttpUtil.postWithHeader(dingTalkSendUrl, message, headers);
            System.out.println(s);
        } catch (Exception e) {
            log.error("==== feishu notify ==== execute err:", e);
        }
        return null;
    }

    //根据appKey和appsecret来拿到我们的dingtalk平台的token
    private String getToken(){
        try {
            String jsonResponse = SmartHttpUtil.get(UriComponentsBuilder.fromHttpUrl(dingTalkTokenUrl)
                                                .queryParam("appkey", appkey)
                                                .queryParam("appsecret", appsecret)
                                                .toUriString());
            String accessToken = JSON.parseObject(jsonResponse).getString("access_token");
            log.info("Token:{}",accessToken);
            return accessToken;
        } catch (Exception e) {
            log.error("==== feishu notify ==== execute err:", e);
        }
        return null;
    }

}

如何拿到appKey和appsecret

在钉钉开发者后台,找到对应的企业应用

开发者后台统一登录 - 钉钉统一身份认证

点击应用里的凭证信息,就可以找到我们的appKey和appsecret了

这样子我们就可以成功拿到Token


然后我们向特定群聊发起请求,但是我们要找到特定的群聊我们才可以发送我们的卡片啊

如何找到群聊Id-openConversationId

打开JSAPI Explorer

调用chooseChat

JSAPI Explorer


用手机设备扫码


运行调试,手机选择群聊得到群聊信息

我们输入我们的cropId,然后运行调试

这样子我们就得到我们的chatId和OpenConversationId了

我们记住我们的群聊场域Id


创建消息卡片模板

开发者后台统一登录 - 钉钉统一身份认证

去到开发平台的卡片平台添加模板,然后复制得到我们的模板id

我们先记住这个id

复制代码
28553af7-0e99-4e94-b540-56027baddf28.schema

枚举类放我们的群聊场域Id

复制代码
package com.example.kiratest.Notify.Enum;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONAware;
import com.alibaba.fastjson.JSONObject;
import com.google.common.base.CaseFormat;
import lombok.Data;

import java.util.LinkedHashMap;
import java.util.Objects;

/**
 * 枚举类接口
 *
 * @Author 1024创新实验室: 胡克
 * @Date 2018-07-17 21:22:12
 * @Wechat zhuoda1024
 * @Email [email protected]
 * @Copyright  <a href="https://1024lab.net">1024创新实验室</a>
 */
public interface BaseEnum {

    /**
     * 获取枚举类的值
     *
     * @return
     */
    Object getValue();

    /**
     * 获取枚举类的说明
     *
     * @return String
     */
    String getDesc();

    /**
     * 比较参数是否与枚举类的value相同
     *
     * @param value
     * @return boolean
     */
    default boolean equalsValue(Object value) {
        return Objects.equals(getValue(), value);
    }

    /**
     * 比较枚举类是否相同
     *
     * @param baseEnum
     * @return boolean
     */
    default boolean equals(BaseEnum baseEnum) {
        return Objects.equals(getValue(), baseEnum.getValue()) && Objects.equals(getDesc(), baseEnum.getDesc());
    }

    /**
     * 返回枚举类的说明
     *
     * @param clazz 枚举类类对象
     * @return
     */
    static String getInfo(Class<? extends BaseEnum> clazz) {
        BaseEnum[] enums = clazz.getEnumConstants();
        LinkedHashMap<String, JSONObject> json = new LinkedHashMap<>(enums.length);
        for (BaseEnum e : enums) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("value", new DeletedQuotationAware(e.getValue()));
            jsonObject.put("desc", new DeletedQuotationAware(e.getDesc()));
            json.put(e.toString(), jsonObject);
        }

        String enumJson = JSON.toJSONString(json, true);
        enumJson = enumJson.replaceAll("\"", "");
        enumJson = enumJson.replaceAll("\t", "&nbsp;&nbsp;");
        enumJson = enumJson.replaceAll("\n", "<br>");
        String prefix = "  <br>  export const " + CaseFormat.UPPER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, clazz.getSimpleName() + " = <br> ");
        return prefix + enumJson + " <br>";
    }

    @Data
    class DeletedQuotationAware implements JSONAware {

        private String value;

        public DeletedQuotationAware(Object value) {
            if (value instanceof String) {
                this.value = "'" + value + "'";
            } else {
                this.value = value.toString();
            }
        }

        @Override
        public String toJSONString() {
            return value;
        }
    }
}

package com.example.kiratest.Notify.Enum;



public enum MsgTypeEnum implements BaseEnum {

   

    NOTIFY2(1, "通知类消息","dtv1.card//IM_GROUP.cid6Ks/gaDvofWDO3rp4XyA1A==");

 
    private Integer value;
    private String desc;
    private String openSpaceId;

    MsgTypeEnum(Integer value, String desc, String openSpaceId) {
        this.value = value;
        this.desc = desc;
        this.openSpaceId = openSpaceId;
    }


    @Override
    public Integer getValue() {
        return value;
    }

    @Override
    public String getDesc() {
        return desc;
    }

    public String getOpenSpaceId() {
        return openSpaceId;
    }
}

写一个Main函数发起请求

逻辑解析

我们要用我们封装好的CardRequest类来发起请求

如果我们的卡片是要传变量的,我们就往CardRequest对象里面来放我们的信息

但我们这个Demo只是发送普通的设计好的卡片

复制代码
pbNotifierMsg.getCardData().getCardParamMap().getTableBean().setData(XXX);

我们放CardRequest对象里面放我们的信息

1.枚举类里我们的群聊的场域Id

2.我们的卡片模板Id

3.这个是我们的请求的唯一Id,方便我们的以后排查定位,我们直接用UUID生成就好了

复制代码
        //这个是我的群聊Id
        //详细看枚举类,我的枚举类是这样的      NOTIFY2(1, "通知类消息","dtv1.card//IM_GROUP.cid6Ks/gaDvofWDO3rp4XyA1A==")
        pbNotifierMsg.setOpenSpaceId(MsgTypeEnum.NOTIFY2.getOpenSpaceId());
        //这个是我的模板Id
        pbNotifierMsg.setCardTemplateId("28553af7-0e99-4e94-b540-56027baddf28.schema");
        pbNotifierMsg.setOutTrackId(UUID.randomUUID().toString());

然后我们把CardRequest对象转成Json字符串,然后通过Notify类来发送请求


Main函数代码

ps:这个是给我们发送的消息起名字的

复制代码
    public static CardRequest pbNotifierMsg() {
        return new CardRequest("offer监控通知", null);
    }

Offer监控是我们的机器人名字,Offer监控通知是我们的这次通知的名字

完整Main函数代码如下:

复制代码
package com.example.kiratest.Notify;

import com.alibaba.fastjson.JSON;
import com.example.kiratest.Notify.Enum.MsgTypeEnum;
import com.example.kiratest.Notify.POJO.CardRequest;
import com.example.kiratest.Notify.POJO.DingtalkTableItem;

import java.util.UUID;

public class KiraMain {
    public static void main(String[] args) {


        //卡片请求对象
        CardRequest pbNotifierMsg = pbNotifierMsg();

        //如果是特定的卡片我们可以按照特定的格式往里面发放数据
//        pbNotifierMsg.getCardData().getCardParamMap().getTableBean().setData(XXX);
        DingtalkTableItem tableBean = pbNotifierMsg.getCardData().getCardParamMap().getTableBean();

        pbNotifierMsg.getCardData().getCardParamMap().setTable(JSON.toJSONString(tableBean));
        //这个是我的群聊Id
        //详细看枚举类,我的枚举类是这样的      NOTIFY2(1, "通知类消息","dtv1.card//IM_GROUP.cid6Ks/gaDvofWDO3rp4XyA1A==")
        pbNotifierMsg.setOpenSpaceId(MsgTypeEnum.NOTIFY2.getOpenSpaceId());
        //这个是我的模板Id
        pbNotifierMsg.setCardTemplateId("28553af7-0e99-4e94-b540-56027baddf28.schema");
        pbNotifierMsg.setOutTrackId(UUID.randomUUID().toString());

        //将卡片对象转成String
        String jsonString = JSON.toJSONString(pbNotifierMsg);

        DingtalkNotifier dingtalkNotifier = new DingtalkNotifier();

        //发起请求
        dingtalkNotifier.notify(jsonString, null);
    }

    public static CardRequest pbNotifierMsg() {
        return new CardRequest("offer监控通知", null);
    }


}

封装API用到的实体类

复制代码
package com.example.kiratest.Notify.POJO;

import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;
import lombok.experimental.Accessors;

@Data
@Accessors(chain = true)
public class CardData {
    @JSONField(name = "cardParamMap")
    private CardParamMap cardParamMap = new CardParamMap();

    // Getters and Setters
}

package com.example.kiratest.Notify.POJO;

import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;
import lombok.experimental.Accessors;

@Data
@Accessors(chain = true)
public class CardParamMap {
    private String title;
    private String table;
    private String config = "{\"autoLayout\": true}";
    @JSONField(serialize = false)
    private DingtalkTableItem tableBean = new DingtalkTableItem();

    // Getters and Setters
}

package com.example.kiratest.Notify.POJO;

import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;
import lombok.experimental.Accessors;

import java.util.List;

@Data
@Accessors(chain = true)
public class CardRequest {
    @JSONField(name = "cardTemplateId")
    private String cardTemplateId;

    @JSONField(name = "outTrackId")
    private String outTrackId ;

    @JSONField(name = "cardData")
    private CardData cardData = new CardData();

    @JSONField(name = "imGroupOpenSpaceModel")
    private ImGroupOpenSpaceModel imGroupOpenSpaceModel = new ImGroupOpenSpaceModel();

    @JSONField(name = "openSpaceId")
    private String openSpaceId;

    @JSONField(name = "imGroupOpenDeliverModel")
    private ImGroupOpenDeliverModel imGroupOpenDeliverModel = new ImGroupOpenDeliverModel();

    public CardRequest(String title, List<DingtalkColumnsItem> columns) {
        this.getCardData().getCardParamMap().setTitle(title);
        this.getCardData().getCardParamMap().getTableBean().setMeta(columns);
        this.getImGroupOpenSpaceModel().getLastMessageI18n().setZhCn(title);

    }

}

package com.example.kiratest.Notify.POJO;

import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;
import lombok.experimental.Accessors;

import java.io.Serializable;

@Data
@Accessors(chain = true)
public class DingtalkColumnsItem implements Serializable {

    @JSONField(name="dataType")
    private String dataType;

    @JSONField(name="alias")
    private String alias;

    @JSONField(name="aliasName")
    private String aliasName;

    @JSONField(name="weight")
    private int weight;

}

package com.example.kiratest.Notify.POJO;

import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;
import lombok.experimental.Accessors;

import java.io.Serializable;

@Data
@Accessors(chain = true)
public class DingtalkRowsItem implements Serializable {

    @JSONField(name="packageName")
    private String packageName;

    @JSONField(name="googlePlayVersionCode")
    private String googlePlayVersionCode;

    @JSONField(name="innerVersionCode")
    private String innerVersionCode;

    @JSONField(name="apkcomboVersionCode")
    private String apkcomboVersionCode;

    @JSONField(name = "apkmirrorVersionCode")
    private String apkmirrorVersionCode;

    @JSONField(name = "offerId")
    private String offerId;

    @JSONField(name = "affiliateId")
    private String affiliateId;

    @JSONField(name = "timezone")
    private Integer timezone;

    @JSONField(name = "cap")
    private Integer cap;

    @JSONField(name = "pbNumber")
    private Integer pbNumber;

}

package com.example.kiratest.Notify.POJO;

import lombok.Data;
import lombok.experimental.Accessors;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

@Data
@Accessors(chain = true)
public class DingtalkTableItem implements Serializable {


    //@JSONField(name="columns")
    private List<DingtalkColumnsItem> meta;

    //@JSONField(name="rows")
    private List<DingtalkRowsItem> data = new ArrayList<>();


}

package com.example.kiratest.Notify.POJO;

import lombok.Data;
import lombok.experimental.Accessors;

@Data
@Accessors(chain = true)
public class ImGroupOpenDeliverModel {
    private String robotCode = "dingzrr5q24mlutd6knl";
    // Getters and Setters
}

package com.example.kiratest.Notify.POJO;

import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;
import lombok.experimental.Accessors;

@Data
@Accessors(chain = true)
public class ImGroupOpenSpaceModel {
    @JSONField(name = "supportForward")
    private boolean supportForward;

    @JSONField(name = "lastMessageI18n")
    private LastMessageI18n lastMessageI18n = new LastMessageI18n();

    // Getters and Setters
}

package com.example.kiratest.Notify.POJO;

import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;
import lombok.experimental.Accessors;

@Data
@Accessors(chain = true)
public class LastMessageI18n {
    @JSONField(name = "ZH_CN")
    private String zhCn;

    // Getters and Setters
}

package com.example.kiratest.Notify.POJO;

import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;
import lombok.experimental.Accessors;

import java.io.Serializable;

@Data
@Accessors(chain = true)
public class RowsItem implements Serializable {

    @JSONField(name="packageName")
    private String packageName;

    @JSONField(name="googlePlayVersionCode")
    private String googlePlayVersionCode;

    @JSONField(name="innerVersionCode")
    private String innerVersionCode;

    @JSONField(name="apkcomboVersionCode")
    private String apkcomboVersionCode;

    @JSONField(name = "apkmirrorVersionCode")
    private String apkmirrorVersionCode;

    @JSONField(name = "offerId")
    private String offerId;

    @JSONField(name = "affiliateId")
    private String affiliateId;

    @JSONField(name = "timezone")
    private Integer timezone;

    @JSONField(name = "cap")
    private Integer cap;

    @JSONField(name = "pbNumber")
    private Integer pbNumber;
}

用到的自定义工具类

复制代码
package com.example.kiratest.Notify.Util;

import jakarta.validation.ConstraintViolation;
import jakarta.validation.Validation;
import jakarta.validation.Validator;
import org.springframework.beans.BeanUtils;

import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * bean相关工具类
 *
 * @Author 1024创新实验室-主任: 卓大
 * @Date 2018-01-15 10:48:23
 * @Wechat zhuoda1024
 * @Email [email protected]
 * @Copyright  <a href="https://1024lab.net">1024创新实验室</a>
 */
public class SmartBeanUtil {

    /**
     * 验证器
     */
    private static final Validator VALIDATOR = Validation.buildDefaultValidatorFactory().getValidator();

    /**
     * 复制bean的属性
     *
     * @param source 源 要复制的对象
     * @param target 目标 复制到此对象
     */
    public static void copyProperties(Object source, Object target) {
        BeanUtils.copyProperties(source, target);
    }

    /**
     * 复制对象
     *
     * @param source 源 要复制的对象
     * @param target 目标 复制到此对象
     * @param <T>
     * @return
     */
    public static <T> T copy(Object source, Class<T> target) {
        if (source == null || target == null) {
            return null;
        }
        try {
            T newInstance = target.newInstance();
            BeanUtils.copyProperties(source, newInstance);
            return newInstance;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 复制list
     *
     * @param source
     * @param target
     * @param <T>
     * @param <K>
     * @return
     */
    public static <T, K> List<K> copyList(List<T> source, Class<K> target) {
        if (null == source || source.isEmpty()) {
            return Collections.emptyList();
        }
        return source.stream().map(e -> copy(e, target)).collect(Collectors.toList());
    }

    /**
     * 手动验证对象 Model的属性
     * 需要配合 hibernate-validator 校验注解
     *
     * @param t
     * @return String 返回null代表验证通过,否则返回错误的信息
     */
    public static <T> String verify(T t) {
        // 获取验证结果
        Set<ConstraintViolation<T>> validate = VALIDATOR.validate(t);
        if (validate.isEmpty()) {
            // 验证通过
            return null;
        }
        // 返回错误信息
        List<String> messageList = validate.stream().map(ConstraintViolation::getMessage).collect(Collectors.toList());
        return messageList.toString();
    }
}

package com.example.kiratest.Notify.Util;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
import java.util.Map;

public class SmartHttpUtil {

    private static final HttpClient client = HttpClient.newBuilder()
            .version(HttpClient.Version.HTTP_2)
            .connectTimeout(Duration.ofSeconds(10))
            .build();

    public static String get(String url) throws Exception {
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(url))
                .timeout(Duration.ofSeconds(10))
                .GET()
                .build();

        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
        return handleResponse(response);
    }


    public static String postWithHeader(String url, String json, Map<String,String> header) throws Exception {
        HttpRequest.Builder requestBuilder  = HttpRequest.newBuilder()
                .uri(URI.create(url))
                .timeout(Duration.ofSeconds(10))
                .header("Content-Type", "application/json")
                .POST(HttpRequest.BodyPublishers.ofString(json));
        // 遍历 header Map,添加所有的 header
        if (header != null) {
            for (Map.Entry<String, String> entry : header.entrySet()) {
                requestBuilder.header(entry.getKey(), entry.getValue());
            }
        }
        HttpResponse<String> response = client.send(requestBuilder.build(), HttpResponse.BodyHandlers.ofString());
        return handleResponse(response);
    }

    private static String handleResponse(HttpResponse<String> response) throws Exception {
        if (response.statusCode() != 200) {
            throw new Exception("HTTP error code: " + response.statusCode() + " - " + response.body());
        }
        return response.body();
    }


}

用到的依赖

复制代码
<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.14</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>5.2.3</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>2.0.52</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>dingtalk</artifactId>
            <version>2.1.42</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.dingtalk.open/app-stream-client -->
        <dependency>
            <groupId>com.dingtalk.open</groupId>
            <artifactId>app-stream-client</artifactId>
            <version>1.3.7</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>33.4.6-jre</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-validation -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
            <version>3.4.4</version>
        </dependency>
<!--        &lt;!&ndash; https://mvnrepository.com/artifact/com.dingtalk.open/dingtalk-stream &ndash;&gt;-->
<!--        <dependency>-->
<!--            <groupId>com.dingtalk.open</groupId>-->
<!--            <artifactId>dingtalk-stream</artifactId>-->
<!--            <version>1.3.7</version>-->
<!--        </dependency>-->
        <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.36</version>
            <scope>provided</scope>
        </dependency>

            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter</artifactId>
                <version>3.4.4</version>
                <exclusions>
                    <exclusion>
                        <groupId>commons-logging</groupId>
                        <artifactId>commons-logging</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>

    </dependencies>

思路总结

我们通过开发者平台点击具体的钉钉应用

来拿到我们钉钉应用的appKey和appSecret,向dingtalk平台发起请求拿到我们的Token

这样子我们就可以使用我们的Token在代码中访问使用我们的应用了

然后我们去卡片平台拿到我们的卡片模板Id

和在JSAPI Explorer拿到我们的群聊场域Id,放到我们的枚举类里面

这样子我们就可以根据拿到的Token定位到具体的机器人

根据OpenConversationId群聊场域Id定位到我们的群聊

根据CardTemplate卡片模板Id来找到我们要推送的特定卡片

然后把这些信息放到CardRequest类对象里,再把对象转为Json,通过Notify实现类的notify()方法就可以发起调用了

这样子我们就可以实现,在特定的群聊根据特定的机器人来推送特定的卡片了


Notify类按照格式传输数据

这个是发送我们构造好的数据,在卡片模板的基础上来传我们的变量


main方法跑CradRequest请求

复制代码
package com.example.kiratest.Notify;

import com.alibaba.fastjson.JSON;
import com.example.kiratest.Notify.Enum.MsgTypeEnum;
import com.example.kiratest.Notify.POJO.CardRequest;
import com.example.kiratest.Notify.POJO.DingtalkColumnsItem;
import com.example.kiratest.Notify.POJO.DingtalkRowsItem;
import com.example.kiratest.Notify.POJO.DingtalkTableItem;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@Slf4j
public class Main {
    public static void main(String[] args) {


        DingtalkRowsItem dingtalkRowsItem= new DingtalkRowsItem()
                .setOfferId("1")
                .setAffiliateId("1")
                .setPackageName("阮志荣")
                .setCap(300)
                .setPbNumber(80)
                .setTimezone(3000);



        //CardRequest
        CardRequest pbNotifierMsg = pbNotifierMsg();
        //转换成发起请求的对象
        List<DingtalkRowsItem> dingTalkRowsItems = new ArrayList<>();
        dingTalkRowsItems.add(dingtalkRowsItem);
        //构建CardRequest
        pbNotifierMsg.getCardData().getCardParamMap().getTableBean().setData(dingTalkRowsItems);
        DingtalkTableItem tableBean = pbNotifierMsg.getCardData().getCardParamMap().getTableBean();
        pbNotifierMsg.getCardData().getCardParamMap().setTable(JSON.toJSONString(tableBean));
        pbNotifierMsg.setOpenSpaceId(MsgTypeEnum.NOTIFY2.getOpenSpaceId());//群聊场域Id
        pbNotifierMsg.setCardTemplateId("fac74867-f2a3-4805-a841-093306a616d9.schema");//卡片模板Id
        pbNotifierMsg.setOutTrackId(UUID.randomUUID().toString());//请求唯一Id

        //将CradRequest对象变成Json字符串
        String jsonString = JSON.toJSONString(pbNotifierMsg);

        DingtalkNotifier dingtalkNotifier = new DingtalkNotifier();

        dingtalkNotifier.notify(jsonString, null);
    }


    //我们主要有5个参数 offerId,affilicateId,packageName,cap,pbNumber
    public static CardRequest pbNotifierMsg() {
        List<DingtalkColumnsItem> columnsItems = new ArrayList<>();
        columnsItems.add(new DingtalkColumnsItem().setDataType("STRING")
                .setAlias("offerId").setAliasName("offerId").setWeight(20));
        columnsItems.add(new DingtalkColumnsItem().setDataType("STRING")
                .setAlias("affiliateId").setAliasName("affiliateId").setWeight(20));
        columnsItems.add(new DingtalkColumnsItem().setDataType("STRING")
                .setAlias("packageName").setAliasName("packageName").setWeight(20));
        columnsItems.add(new DingtalkColumnsItem().setDataType("STRING")
                .setAlias("cap").setAliasName("cap数").setWeight(20));
        columnsItems.add(new DingtalkColumnsItem().setDataType("STRING")
                .setAlias("pbNumber").setAliasName("上游转化数").setWeight(20));
        return new CardRequest("offer监控通知", columnsItems);
    }
}

pbNotifierMsg()方法放入参数类型

复制代码
 //我们主要有5个参数 offerId,affilicateId,packageName,cap,pbNumber
    public static CardRequest pbNotifierMsg() {
        List<DingtalkColumnsItem> columnsItems = new ArrayList<>();
        columnsItems.add(new DingtalkColumnsItem().setDataType("STRING")
                .setAlias("offerId").setAliasName("offerId").setWeight(20));
        columnsItems.add(new DingtalkColumnsItem().setDataType("STRING")
                .setAlias("affiliateId").setAliasName("affiliateId").setWeight(20));
        columnsItems.add(new DingtalkColumnsItem().setDataType("STRING")
                .setAlias("packageName").setAliasName("packageName").setWeight(20));
        columnsItems.add(new DingtalkColumnsItem().setDataType("STRING")
                .setAlias("cap").setAliasName("cap数").setWeight(20));
        columnsItems.add(new DingtalkColumnsItem().setDataType("STRING")
                .setAlias("pbNumber").setAliasName("上游转化数").setWeight(20));
        return new CardRequest("offer监控通知", columnsItems);
    }

我们的变量是offerId,affliatedId,packageName,cap,上游转化数


pbNotifierMsg()方法构造图片显示参数

我们加多了一个新变量,然后发现,我们的卡片也多出来一个新变量

复制代码
    //我们主要有5个参数 offerId,affilicateId,packageName,cap,pbNumber
    public static CardRequest pbNotifierMsg() {
        List<DingtalkColumnsItem> columnsItems = new ArrayList<>();
        columnsItems.add(new DingtalkColumnsItem().setDataType("STRING")
                .setAlias("offerId").setAliasName("offerId").setWeight(20));
        columnsItems.add(new DingtalkColumnsItem().setDataType("STRING")
                .setAlias("affiliateId").setAliasName("affiliateId").setWeight(20));
        columnsItems.add(new DingtalkColumnsItem().setDataType("STRING")
                .setAlias("packageName").setAliasName("packageName").setWeight(20));
        columnsItems.add(new DingtalkColumnsItem().setDataType("STRING")
                .setAlias("cap").setAliasName("cap数").setWeight(20));
        columnsItems.add(new DingtalkColumnsItem().setDataType("STRING")
                .setAlias("pbNumber").setAliasName("上游转化数").setWeight(20));
        columnsItems.add(new DingtalkColumnsItem().setDataType("STRING")
                .setAlias("number").setAliasName("测试新变量").setWeight(20));
        return new CardRequest("offer监控通知", columnsItems);
    }

卡片模板设置(表格)

因为我们是表格格式,所以我们可以用pbNotifierMsg那种方式来传参数

我们直接自己弄一个卡片模板,里面弄一个表格格式就好了

相关推荐
云边小网安14 分钟前
java集合(十) ---- LinkedList 类
java·开发语言·青少年编程·java集合
乐神嘎嘎嘎17 分钟前
springboot速通
java·spring boot
Zephyrtoria1 小时前
区间合并:区间合并问题
java·开发语言·数据结构·算法
yuren_xia6 小时前
RabbitMQ 知识详解(Java版)
java·rabbitmq·java-rabbitmq
kfyty7256 小时前
轻量级 ioc 框架 loveqq,支持接口上传 jar 格式的 starter 启动器并支持热加载其中的 bean
java·jvm·ioc·jar·热加载
早起鸟儿7 小时前
docker-Dockerfile 配置
java·linux·运维·docker
云边小网安7 小时前
java集合篇(六) ---- ListIterator 接口
java·开发语言·青少年编程·java集合
都叫我大帅哥7 小时前
Spring WebFlux:响应式编程的“未来战士”还是“花架子”?
java·spring·flux
都叫我大帅哥7 小时前
Reactor 深度解析:响应式编程的「核反应堆」是如何工作的?
java·spring
不太厉害的程序员7 小时前
NC65配置xml找不到Bean
xml·java·后端·eclipse