yumeng 3 недель назад
Родитель
Сommit
2a36ef592c

+ 1 - 1
src/main/java/com/adx/tencent/storage/TiDBColdStore.java

@@ -206,7 +206,7 @@ public class TiDBColdStore {
                 record.getCallbackUrl(), record.getEventType(), record.getEventTimeMs(),
                 record.getCallbackUrl(), record.getEventType(), record.getEventTimeMs(),
                 record.getPurchase(), record.getStatus(), record.isOk() ? 1 : 0,
                 record.getPurchase(), record.getStatus(), record.isOk() ? 1 : 0,
                 attempt, record.getResponseBody(), record.getErrorMessage(),
                 attempt, record.getResponseBody(), record.getErrorMessage(),
-                Timestamp.from(record.getCreatedAt())
+                record.getRequestBody(), Timestamp.from(record.getCreatedAt())
             );
             );
         }
         }
     }
     }

+ 1 - 0
src/main/java/com/adx/tencent/storage/mapper/MediaCallbackMapper.java

@@ -20,6 +20,7 @@ public interface MediaCallbackMapper {
                 @Param("attempt") int attempt,
                 @Param("attempt") int attempt,
                 @Param("responseBody") String responseBody,
                 @Param("responseBody") String responseBody,
                 @Param("errorMessage") String errorMessage,
                 @Param("errorMessage") String errorMessage,
+                @Param("requestBody") String requestBody,
                 @Param("createdAt") java.sql.Timestamp createdAt);
                 @Param("createdAt") java.sql.Timestamp createdAt);
 
 
     int countSuccessfulByDedupeKey(@Param("dedupeKey") String dedupeKey);
     int countSuccessfulByDedupeKey(@Param("dedupeKey") String dedupeKey);

+ 12 - 14
src/main/java/com/adx/tencent/tencent/TencentClient.java

