1. 快速集成

  • 引入依赖
    1. <dependency>
    2. <groupId>com.pig4cloud.plugin</groupId>
    3. <artifactId>dinger-spring-boot-starter</artifactId>
    4. <version>0.0.1</version>
    5. </dependency>
  • 修改配置文件
    1. spring:
    2. dinger:
    3. project-id: ${spring.application.name}
    4. dingers:
    5. # 使用钉钉机器人, 请根据自己机器人配置信息进行修改
    6. dingtalk:
    7. tokenId: tokenId
    8. secret: secret
  • 使用

    1. @Component
    2. public class AppInit implements InitializingBean {
    3. @Autowired
    4. private DingerSender dingerSender;
    5. @Override
    6. public void afterPropertiesSet() throws Exception {
    7. // 发送text类型消息
    8. dingerSender.send(
    9. MessageSubType.TEXT,
    10. DingerRequest.request("Hello World, Hello Dinger")
    11. );
    12. // 发送markdown类型消息
    13. dingerSender.send(
    14. MessageSubType.MARKDOWN,
    15. DingerRequest.request("Hello World, Hello Dinger", "启动通知")
    16. );
    17. }
    18. }

2. 混合使用钉钉机器人与企业微信机器人

  • 修改配置文件
    1. spring:
    2. dinger:
    3. project-id: ${spring.application.name}
    4. # 默认使用企业微信
    5. default-dinger: wetalk
    6. dingers:
    7. # 使用钉钉机器人, 请根据自己机器人配置信息进行修改
    8. dingtalk:
    9. tokenId: tokenId
    10. secret: secret
    11. # 使用企业微信机器人, 请根据自己机器人配置信息进行修改
    12. wetalk:
    13. token-id: token-id
  • 使用
    1. @Component
    2. public class AppInit implements InitializingBean {
    3. @Autowired
    4. private DingerSender dingerSender;
    5. @Override
    6. public void afterPropertiesSet() throws Exception {
    7. // 指定发送给默认Dinger(详见配置spring.dinger.default-dinger参数值)
    8. dingerSender.send(MessageSubType.TEXT, DingerRequest.request("Hello World, Hello Dinger"));
    9. // 指定发送给钉钉
    10. dingerSender.send(DingerType.DINGTALK, MessageSubType.MARKDOWN, DingerRequest.request("Hello World, Hello Dinger", "启动通知"));
    11. }
    12. }

3. 动态配置机器人

场景说明: 对于同一个消息体, 发送给钉钉机器人的同时也需要发送给企业微信机器人。

  • 配置文件
    1. spring:
    2. dinger:
    3. project-id: ${spring.application.name}
    4. # 默认使用钉钉
    5. default-dinger: dingtalk
    6. dingers:
    7. # 使用钉钉机器人, 请根据自己机器人配置信息进行修改
    8. dingtalk:
    9. tokenId: tokenId
    10. secret: secret
    11. # 使用企业微信机器人, 请根据自己机器人配置信息进行修改
    12. wetalk:
    13. token-id: token-id
  • 使用

    1. @RestController
    2. @Slf4j
    3. public class DemoController {
    4. @Autowired
    5. private UserDinger userDinger;
    6. @Value("${spring.dinger.dingers.wetalk.tokenId}")
    7. private String wetalkToken;
    8. @GetMapping("/send")
    9. public Response send() {
    10. // 发送给钉钉群
    11. DingerResponse dingSuccess = userDinger.success("pig");
    12. log.info(objectMapper.writeValueAsString(dingSuccess));
    13. // 动态配置企业微信机器人信息
    14. DingerHelper.assignDinger(DingerType.WETALK, wetalkToken, false);
    15. // 发送给企业微信群
    16. DingerResponse weSuccess = userDinger.success("pig");
    17. log.info(objectMapper.writeValueAsString(weSuccess));
    18. return Repsonse.success();
    19. }
    20. }

4. 配置多机器人

由于钉钉企业微信有消息发送频率限制-每个机器人每分钟最多发送20条,这种限制可能导致消息发送失败的问题,而多机器人配置就是为了解决这种情况的。

