|
|
@@ -18,6 +18,8 @@ import org.springframework.web.server.ResponseStatusException;
|
|
|
import jakarta.servlet.http.HttpServletRequest;
|
|
|
import jakarta.servlet.http.HttpServletResponse;
|
|
|
|
|
|
+import java.net.URLDecoder;
|
|
|
+import java.nio.charset.StandardCharsets;
|
|
|
import java.time.Instant;
|
|
|
import java.util.*;
|
|
|
import java.util.concurrent.Semaphore;
|
|
|
@@ -361,7 +363,7 @@ public class TrackingController {
|
|
|
|
|
|
private String mediaTraceId(Map<String, String> params) {
|
|
|
for (String key : List.of("click_id", "impression_id", "trace_id", "callback", "request_id",
|
|
|
- "oaid", "imei", "idfa", "caid")) {
|
|
|
+ "oaid", "imei", "idfa", "caid", "muid")) {
|
|
|
String v = params.get(key);
|
|
|
if (v != null && !v.isBlank()) return v;
|
|
|
}
|
|
|
@@ -465,15 +467,114 @@ public class TrackingController {
|
|
|
putUid(uid, "idfaMd5", firstParam(p, "idfa_md5", "idfaMd5"));
|
|
|
putUid(uid, "oaid", p.get("oaid"));
|
|
|
putUid(uid, "oaidMd5", firstParam(p, "oaid_md5", "oaidMd5", "hash_oaid"));
|
|
|
- // 百度ADX要求muid不能为空,Android用IMEI MD5,无则用oaidMd5或dpidMd5兜底
|
|
|
- String muid = firstParam(p, "muid", "imei_md5", "imeiMd5", "did_md5", "didMd5");
|
|
|
- if (muid == null || muid.isBlank()) {
|
|
|
- muid = firstParam(p, "hash_oaid", "oaid_md5", "oaidMd5", "hash_android_id", "dpid_md5", "dpidMd5");
|
|
|
+ List<Map<String, Object>> caid = baiduCaidFromParams(p);
|
|
|
+ if (!caid.isEmpty()) {
|
|
|
+ uid.put("caid", caid);
|
|
|
}
|
|
|
- putUid(uid, "muid", muid);
|
|
|
return uid;
|
|
|
}
|
|
|
|
|
|
+ private List<Map<String, Object>> baiduCaidFromParams(Map<String, String> params) {
|
|
|
+ String rawCaid = firstParam(params, "caid");
|
|
|
+ if (rawCaid == null || rawCaid.isBlank()) {
|
|
|
+ return Collections.emptyList();
|
|
|
+ }
|
|
|
+ List<Map<String, Object>> parsed = parseTencentCaid(rawCaid);
|
|
|
+ if (!parsed.isEmpty()) {
|
|
|
+ return parsed;
|
|
|
+ }
|
|
|
+
|
|
|
+ Map<String, Object> caidItem = new LinkedHashMap<>();
|
|
|
+ caidItem.put("id", rawCaid);
|
|
|
+ return List.of(caidItem);
|
|
|
+ }
|
|
|
+
|
|
|
+ private List<Map<String, Object>> parseTencentCaid(String rawCaid) {
|
|
|
+ String decoded = decodeCaid(rawCaid);
|
|
|
+ if (decoded == null || decoded.isBlank()) {
|
|
|
+ return Collections.emptyList();
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ Object value = objectMapper.readValue(decoded, Object.class);
|
|
|
+ if (value instanceof List<?> list) {
|
|
|
+ List<Map<String, Object>> result = new ArrayList<>();
|
|
|
+ for (Object item : list) {
|
|
|
+ Map<String, Object> caid = toBaiduCaidItem(item);
|
|
|
+ if (!caid.isEmpty()) result.add(caid);
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+ if (value instanceof Map<?, ?> map) {
|
|
|
+ Map<String, Object> caid = toBaiduCaidItem(map);
|
|
|
+ if (!caid.isEmpty()) {
|
|
|
+ return List.of(caid);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.debug("[腾讯][百度请求] caid parse failed raw={} decoded={}", rawCaid, decoded);
|
|
|
+ }
|
|
|
+ return Collections.emptyList();
|
|
|
+ }
|
|
|
+
|
|
|
+ private String decodeCaid(String rawCaid) {
|
|
|
+ try {
|
|
|
+ return URLDecoder.decode(rawCaid, StandardCharsets.UTF_8);
|
|
|
+ } catch (Exception e) {
|
|
|
+ return rawCaid;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private Map<String, Object> toBaiduCaidItem(Object source) {
|
|
|
+ if (!(source instanceof Map<?, ?> map)) {
|
|
|
+ return Collections.emptyMap();
|
|
|
+ }
|
|
|
+ String id = firstNonBlankValue(map, "qaid", "id", "caid");
|
|
|
+ if (id == null) {
|
|
|
+ return Collections.emptyMap();
|
|
|
+ }
|
|
|
+ Map<String, Object> caidItem = new LinkedHashMap<>();
|
|
|
+ caidItem.put("id", id);
|
|
|
+
|
|
|
+ String version = firstNonBlankValue(map, "version");
|
|
|
+ if (version != null) {
|
|
|
+ caidItem.put("version", version);
|
|
|
+ }
|
|
|
+ Long generateTime = firstLongValue(map, "generateTime");
|
|
|
+ if (generateTime != null) {
|
|
|
+ caidItem.put("generateTime", generateTime);
|
|
|
+ }
|
|
|
+ Long vendor = firstLongValue(map, "vendor");
|
|
|
+ if (vendor != null) {
|
|
|
+ caidItem.put("vendor", vendor);
|
|
|
+ }
|
|
|
+ return caidItem;
|
|
|
+ }
|
|
|
+
|
|
|
+ private String firstNonBlankValue(Map<?, ?> map, String... keys) {
|
|
|
+ for (String key : keys) {
|
|
|
+ Object value = map.get(key);
|
|
|
+ if (value == null) continue;
|
|
|
+ String text = String.valueOf(value).trim();
|
|
|
+ if (!text.isEmpty()) return text;
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ private Long firstLongValue(Map<?, ?> map, String... keys) {
|
|
|
+ for (String key : keys) {
|
|
|
+ Object value = map.get(key);
|
|
|
+ if (value == null) continue;
|
|
|
+ if (value instanceof Number n) {
|
|
|
+ return n.longValue();
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ return Long.parseLong(String.valueOf(value).trim());
|
|
|
+ } catch (NumberFormatException ignored) {
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
private void putUid(Map<String, Object> uid, String key, String value) {
|
|
|
if (value != null && !value.isBlank()) uid.put(key, value);
|
|
|
}
|