|
@@ -0,0 +1,190 @@
|
|
|
|
|
+package cn.com.ctop.job.bytedance.data.service.impl;
|
|
|
|
|
+
|
|
|
|
|
+import cn.com.ctop.job.bytedance.data.mapper.PromoteLinkRefreshMapper;
|
|
|
|
|
+import cn.com.ctop.job.bytedance.data.service.IBytedancePromoteRefreshService;
|
|
|
|
|
+import cn.com.ctop.job.bytedance.data.utils.Check;
|
|
|
|
|
+import cn.com.ctop.job.bytedance.data.utils.HttpUtils;
|
|
|
|
|
+import cn.com.ctop.job.bytedance.utils.FeishuRobotUtil;
|
|
|
|
|
+import com.alibaba.fastjson.JSON;
|
|
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
|
|
+import io.netty.util.internal.StringUtil;
|
|
|
|
|
+import org.apache.commons.lang.StringUtils;
|
|
|
|
|
+import org.springframework.data.redis.core.RedisTemplate;
|
|
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
|
|
+
|
|
|
|
|
+import javax.annotation.Resource;
|
|
|
|
|
+import java.io.IOException;
|
|
|
|
|
+import java.util.ArrayList;
|
|
|
|
|
+import java.util.HashMap;
|
|
|
|
|
+import java.util.List;
|
|
|
|
|
+import java.util.Map;
|
|
|
|
|
+
|
|
|
|
|
+@Service
|
|
|
|
|
+public class BytedancePromoteRefreshServiceImpl implements IBytedancePromoteRefreshService {
|
|
|
|
|
+ @Resource
|
|
|
|
|
+ PromoteLinkRefreshMapper promoteLinkRefreshMapper;
|
|
|
|
|
+
|
|
|
|
|
+ @Resource
|
|
|
|
|
+ private RedisTemplate redis2Template_db5;
|
|
|
|
|
+
|
|
|
|
|
+ public static final String HOOK_URL="https://open.feishu.cn/open-apis/bot/v2/hook/a0fcfb57-c053-47bd-b1e7-b826f44841e4";
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public void run() throws IOException {
|
|
|
|
|
+ List<JSONObject> list = getRefreshList();
|
|
|
|
|
+ if (Check.isNull(list) || list.isEmpty()) {
|
|
|
|
|
+ return; // 没有需要刷新的链接
|
|
|
|
|
+ }
|
|
|
|
|
+ long startTime = System.currentTimeMillis();
|
|
|
|
|
+ List<String> errorMsg = new ArrayList<>();
|
|
|
|
|
+ for (JSONObject linkInfo : list) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ JSONObject response = refreshLink(linkInfo);
|
|
|
|
|
+ if (response.getInteger("code") != 0) {
|
|
|
|
|
+ errorMsg.add(response.getString("msg"));
|
|
|
|
|
+ System.out.println("刷新链接失败: " + response.getString("msg"));
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ System.err.println("刷新链接时发生异常: " + e.getMessage());
|
|
|
|
|
+ errorMsg.add("刷新链接时发生异常: " + e.getMessage());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ long endTime = System.currentTimeMillis();
|
|
|
|
|
+ if (!errorMsg.isEmpty()){
|
|
|
|
|
+ //feishu
|
|
|
|
|
+ errorMsg.add(0, "**批量开户推广链刷新任务报错**");
|
|
|
|
|
+ FeishuRobotUtil.sendTextToWebhook(StringUtils.join(errorMsg, "\n"), HOOK_URL);
|
|
|
|
|
+ }
|
|
|
|
|
+ long duration = (endTime - startTime) / 1000 / 60; // 转换为分钟
|
|
|
|
|
+ if (duration > 10){
|
|
|
|
|
+ System.out.println("批量刷新推广链接任务耗时预警: " + duration + "分钟");
|
|
|
|
|
+ FeishuRobotUtil.sendTextToWebhook("批量刷新推广链接任务耗时预警: " + duration + "分钟", HOOK_URL);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ System.out.println("批量刷新推广链接任务完成,耗时: " + duration + "分钟");
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public List<JSONObject> getRefreshList() {
|
|
|
|
|
+ Long now = System.currentTimeMillis() / 1000;
|
|
|
|
|
+ Long targetTime = now + 60 * 60 * 24; // 24 hours later
|
|
|
|
|
+ return promoteLinkRefreshMapper.refreshList(targetTime);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 刷新推广链接
|
|
|
|
|
+ * @param linkInfo
|
|
|
|
|
+ * @return code:错误码 msg:错误信息
|
|
|
|
|
+ */
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public JSONObject refreshLink(JSONObject linkInfo) {
|
|
|
|
|
+ //select tb1.task_id, tb1.advertiser_id, tb1.promoter_id, tb1.link_uuid, tb4.expire_time, tb2.media_type, tb3.app_plat_type,
|
|
|
|
|
+ // tb3.movie_id as video_id, tb5.id as video_detail_id, tb1.promoter_uri, tb2.app_id
|
|
|
|
|
+ String uuid = linkInfo.getString("link_uuid");
|
|
|
|
|
+ String appId = linkInfo.getString("app_id");
|
|
|
|
|
+ String appletId = linkInfo.getString("applet_id");
|
|
|
|
|
+ Long linkId = linkInfo.getLong("promoter_id");
|
|
|
|
|
+ Long videoId = linkInfo.getLong("video_id");
|
|
|
|
|
+ Long videoDetailId = linkInfo.getLong("video_detail_id");
|
|
|
|
|
+ String promoterUri = linkInfo.getString("promoter_uri");
|
|
|
|
|
+
|
|
|
|
|
+ Integer mediaType = linkInfo.getInteger("media_type");
|
|
|
|
|
+ Integer appPlatType = linkInfo.getInteger("app_plat_type");
|
|
|
|
|
+ if (mediaType == 1){
|
|
|
|
|
+ if (appPlatType == 1){
|
|
|
|
|
+ String tokenKey = "wechat-applet-access-token-key-"+appletId;
|
|
|
|
|
+ Object tokenobj = redis2Template_db5.opsForValue().get(tokenKey);
|
|
|
|
|
+ if (Check.isNull(tokenobj)){
|
|
|
|
|
+ return response(400, "微信小程序access_token不存在,请先获取: "+appId);
|
|
|
|
|
+ }
|
|
|
|
|
+ String token = String.valueOf(tokenobj);
|
|
|
|
|
+
|
|
|
|
|
+ //wx
|
|
|
|
|
+ String path = promoterUri.split("\\?")[0];
|
|
|
|
|
+ String query = promoterUri.split("\\?")[1];
|
|
|
|
|
+
|
|
|
|
|
+ String url = "https://api.weixin.qq.com/wxa/generate_urllink?access_token="+token;
|
|
|
|
|
+ Map<String, Object> params = new HashMap<>();
|
|
|
|
|
+ params.put("path", path);
|
|
|
|
|
+ if (StringUtil.isNullOrEmpty(query)) {
|
|
|
|
|
+ params.put("query", query);
|
|
|
|
|
+ }
|
|
|
|
|
+ params.put("expire_type", 1);
|
|
|
|
|
+ params.put("expire_interval", 30);
|
|
|
|
|
+ Long expireTime = System.currentTimeMillis()/1000 + (86400L * 29); // 29天
|
|
|
|
|
+ String res = HttpUtils.httpPostRequest(url, params, null);
|
|
|
|
|
+ if (Check.isNull(res)) {
|
|
|
|
|
+ return response(500, "获取微信跳转链接失败");
|
|
|
|
|
+ }
|
|
|
|
|
+ JSONObject jsonResponse = JSON.parseObject(res);
|
|
|
|
|
+ if (jsonResponse.getInteger("errcode") != 0) {
|
|
|
|
|
+ return response(500, "获取微信跳转链接失败: " + jsonResponse.getString("errmsg"));
|
|
|
|
|
+ }
|
|
|
|
|
+ String link = jsonResponse.getString("url_link");
|
|
|
|
|
+ int updateCount = promoteLinkRefreshMapper.updateLink(uuid, link, expireTime);
|
|
|
|
|
+ return response(0, null);
|
|
|
|
|
+
|
|
|
|
|
+ }else if (appPlatType ==2){
|
|
|
|
|
+ String tokenKey = "client-token-key_"+ appId;
|
|
|
|
|
+ Object tokenobj = redis2Template_db5.opsForValue().get(tokenKey);
|
|
|
|
|
+ if (Check.isNull(tokenobj)){
|
|
|
|
|
+ return response(400, "抖音小程序access_token不存在,请先获取: "+appId);
|
|
|
|
|
+ }
|
|
|
|
|
+ String token = String.valueOf(tokenobj);
|
|
|
|
|
+
|
|
|
|
|
+ //douyin
|
|
|
|
|
+ String path = promoterUri.split("\\?")[0];
|
|
|
|
|
+ String url = "https://open.douyin.com/api/apps/v1/url_link/generate/";
|
|
|
|
|
+ Map<String, String> query = new HashMap<>();
|
|
|
|
|
+ query.put("link_id", String.valueOf(linkId));
|
|
|
|
|
+ query.put("video_id", String.valueOf(videoId));
|
|
|
|
|
+ query.put("video_detail_id", String.valueOf(videoDetailId));
|
|
|
|
|
+ query.put("type", String.valueOf(mediaType));
|
|
|
|
|
+ query.put("source", "link");
|
|
|
|
|
+ Map<String, Object> params = new HashMap<>();
|
|
|
|
|
+ params.put("app_id", appId);
|
|
|
|
|
+ params.put("app_name", "douyin");
|
|
|
|
|
+ params.put("path", path);
|
|
|
|
|
+ params.put("query", JSON.toJSONString(query));
|
|
|
|
|
+
|
|
|
|
|
+ long now = System.currentTimeMillis() / 1000;
|
|
|
|
|
+ long expireTime = now + (86400) * 179; // 170天有效期
|
|
|
|
|
+ params.put("expire_time", String.valueOf(expireTime));
|
|
|
|
|
+
|
|
|
|
|
+ Map<String, String> headers = new HashMap<>();
|
|
|
|
|
+ headers.put("Access-Token", token);
|
|
|
|
|
+ headers.put("Content-Type", "application/json");
|
|
|
|
|
+
|
|
|
|
|
+ String res = HttpUtils.httpPostRequest(url, params, headers);
|
|
|
|
|
+ if (Check.isNull(res)) {
|
|
|
|
|
+ return response(500, "获取抖音跳转链接失败: 响应内容为空");
|
|
|
|
|
+ }
|
|
|
|
|
+ JSONObject jsonResponse = JSON.parseObject(res);
|
|
|
|
|
+ if (jsonResponse.getInteger("err_no") != 0) {
|
|
|
|
|
+ return response(500, "获取抖音跳转链接失败: " + jsonResponse.getString("message"));
|
|
|
|
|
+ }else {
|
|
|
|
|
+ JSONObject data = jsonResponse.getJSONObject("data");
|
|
|
|
|
+ if (data == null || !data.containsKey("url_link")) {
|
|
|
|
|
+ return response(500, "获取抖音跳转链接失败: "+ res);
|
|
|
|
|
+ }
|
|
|
|
|
+ String link = data.getString("url_link");
|
|
|
|
|
+ //更新数据库
|
|
|
|
|
+ int updateCount = promoteLinkRefreshMapper.updateLink(uuid, link, expireTime);
|
|
|
|
|
+ return response(0, null);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }else {
|
|
|
|
|
+ //adq等
|
|
|
|
|
+ }
|
|
|
|
|
+ return response(0, null);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private JSONObject response(int code, String msg) {
|
|
|
|
|
+ JSONObject response = new JSONObject();
|
|
|
|
|
+ response.put("code", code);
|
|
|
|
|
+ response.put("msg", msg);
|
|
|
|
|
+ return response;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|