浏览代码

监测链接检查任务

syh 4 年之前
父节点
当前提交
02173f3bad

+ 93 - 0
jeecg-boot-module-system/src/test/java/org/jeecg/SampleTest.java

@@ -12,8 +12,12 @@ import cn.com.ctop.common.module.service.*;
 import cn.com.ctop.common.module.utils.CtopAdConstant;
 import cn.com.ctop.kuaishou.modules.graphql.service.IKuaishouWebInterfaceService;
 import cn.com.ctop.kuaishou.modules.report.service.IKuaishouReportDailyAgentService;
+import cn.com.ctop.toutiao.modules.material.entity.ByteDanceAdvertisePlan;
+import cn.com.ctop.toutiao.modules.material.service.IByteDanceAdvertisePlanService;
 import cn.com.ctop.toutiao.modules.material.service.IByteDanceAdvertiserDataService;
+import cn.com.ctop.toutiao.modules.material.service.IByteDanceCreativeService;
 import cn.com.ctop.toutiao.modules.report.service.IReportService;
+import com.alibaba.fastjson.JSONObject;
 import lombok.extern.slf4j.Slf4j;
 import org.jeecg.common.util.DateUtils;
 import org.junit.Test;
@@ -27,6 +31,7 @@ import java.io.File;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
@@ -49,6 +54,7 @@ public class SampleTest {
     @Test
     public void loadBytedanceCreativeData() {
         List<UserAllocation>allocations = userAllocationService.getByParams(633L,null,0);
+
         if(null!=allocations&&!allocations.isEmpty()){
             for (UserAllocation allocation:allocations) {
                 CtopOauthToken token = oauthTokenService.getTokenByAccountId(allocation.getAccountId());
@@ -58,6 +64,93 @@ public class SampleTest {
     }
 
     @Autowired
+    private IByteDanceAdvertisePlanService advertisePlanService;
+    @Autowired
+    private IByteDanceCreativeService creativeService;
+    @Test
+    public void checkBytedanceCreativeMonitorLink() {
+        UserAllocation allocation = allocationService.getByAccountId(1655865770409997L);
+//        advertiserDataService.getAdvertiserPlan(token, "", null, null);
+        List<ByteDanceAdvertisePlan> plans = advertisePlanService.getAllPlans(allocation.getAccountId());
+        if(null!=plans&&!plans.isEmpty()){
+            for (ByteDanceAdvertisePlan plan:plans) {
+                Map<String, Object> creativeDetail = creativeService.getCreativeDetail(allocation.getAccountId(), plan.getId());
+                if(null!=creativeDetail.get("data")){
+                    JSONObject data = (JSONObject) creativeDetail.get("data");
+                    System.out.println(data.toJSONString());
+                    checkMonitorLink(data,plan,allocation);
+                }
+            }
+        }
+    }
+
+    private void checkMonitorLink(JSONObject data, ByteDanceAdvertisePlan plan, UserAllocation allocation) {
+        String downloadUrl = plan.getDownloadUrl();
+        boolean errorflag = false;
+        String errorMsg = "";
+        String token = plan.getName().split("-")[0];
+        String tokenInfo = "surl_token="+token;
+        String appType = plan.getAppType();
+
+        if(null!=downloadUrl){
+            if(null!=appType&&appType.equals("APP_IOS")){
+                if(!downloadUrl.equals("https://apps.apple.com/cn/app/id1468454200")){
+                    errorMsg+= "应用下载链接填写异常;";
+                    errorflag = true;
+                }
+            }
+            if(null!=appType&&appType.equals("APP_ANDROID")){
+                if(!downloadUrl.contains(token)){
+                    errorMsg+= "应用下载链接填写异常;";
+                    errorflag = true;
+                }
+            }
+        }
+        //展示监测链接
+        String trackUrl = data.getString("trackUrl");
+        if(null!=trackUrl&&!trackUrl.trim().equals("")){
+            if(!trackUrl.contains(tokenInfo)){
+                errorMsg+= "展示监测链接填写异常;";
+                errorflag = true;
+            }
+        }
+        //点击监测链接
+        String actionTrackUrl = data.getString("actionTrackUrl");
+        if(null!=actionTrackUrl&&!actionTrackUrl.trim().equals("")){
+            if(null!=appType&&appType.equals("APP_IOS")){
+                if(!actionTrackUrl.contains(tokenInfo)||!actionTrackUrl.contains("app_platform=ios")){
+                    errorMsg+= "点击监测链接填写异常;";
+                    errorflag = true;
+                }
+            }
+            if(null!=appType&&appType.equals("APP_ANDROID")){
+                if(!actionTrackUrl.contains(tokenInfo)||!actionTrackUrl.contains("tt/1967")){
+                    errorMsg+= "点击监测链接填写异常;";
+                    errorflag = true;
+                }
+            }
+        }
+        //视频有效播放监测链接
+        String videoPlayEffectiveTrackUrl = data.getString("videoPlayEffectiveTrackUrl");
+        if(null!=videoPlayEffectiveTrackUrl&&!videoPlayEffectiveTrackUrl.trim().equals("")){
+            if(!actionTrackUrl.contains(tokenInfo)){
+                errorMsg+= "视频有效播放监测链接填写异常;";
+                errorflag = true;
+            }
+        }
+        if(errorflag){
+            sendMessage(allocation,"警告:账户:"+allocation.getAuthName()+"(id:"+allocation.getAccountId()+")下的广告计划:"+plan.getName()+"(id:"+plan.getId()+")"+"监测链接异常>>"+errorMsg);
+        }
+    }
+
+    @Autowired
+    private ISendMessageService sendMessageService;
+    private void sendMessage(UserAllocation allocation, String errorMsg) {
+        sendMessageService.sendMessage(allocation.getUserId(),errorMsg);
+    }
+
+
+    @Autowired
     private IBindAccountLoginService bindAccountLoginService;
     @Autowired
     private IKuaishouWebInterfaceService kuaishouWebInterfaceService;

+ 1 - 0
module-common/src/main/java/cn/com/ctop/common/module/entity/Project.java

@@ -114,6 +114,7 @@ public class Project {
      * 最高深度转化出价
      */
     private BigDecimal maxDeepCpaBid;
+    private Integer checkLink;
     /**
      * 创建时间
      */

+ 3 - 0
module-common/src/main/java/cn/com/ctop/common/module/service/IProjectService.java

@@ -3,6 +3,8 @@ package cn.com.ctop.common.module.service;
 import cn.com.ctop.common.module.entity.Project;
 import com.baomidou.mybatisplus.extension.service.IService;
 
+import java.util.List;
+
 /**
  * 项目
  *
@@ -12,4 +14,5 @@ import com.baomidou.mybatisplus.extension.service.IService;
  */
 public interface IProjectService extends IService<Project> {
 
+    List<Project> listByMediaType(int projectType,int checkLink);
 }

+ 11 - 0
module-common/src/main/java/cn/com/ctop/common/module/service/impl/ProjectServiceImpl.java

@@ -3,9 +3,12 @@ package cn.com.ctop.common.module.service.impl;
 import cn.com.ctop.common.module.entity.Project;
 import cn.com.ctop.common.module.mapper.ProjectMapper;
 import cn.com.ctop.common.module.service.IProjectService;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import org.springframework.stereotype.Service;
 
+import java.util.List;
+
 /**
  * 项目
  *
@@ -16,4 +19,12 @@ import org.springframework.stereotype.Service;
 @Service
 public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> implements IProjectService {
 
+    @Override
+    public List<Project> listByMediaType(int projectType,int checkLink) {
+        QueryWrapper<Project>queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq("media_id",projectType);
+        queryWrapper.eq("checkLink",checkLink);
+        queryWrapper.orderByDesc("id");
+        return this.list(queryWrapper);
+    }
 }

+ 1 - 0
module-common/src/main/java/cn/com/ctop/common/module/utils/StatusCode.java

@@ -21,6 +21,7 @@ public enum StatusCode {
     COMMON_SUCCESS("操作成功", 0, true),
     COMMON_PARAM_ERROR("参数异常", -1, false),
     COMMON_ACCOUNT_ERROR("参数异常", -2, false),
+    COMMON_INTERNET_ERROR("网络请求异常", -3, false),
     COMMON_DATA_NOT_EXIST("数据不存在或者已经被删除", -101, false),
     BYTEDANCE_PLAN_DATA_NOT_EXIST("此计划不存在或者已经被删除", -101, false),
     BYTEDANCE_ACCOUNT_DATA_NOT_EXIST("此账户尚未绑定或已停投", -101, false),

+ 124 - 0
module-job-bytedance/src/main/java/cn/com/ctop/job/bytedance/handler/BytedanceMonitoringLinksCheckJob.java

@@ -0,0 +1,124 @@
+package cn.com.ctop.job.bytedance.handler;
+
+import cn.com.ctop.common.module.entity.Project;
+import cn.com.ctop.common.module.entity.UserAllocation;
+import cn.com.ctop.common.module.service.ICtopOauthTokenService;
+import cn.com.ctop.common.module.service.IProjectService;
+import cn.com.ctop.common.module.service.ISendMessageService;
+import cn.com.ctop.common.module.service.IUserAllocationService;
+import cn.com.ctop.toutiao.modules.material.entity.ByteDanceAdvertisePlan;
+import cn.com.ctop.toutiao.modules.material.service.IByteDanceAdvertisePlanService;
+import cn.com.ctop.toutiao.modules.material.service.IByteDanceCreativeService;
+import com.alibaba.fastjson.JSONObject;
+import com.xxl.job.core.biz.model.ReturnT;
+import com.xxl.job.core.handler.annotation.XxlJob;
+import com.xxl.job.core.log.XxlJobLogger;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.util.List;
+import java.util.Map;
+
+public class BytedanceMonitoringLinksCheckJob {
+    @Autowired
+    private ICtopOauthTokenService tokenService;
+    @Autowired
+    private IUserAllocationService allocationService;
+    @Autowired
+    private IByteDanceAdvertisePlanService advertisePlanService;
+    @Autowired
+    private IByteDanceCreativeService creativeService;
+    @Autowired
+    private ISendMessageService sendMessageService;
+    @Autowired
+    private IProjectService projectService;
+
+    @XxlJob("bytedanceMaterialsLoadJob")
+    public ReturnT<String> execute(String param) throws Exception{
+        List<Project> projects = projectService.listByMediaType(3,1);
+        if(null==projects||projects.isEmpty()){
+            return ReturnT.SUCCESS;
+        }
+        for (Project project:projects) {
+            List<UserAllocation>allocations = allocationService.getByParams(project.getId(),null,0);
+            if(null==allocations||allocations.isEmpty()){
+                continue;
+            }
+            for(UserAllocation allocation:allocations){
+                List<ByteDanceAdvertisePlan> plans = advertisePlanService.getAllPlans(allocation.getAccountId());
+                if(null!=plans&&!plans.isEmpty()){
+                    for (ByteDanceAdvertisePlan plan:plans) {
+                        Map<String, Object> creativeDetail = creativeService.getCreativeDetail(allocation.getAccountId(), plan.getId());
+                        if(null!=creativeDetail.get("data")){
+                            JSONObject data = (JSONObject) creativeDetail.get("data");
+                            checkMonitorLink(data,plan,allocation);
+                        }
+                    }
+                }
+            }
+        }
+        XxlJobLogger.log("监测链接检查完成");
+        return ReturnT.SUCCESS;
+    }
+
+    private void checkMonitorLink(JSONObject data, ByteDanceAdvertisePlan plan, UserAllocation allocation) {
+        String downloadUrl = plan.getDownloadUrl();
+        boolean errorflag = false;
+        String errorMsg = "";
+        String token = plan.getName().split("-")[0];
+        String tokenInfo = "surl_token="+token;
+        String appType = plan.getAppType();
+
+        if(null!=downloadUrl){
+            if(null!=appType&&appType.equals("APP_IOS")){
+                if(!downloadUrl.equals("https://apps.apple.com/cn/app/id1468454200")){
+                    errorMsg+= "应用下载链接填写异常;";
+                    errorflag = true;
+                }
+            }
+            if(null!=appType&&appType.equals("APP_ANDROID")){
+                if(!downloadUrl.contains(token)){
+                    errorMsg+= "应用下载链接填写异常;";
+                    errorflag = true;
+                }
+            }
+        }
+        //展示监测链接
+        String trackUrl = data.getString("trackUrl");
+        if(null!=trackUrl&&!trackUrl.trim().equals("")){
+            if(!trackUrl.contains(tokenInfo)){
+                errorMsg+= "展示监测链接填写异常;";
+                errorflag = true;
+            }
+        }
+        //点击监测链接
+        String actionTrackUrl = data.getString("actionTrackUrl");
+        if(null!=actionTrackUrl&&!actionTrackUrl.trim().equals("")){
+            if(null!=appType&&appType.equals("APP_IOS")){
+                if(!actionTrackUrl.contains(tokenInfo)||!actionTrackUrl.contains("app_platform=ios")){
+                    errorMsg+= "点击监测链接填写异常;";
+                    errorflag = true;
+                }
+            }
+            if(null!=appType&&appType.equals("APP_ANDROID")){
+                if(!actionTrackUrl.contains(tokenInfo)||!actionTrackUrl.contains("tt/1967")){
+                    errorMsg+= "点击监测链接填写异常;";
+                    errorflag = true;
+                }
+            }
+        }
+        //视频有效播放监测链接
+        String videoPlayEffectiveTrackUrl = data.getString("videoPlayEffectiveTrackUrl");
+        if(null!=videoPlayEffectiveTrackUrl&&!videoPlayEffectiveTrackUrl.trim().equals("")){
+            if(!actionTrackUrl.contains(tokenInfo)){
+                errorMsg+= "视频有效播放监测链接填写异常;";
+                errorflag = true;
+            }
+        }
+        if(errorflag){
+            sendMessage(allocation,"警告:账户:"+allocation.getAuthName()+"(id:"+allocation.getAccountId()+")下的广告计划:"+plan.getName()+"(id:"+plan.getId()+")"+"监测链接异常>>"+errorMsg);
+        }
+    }
+    private void sendMessage(UserAllocation allocation, String errorMsg) {
+        sendMessageService.sendMessage(allocation.getUserId(),errorMsg);
+    }
+}

+ 5 - 0
module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/material/entity/ByteDanceAdvertisePlan.java

@@ -380,6 +380,11 @@ public class ByteDanceAdvertisePlan {
             this.downloadType = downloadType;
         }
 
+        String downloadUrl = dataObject.getString("download_url");
+        if (null != downloadUrl && !"".equals(downloadUrl.trim())) {
+            this.downloadUrl = downloadUrl;
+        }
+
         String externalUrl = dataObject.getString("external_url");
         if (null != externalUrl && !"".equals(externalUrl.trim())) {
             this.externalUrl = externalUrl;

+ 2 - 2
module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/material/service/IByteDanceAdvertisePlanService.java

@@ -3,9 +3,7 @@ package cn.com.ctop.toutiao.modules.material.service;
 import cn.com.ctop.common.module.entity.CtopOauthToken;
 import cn.com.ctop.toutiao.modules.material.entity.ByteDanceAdvertisePlan;
 import com.alibaba.fastjson.JSONArray;
-import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.extension.service.IService;
-import jdk.nashorn.internal.scripts.JS;
 
 import java.math.BigDecimal;
 import java.util.List;
@@ -45,4 +43,6 @@ public interface IByteDanceAdvertisePlanService extends IService<ByteDanceAdvert
 
     //查询需要预警的深度转化出价
     List<String> selectWarningCpaBid(Long accountId, BigDecimal maxCapBid);
+
+    List<ByteDanceAdvertisePlan> getAllPlans(Long accountId);
 }

+ 9 - 0
module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/material/service/impl/ByteDanceAdvertisePlanServiceImpl.java

@@ -9,6 +9,7 @@ import cn.com.ctop.toutiao.modules.material.mapper.ByteDanceAdvertisePlanMapper;
 import cn.com.ctop.toutiao.modules.material.service.IByteDanceAdvertisePlanService;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -408,6 +409,14 @@ public class ByteDanceAdvertisePlanServiceImpl extends ServiceImpl<ByteDanceAdve
         return byteDanceAdvertisePlanMapper.selectWarningCpaBid(accountId, maxCapBid);
     }
 
+    @Override
+    public List<ByteDanceAdvertisePlan> getAllPlans(Long accountId) {
+        QueryWrapper<ByteDanceAdvertisePlan>queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq("account_id",accountId+"");
+        queryWrapper.ne("opt_status","AD_STATUS_DELETE");
+        return this.list(queryWrapper);
+    }
+
     private Map<String, Object> queryAdByAdId(CtopOauthToken token, Long accountId, List adId){
 
         Map<String, String> headers = new HashMap<>();

+ 11 - 1
module-toutiao/src/main/java/cn/com/ctop/toutiao/modules/material/service/impl/ByteDanceCreativeServiceImpl.java

@@ -207,16 +207,19 @@ public class ByteDanceCreativeServiceImpl extends ServiceImpl<ByteDanceCreativeM
         Map<String,Object>resultMap = new HashMap<>();
         if(null == planId||planId == 0||null == accountId||accountId == 0){
             ResultMapUtils.setResultMap(resultMap,StatusCode.COMMON_PARAM_ERROR);
+            resultMap.put("data",null);
             return resultMap;
         }
         UserAllocation allocation = userAllocationService.getByAccountId(accountId);
         if(null == allocation||allocation.getAccountStatus()!=0){
             ResultMapUtils.setResultMap(resultMap,StatusCode.BYTEDANCE_PLAN_DATA_NOT_EXIST);
+            resultMap.put("data",null);
             return resultMap;
         }
         ByteDanceAdvertisePlan plan = byteDanceAdvertisePlanService.getById(planId);
         if(null == plan||plan.getOptStatus().equals("AD_STATUS_DELETE")){
             ResultMapUtils.setResultMap(resultMap,StatusCode.BYTEDANCE_ACCOUNT_DATA_NOT_EXIST);
+            resultMap.put("data",null);
             return resultMap;
         }
         CtopOauthToken token = tokenService.getTokenByAccountId(accountId);
@@ -227,12 +230,18 @@ public class ByteDanceCreativeServiceImpl extends ServiceImpl<ByteDanceCreativeM
         data.put("advertiser_id", token.getAccountId());
         data.put("ad_id",planId);
         JSONObject result = HttpUtils.bytedanceGetRequest(token.getAccessToken(),url,data);
+        if(null == result){
+            ResultMapUtils.setResultMap(resultMap,StatusCode.COMMON_INTERNET_ERROR);
+            resultMap.put("data",null);
+            return resultMap;
+        }
         Integer code = result.getInteger("code");
         String message = result.getString("message");
         if (null ==  code) {
             log.info("广告创意获取详情失败,accountId:{},message:{}", accountId, message);
             resultMap.put("success", false);
             resultMap.put("code", -1);
+            result.put("data",null);
             resultMap.put("message", message);
             return resultMap;
         }
@@ -240,7 +249,7 @@ public class ByteDanceCreativeServiceImpl extends ServiceImpl<ByteDanceCreativeM
             //尚未创建创意
             resultMap.put("success", true);
             resultMap.put("code", 0);
-            result.put("data","");
+            result.put("data",null);
             resultMap.put("message", message);
             return resultMap;
         }
@@ -248,6 +257,7 @@ public class ByteDanceCreativeServiceImpl extends ServiceImpl<ByteDanceCreativeM
             log.info("广告创意获取详情失败,accountId:{},message:{}", accountId, message);
             resultMap.put("success", false);
             resultMap.put("code", -1);
+            result.put("data",null);
             resultMap.put("message", message);
             return resultMap;
         }