XuqmGroup-Server/push-service/src/main/java/com/xuqm/push/service/ImPresenceClient.java
XuqmGroup 99d6a8d6a4 feat(push): 添加多厂商推送集成支持
- 实现了华为 HMS 推送服务集成
- 实现了小米推送服务集成
- 实现了 OPPO 推送服务集成
- 实现了 vivo 推送服务集成
- 实现了荣耀推送服务集成
- 实现了 FCM 推送服务集成
- 添加了统一的厂商推送接口和检测机制
- 添加了推送配置 API 和存储管理
- 添加了推送令牌管理和设备注册功能
- 添加了模拟器环境的推送测试用例
2026-05-05 17:54:59 +08:00

91 行
3.3 KiB
Java

package com.xuqm.push.service;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;
import java.util.Map;
import java.util.Optional;
@Component
public class ImPresenceClient {
private final RestTemplate restTemplate = new RestTemplate();
private final ObjectMapper objectMapper;
@Value("${push.im-service-base-url:http://im-service:8082}")
private String imServiceBaseUrl;
@Value("${push.internal-token:xuqm-internal-token}")
private String internalToken;
public ImPresenceClient(ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
}
public Optional<PresenceStatus> resolveToken(String token) {
try {
HttpHeaders headers = internalHeaders();
HttpEntity<String> request = new HttpEntity<>(
objectMapper.writeValueAsString(Map.of("token", token)),
headers);
String body = restTemplate.postForObject(
imServiceBaseUrl + "/api/im/internal/presence/resolve-token",
request,
String.class);
return parse(body);
} catch (Exception ignored) {
return Optional.empty();
}
}
public Optional<PresenceStatus> userStatus(String appId, String userId) {
try {
HttpHeaders headers = internalHeaders();
HttpEntity<Void> request = new HttpEntity<>(headers);
String uri = UriComponentsBuilder.fromHttpUrl(imServiceBaseUrl + "/api/im/internal/presence/users/{userId}")
.queryParam("appId", appId)
.build(userId)
.toString();
String body = restTemplate.exchange(
uri,
org.springframework.http.HttpMethod.GET,
request,
String.class).getBody();
return parse(body);
} catch (Exception ignored) {
return Optional.empty();
}
}
private HttpHeaders internalHeaders() {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.set("X-Internal-Token", internalToken);
return headers;
}
private Optional<PresenceStatus> parse(String body) throws Exception {
if (body == null || body.isBlank()) {
return Optional.empty();
}
JsonNode data = objectMapper.readTree(body).path("data");
if (data.isMissingNode() || data.isNull()) {
return Optional.empty();
}
return Optional.of(new PresenceStatus(
data.path("appId").asText(null),
data.path("userId").asText(null),
data.path("online").asBoolean(false),
data.path("lastSeenAt").asLong(0L)));
}
public record PresenceStatus(String appId, String userId, boolean online, long lastSeenAt) {}
}