71 lines
3.0 KiB
Java
71 lines
3.0 KiB
Java
package com.iot.gateway.webhook;
|
|
|
|
import com.iot.gateway.entity.OpenWebhook;
|
|
import com.iot.gateway.mapper.OpenWebhookMapper;
|
|
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.List;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.stereotype.Service;
|
|
|
|
@Slf4j
|
|
@Service
|
|
public class WebhookDispatchService {
|
|
|
|
@Autowired
|
|
private OpenWebhookMapper webhookMapper;
|
|
|
|
private final HttpClient httpClient = HttpClient.newBuilder()
|
|
.connectTimeout(Duration.ofSeconds(5))
|
|
.build();
|
|
|
|
public void dispatchAlarm(Long tenantId, String title, String content) {
|
|
List<OpenWebhook> channels = webhookMapper.selectList(null).stream()
|
|
.filter(w -> w.getStatus() == 1 && (w.getTenantId().equals(tenantId) || tenantId == null))
|
|
.filter(w -> w.getEvents() != null && w.getEvents().contains("device.alarm"))
|
|
.toList();
|
|
|
|
for (OpenWebhook ch : channels) {
|
|
sendAsync(ch, title, content);
|
|
}
|
|
}
|
|
|
|
public boolean sendDirect(String channelType, String webhookUrl, String title, String content) {
|
|
String payload = formatMessage(channelType, title, content);
|
|
try {
|
|
HttpRequest request = HttpRequest.newBuilder()
|
|
.uri(URI.create(webhookUrl))
|
|
.header("Content-Type", "application/json; charset=utf-8")
|
|
.timeout(Duration.ofSeconds(5))
|
|
.POST(HttpRequest.BodyPublishers.ofString(payload))
|
|
.build();
|
|
HttpResponse<String> resp = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
|
|
return resp.statusCode() >= 200 && resp.statusCode() < 300;
|
|
} catch (Exception e) {
|
|
log.warn("发送 Webhook 消息失败: url={}, err={}", webhookUrl, e.getMessage());
|
|
return false;
|
|
}
|
|
}
|
|
|
|
private void sendAsync(OpenWebhook webhook, String title, String content) {
|
|
new Thread(() -> sendDirect(webhook.getChannelType(), webhook.getWebhookUrl(), title, content)).start();
|
|
}
|
|
|
|
private String formatMessage(String type, String title, String content) {
|
|
String safeTitle = title != null ? title.replace("\"", "\\\"") : "IoT 平台通知";
|
|
String safeContent = content != null ? content.replace("\"", "\\\"") : "";
|
|
|
|
if ("wechat_work".equalsIgnoreCase(type) || "dingtalk".equalsIgnoreCase(type)) {
|
|
return "{\"msgtype\":\"text\",\"text\":{\"content\":\"" + safeTitle + "\\n" + safeContent + "\"}}";
|
|
} else if ("feishu".equalsIgnoreCase(type)) {
|
|
return "{\"msg_type\":\"text\",\"content\":{\"text\":\"" + safeTitle + "\\n" + safeContent + "\"}}";
|
|
} else {
|
|
return "{\"title\":\"" + safeTitle + "\",\"content\":\"" + safeContent + "\",\"time\":" + System.currentTimeMillis() + "}";
|
|
}
|
|
}
|
|
}
|