|
@@ -0,0 +1,746 @@
|
|
|
+package org.jeecg.modules.bytedance.advertise.dockapi;
|
|
|
+
|
|
|
+import com.alibaba.fastjson.JSONArray;
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.jeecg.common.api.vo.Result;
|
|
|
+import org.jeecg.modules.bytedance.advertise.entity.ByteDanceAdvertisePlan;
|
|
|
+import org.jeecg.modules.bytedance.advertise.vo.AdGroupSearchVo;
|
|
|
+import org.jeecg.modules.bytedance.advertise.vo.ByteDanceSearchVo;
|
|
|
+import org.jeecg.modules.bytedance.advertise.vo.PlanSearchVo;
|
|
|
+import org.jeecg.modules.bytedance.common.entity.CtopOauthToken;
|
|
|
+import org.jeecg.modules.bytedance.common.utils.HttpUtils;
|
|
|
+import org.jeecg.modules.bytedance.common.utils.PropertiesUtils;
|
|
|
+
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 头条-巨量引擎API 接口
|
|
|
+ * zianY
|
|
|
+ * 2021/4/16
|
|
|
+ **/
|
|
|
+
|
|
|
+@Slf4j
|
|
|
+public class marketing {
|
|
|
+
|
|
|
+ private static final String urlPath = PropertiesUtils.getValue("bytedance_config", "bytedance_api_url");
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ *
|
|
|
+ * @description: 获取账户日预算
|
|
|
+ *
|
|
|
+ * @param token 授权access_token
|
|
|
+ * @param advertiser_ids 广告主id列表,长度限制:[1,100]
|
|
|
+ * @return: java.util.Map<java.lang.String,java.lang.Object>
|
|
|
+ * @author: zianY
|
|
|
+ */
|
|
|
+ public static Result getBudget(CtopOauthToken token, List<Long> advertiser_ids) {
|
|
|
+ JSONObject params = new JSONObject();
|
|
|
+ //广告主id列表,长度限制:[1,100]
|
|
|
+ params.put("advertiser_ids", advertiser_ids);
|
|
|
+ //调用api接口--获取账户日预算
|
|
|
+ JSONObject jsonObject = HttpUtils.bytedanceGetRequest(token.getAccessToken(),
|
|
|
+ urlPath+ PropertiesUtils.getValue("bytedance_config", "bytedance_v2_ad_get_budget"),
|
|
|
+ params);
|
|
|
+ int code = jsonObject.getInteger("code");
|
|
|
+ if (code!=0) {
|
|
|
+ log.info("获取账户日预算接口异常==》accountId:{},message:{}", token.getAccountId(), jsonObject.getString("message"));
|
|
|
+ return Result.error(jsonObject.getString("message"));
|
|
|
+ }
|
|
|
+ return Result.successMsg("获取账户日预算成功",jsonObject.get("data"));
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ *
|
|
|
+ * @description: 更新账户日预算
|
|
|
+ *
|
|
|
+ * @param token 授权access_token
|
|
|
+ * @param budgetMode 预算模式
|
|
|
+ * @param budget 预算值
|
|
|
+ * @return: java.util.Map<java.lang.String,java.lang.Object>
|
|
|
+ */
|
|
|
+ public static Result updateBudget(CtopOauthToken token, String budgetMode, String budget) {
|
|
|
+ JSONObject params = new JSONObject();
|
|
|
+ //广告主ID
|
|
|
+ params.put("advertiser_id", token.getAccountId());
|
|
|
+ //预算模式
|
|
|
+ // BUDGET_MODE_DAY(日预算)
|
|
|
+ //BUDGET_MODE_INFINITE(不限)
|
|
|
+ params.put("budget_mode", budgetMode);
|
|
|
+ //预算值
|
|
|
+ params.put("budget", budget);
|
|
|
+ //调用api接口--更新广告主账号设置的预算类型与预算
|
|
|
+ JSONObject jsonObject = HttpUtils.bytedancePostRequest(token.getAccessToken(),
|
|
|
+ urlPath+ PropertiesUtils.getValue("bytedance_config", "bytedance_v2_ad_update_budget"),
|
|
|
+ params);
|
|
|
+ int code = jsonObject.getInteger("code");
|
|
|
+ if (code!=0) {
|
|
|
+ log.info("修改计划预算接口异常==》accountId:{},message:{}", token.getAccountId(), jsonObject.getString("message"));
|
|
|
+ return Result.error(jsonObject.getString("message"));
|
|
|
+ }
|
|
|
+ return Result.successMsg("修改计划预算成功",null);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ *
|
|
|
+ * @description: 查询广告主下存在的的人群包列表和信息
|
|
|
+ *
|
|
|
+ * @param token
|
|
|
+ * @return: org.jeecg.common.api.vo.Result
|
|
|
+ * @author: zianY
|
|
|
+ */
|
|
|
+ public static Result selectCustomAudience(CtopOauthToken token) {
|
|
|
+ JSONObject params = new JSONObject();
|
|
|
+ //广告主ID
|
|
|
+ params.put("advertiser_id", token.getAccountId());
|
|
|
+ //查询类型,枚举值:"0":该广告主创建的人群包和被推送给该广告主的人群包,"1":状态为可投放的人群包
|
|
|
+ params.put("select_type", "1");
|
|
|
+ params.put("offset", "0");
|
|
|
+ params.put("limit", "100");
|
|
|
+ JSONObject jsonObject = HttpUtils.bytedanceGetRequest(token.getAccessToken(),
|
|
|
+ PropertiesUtils.getValue("bytedance_config", "bytedance_v2_dmp_custom_audience_select"),
|
|
|
+ params);
|
|
|
+ Integer code = jsonObject.getInteger("code");
|
|
|
+ String message = jsonObject.getString("message");
|
|
|
+ if (null == code || !code.equals(0)) {
|
|
|
+ log.info("获取人群包信息接口异常==》accountId:{},message:{}", token.getAccountId(), message);
|
|
|
+ return Result.error(message);
|
|
|
+ }
|
|
|
+ JSONArray data = jsonObject.getJSONObject("data").getJSONArray("custom_audience_list");
|
|
|
+ if (null == data || data.isEmpty()) {
|
|
|
+ log.info("人群包信息不存在==》accountId:{},message:{}", token.getAccountId(), message);
|
|
|
+ return Result.error("人群包信息不存在");
|
|
|
+ }
|
|
|
+ return Result.successMsg("人群包信息获取成功",data);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ *
|
|
|
+ * @description: 获取创意审核建议
|
|
|
+ *
|
|
|
+ * @param token
|
|
|
+ * @param creativeIds 广告创意ID 长度限制:1~10。创意ID需要属于当前广告主,否则会报错。只有审核不通过的创意才有审核建议,审核通过的创意没有审核建议。
|
|
|
+ * (所有的程序化创意都是审核通过的)
|
|
|
+ * @return: org.jeecg.common.api.vo.Result
|
|
|
+ * @author: zianY
|
|
|
+ */
|
|
|
+ public static Result getCreativeRejectReason(CtopOauthToken token,String creativeIds) {
|
|
|
+ JSONObject params = new JSONObject();
|
|
|
+ //广告主ID
|
|
|
+ params.put("advertiser_id", token.getAccountId());
|
|
|
+ //广告创意ID
|
|
|
+ params.put("creative_ids", creativeIds);
|
|
|
+ JSONObject jsonObject = HttpUtils.bytedanceGetRequest(token.getAccessToken(),
|
|
|
+ PropertiesUtils.getValue("bytedance_config", "bytedance_v2_create_reject_reason"),
|
|
|
+ params);
|
|
|
+ Integer code = jsonObject.getInteger("code");
|
|
|
+ String message = jsonObject.getString("message");
|
|
|
+ if (null == code || !code.equals(0)) {
|
|
|
+ log.info("获取创意审核建议接口异常==》accountId:{},message:{}", token.getAccountId(), message);
|
|
|
+ return Result.error(message);
|
|
|
+ }
|
|
|
+ JSONArray data = jsonObject.getJSONObject("data").getJSONArray("list");
|
|
|
+ if (null == data || data.isEmpty()) {
|
|
|
+ log.info("创意审核建议不存在==》accountId:{},message:{}", token.getAccountId(), message);
|
|
|
+ return Result.error("创意审核建议不存在");
|
|
|
+ }
|
|
|
+ return Result.successMsg("获取创意审核建议成功",data);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ *
|
|
|
+ * @description: 获取创意素材信息
|
|
|
+ *
|
|
|
+ * @param token
|
|
|
+ * @param creativeIds 创意ID集合,支持最大长度为100。创意ID需属于当前广告主,否则会报错
|
|
|
+ * @return: org.jeecg.common.api.vo.Result
|
|
|
+ * @author: zianY
|
|
|
+ */
|
|
|
+ public static Result getMaterialRead(CtopOauthToken token,String[] creativeIds) {
|
|
|
+
|
|
|
+ JSONObject params = new JSONObject();
|
|
|
+ //广告主ID
|
|
|
+ params.put("advertiser_id", token.getAccountId());
|
|
|
+ //创意ID集合
|
|
|
+ params.put("creative_ids", creativeIds);
|
|
|
+ //查询字段集合, 默认查询所有字段
|
|
|
+ //String[] fields={"id", "ad_id", "advertiser_id", "title", "image_info","image_mode", "opt_status"};
|
|
|
+ //params.put("fields",fields);
|
|
|
+ JSONObject jsonObject = HttpUtils.bytedanceGetRequest(token.getAccessToken(),
|
|
|
+ urlPath + PropertiesUtils.getValue("bytedance_config", "bytedance_v2_creative_material_get"),
|
|
|
+ params);
|
|
|
+ Integer code = jsonObject.getInteger("code");
|
|
|
+ if (null == code || !code.equals(0)) {
|
|
|
+ log.error("获取广告主创意素材信息接口异常==》accountId:{},message:{}", token.getAccountId(), jsonObject.getString("message"));
|
|
|
+ return Result.error("获取广告主创意素材信息接口异常");
|
|
|
+ }
|
|
|
+ JSONArray data = jsonObject.getJSONArray("data");
|
|
|
+ if (null == data || data.isEmpty()) {
|
|
|
+ return Result.successMsg("获取广告主预算信息为空。",null);
|
|
|
+ }
|
|
|
+ return Result.successMsg("获取广告主预算信息完成",jsonObject.get("data"));
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ *
|
|
|
+ * @description: 修改创意状态
|
|
|
+ *
|
|
|
+ * @param token
|
|
|
+ * @param creativeIds 创意ID列表,长度限制1~100;创意ID需属于广告主,否则会报错!
|
|
|
+ * @param optStatus 操作, "enable"表示启用, "disable"表示暂停
|
|
|
+ * @return: org.jeecg.common.api.vo.Result
|
|
|
+ * @author: zianY
|
|
|
+ */
|
|
|
+ public static Result updateCreativeStatus(CtopOauthToken token, String[] creativeIds, String optStatus) {
|
|
|
+ JSONObject params = new JSONObject();
|
|
|
+ params.put("advertiser_id", token.getAccountId());
|
|
|
+ params.put("creative_ids", creativeIds);
|
|
|
+ params.put("opt_status", optStatus);
|
|
|
+ JSONObject jsonObject = HttpUtils.bytedancePostRequest(token.getAccessToken(),
|
|
|
+ urlPath + PropertiesUtils.getValue("bytedance_config", "bytedance_v2_creative_update_status"),
|
|
|
+ params);
|
|
|
+ Integer code = jsonObject.getInteger("code");
|
|
|
+ String message = jsonObject.getString("message");
|
|
|
+ if (null == code || !code.equals(0)) {
|
|
|
+ log.info("修改创意状态接口异常==》accountId:{},message:{}", token.getAccountId(), message);
|
|
|
+ return Result.error("修改创意状态接口异常。");
|
|
|
+ }
|
|
|
+ JSONObject data = jsonObject.getJSONObject("data");
|
|
|
+ if (null == data || data.isEmpty()) {
|
|
|
+ log.info("修改创意状态返回数据为空==》accountId:{},message:{}", token.getAccountId(), message);
|
|
|
+ return Result.error("修改创意状态返回数据为空。");
|
|
|
+ }
|
|
|
+ JSONArray ids = data.getJSONArray("creative_ids");
|
|
|
+ return Result.successMsg("创意状态修改成功。",ids);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ *
|
|
|
+ * @description: 创建广告组
|
|
|
+ *
|
|
|
+ * @param token
|
|
|
+ * @param campaignName 广告组名称
|
|
|
+ * @param budgetMode 广告组预算类型
|
|
|
+ * //BUDGET_MODE_INFINITE 不限
|
|
|
+ * //BUDGET_MODE_DAY 日预算
|
|
|
+ * //BUDGET_MODE_TOTAL 总预算
|
|
|
+ *
|
|
|
+ * @param budget 广告组预算
|
|
|
+ * 取值范围: ≥ 0
|
|
|
+ * 当budget_mode为"BUDGET_MODE_DAY"时,必填,且日预算不少于300元
|
|
|
+ *
|
|
|
+ * @return: org.jeecg.common.api.vo.Result
|
|
|
+ * @time: 2021/4/19 10:47
|
|
|
+ */
|
|
|
+ public static Result createCampaign(CtopOauthToken token,String campaignName,String budgetMode, String budget,String landingType) {
|
|
|
+ JSONObject param = new JSONObject();
|
|
|
+ //广告主id
|
|
|
+ param.put("advertiser_id",token.getAccountId());
|
|
|
+ //广告组名称,长度为1-100个字符,其中1个中文字符算2位
|
|
|
+ param.put("campaign_name",campaignName);
|
|
|
+ //广告组状态 "enable","disable"默认值:enable开启状态
|
|
|
+ param.put("operation","enable");
|
|
|
+ param.put("budget_mode", budgetMode);
|
|
|
+ //广告组预算
|
|
|
+ param.put("budget",budget);
|
|
|
+ //广告组推广目的
|
|
|
+ param.put("landing_type",landingType);
|
|
|
+
|
|
|
+ JSONObject data = HttpUtils.bytedancePostRequest(token.getAccessToken(),
|
|
|
+ urlPath+PropertiesUtils.getValue("bytedance_config", "bytedance_v2_campaign_create"),
|
|
|
+ param);
|
|
|
+ if(data == null){
|
|
|
+ log.error("创建广告组异常=>param:{}",param.toJSONString());
|
|
|
+ return Result.error("头条API创建广告组异常");
|
|
|
+ }
|
|
|
+ Integer code = data.getInteger("code");
|
|
|
+ String message = data.getString("message");
|
|
|
+ if(null == code||!code.equals(0)){
|
|
|
+ log.error("创建广告组数据异常=>{},parmas:{}",message,param.toJSONString());
|
|
|
+ return Result.error(message);
|
|
|
+ }
|
|
|
+ //广告组id
|
|
|
+ return Result.successMsg("广告组创建成功",data.getJSONObject("data").getLong("campaign_id"));
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ //创建计划
|
|
|
+ public static Result createAdvertiserPlan(CtopOauthToken token, String landingType, ByteDanceAdvertisePlan byteDanceAdvertisePlan) {
|
|
|
+
|
|
|
+ JSONObject params = new JSONObject();
|
|
|
+ //广告主ID
|
|
|
+ params.put("advertiser_id", byteDanceAdvertisePlan.getAccountId());
|
|
|
+ //广告组ID
|
|
|
+ params.put("campaign_id", byteDanceAdvertisePlan.getCampaignId());
|
|
|
+ //广告计划名称,长度为1-100个字符,其中1个中文字符算2位。名称不可重复,否则会报错
|
|
|
+ params.put("name", byteDanceAdvertisePlan.getName());
|
|
|
+ //计划状态 默认值: "enable"开启状态 允许值: "enable"开启,"disable"关闭
|
|
|
+ params.put("operation", byteDanceAdvertisePlan.getOperation() == null ? "enable" : byteDanceAdvertisePlan.getOperation());
|
|
|
+ // 投放范围 "DEFAULT"默认, "UNION"穿山甲
|
|
|
+ params.put("delivery_range", byteDanceAdvertisePlan.getDeliveryRange() == null ? "DEFAULT" : byteDanceAdvertisePlan.getDeliveryRange());
|
|
|
+ //投放形式(穿山甲视频创意类型) 当delivery_range为"UNION"时必填
|
|
|
+ // 允许值: "ORIGINAL_VIDEO"原生, "REWARDED_VIDEO"激励视频,"SPLASH_VIDEO"开屏
|
|
|
+ params.put("union_video_type", byteDanceAdvertisePlan.getUnionVideoType() == null ? "ORIGINAL_VIDEO" : byteDanceAdvertisePlan.getUnionVideoType());
|
|
|
+
|
|
|
+ //投放内容
|
|
|
+ //推广目的为应用推广(landing_type=APP)时投放目标参数
|
|
|
+ if ("APP".equals(landingType)) {
|
|
|
+ //下载方式 可选值:DOWNLOAD_URL下载链接,QUICK_APP_URL快应用+下载链接,EXTERNAL_URL落地页链接
|
|
|
+ params.put("download_type", byteDanceAdvertisePlan.getDownloadType());
|
|
|
+ //下载链接
|
|
|
+ // 类型为下载链接
|
|
|
+ if ("DOWNLOAD_URL".equals(byteDanceAdvertisePlan.getDownloadType())){
|
|
|
+ params.put("download_url", byteDanceAdvertisePlan.getDownloadUrl());
|
|
|
+ //下载的应用类型,当download_type为DOWNLOAD_URL时必填
|
|
|
+ //允许值: "APP_ANDROID"Android APP, "APP_IOS"IOS APP
|
|
|
+ params.put("app_type", byteDanceAdvertisePlan.getAppType());
|
|
|
+
|
|
|
+ }
|
|
|
+ // 类型为 快应用+下载链接
|
|
|
+ if ("QUICK_APP_URL".equals(byteDanceAdvertisePlan.getDownloadType())){
|
|
|
+ params.put("quick_app_url", byteDanceAdvertisePlan.getDownloadUrl());
|
|
|
+ }
|
|
|
+ // 类型为下载链接
|
|
|
+ if ("EXTERNAL_URL".equals(byteDanceAdvertisePlan.getDownloadType())){
|
|
|
+ params.put("external_url", byteDanceAdvertisePlan.getDownloadUrl());
|
|
|
+ }
|
|
|
+
|
|
|
+ params.put("package", byteDanceAdvertisePlan.getToutiaoPackage());
|
|
|
+ params.put("app_type",byteDanceAdvertisePlan.getAppType());
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+// TODO 优化目标
|
|
|
+// convert_id 转化目标
|
|
|
+
|
|
|
+
|
|
|
+ //直达链接(点击唤起APP)
|
|
|
+ params.put("open_url", byteDanceAdvertisePlan.getOpenUrl());
|
|
|
+
|
|
|
+ //搜索快投功能,允许值:HAS_OPEN:启用,DISABLED:不启用 TODO
|
|
|
+ params.put("feed_delivery_search", "搜索快投");
|
|
|
+
|
|
|
+ //用户定向
|
|
|
+
|
|
|
+ //允许值: "CITY"省市, "COUNTY"区县, "BUSINESS_DISTRICT"商圈,"NONE"不限
|
|
|
+ params.put("district", byteDanceAdvertisePlan.getScheduleType());
|
|
|
+ //性别 允许值: "GENDER_FEMALE", "GENDER_MALE", "NONE"
|
|
|
+ params.put("gender", byteDanceAdvertisePlan.getGender());
|
|
|
+
|
|
|
+ //允许值: "AGE_BETWEEN_18_23", "AGE_BETWEEN_24_30","AGE_BETWEEN_31_40", "AGE_BETWEEN_41_49", "AGE_ABOVE_50"
|
|
|
+ //年龄不限 不传该字段
|
|
|
+ //params.put("age", byteDanceAdvertisePlan.getAge());
|
|
|
+ //自定义人群 不限 不传该字段
|
|
|
+ // 定向人群包列表(自定义人群)
|
|
|
+ //params.put("retargeting_tags_include", );
|
|
|
+ //排除人群包列表(自定义人群)
|
|
|
+ //params.put("retargeting_tags_exclude", );
|
|
|
+
|
|
|
+ //媒体定向
|
|
|
+ //params.put("superior_popularity_type", byteDanceAdvertisePlan.getSuperiorPopularityType());
|
|
|
+ //平台
|
|
|
+ //params.put("platform", byteDanceAdvertisePlan.getPlatform());
|
|
|
+ //网络
|
|
|
+ //params.put("ac", byteDanceAdvertisePlan.getAc());
|
|
|
+
|
|
|
+ //过滤已安装 当推广目标为安卓应用下载时可填 0表示不限,1表示过滤,2表示定向。默认为不限
|
|
|
+ params.put("hide_if_exists", byteDanceAdvertisePlan.getHideIfExists());
|
|
|
+ //过滤已转化用户 NO_EXCLUDE-不过滤;AD-广告计划(默认);CAMPAIGN-广告组; ADVERTISER-广告账户; APP-APP; CUSTOMER-公司账户
|
|
|
+ params.put("hide_if_converted", byteDanceAdvertisePlan.getHideIfConverted());
|
|
|
+ //是否启用智能放量 0、1。缺省为 0
|
|
|
+ params.put("auto_extend_enabled", byteDanceAdvertisePlan.getAutoExtendEnabled());
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ //预算与出价
|
|
|
+ //投放场景 允许值: 常规投放"SMART_BID_CUSTOM", 放量投放"SMART_BID_CONSERVATIVE"
|
|
|
+ params.put("smart_bid_type", "投放场景");
|
|
|
+
|
|
|
+ //预算 出价方式为CPC、CPM、CPV时,不少于100元;出价方式为OCPM、OCPC时,不少于300元
|
|
|
+ params.put("budget", byteDanceAdvertisePlan.getBudget());
|
|
|
+ //投放时间类型 允许值: "SCHEDULE_FROM_NOW"从今天起长期投放, "SCHEDULE_START_END"设置开始和结束日期
|
|
|
+ params.put("schedule_type", byteDanceAdvertisePlan.getScheduleType());
|
|
|
+ //投放时段,默认全时段投放
|
|
|
+ params.put("schedule_time", byteDanceAdvertisePlan.getScheduleTime());
|
|
|
+ //付费方式(计划出价类型) 决定投放目标的类型,比如CPC表示点击量,OCPM表示转化量
|
|
|
+ params.put("pricing", byteDanceAdvertisePlan.getPricing());
|
|
|
+
|
|
|
+ //目标转化出价/预期成本, 当pricing为"OCPM"、"OCPC"出价方式时必填)
|
|
|
+ //pricing为"OCPC"时取值范围:0.1-10000元;
|
|
|
+ //pricing为"OCPM"时取值范围:0.1-10000元;
|
|
|
+ //出价不能大于预算否则会报错
|
|
|
+ params.put("cpa_bid", byteDanceAdvertisePlan.getCpaBid());
|
|
|
+
|
|
|
+
|
|
|
+ //第三方检测链接 TODO
|
|
|
+
|
|
|
+
|
|
|
+ JSONObject jsonObject = HttpUtils.bytedancePostRequest(token.getAccessToken(),
|
|
|
+ urlPath + PropertiesUtils.getValue("bytedance_config", "bytedance_v2_ad_create"), params);
|
|
|
+ Integer code = jsonObject.getInteger("code");
|
|
|
+ if (null == code || !code.equals(0)) {
|
|
|
+ log.error("广告计划创建失败==》accountId:{},message:{}", token.getAccountId(), jsonObject.getString("message"));
|
|
|
+ Result.error(jsonObject.getString("message"));
|
|
|
+
|
|
|
+ }
|
|
|
+ byteDanceAdvertisePlan.setId(jsonObject.getJSONObject("data").getLong("ad_id"));
|
|
|
+ return Result.successMsg("广告计划创建成功",byteDanceAdvertisePlan);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 创建广告创意
|
|
|
+ * @param
|
|
|
+ * @param adId
|
|
|
+ * @param data
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public Result creativeCreate(CtopOauthToken token, Long adId, JSONObject data) {
|
|
|
+ Map<String, Object> resultMap = new HashMap<>();
|
|
|
+ //广告主ID
|
|
|
+ data.put("advertiser_id", token.getAccountId());
|
|
|
+ //广告计划ID
|
|
|
+ data.put("ad_id", adId);
|
|
|
+ //广告 投放位置 三选一
|
|
|
+ if (!data.getString("smart_inventory").isEmpty()){
|
|
|
+ //优选广告位,0表示不使用优选,1表示使用
|
|
|
+ data.put("smart_inventory", data.getString("smart_inventory"));
|
|
|
+ }
|
|
|
+ if (!data.getString("inventory_type").isEmpty()){
|
|
|
+ //广告位置(按媒体指定位置)
|
|
|
+ data.put("inventory_type", data.getString("inventory_type"));
|
|
|
+ }
|
|
|
+ if (!data.getString("scene_inventory").isEmpty()){
|
|
|
+ //场景广告位
|
|
|
+ data.put("scene_inventory", data.getString("scene_inventory"));
|
|
|
+ }
|
|
|
+ //监测链接
|
|
|
+ //data.put("action_track_url", data.getString("action_track_url"));
|
|
|
+ //创意方式,当值为"STATIC_ASSEMBLE"表示程序化创意,其他情况不传字段
|
|
|
+ data.put("creative_material_mode", data.getString("creative_material_mode"));
|
|
|
+
|
|
|
+ //TODO创意内容
|
|
|
+
|
|
|
+ //素材信息
|
|
|
+ data.put("image_list", data.getJSONArray("image_list"));
|
|
|
+ //标题信息
|
|
|
+ data.put("image_list", data.getJSONArray("image_list"));
|
|
|
+
|
|
|
+ //TODO 来源
|
|
|
+
|
|
|
+ //创意分类
|
|
|
+ data.put("third_industry_id", data.getString("third_industry_id"));
|
|
|
+ //创意标签 创意标签。最多20个标签,且每个标签长度不超过10个字符
|
|
|
+ data.put("ad_keywords", data.getString("ad_keywords"));
|
|
|
+
|
|
|
+
|
|
|
+ JSONObject result = HttpUtils.bytedancePostRequest(token.getAccessToken(),
|
|
|
+ urlPath+PropertiesUtils.getValue("bytedance_config", "bytedance_v2_creative_create_v2"),
|
|
|
+ data);
|
|
|
+
|
|
|
+ Integer code = result.getInteger("code");
|
|
|
+ String message = result.getString("message");
|
|
|
+ if (null == code || code != 0) {
|
|
|
+ return Result.error("广告计划("+adId+"):创建创意信息异常--->>>"+message);
|
|
|
+ }
|
|
|
+ return Result.successMsg("广告计划("+adId+"):"+"创意创建成功",null);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ *
|
|
|
+ * @description: 创意详细信息
|
|
|
+ *
|
|
|
+ * @param token
|
|
|
+ * @param advertiserId 广告主id
|
|
|
+ * @param adId 计划ID
|
|
|
+ * @return: org.jeecg.common.api.vo.Result
|
|
|
+ * @author: zianY
|
|
|
+ * @time: 2021/4/19 15:23
|
|
|
+ */
|
|
|
+ public static Result creativeRead(CtopOauthToken token,String advertiserId,String adId) {
|
|
|
+ JSONObject param = new JSONObject();
|
|
|
+ param.put("advertiser_id",advertiserId);
|
|
|
+ param.put("ad_id",adId);
|
|
|
+ JSONObject data = HttpUtils.bytedancePostRequest(token.getAccessToken(),
|
|
|
+ urlPath+PropertiesUtils.getValue("bytedance_config", "bytedance_v2_creative_read"),
|
|
|
+ param);
|
|
|
+ if(data == null){
|
|
|
+ log.error("获取创意详细信息异常=>param:{}",param.toJSONString());
|
|
|
+ return Result.error("获取创意详细信息异常");
|
|
|
+ }
|
|
|
+ Integer code = data.getInteger("code");
|
|
|
+ String message = data.getString("message");
|
|
|
+ if(null == code||!code.equals(0)){
|
|
|
+ log.error("获取创意详细信息异常=>{},parmas:{}",message,param.toJSONString());
|
|
|
+ return Result.error(message);
|
|
|
+ }
|
|
|
+ return Result.successMsg("获取创意详细信息成功",data.getJSONObject("data"));
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ *
|
|
|
+ * @description: 获取创意列表信息
|
|
|
+ *
|
|
|
+ * @param token
|
|
|
+ * @param pageNumber
|
|
|
+ * @param byteDanceSearchVoList 创意入参信息
|
|
|
+ * @return: org.jeecg.common.api.vo.Result
|
|
|
+ * @author: zianY
|
|
|
+ */
|
|
|
+ public static Result getAdvertiserCreativeByPageNumber(CtopOauthToken token, Integer pageNumber, List<ByteDanceSearchVo> byteDanceSearchVoList) {
|
|
|
+ JSONObject params = new JSONObject();
|
|
|
+ params.put("advertiser_id", token.getAccountId());
|
|
|
+ if (null != byteDanceSearchVoList){
|
|
|
+ params.put("filtering", byteDanceSearchVoList);
|
|
|
+ }
|
|
|
+ params.put("page", pageNumber + "");
|
|
|
+ params.put("page_size",100);
|
|
|
+ JSONObject jsonObject = HttpUtils.bytedanceGetRequest(token.getAccessToken(),
|
|
|
+ urlPath + PropertiesUtils.getValue("bytedance_config", "bytedance_v2_creative_get"),params);
|
|
|
+ Integer code = jsonObject.getInteger("code");
|
|
|
+ if (null == code || !code.equals(0)) {
|
|
|
+ log.info("获取广告主广告创意信息接口异常==》accountId:{},message:{}", token.getAccountId(), jsonObject.getString("message"));
|
|
|
+ return Result.error("获取广告主广告创意信息接口异常");
|
|
|
+ }
|
|
|
+ JSONArray data = jsonObject.getJSONObject("data").getJSONArray("list");
|
|
|
+ if (null == data || data.isEmpty()) {
|
|
|
+ log.info("广告主广告创意信息不存在==》accountId:{},message:{}", token.getAccountId(), jsonObject.getString("message"));
|
|
|
+ return Result.error("广告主广告创意信息不存在");
|
|
|
+ }
|
|
|
+ return Result.successMsg("获取广告主创意列表成功。",data);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ *
|
|
|
+ * @description: 获取计划审核建议
|
|
|
+ *
|
|
|
+ * @param token
|
|
|
+ * @param advertiserId 广告主ID
|
|
|
+ * @param adIds 广告计划 ID,最多传10个广告计划ID
|
|
|
+ * @return: org.jeecg.common.api.vo.Result
|
|
|
+ * @author: zianY
|
|
|
+ */
|
|
|
+ public static Result getRejectReason(CtopOauthToken token, String advertiserId, List<String> adIds) {
|
|
|
+ JSONObject params = new JSONObject();
|
|
|
+ params.put("advertiser_id", advertiserId);
|
|
|
+ params.put("ad_ids", adIds);
|
|
|
+
|
|
|
+ JSONObject jsonObject = HttpUtils.bytedanceGetRequest(token.getAccessToken(),
|
|
|
+ urlPath + PropertiesUtils.getValue("bytedance_config", "bytedance_v2_ad_create_reasion"),params);
|
|
|
+ Integer code = jsonObject.getInteger("code");
|
|
|
+ if (null == code || !code.equals(0)) {
|
|
|
+ log.info("获取广告主计划审核建议接口异常==》accountId:{},message:{}", token.getAccountId(), jsonObject.getString("message"));
|
|
|
+ return Result.error("获取广告主计划审核建议接口异常");
|
|
|
+ }
|
|
|
+ JSONArray data = jsonObject.getJSONObject("data").getJSONArray("list");
|
|
|
+ if (null == data || data.isEmpty()) {
|
|
|
+ log.info("获取广告主计划审核建议不存在==》accountId:{},message:{}", token.getAccountId(), jsonObject.getString("message"));
|
|
|
+ return Result.error("获取广告主计划审核建议不存在");
|
|
|
+ }
|
|
|
+ return Result.successMsg("获取广告主计划审核建议成功。",data);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ *
|
|
|
+ * @description: 更新计划出价
|
|
|
+ *
|
|
|
+ * @param token
|
|
|
+ * @param advertiserId 广告主ID
|
|
|
+ * @param listMap ad_id 广告计划ID
|
|
|
+ * bid 出价,单位“元”,
|
|
|
+ * @return: org.jeecg.common.api.vo.Result
|
|
|
+ * @author: zianY
|
|
|
+ */
|
|
|
+ public static Result updatePlanBid(CtopOauthToken token,String advertiserId,List<Map<String,Object>> listMap) {
|
|
|
+ JSONObject params = new JSONObject();
|
|
|
+ params.put("advertiser_id", advertiserId);
|
|
|
+ params.put("data", listMap);
|
|
|
+ JSONObject jsonObject = HttpUtils.bytedancePostRequest(token.getAccessToken(),
|
|
|
+ PropertiesUtils.getValue("bytedance_config", "bytedance_v2_ad_update_bid"), params);
|
|
|
+ int code = jsonObject.getInteger("code");
|
|
|
+ Map<String, Object> resultMap = new HashMap<>();
|
|
|
+ if (code != 0) {
|
|
|
+ log.info("修改计划出价接口异常==》accountId:{},message:{}", token.getAccountId(), jsonObject.getString("message"));
|
|
|
+ return Result.error("修改计划出价接口异常");
|
|
|
+ }
|
|
|
+ return Result.successMsg("修改计划出价成功",jsonObject.getString("data"));
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ *
|
|
|
+ * @description: 修改计划预算
|
|
|
+ *
|
|
|
+ * @param token
|
|
|
+ * @param advertiserId 广告主ID
|
|
|
+ * @param listMap ad_id 广告计划ID
|
|
|
+ * budget 预算,单位:元。
|
|
|
+ * @return: org.jeecg.common.api.vo.Result
|
|
|
+ * @author: zianY
|
|
|
+ */
|
|
|
+ public static Result updatePlanBudget(CtopOauthToken token,String advertiserId,List<Map<String,Object>> listMap) {
|
|
|
+ JSONObject params = new JSONObject();
|
|
|
+ params.put("advertiser_id", advertiserId);
|
|
|
+ params.put("data", listMap);
|
|
|
+ JSONObject jsonObject = HttpUtils.bytedancePostRequest(token.getAccessToken(),
|
|
|
+ PropertiesUtils.getValue("bytedance_config", "bytedance_v2_ad_update_budget_plan"), params);
|
|
|
+ int code = jsonObject.getInteger("code");
|
|
|
+ Map<String, Object> resultMap = new HashMap<>();
|
|
|
+ if (code != 0) {
|
|
|
+ log.info("修改计划预算接口异常==》accountId:{},message:{}", token.getAccountId(), jsonObject.getString("message"));
|
|
|
+ return Result.error("修改计划预算接口异常");
|
|
|
+ }
|
|
|
+ return Result.successMsg("修改计划预算成功",jsonObject.getString("data"));
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ *
|
|
|
+ * @description: 更新计划状态
|
|
|
+ *
|
|
|
+ * @param token
|
|
|
+ * @param adIds 计划ID集合,限制1~100. 广告计划id需属于广告主,否则会报错!
|
|
|
+ * @param optStatus 操作, "enable"表示启用计划, "delete"表示删除计划, "disable"表示暂停计划。
|
|
|
+ * @return: org.jeecg.common.api.vo.Result
|
|
|
+ * @author: zianY
|
|
|
+ */
|
|
|
+ public static Result updPlanStatus(CtopOauthToken token, List<String> adIds, String optStatus) {
|
|
|
+ JSONObject params = new JSONObject();
|
|
|
+ params.put("advertiser_id", token.getAccountId());
|
|
|
+ params.put("ad_ids", adIds);
|
|
|
+ params.put("opt_status", optStatus);
|
|
|
+ JSONObject jsonObject = HttpUtils.bytedancePostRequest(token.getAccessToken(),
|
|
|
+ urlPath + PropertiesUtils.getValue("bytedance_config", "bytedance_v2_ad_update_status"),
|
|
|
+ params);
|
|
|
+ Integer code = jsonObject.getInteger("code");
|
|
|
+ Map<String, Object> resultMap = new HashMap<>();
|
|
|
+ if (code != 0) {
|
|
|
+ log.error("广告计划更新状态接口异常==》accountId:{},message:{}", token.getAccountId(), jsonObject.getString("message"));
|
|
|
+ return Result.error("广告计划更新状态接口异常");
|
|
|
+ }
|
|
|
+ return Result.successMsg("广告组状态修改成功",jsonObject.getString("data"));
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ *
|
|
|
+ * @description: 获取广告计划
|
|
|
+ *
|
|
|
+ * @param token
|
|
|
+ * @param planSearchVoList 广告计划 入参
|
|
|
+ * @return: org.jeecg.common.api.vo.Result
|
|
|
+ * @author: zianY
|
|
|
+ */
|
|
|
+ public static Result getPlanList(CtopOauthToken token, List<PlanSearchVo> planSearchVoList) {
|
|
|
+ JSONObject params = new JSONObject();
|
|
|
+ params.put("advertiser_id", token.getAccountId());
|
|
|
+ params.put("filtering", planSearchVoList);
|
|
|
+ JSONObject jsonObject = HttpUtils.bytedancePostRequest(token.getAccessToken(),
|
|
|
+ urlPath + PropertiesUtils.getValue("bytedance_config", "bytedance_v2_ad_get_plan"),
|
|
|
+ params);
|
|
|
+ Integer code = jsonObject.getInteger("code");
|
|
|
+ Map<String, Object> resultMap = new HashMap<>();
|
|
|
+ if (code != 0) {
|
|
|
+ log.error("获取广告计划接口异常==》accountId:{},message:{}", token.getAccountId(), jsonObject.getString("message"));
|
|
|
+ return Result.error("获取广告计划接口异常");
|
|
|
+ }
|
|
|
+ return Result.successMsg("获取广告计划成功",jsonObject.getString("data"));
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ *
|
|
|
+ * @description: 广告组更新状态
|
|
|
+ *
|
|
|
+ * @param token
|
|
|
+ * @param campaignIds 广告组ID,不超过100个,且广告组ID属于广告主ID否则会报错;
|
|
|
+ * @param optStatus 操作, "enable"表示启用, "delete"表示删除, "disable"表示暂停;
|
|
|
+ * @return: org.jeecg.common.api.vo.Result
|
|
|
+ * @author: zianY
|
|
|
+ */
|
|
|
+ public static Result updateCampaignStatus(CtopOauthToken token,List<String> campaignIds, String optStatus) {
|
|
|
+ JSONObject params = new JSONObject();
|
|
|
+ //广告主id
|
|
|
+ params.put("advertiser_id", token.getAccountId());
|
|
|
+ params.put("campaign_ids", campaignIds);
|
|
|
+ params.put("opt_status", optStatus);
|
|
|
+ JSONObject jsonObject = HttpUtils.bytedancePostRequest(token.getAccessToken(),
|
|
|
+ urlPath + PropertiesUtils.getValue("bytedance_config", "bytedance_v2_campaign_update_status"), params);
|
|
|
+ Integer code = jsonObject.getInteger("code");
|
|
|
+ if (null == code || !code.equals(0)) {
|
|
|
+ log.info("广告组更新状态接口异常==》accountId:{},message:{}", token.getAccountId(), jsonObject.getString("message"));
|
|
|
+ return Result.error("广告组更新状态接口异常");
|
|
|
+ }
|
|
|
+ JSONObject data = jsonObject.getJSONObject("data");
|
|
|
+ if (null == data) {
|
|
|
+ log.info("广告组更新状态操作异常==》accountId:{},message:{}", token.getAccountId(), jsonObject.getString("message"));
|
|
|
+ return Result.error("广告组更新状态操作异常");
|
|
|
+ }
|
|
|
+ return Result.successMsg("广告组更新状态成功。",jsonObject.getString("data"));
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ *
|
|
|
+ * @description: 获取广告组
|
|
|
+ *
|
|
|
+ * @param token
|
|
|
+ * @param adGroupSearchVoList 广告组 入参
|
|
|
+ * @param page
|
|
|
+ * @param pageSize
|
|
|
+ * @return: org.jeecg.common.api.vo.Result
|
|
|
+ * @author: zianY
|
|
|
+ */
|
|
|
+ public static Result getCampaignGroupList(CtopOauthToken token,List<AdGroupSearchVo> adGroupSearchVoList,int page,int pageSize) {
|
|
|
+
|
|
|
+ JSONObject params = new JSONObject();
|
|
|
+ params.put("advertiser_id", token.getAccountId());
|
|
|
+ params.put("filtering", adGroupSearchVoList);
|
|
|
+ params.put("page", page);
|
|
|
+ params.put("page_size", pageSize);
|
|
|
+ JSONObject jsonObject = HttpUtils.bytedanceGetRequest(token.getAccessToken(),
|
|
|
+ urlPath + PropertiesUtils.getValue("bytedance_config", "bytedance_v2_campaign_get"),
|
|
|
+ params);
|
|
|
+ Integer code = jsonObject.getInteger("code");
|
|
|
+ if (null == code || !code.equals(0)) {
|
|
|
+ log.error("获取广告组信息接口异常==》accountId:{},message:{}", token.getAccountId(), jsonObject.getString("message"));
|
|
|
+ return Result.error(jsonObject.getString("message"));
|
|
|
+ }
|
|
|
+ JSONArray data = jsonObject.getJSONObject("data").getJSONArray("list");
|
|
|
+ if (null == data || data.isEmpty()) {
|
|
|
+ log.info("获取广告组信息为空==》accountId:{},message:{}", token.getAccountId(), jsonObject.getString("message"));
|
|
|
+ return Result.error("获取广告组信息为空");
|
|
|
+ }
|
|
|
+ return Result.successMsg("获取广告组信息成功",data);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+}
|