目前提供两种方式多机器人配置支持,大家可以根据实际情况选择合适的配置方式,相对于全局配置方式,Dinger级别是更细粒度的配置方式。

  • 全局启用多机器人配置功能

    1. @SpringBootApplication
    2. // 启用多机器人配置功能
    3. @EnableMultiDinger(
    4. // 启用钉钉多机器人配置
    5. @MultiDinger(
    6. dinger = DingerType.DINGTALK,
    7. handler = DingTalkMultiHandler.class
    8. )
    9. )
    10. public class DemoApplication {
    11. public static void main(String[] args) {
    12. SpringApplication.run(DemoApplication.class, args);
    13. }
    14. }


    配置机器人信息及多机器人使用算法
    DingerConfigHandler中支持@Autowire注解来注入bean对象。

  • Dinger级别开启多机器人配置

    1. @SpringBootApplication
    2. @DingerScan(basePackages = "com.pig4cloud.pig.admin.dinger")
    3. // 启用多机器人配置功能
    4. @EnableMultiDinger
    5. public class DemoApplication {
    6. public static void main(String[] args) {
    7. SpringApplication.run(DemoApplication.class, args);
    8. }
    9. }


    Dinger层配置

    1. // 为UserDinger配置多机器人功能
    2. @MultiHandler(
    3. @MultiDinger(
    4. dinger = DingerType.DINGTALK,
    5. handler = DingTalkMultiHandler.class)
    6. )
    7. public interface UserDinger {
    8. @DingerText(value = "恭喜用户${loginName}登录成功!")
    9. DingerResponse success(@Parameter("loginName") String userName);
    10. @DingerMarkdown(
    11. value = "#### 用户登录通知\n - 用户Id: ${userId}\n - 用户名: ${userName}",
    12. title = "用户登录反馈"
    13. )
    14. DingerResponse failed(long userId, String userName);
    15. }


    @Dinger中指定的Dinger类型如果和@MultiHandler中不一致会致使多机器配置失效而选择默认配置发送

  • 系统默认四种AlgorithmHandler算法

    • DefaultHandler: 返回默认使用的机器人账号
    • DingerHandler: 消息频率限制-每个机器人每分钟最多发送20条算法
      • 每分钟发送次数可通过启动参数进行更改-Dmulti.dinger.minute.limit.count=10
      • eg:java -Dmulti.dinger.minute.limit.count=10 -jar service.jar
    • RandomHandler: 随机选择算法
    • RoundRobinHandler: 轮询算法
    • 自定义算法
      1. public class CustomAlgorithmHandler implements AlgorithmHandler {
      2. @Override
      3. public DingerConfig handler(List<DingerConfig> dingerConfigs, DingerConfig defaultDingerConfig) {
      4. // 多机器人使用逻辑代码...
      5. return dingerConfigs.get(1);
      6. }
      7. }

5. 统一消息管理体

  • 引入依赖
    1. <dependency>
    2. <groupId>com.pig4cloud.plugin</groupId>
    3. <artifactId>dinger-spring-boot-starter</artifactId>
    4. <version>0.0.1</version>
    5. </dependency>
  • 启动类引入DingerScan注解
    1. @SpringBootApplication
    2. // 标识Dinger层扫描路径
    3. @DingerScan(basePackages = "com.pig4cloud.pig.admin.dinger")
    4. public class DemoApplication {
    5. public static void main(String[] args) {
    6. SpringApplication.run(DemoApplication.class, args);
    7. }
    8. }