@@ -167,24 +167,14 @@ public class TencentClient {
 
 
     /**
     /**
      * 构造 callback POST 请求,始终携带鉴权 header。
      * 构造 callback POST 请求,始终携带鉴权 header。
-     * 2025-03-31 起腾讯不再支持 HTTP 无鉴权上报,所有请求均需鉴权。
      */
      */
     private HttpRequest buildCallbackRequest(String callbackUrl, byte[] payload) {
     private HttpRequest buildCallbackRequest(String callbackUrl, byte[] payload) {
-        // 强制 https(兼容旧的 http://tracking.e.qq.com 格式)
-        String url = callbackUrl;
-        if (url.startsWith("http://tracking.e.qq.com")) {
-            url = url.replace("http://tracking.e.qq.com", "https://api.e.qq.com");
-        } else if (url.startsWith("http://")) {
-            url = url.replace("http://", "https://");
-        }
-
         HttpRequest.Builder reqBuilder = HttpRequest.newBuilder()
         HttpRequest.Builder reqBuilder = HttpRequest.newBuilder()
-                .uri(URI.create(url))
+                .uri(URI.create(callbackUrl))
                 .POST(HttpRequest.BodyPublishers.ofByteArray(payload))
                 .POST(HttpRequest.BodyPublishers.ofByteArray(payload))
                 .header("Content-Type", "application/json")
                 .header("Content-Type", "application/json")
                 .timeout(Duration.ofSeconds(15));
                 .timeout(Duration.ofSeconds(15));
 
 
-        // 始终添加鉴权 header
         String currentToken = accessTokenSupplier.get();
         String currentToken = accessTokenSupplier.get();
         if (currentToken != null && !currentToken.isBlank()) {
         if (currentToken != null && !currentToken.isBlank()) {
             long timestamp = Instant.now().getEpochSecond();
             long timestamp = Instant.now().getEpochSecond();
@@ -255,12 +245,20 @@ public class TencentClient {
             UserAction.ActionParam param = new UserAction.ActionParam();
             UserAction.ActionParam param = new UserAction.ActionParam();
             param.setValue((int) (payment.getPayment() * 100)); // 分
             param.setValue((int) (payment.getPayment() * 100)); // 分
             action.setActionParam(param);
             action.setActionParam(param);
+        } else if ("START_APP".equals(actionType)) {
+            // 留存行为必须带 length_of_stay(文档要求)
+            UserAction.ActionParam param = new UserAction.ActionParam();
+            int lengthOfStay = switch (payment.getAct()) {
+                case 8 -> 7;   // 7日留存
+                case 9 -> 3;   // 3日留存
+                default -> 1;  // 次日留存 (act=4 或其他)
+            };
+            param.setLengthOfStay(lengthOfStay);
+            action.setActionParam(param);
         } else if ("CUSTOM".equals(actionType)) {
         } else if ("CUSTOM".equals(actionType)) {
             UserAction.ActionParam param = new UserAction.ActionParam();
             UserAction.ActionParam param = new UserAction.ActionParam();
             String customAction = switch (payment.getAct()) {
             String customAction = switch (payment.getAct()) {
-                case 7 -> "key_behavior";
-                case 8 -> "7day_retention";
-                case 9 -> "3day_retention";
+                case 7 -> "UV_CORE_ACTION";  // 关键行为(文档标准值)
                 default -> "custom_" + payment.getAct();
                 default -> "custom_" + payment.getAct();
             };
             };
             param.setCustomAction(customAction);
             param.setCustomAction(customAction);

+ 5 - 0
src/main/java/com/adx/tencent/tencent/model/UserAction.java

@@ -56,11 +56,16 @@ public class UserAction {
         @JsonProperty("value")
         @JsonProperty("value")
         private Integer value;
         private Integer value;
 
 
+        @JsonProperty("length_of_stay")
+        private Integer lengthOfStay;
+
         @JsonProperty("custom_action")
         @JsonProperty("custom_action")
         private String customAction;
         private String customAction;
 
 
         public Integer getValue() { return value; }
         public Integer getValue() { return value; }
         public void setValue(Integer v) { this.value = v; }
         public void setValue(Integer v) { this.value = v; }
+        public Integer getLengthOfStay() { return lengthOfStay; }
+        public void setLengthOfStay(Integer v) { this.lengthOfStay = v; }
         public String getCustomAction() { return customAction; }
         public String getCustomAction() { return customAction; }
         public void setCustomAction(String v) { this.customAction = v; }
         public void setCustomAction(String v) { this.customAction = v; }
     }
     }

+ 4 - 4
src/main/resources/application-dev.yml

@@ -23,7 +23,7 @@ adx:
     "2": PURCHASE          # 付费
     "2": PURCHASE          # 付费
     "3": REGISTER          # 注册
     "3": REGISTER          # 注册
     "5": COMPLETE_ORDER    # 完成订单
     "5": COMPLETE_ORDER    # 完成订单
-    "6": START_APP         # 启动应用
+    "6": OPTIMIZATIONGOAL_PROMOTION_VIEW_KEY_PAGE_UV         # 启动应用
     "7": CUSTOM            # 自定义-关键行为
     "7": CUSTOM            # 自定义-关键行为
     "8": CUSTOM            # 自定义-7日留存
     "8": CUSTOM            # 自定义-7日留存
     "9": CUSTOM            # 自定义-3日留存
     "9": CUSTOM            # 自定义-3日留存
@@ -40,11 +40,11 @@ adx:
   tidb-password: "hcst@2025"
   tidb-password: "hcst@2025"
 
 
   # --- Task ---
   # --- Task ---
-  skip-leader-election: false
+  skip-leader-election: true
 
 
   # --- Conversion Sync ---
   # --- Conversion Sync ---
-  conversion-sync-enabled: false
+  conversion-sync-enabled: true
   conversion-sync-interval: 30s
   conversion-sync-interval: 30s
 
 
   # --- Callback Retry ---
   # --- Callback Retry ---
-  callback-retry-enabled: false
+  callback-retry-enabled: true

+ 9 - 9
src/main/resources/application-prod.yml

@@ -20,15 +20,15 @@ adx:
   tencent-android-user-action-set-id: 1222435591
   tencent-android-user-action-set-id: 1222435591
   tencent-ios-user-action-set-id: 1222435768
   tencent-ios-user-action-set-id: 1222435768
   tencent-act-map:
   tencent-act-map:
-    "1": ACTIVATE_APP
-    "2": PURCHASE
-    "3": REGISTER
-    "4": ONE_DAY_RETENTION
-    "5": COMPLETE_ORDER
-    "6": OPTIMIZATIONGOAL_PROMOTION_VIEW_KEY_PAGE
-    "7": CUSTOM
-    "8": CUSTOM
-    "9": CUSTOM
+    "1": ACTIVATE_APP          # 激活
+    "2": PURCHASE              # 付费
+    "3": REGISTER              # 注册
+    "4": START_APP             # 次日留存 (length_of_stay=1)
+    "5": COMPLETE_ORDER        # 下单
+    "6": VIEW_CONTENT          # 关键页面访问
+    "7": CUSTOM                # 关键行为
+    "8": START_APP             # 7日留存 (length_of_stay=7)
+    "9": START_APP             # 3日留存 (length_of_stay=3)
 
 
   # --- Redis ---
   # --- Redis ---
   redis-addr: "172.30.0.25:6379"
   redis-addr: "172.30.0.25:6379"

+ 1 - 1
src/main/resources/logback-spring.xml

@@ -50,7 +50,7 @@
             <appender-ref ref="CONSOLE"/>
             <appender-ref ref="CONSOLE"/>
             <appender-ref ref="FILE"/>
             <appender-ref ref="FILE"/>
         </root>
         </root>
-        <logger name="com.adx.tencent" level="DEBUG"/>
+        <logger name="com.adx.tencent" level="INFO"/>
     </springProfile>
     </springProfile>
 
 
     <!-- ============ 测试环境 ============ -->
     <!-- ============ 测试环境 ============ -->