| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191 |
- package com.adx.tencent.honor;
- import com.adx.tencent.baidu.model.PaymentInfo;
- import com.adx.tencent.honor.model.HonorBidRecord;
- import com.adx.tencent.honor.model.HonorMediaCallbackRecord;
- import com.fasterxml.jackson.databind.ObjectMapper;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import java.net.URI;
- import java.net.URLEncoder;
- import java.net.http.HttpClient;
- import java.net.http.HttpRequest;
- import java.net.http.HttpResponse;
- import java.nio.charset.StandardCharsets;
- import java.time.Duration;
- import java.time.Instant;
- import java.util.LinkedHashMap;
- import java.util.Locale;
- import java.util.Map;
- public class HonorClient {
- private static final Logger log = LoggerFactory.getLogger(HonorClient.class);
- private static final String FIXED_CHANNEL_ID = "9";
- private final String baseUrl;
- private final ObjectMapper objectMapper;
- private final HttpClient httpClient;
- public HonorClient(String baseUrl, String channelId, ObjectMapper objectMapper) {
- this.baseUrl = (baseUrl == null || baseUrl.isBlank())
- ? "https://ads-drcn.platform.hihonorcloud.com"
- : baseUrl.replaceAll("/+$", "");
- this.objectMapper = objectMapper;
- this.httpClient = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
- }
- public HonorMediaCallbackRecord sendConversion(HonorBidRecord bid, PaymentInfo payment, int conversionId) {
- HonorMediaCallbackRecord record = new HonorMediaCallbackRecord();
- record.setQk(payment.getQk());
- record.setTagId(bid.getTagId());
- record.setEventType(payment.getAct());
- record.setPurchase(payment.getPayment());
- record.setAttempt(1);
- record.setCreatedAt(Instant.now());
- Map<String, String> params = buildParams(bid, payment, conversionId);
- String callbackUrl = baseUrl + "/api/ad-tracking/v1/conversion?" + toQuery(params);
- record.setCallbackUrl(callbackUrl);
- record.setRequestBody(toJson(params));
- record.setEventTimeMs(Long.parseLong(params.get("conversionTime")));
- try {
- HttpRequest request = HttpRequest.newBuilder()
- .uri(URI.create(callbackUrl))
- .GET()
- .timeout(Duration.ofSeconds(15))
- .build();
- HttpResponse<byte[]> response = httpClient.send(request, HttpResponse.BodyHandlers.ofByteArray());
- String body = new String(response.body(), StandardCharsets.UTF_8);
- record.setStatus(response.statusCode());
- record.setResponseBody(body);
- record.setOk(response.statusCode() >= 200 && response.statusCode() < 300);
- if (!record.isOk()) {
- record.setErrorMessage("HTTP status: " + response.statusCode());
- }
- log.info("[Honor] callback结果: qk={}, tagId={}, conversionId={}, status={}, ok={}, response={}",
- payment.getQk(), bid.getTagId(), conversionId, response.statusCode(), record.isOk(), body);
- } catch (Exception e) {
- record.setOk(false);
- record.setErrorMessage(e.getMessage());
- log.warn("[Honor] callback失败: qk={}, tagId={}, conversionId={}, error={}",
- payment.getQk(), bid.getTagId(), conversionId, e.getMessage());
- }
- return record;
- }
- public HonorMediaCallbackRecord retryCallback(HonorMediaCallbackRecord original) throws Exception {
- HonorMediaCallbackRecord retry = copy(original);
- retry.setAttempt(original.getAttempt() + 1);
- retry.setCreatedAt(Instant.now());
- HttpRequest request = HttpRequest.newBuilder()
- .uri(URI.create(original.getCallbackUrl()))
- .GET()
- .timeout(Duration.ofSeconds(15))
- .build();
- HttpResponse<byte[]> response = httpClient.send(request, HttpResponse.BodyHandlers.ofByteArray());
- retry.setStatus(response.statusCode());
- retry.setResponseBody(new String(response.body(), StandardCharsets.UTF_8));
- retry.setOk(response.statusCode() >= 200 && response.statusCode() < 300);
- if (!retry.isOk()) retry.setErrorMessage("HTTP status: " + response.statusCode());
- return retry;
- }
- private Map<String, String> buildParams(HonorBidRecord bid, PaymentInfo payment, int conversionId) {
- Map<String, String> mediaParams = bid.getMediaParams();
- long monitorTime = parseLong(mediaParams, "eventTime");
- long conversionTime = Math.max(Instant.now().toEpochMilli(), monitorTime + 1);
- Map<String, String> params = new LinkedHashMap<>();
- put(params, "trackId", value(mediaParams, "trackId"));
- params.put("conversionId", String.valueOf(conversionId));
- params.put("conversionTime", String.valueOf(conversionTime));
- put(params, "advertiserId", value(mediaParams, "advertiserId"));
- put(params, "oaid", value(mediaParams, "oaid"));
- params.put("id_type", "0");
- params.put("channelId", FIXED_CHANNEL_ID);
- put(params, "pkgName", firstNonBlank(value(mediaParams, "pkgName"), bid.getPackageName()));
- put(params, "extra", urlEncode("{\"tagId\":\"" + bid.getTagId() + "\"}"));
- if (conversionId == 10004) {
- params.put("payAmount", String.format(Locale.ROOT, "%.2f",
- payment.getGmv() > 0 ? payment.getGmv() : payment.getPayment()));
- put(params, "orderId", buildOrderId(payment));
- }
- return params;
- }
- private static HonorMediaCallbackRecord copy(HonorMediaCallbackRecord src) {
- HonorMediaCallbackRecord copy = new HonorMediaCallbackRecord();
- copy.setDedupeKey(src.getDedupeKey());
- copy.setQk(src.getQk());
- copy.setTagId(src.getTagId());
- copy.setCallbackUrl(src.getCallbackUrl());
- copy.setEventType(src.getEventType());
- copy.setEventTimeMs(src.getEventTimeMs());
- copy.setPurchase(src.getPurchase());
- copy.setStatus(src.getStatus());
- copy.setOk(src.isOk());
- copy.setAttempt(src.getAttempt());
- copy.setResponseBody(src.getResponseBody());
- copy.setErrorMessage(src.getErrorMessage());
- copy.setRequestBody(src.getRequestBody());
- copy.setCreatedAt(src.getCreatedAt());
- return copy;
- }
- private String toJson(Object value) {
- try {
- return objectMapper.writeValueAsString(value);
- } catch (Exception e) {
- return String.valueOf(value);
- }
- }
- private static String toQuery(Map<String, String> params) {
- StringBuilder sb = new StringBuilder();
- boolean first = true;
- for (Map.Entry<String, String> entry : params.entrySet()) {
- if (entry.getValue() == null || entry.getValue().isBlank()) continue;
- if (!first) sb.append('&');
- first = false;
- sb.append(urlEncode(entry.getKey())).append('=').append(urlEncode(entry.getValue()));
- }
- return sb.toString();
- }
- private static String urlEncode(String value) {
- return URLEncoder.encode(value, StandardCharsets.UTF_8);
- }
- private static void put(Map<String, String> params, String key, String value) {
- if (value != null && !value.isBlank()) params.put(key, value);
- }
- private static String value(Map<String, String> params, String key) {
- return params != null ? params.get(key) : null;
- }
- private static long parseLong(Map<String, String> params, String key) {
- try {
- return Long.parseLong(value(params, key));
- } catch (Exception e) {
- return 0L;
- }
- }
- private static String firstNonBlank(String... values) {
- for (String value : values) {
- if (value != null && !value.isBlank()) return value;
- }
- return null;
- }
- private static String buildOrderId(PaymentInfo payment) {
- String raw = (payment.getTu() != null ? payment.getTu() : "")
- + "_" + (payment.getQk() != null ? payment.getQk() : "")
- + "_" + payment.getAct();
- return raw.length() <= 64 ? raw : raw.substring(0, 64);
- }
- }
|