DingerScan的basePackages属性值注意更改为实际项目中定义的dinger接口层包路径

  • 定义消息体
    有两种方式进行Dinger消息体定义,分别是注解方式和XML配置方式,两种方式任选一种使用即可 。

    • 注解方式
      修改配置文件

      1. spring:
      2. dinger:
      3. project-id: ${spring.application.name}
      4. dingers:
      5. # 使用钉钉机器人, 请根据自己机器人配置信息进行修改
      6. dingtalk:
      7. tokenId: tokenId
      8. secret: secret


      Dinger接口类
      ``java public interface UserDinger { //@`群里指定成员 @DingerText(value = “恭喜用户${userName}登录成功!”, phones = “13520200906”) DingerResponse success(String userName);

      @DingerMarkdown(

      1. value = "#### 用户登录通知\n - 用户Id: ${userId}\n - 用户名: ${userName}",
      2. title = "用户登录反馈"

      ) DingerResponse failed(long userId, String userName);

      // @群里全部成员 @DingerText(value = “恭喜用户${loginName}登录成功!”, atAll = true) DingerResponse login(@Parameter(“loginName”) String userName);

  1. // wetalk不支持markdown格式的`@`功能
  2. @DingerMarkdown(
  3. value = "#### 注销登录 @13520200906 @13520200908 \n - 用户Id: ${uId}\n - 用户名: ${loginName}",
  4. title = "用户登录反馈",
  5. phones = {"13520200906", "13520200908"}
  6. )
  7. DingerResponse logout(@Parameter("uId") long userId, @Parameter("loginName") String userName);

}

  1. - xml配置<br />修改配置文件
  2. ```yaml
  3. spring:
  4. dinger:
  5. project-id: ${spring.application.name}
  6. dingers:
  7. # 使用钉钉机器人, 请根据自己机器人配置信息进行修改
  8. dingtalk:
  9. tokenId: tokenId
  10. secret: secret
  11. # 使用xml配置方式时, 必填
  12. dinger-locations: classpath*:dinger/*.xml


Dinger接口类

  1. public interface UserDinger {
  2. DingerResponse success(String userName);
  3. DingerResponse failed(long userId, String userName);
  4. DingerResponse login(@Parameter("loginName") String userName);
  5. DingerResponse logout(@Parameter("uId") long userId, @Parameter("loginName") String userName);
  6. }


Dinger消息XML定义

  1. <message id="success" type="TEXT">
  2. <body>
  3. <content>
  4. 恭喜用户${userName}登录成功!
  5. </content>
  6. <!-- `@`群里指定成员 -->
  7. <phones>
  8. <phone value="13520200906"/>
  9. </phones>
  10. </body>
  11. </message>
  12. <message id="failed" type="MARKDOWN">
  13. <body>
  14. <content title="用户登录反馈">
  15. #### 用户登录通知
  16. - 用户Id: ${userId}
  17. - 用户名: ${userName}
  18. </content>
  19. </body>
  20. </message>
  21. <message id="login" type="TEXT">
  22. <body>
  23. <content>
  24. 恭喜用户${loginName}登录成功!
  25. </content>
  26. <!-- `@`群里全部成员 -->
  27. <phones atAll="true" />
  28. </body>
  29. </message>
  30. <!-- wetalk不支持markdown格式的`@`功能 -->
  31. <message id="logout" type="MARKDOWN">
  32. <body>
  33. <content title="用户登录反馈">
  34. #### 注销登录 @13520200906 @13520200908
  35. - 用户Id: ${uId}
  36. - 用户名: ${loginName}
  37. </content>
  38. <!-- `@`群里指定成员 -->
  39. <phones>
  40. <phone value="13520200906"/>
  41. <phone value="13520200908"/>
  42. </phones>
  43. </body>
  44. </message>
  • 使用 ```java @RestController @Slf4j public class DemoController { @Autowired private UserDinger userDinger;

    @GetMapping(“/success”) public Response success() {

    1. return Response.success(
    2. userDinger.success("Jaemon")
    3. );

    }

    @GetMapping(“/failed”) public Response failed() {

    1. return Response.success(
    2. userDinger.failed(1, "AnswerAIL")
    3. );

    }

    @GetMapping(“/login”) public Response login() {

    1. return Response.success(
    2. userDinger.login("Jaemon")
    3. );

    } @GetMapping(“/logout”) public Response logout() {

    1. return Response.success(
    2. userDinger.logout(1,"AnswerAIL")
    3. );

    }

}

  1. <a name="09ba03c5"></a>
  2. #### 6. 支持的消息类型
  3. | 消息类型/Dinger类型 | DingTalk(钉钉) | WeTalk(企业微信) |
  4. | --- | --- | --- |
  5. | TEXT | √ | √ |
  6. | MARKDOWN | √ | √ |
  7. | IMAGETEXT | √ | √ |
  8. | LINK | √ | × |
  9. **图文、link方式使用**
  10. - 修改配置文件
  11. ```yaml
  12. spring:
  13. dinger:
  14. project-id: ${spring.application.name}
  15. default-dinger: dingtalk
  16. dinger-locations: classpath*:dinger/*.xml # xml方式下必须配置
  17. dingers:
  18. dingtalk:
  19. tokenId: tokenId
  20. secret: secret
  21. wetalk:
  22. tokenId: tokenId
  • 启动类引入DingerScan注解
    1. @SpringBootApplication
    2. @DingerScan(basePackages = "com.pig4cloud.pig.admin.dinger")
    3. public class DemoApplication {
    4. public static void main(String[] args) {
    5. SpringApplication.run(DemoApplication.class, args);
    6. }
    7. }
  • 定义Dinger

    • 注解方式 ```java public interface UserDinger { // 图文类型 @DingerImageText DingerResponse imageText(List images);

      // link类型, 只支持Dingtalk @DingerLink DingerResponse link(LinkDeo link);

}

  1. - xml方式<br />xml方式**必须**配置`dinger-locations`配置项
  2. ```java
  3. public interface UserDinger {
  4. DingerResponse imageText(List<ImageTextDeo> images);
  5. DingerResponse link(LinkDeo link);
  6. }
  • 使用

    1. @Component
    2. public class AppInit implements InitializingBean {
    3. @Autowired
    4. private UserDinger userDinger;
    5. @Override
    6. public void afterPropertiesSet() throws Exception {
    7. String picUrl = "http://pigx.pig4cloud.com/img/logo.png";
    8. List<ImageTextDeo> images = new ArrayList<>();
    9. images.add(
    10. ImageTextDeo.instance(
    11. "pig", "https://gitee.com/log4j/pig", picUrl
    12. )
    13. );
    14. // 发送图文类型消息
    15. userDinger.imageText(images);
    16. // 发送link类型消息, 只支持钉钉
    17. userDinger.link(
    18. LinkDeo.instance(
    19. "pig",
    20. "pig4cloud",
    21. "https://gitee.com/log4j/pig",
    22. picUrl
    23. )
    24. );
    25. }
    26. }

7. 个性化拓展配置

  • 独立配置

    1. 手动发送方式消息自定义

      1. @Component
      2. @Slf4j
      3. public class AppInit implements InitializingBean {
      4. @Autowired
      5. private DingerSender dingerSender;
      6. @Override
      7. public void afterPropertiesSet() throws Exception {
      8. // 发送text类型消息
      9. dingerSender.send(
      10. MessageSubType.TEXT,
      11. DingerRequest.request("Hello World, Hello Dinger")
      12. );
      13. // 发送markdown类型消息
      14. dingerSender.send(
      15. MessageSubType.MARKDOWN,
      16. DingerRequest.request("Hello World, Hello Dinger", "启动通知")
      17. );
      18. }
      19. }


      b. 其他扩展配置
      以下个性化配置项均可适用于手动发送和消息体统一管理方式 ```java @Configuration @Slf4j public class MyDingerConfiguration { // 自定义异步回调函数-用于异步发送时 @Bean public DingerAsyncCallback dingerAsyncCallback() { return (dingerId, result) -> {

      1. log.info("dingerId={}, response result={}.", dingerId, result);

      }; }

  1. // 自定义DingerId生成器, dingerId为每次调用返回体中的logid值
  2. @Bean
  3. public DingerIdGenerator dingerIdGenerator() {
  4. return () -> UUID.randomUUID().toString();
  5. }
  6. // 自定义异常回调函数
  7. @Bean
  8. public DingerExceptionCallback dingerExceptionCallback() {
  9. return dingerCallback -> {
  10. log.error("dingerId={}, message={}.",
  11. dingerCallback.getDkid(), dingerCallback.getMessage());
  12. };
  13. }
  14. // 自定义异步执行线程池
  15. @Bean
  16. public Executor dingerExecutor() {
  17. ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
  18. executor.setThreadNamePrefix("DingerAsync-");
  19. executor.setCorePoolSize(30);
  20. executor.setMaxPoolSize(30);
  21. executor.initialize();
  22. return executor;
  23. }
  24. // 自定义restTemplate客户端
  25. @Bean
  26. public RestTemplate dingerRestTemplate() {
  27. SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
  28. factory.setReadTimeout(100 * 1000);
  29. factory.setConnectTimeout(100 * 1000);
  30. return new RestTemplate(factory);
  31. }

}

  1. - 整体配置
  2. ```java
  3. @Configuration
  4. @Slf4j
  5. public class MyDingerConfiguration extends DingerConfigurerAdapter {
  6. @Override
  7. public void configure(DingerManagerBuilder config) throws Exception {
  8. config
  9. .textMessage(...)
  10. .markDownMessage(...)
  11. .dingerAsyncCallback(...)
  12. .dingerIdGenerator(...)
  13. .dingerExceptionCallback(...)
  14. .dingTalkExecutor(...)
  15. .dingerRestTemplate(...);
  16. }
  17. }

8. 注解说明

注解 功能描述 使用说明
@DingerScan 标识Dinger层扫描路径 在SpringBoot启动类中定义使用
@Dinger 指定当前XXXDinger使用的机器人类型 在XXXDinger.java接口类上
@DingerClose 用于关闭 XXXDinger.java 或者指定其中的一个至多个方法 XXXDinger.java接口层(接口类或接口方法上均可) - 作用于Dinger类上,关闭Dinger类中所有方法通知; - 作用于方法上, 关闭当前方法通知;
@AsyncExecute 用于 XXXDinger.java 层(注解和XML)级别异步发送 在XXXDinger.java接口类上
@DingerConfiguration 用于 XXXDinger.java 层(注解和XML)级别机器人信息配置 XXXDinger.java接口类上
@DingerText 注解方式定义Text消息体 XXXDinger.java接口层接口方法上
@DingerMarkdown 注解方式定义Markdown消息体 XXXDinger.java接口层接口方法上
@DingerImageText 注解方式定义图文类型消息体 XXXDinger.java接口层接口方法上
@DingerLink 注解方式定义Link类型消息体 XXXDinger.java接口层接口方法上
@Parameter 如果消息体中使用的参数变量和方法定义的参数名称不一致
,可使用该注解进行个性化设置参数变量名称
XXXDinger.java接口层接口方法参数上
@EnableMultiDinger 启动多钉钉机器人配置 在SpringBoot启动类中定义使用
@MultiHandler 为Dinger层指定对应的多机器人处理器 XXXDinger.java接口类上

❤ 问题咨询

手势点击蓝字求关注简约风动态引导关注__2022-09-07+23_18_38.gif