Implementing Secure DingTalk Robot Notifications in Spring Boot

Maven Dependencies

First, include the necessary dependencies for the web module and Lombok to reduce boilerplate code in the configuration classes.

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
</dependencies>

Configuration Properties

Create a configuration class to map the DingTalk Webhook URL and the signing secret from your application properties. This keeps sensitive data out of the business logic.

@Data
@Configuration
@ConfigurationProperties(prefix = "dingtalk.bot")
public class DingTalkProperties {
    private String webhook;
    private String secret;
}

Notification Service

Implement a service that handles the HmacSHA256 signature generation and constructs the HTTP request to the DingTalk API. This example uses Spring's RestTemplate for the request.

@Service
@RequiredArgsConstructor
public class NotificationService {
    private final DingTalkProperties properties;
    private final RestTemplate restTemplate = new RestTemplate();

    public void dispatchAlert(String content) {
        try {
            long timestamp = System.currentTimeMillis();
            String sign = computeSignature(timestamp, properties.getSecret());
            String targetUrl = properties.getWebhook() + "&timestamp=" + timestamp + "&sign=" + sign;

            Map<String, Object> payload = new HashMap<>();
            payload.put("msgtype", "text");
            Map<String, String> textBody = new HashMap<>();
            textBody.put("content", content);
            payload.put("text", textBody);

            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            HttpEntity<Map<String, Object>> entity = new HttpEntity<>(payload, headers);

            restTemplate.postForEntity(targetUrl, entity, String.class);
        } catch (Exception e) {
            throw new RuntimeException("Failed to send DingTalk notification", e);
        }
    }

    private String computeSignature(Long timestamp, String secret) throws Exception {
        String stringToSign = timestamp + "\n" + secret;
        Mac mac = Mac.getInstance("HmacSHA256");
        mac.init(new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
        byte[] signData = mac.doFinal(stringToSign.getBytes(StandardCharsets.UTF_8));
        return URLEncoder.encode(Base64.getEncoder().encodeToString(signData), StandardCharsets.UTF_8);
    }
}

REST Controller

Expose a simple endpoint to trigger the notification mechanism.

@RestController
@RequestMapping("/api/notify")
@RequiredArgsConstructor
public class AlertController {

    private final NotificationService notificationService;

    @GetMapping("/trigger")
    public ResponseEntity<String> sendTestMessage() {
        notificationService.dispatchAlert("Hello World: Integration test successful.");
        return ResponseEntity.ok("Notification sent successfully.");
    }
}

Tags: java spring-boot DingTalk Webhook Integration

Posted on Thu, 14 May 2026 16:59:42 +0000 by ld0121