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() + "×tamp=" + 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.");
}
}