From 83bada952216c0b1b0746022236175c90f3627cf Mon Sep 17 00:00:00 2001 From: Syd Xu Date: Fri, 11 Oct 2024 17:18:15 +0800 Subject: [PATCH 1/2] =?UTF-8?q?feat(local):=20=E5=A2=9E=E5=8A=A0=E6=9C=AC?= =?UTF-8?q?=E5=9C=B0=E6=8E=A8=E7=9B=B8=E5=85=B3API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + marketing-api/LOCAL.md | 23 +++ .../api/local/aweme/authorized_get.go | 17 ++ marketing-api/api/local/aweme/doc.go | 2 + marketing-api/api/local/customaudience/doc.go | 2 + marketing-api/api/local/customaudience/get.go | 17 ++ marketing-api/api/local/doc.go | 2 + marketing-api/api/local/poi/doc.go | 2 + .../api/local/poi/multi_poi_ids_get.go | 17 ++ marketing-api/api/local/product/doc.go | 2 + marketing-api/api/local/product/get.go | 17 ++ .../api/local/product/get_by_poiids.go | 20 ++ marketing-api/api/local/project/create.go | 19 ++ marketing-api/api/local/project/detail.go | 18 ++ marketing-api/api/local/project/doc.go | 2 + marketing-api/api/local/project/list.go | 18 ++ .../api/local/project/status_update.go | 17 ++ marketing-api/api/local/project/update.go | 16 ++ marketing-api/api/local/promotion/create.go | 18 ++ marketing-api/api/local/promotion/detail.go | 18 ++ marketing-api/api/local/promotion/doc.go | 2 + marketing-api/api/local/promotion/list.go | 18 ++ .../api/local/promotion/status_update.go | 17 ++ marketing-api/api/local/promotion/update.go | 14 ++ marketing-api/api/local/report/doc.go | 2 + .../api/local/report/material_get.go | 18 ++ marketing-api/api/local/report/project_get.go | 18 ++ .../api/local/report/promotion_get.go | 18 ++ marketing-api/enum/holiday.go | 29 +++ marketing-api/enum/learning_phase.go | 2 + marketing-api/enum/local/ad_type.go | 13 ++ marketing-api/enum/local/bid_type.go | 13 ++ marketing-api/enum/local/city_divide.go | 11 ++ .../enum/local/converted_time_duration.go | 19 ++ .../enum/local/custom_audience_tags_type.go | 11 ++ marketing-api/enum/local/delivery_goal.go | 11 ++ .../enum/local/delivery_poi_model.go | 11 ++ marketing-api/enum/local/external_action.go | 31 +++ marketing-api/enum/local/gender.go | 13 ++ marketing-api/enum/local/hide_if_converted.go | 19 ++ marketing-api/enum/local/image_mode.go | 11 ++ .../enum/local/local_delivery_scene.go | 23 +++ marketing-api/enum/local/location_type.go | 15 ++ marketing-api/enum/local/marketing_goal.go | 13 ++ marketing-api/enum/local/poi_around_radius.go | 19 ++ marketing-api/enum/local/project_status.go | 25 +++ marketing-api/enum/local/promotion_status.go | 57 ++++++ marketing-api/enum/local/schedule_type.go | 13 ++ marketing-api/enum/material_mode.go | 2 + .../enum/promotion_reject_reason_type.go | 2 + marketing-api/enum/stat_time_granularity.go | 2 + marketing-api/enum/weekday.go | 21 ++ .../model/local/aweme/authorized_get.go | 65 +++++++ marketing-api/model/local/aweme/aweme.go | 28 +++ marketing-api/model/local/aweme/doc.go | 2 + .../local/customaudience/custom_audience.go | 15 ++ .../model/local/customaudience/doc.go | 2 + .../model/local/customaudience/get.go | 54 ++++++ marketing-api/model/local/doc.go | 2 + marketing-api/model/local/poi/doc.go | 2 + marketing-api/model/local/poi/multi_poi.go | 9 + .../model/local/poi/multi_poi_ids_get.go | 47 +++++ marketing-api/model/local/product/doc.go | 2 + marketing-api/model/local/product/get.go | 66 +++++++ .../model/local/product/get_by_poiids.go | 35 ++++ marketing-api/model/local/product/product.go | 17 ++ marketing-api/model/local/project/audience.go | 136 +++++++++++++ marketing-api/model/local/project/create.go | 179 ++++++++++++++++++ marketing-api/model/local/project/detail.go | 33 ++++ marketing-api/model/local/project/doc.go | 2 + marketing-api/model/local/project/list.go | 112 +++++++++++ marketing-api/model/local/project/project.go | 175 +++++++++++++++++ .../model/local/project/status_update.go | 58 ++++++ marketing-api/model/local/project/update.go | 87 +++++++++ marketing-api/model/local/promotion/create.go | 51 +++++ .../local/promotion/customer_material.go | 61 ++++++ marketing-api/model/local/promotion/detail.go | 32 ++++ marketing-api/model/local/promotion/doc.go | 2 + marketing-api/model/local/promotion/list.go | 140 ++++++++++++++ .../model/local/promotion/promotion.go | 57 ++++++ .../model/local/promotion/status_update.go | 58 ++++++ marketing-api/model/local/promotion/update.go | 33 ++++ marketing-api/model/local/report/doc.go | 2 + .../model/local/report/material_get.go | 97 ++++++++++ .../model/local/report/project_get.go | 105 ++++++++++ .../model/local/report/promotion_get.go | 105 ++++++++++ marketing-api/model/local/report/report.go | 119 ++++++++++++ 87 files changed, 2731 insertions(+) create mode 100644 marketing-api/LOCAL.md create mode 100644 marketing-api/api/local/aweme/authorized_get.go create mode 100644 marketing-api/api/local/aweme/doc.go create mode 100644 marketing-api/api/local/customaudience/doc.go create mode 100644 marketing-api/api/local/customaudience/get.go create mode 100644 marketing-api/api/local/doc.go create mode 100644 marketing-api/api/local/poi/doc.go create mode 100644 marketing-api/api/local/poi/multi_poi_ids_get.go create mode 100644 marketing-api/api/local/product/doc.go create mode 100644 marketing-api/api/local/product/get.go create mode 100644 marketing-api/api/local/product/get_by_poiids.go create mode 100644 marketing-api/api/local/project/create.go create mode 100644 marketing-api/api/local/project/detail.go create mode 100644 marketing-api/api/local/project/doc.go create mode 100644 marketing-api/api/local/project/list.go create mode 100644 marketing-api/api/local/project/status_update.go create mode 100644 marketing-api/api/local/project/update.go create mode 100644 marketing-api/api/local/promotion/create.go create mode 100644 marketing-api/api/local/promotion/detail.go create mode 100644 marketing-api/api/local/promotion/doc.go create mode 100644 marketing-api/api/local/promotion/list.go create mode 100644 marketing-api/api/local/promotion/status_update.go create mode 100644 marketing-api/api/local/promotion/update.go create mode 100644 marketing-api/api/local/report/doc.go create mode 100644 marketing-api/api/local/report/material_get.go create mode 100644 marketing-api/api/local/report/project_get.go create mode 100644 marketing-api/api/local/report/promotion_get.go create mode 100644 marketing-api/enum/holiday.go create mode 100644 marketing-api/enum/local/ad_type.go create mode 100644 marketing-api/enum/local/bid_type.go create mode 100644 marketing-api/enum/local/city_divide.go create mode 100644 marketing-api/enum/local/converted_time_duration.go create mode 100644 marketing-api/enum/local/custom_audience_tags_type.go create mode 100644 marketing-api/enum/local/delivery_goal.go create mode 100644 marketing-api/enum/local/delivery_poi_model.go create mode 100644 marketing-api/enum/local/external_action.go create mode 100644 marketing-api/enum/local/gender.go create mode 100644 marketing-api/enum/local/hide_if_converted.go create mode 100644 marketing-api/enum/local/image_mode.go create mode 100644 marketing-api/enum/local/local_delivery_scene.go create mode 100644 marketing-api/enum/local/location_type.go create mode 100644 marketing-api/enum/local/marketing_goal.go create mode 100644 marketing-api/enum/local/poi_around_radius.go create mode 100644 marketing-api/enum/local/project_status.go create mode 100644 marketing-api/enum/local/promotion_status.go create mode 100644 marketing-api/enum/local/schedule_type.go create mode 100644 marketing-api/enum/weekday.go create mode 100644 marketing-api/model/local/aweme/authorized_get.go create mode 100644 marketing-api/model/local/aweme/aweme.go create mode 100644 marketing-api/model/local/aweme/doc.go create mode 100644 marketing-api/model/local/customaudience/custom_audience.go create mode 100644 marketing-api/model/local/customaudience/doc.go create mode 100644 marketing-api/model/local/customaudience/get.go create mode 100644 marketing-api/model/local/doc.go create mode 100644 marketing-api/model/local/poi/doc.go create mode 100644 marketing-api/model/local/poi/multi_poi.go create mode 100644 marketing-api/model/local/poi/multi_poi_ids_get.go create mode 100644 marketing-api/model/local/product/doc.go create mode 100644 marketing-api/model/local/product/get.go create mode 100644 marketing-api/model/local/product/get_by_poiids.go create mode 100644 marketing-api/model/local/product/product.go create mode 100644 marketing-api/model/local/project/audience.go create mode 100644 marketing-api/model/local/project/create.go create mode 100644 marketing-api/model/local/project/detail.go create mode 100644 marketing-api/model/local/project/doc.go create mode 100644 marketing-api/model/local/project/list.go create mode 100644 marketing-api/model/local/project/project.go create mode 100644 marketing-api/model/local/project/status_update.go create mode 100644 marketing-api/model/local/project/update.go create mode 100644 marketing-api/model/local/promotion/create.go create mode 100644 marketing-api/model/local/promotion/customer_material.go create mode 100644 marketing-api/model/local/promotion/detail.go create mode 100644 marketing-api/model/local/promotion/doc.go create mode 100644 marketing-api/model/local/promotion/list.go create mode 100644 marketing-api/model/local/promotion/promotion.go create mode 100644 marketing-api/model/local/promotion/status_update.go create mode 100644 marketing-api/model/local/promotion/update.go create mode 100644 marketing-api/model/local/report/doc.go create mode 100644 marketing-api/model/local/report/material_get.go create mode 100644 marketing-api/model/local/report/project_get.go create mode 100644 marketing-api/model/local/report/promotion_get.go create mode 100644 marketing-api/model/local/report/report.go diff --git a/README.md b/README.md index dab90581..c810702e 100644 --- a/README.md +++ b/README.md @@ -11,5 +11,6 @@ - [巨量引擎开放平台SDK](https://github.com/bububa/oceanengine/blob/master/marketing-api/OCEANENGINE.md) - [巨量千川开放平台SDK](https://github.com/bububa/oceanengine/blob/master/marketing-api/QIANCHUAN.md) - [巨量星图开放平台SDK](https://github.com/bububa/oceanengine/blob/master/marketing-api/STAR.md) +- [巨量本地推开放平台SDK](https://github.com/bububa/oceanengine/blob/master/marketing-api/LOCAL.md) - [企业号开放平台SDK](https://github.com/bububa/oceanengine/blob/master/marketing-api/ENTERPRISE.md) - [巨量应用市场SDK](https://github.com/bububa/oceanengine/blob/master/marketing-api/SERVE_MARKET.md) diff --git a/marketing-api/LOCAL.md b/marketing-api/LOCAL.md new file mode 100644 index 00000000..83b73fb9 --- /dev/null +++ b/marketing-api/LOCAL.md @@ -0,0 +1,23 @@ +# 本地推 Golang SDK + +- 项目管理模块 (local/project) + - 创建项目 [ Create(ctx context.Context, clt *core.SDKClient, accessToken string, req *project.CreateRequest) (uint64, error) ] + - 更新项目 [ Update(ctx context.Context, clt *core.SDKClient, accessToken string, req *project.UpdateRequest) error ] + - 获取项目列表 [ List(ctx context.Context, clt *core.SDKClient, accessToken string, req *project.ListRequest) (*project.ListResult, error) ] + - 获取项目详情 [ Detail(ctx context.Context, clt *core.SDKClient, accessToken string, req *project.DetailRequest) (*project.ProjectDetail, error) ] + - 批量更新项目状态 [ StatusUpdate(ctx context.Context, clt *core.SDKClient, accessToken string, req *project.StatusUpdateRequest) (*project.UpdateResult, error) ] + - 获取可投商品列表 [ product.Get(ctx context.Context, clt *core.SDKClient, accessToken string, req *product.GetRequest) (*product.GetResult, error) ] + - 获取本地推创编可用抖音号 [ aweme.AuthorizedGet(ctx context.Context, clt *core.SDKClient, accessToken string, req *aweme.AuthorizedGetRequest) (*aweme.AuthorizedGetResult, error) ] + - 查询本地推创编可用人群包 [ customaudience.Get(ctx context.Context, clt *core.SDKClient, accessToken string, req *customaudience.GetRequest) (*customaudience.GetResult, error) ] + - 根据多门店ID拉取门店ID [ poi.MultiPoiIDsGet(ctx context.Context, clt *core.SDKClient, accessToken string, req *poi.MultiPoiIDsGetRequest) (*poi.MultiPoiIDsGetResult, error) ] +- 广告管理模块 (local/promotion) + - 创建广告 [ Create(ctx context.Context, clt *core.SDKClient, accessToken string, req *promotion.CreateRequest) (uint64, error) ] + - 更新广告 [ Update(ctx context.Context, clt *core.SDKClient, accessToken string, req *promotion.UpdateRequest) error ] + - 获取广告列表 [ List(ctx context.Context, clt *core.SDKClient, accessToken string, req *promotion.ListRequest) (*promotion.ListResult, error) ] + - 获取广告详情 [ Detail(ctx context.Context, clt *core.SDKClient, accessToken string, req *promotion.DetailRequest) (*promotion.PromotionDetail, error) ] + - 批量更新广告状态 [ StatusUpdate(ctx context.Context, clt *core.SDKClient, accessToken string, req *promotion.StatusUpdateRequest) (*promotion.UpdateResult, error) ] + - 根据门店ID查询门店下商品ID [ product.GetByPoiIDs(ctx context.Context, clt *core.SDKClient, accessToken string, req *product.GetByPoiIDsRequest) ([]uint64, error) ] +- 本地推数据报表 (local/report) + - 获取项目数据 [ ProjectGet(ctx context.Context, clt *core.SDKClient, accessToken string, req *report.ProjectGetRequest) (*report.ProjectGetResult, error) ] + - 获取广告数据 [ PromotionGet(ctx context.Context, clt *core.SDKClient, accessToken string, req *report.PromotionGetRequest) (*report.PromotionGetResult, error) ] + - 获取素材数据 [ MaterialGet(ctx context.Context, clt *core.SDKClient, accessToken string, req *report.MaterialGetRequest) (*report.MaterialGetResult, error) ] diff --git a/marketing-api/api/local/aweme/authorized_get.go b/marketing-api/api/local/aweme/authorized_get.go new file mode 100644 index 00000000..1dab7db1 --- /dev/null +++ b/marketing-api/api/local/aweme/authorized_get.go @@ -0,0 +1,17 @@ +package aweme + +import ( + "context" + + "github.com/bububa/oceanengine/marketing-api/core" + "github.com/bububa/oceanengine/marketing-api/model/local/aweme" +) + +// AuthorizedGet 获取本地推创编可用抖音号 +func AuthorizedGet(ctx context.Context, clt *core.SDKClient, accessToken string, req *aweme.AuthorizedGetRequest) (*aweme.AuthorizedGetResult, error) { + var resp aweme.AuthorizedGetResponse + if err := clt.GetAPI(ctx, "v3.0/local/aweme/authorized/get/", req, &resp, accessToken); err != nil { + return nil, err + } + return resp.Data, nil +} diff --git a/marketing-api/api/local/aweme/doc.go b/marketing-api/api/local/aweme/doc.go new file mode 100644 index 00000000..ed37fe59 --- /dev/null +++ b/marketing-api/api/local/aweme/doc.go @@ -0,0 +1,2 @@ +// Package aweme 抖音号相关 +package aweme diff --git a/marketing-api/api/local/customaudience/doc.go b/marketing-api/api/local/customaudience/doc.go new file mode 100644 index 00000000..12081413 --- /dev/null +++ b/marketing-api/api/local/customaudience/doc.go @@ -0,0 +1,2 @@ +// Package customaudience 人群包相关 +package customaudience diff --git a/marketing-api/api/local/customaudience/get.go b/marketing-api/api/local/customaudience/get.go new file mode 100644 index 00000000..811b0ca6 --- /dev/null +++ b/marketing-api/api/local/customaudience/get.go @@ -0,0 +1,17 @@ +package customaudience + +import ( + "context" + + "github.com/bububa/oceanengine/marketing-api/core" + "github.com/bububa/oceanengine/marketing-api/model/local/customaudience" +) + +// Get 查询本地推创编可用人群包 +func Get(ctx context.Context, clt *core.SDKClient, accessToken string, req *customaudience.GetRequest) (*customaudience.GetResult, error) { + var resp customaudience.GetResponse + if err := clt.GetAPI(ctx, "v3.0/local/custom_audience/get/", req, &resp, accessToken); err != nil { + return nil, err + } + return resp.Data, nil +} diff --git a/marketing-api/api/local/doc.go b/marketing-api/api/local/doc.go new file mode 100644 index 00000000..7251de81 --- /dev/null +++ b/marketing-api/api/local/doc.go @@ -0,0 +1,2 @@ +// Package local 本地推相关 +package local diff --git a/marketing-api/api/local/poi/doc.go b/marketing-api/api/local/poi/doc.go new file mode 100644 index 00000000..6ff24407 --- /dev/null +++ b/marketing-api/api/local/poi/doc.go @@ -0,0 +1,2 @@ +// Package poi 门店相关 +package poi diff --git a/marketing-api/api/local/poi/multi_poi_ids_get.go b/marketing-api/api/local/poi/multi_poi_ids_get.go new file mode 100644 index 00000000..5ef2963e --- /dev/null +++ b/marketing-api/api/local/poi/multi_poi_ids_get.go @@ -0,0 +1,17 @@ +package poi + +import ( + "context" + + "github.com/bububa/oceanengine/marketing-api/core" + "github.com/bububa/oceanengine/marketing-api/model/local/poi" +) + +// MultiPoiIDsGet 根据多门店ID拉取门店ID +func MultiPoiIDsGet(ctx context.Context, clt *core.SDKClient, accessToken string, req *poi.MultiPoiIDsGetRequest) (*poi.MultiPoiIDsGetResult, error) { + var resp poi.MultiPoiIDsGetResponse + if err := clt.GetAPI(ctx, "v3.0/local/multi_poi_id/poi_ids/get/", req, &resp, accessToken); err != nil { + return nil, err + } + return resp.Data, nil +} diff --git a/marketing-api/api/local/product/doc.go b/marketing-api/api/local/product/doc.go new file mode 100644 index 00000000..8a722b13 --- /dev/null +++ b/marketing-api/api/local/product/doc.go @@ -0,0 +1,2 @@ +// Package product 产品相关 +package product diff --git a/marketing-api/api/local/product/get.go b/marketing-api/api/local/product/get.go new file mode 100644 index 00000000..5762f9f3 --- /dev/null +++ b/marketing-api/api/local/product/get.go @@ -0,0 +1,17 @@ +package product + +import ( + "context" + + "github.com/bububa/oceanengine/marketing-api/core" + "github.com/bububa/oceanengine/marketing-api/model/local/product" +) + +// Get 获取可投商品列表 +func Get(ctx context.Context, clt *core.SDKClient, accessToken string, req *product.GetRequest) (*product.GetResult, error) { + var resp product.GetResponse + if err := clt.GetAPI(ctx, "v3.0/local/product/get/", req, &resp, accessToken); err != nil { + return nil, err + } + return resp.Data, nil +} diff --git a/marketing-api/api/local/product/get_by_poiids.go b/marketing-api/api/local/product/get_by_poiids.go new file mode 100644 index 00000000..bb0ec522 --- /dev/null +++ b/marketing-api/api/local/product/get_by_poiids.go @@ -0,0 +1,20 @@ +package product + +import ( + "context" + + "github.com/bububa/oceanengine/marketing-api/core" + "github.com/bububa/oceanengine/marketing-api/model/local/product" +) + +// GetByPoiIDs 根据门店ID查询门店下商品ID +// 该接口使用场景说明: +// 通过【获取抖音主页视频】接口拉取挂载了商品锚点的视频时,需要传入商品ids。如果为推门店场景,可以通过该接口获取所推广门店下的商品ID,进而拉取到挂载了门店下商品锚点的抖音主页视频进行投放。 +// 仅创编推广目的=团购成交/门店引流/内容加热的计划时,可能涉及该接口的使用;推广目的=获取线索的计划不涉及。 +func GetByPoiIDs(ctx context.Context, clt *core.SDKClient, accessToken string, req *product.GetByPoiIDsRequest) ([]uint64, error) { + var resp product.GetByPoiIDsResponse + if err := clt.GetAPI(ctx, "v3.0/local/product/get_by_poiids/", req, &resp, accessToken); err != nil { + return nil, err + } + return resp.Data.ProductIDs, nil +} diff --git a/marketing-api/api/local/project/create.go b/marketing-api/api/local/project/create.go new file mode 100644 index 00000000..9d3649c2 --- /dev/null +++ b/marketing-api/api/local/project/create.go @@ -0,0 +1,19 @@ +package project + +import ( + "context" + + "github.com/bububa/oceanengine/marketing-api/core" + "github.com/bububa/oceanengine/marketing-api/model/local/project" +) + +// Create 创建项目 +// 创建 巨量引擎体验版 项目 广告主下可创建项目数:200 +// 项目创建成功后,默认为启用状态 +func Create(ctx context.Context, clt *core.SDKClient, accessToken string, req *project.CreateRequest) (uint64, error) { + var resp project.CreateResponse + if err := clt.PostAPI(ctx, "v3.0/local/project/create/", req, &resp, accessToken); err != nil { + return 0, err + } + return resp.Data.ProjectID, nil +} diff --git a/marketing-api/api/local/project/detail.go b/marketing-api/api/local/project/detail.go new file mode 100644 index 00000000..6fced599 --- /dev/null +++ b/marketing-api/api/local/project/detail.go @@ -0,0 +1,18 @@ +package project + +import ( + "context" + + "github.com/bububa/oceanengine/marketing-api/core" + "github.com/bububa/oceanengine/marketing-api/model/local/project" +) + +// Detail 获取项目详情 +// 该接口暂不支持拉取推广目的为获取线索的项目 +func Detail(ctx context.Context, clt *core.SDKClient, accessToken string, req *project.DetailRequest) (*project.ProjectDetail, error) { + var resp project.DetailResponse + if err := clt.GetAPI(ctx, "v3.0/local/project/detail/", req, &resp, accessToken); err != nil { + return nil, err + } + return resp.Data, nil +} diff --git a/marketing-api/api/local/project/doc.go b/marketing-api/api/local/project/doc.go new file mode 100644 index 00000000..bfffe81c --- /dev/null +++ b/marketing-api/api/local/project/doc.go @@ -0,0 +1,2 @@ +// Package project 项目管理模块 +package project diff --git a/marketing-api/api/local/project/list.go b/marketing-api/api/local/project/list.go new file mode 100644 index 00000000..70a0a4f8 --- /dev/null +++ b/marketing-api/api/local/project/list.go @@ -0,0 +1,18 @@ +package project + +import ( + "context" + + "github.com/bububa/oceanengine/marketing-api/core" + "github.com/bububa/oceanengine/marketing-api/model/local/project" +) + +// List 获取项目列表 +// 注意:该接口暂不支持拉取推广目的为获取线索的项目 +func List(ctx context.Context, clt *core.SDKClient, accessToken string, req *project.ListRequest) (*project.ListResult, error) { + var resp project.ListResponse + if err := clt.GetAPI(ctx, "v3.0/local/project/list/", req, &resp, accessToken); err != nil { + return nil, err + } + return resp.Data, nil +} diff --git a/marketing-api/api/local/project/status_update.go b/marketing-api/api/local/project/status_update.go new file mode 100644 index 00000000..e38a0a9d --- /dev/null +++ b/marketing-api/api/local/project/status_update.go @@ -0,0 +1,17 @@ +package project + +import ( + "context" + + "github.com/bububa/oceanengine/marketing-api/core" + "github.com/bububa/oceanengine/marketing-api/model/local/project" +) + +// StatusUpdate 批量更新项目状态 +func StatusUpdate(ctx context.Context, clt *core.SDKClient, accessToken string, req *project.StatusUpdateRequest) (*project.UpdateResult, error) { + var resp project.StatusUpdateResponse + if err := clt.PostAPI(ctx, "v3.0/local/project/status/update/", req, &resp, accessToken); err != nil { + return nil, err + } + return resp.Data, nil +} diff --git a/marketing-api/api/local/project/update.go b/marketing-api/api/local/project/update.go new file mode 100644 index 00000000..60207b29 --- /dev/null +++ b/marketing-api/api/local/project/update.go @@ -0,0 +1,16 @@ +package project + +import ( + "context" + + "github.com/bububa/oceanengine/marketing-api/core" + "github.com/bububa/oceanengine/marketing-api/model/local/project" +) + +// Update 更新项目 +// 接口的更新逻辑为增量更新 +// 定向参数如需设置对应受众为不限:string类型受众设置无限统一传入不限枚举,list类型的受众设置无限统一传入空数组,即[] +// 对于不打算更新的字段,不要传“”或者null,传了会校验 +func Update(ctx context.Context, clt *core.SDKClient, accessToken string, req *project.UpdateRequest) error { + return clt.PostAPI(ctx, "v3.0/local/project/update/", req, nil, accessToken) +} diff --git a/marketing-api/api/local/promotion/create.go b/marketing-api/api/local/promotion/create.go new file mode 100644 index 00000000..61ee64d5 --- /dev/null +++ b/marketing-api/api/local/promotion/create.go @@ -0,0 +1,18 @@ +package promotion + +import ( + "context" + + "github.com/bububa/oceanengine/marketing-api/core" + "github.com/bububa/oceanengine/marketing-api/model/local/promotion" +) + +// Create 创建广告 +// 广告创建成功后,默认为启用状态 +func Create(ctx context.Context, clt *core.SDKClient, accessToken string, req *promotion.CreateRequest) (uint64, error) { + var resp promotion.CreateResponse + if err := clt.PostAPI(ctx, "v3.0/local/promotion/create/", req, &resp, accessToken); err != nil { + return 0, err + } + return resp.Data.PromotionID, nil +} diff --git a/marketing-api/api/local/promotion/detail.go b/marketing-api/api/local/promotion/detail.go new file mode 100644 index 00000000..8edf52e7 --- /dev/null +++ b/marketing-api/api/local/promotion/detail.go @@ -0,0 +1,18 @@ +package promotion + +import ( + "context" + + "github.com/bububa/oceanengine/marketing-api/core" + "github.com/bububa/oceanengine/marketing-api/model/local/promotion" +) + +// Detail 获取广告详情 +// 暂不支持拉取推广目的为获取线索的广告 +func Detail(ctx context.Context, clt *core.SDKClient, accessToken string, req *promotion.DetailRequest) (*promotion.PromotionDetail, error) { + var resp promotion.DetailResponse + if err := clt.GetAPI(ctx, "v3.0/local/promotion/detail/", req, &resp, accessToken); err != nil { + return nil, err + } + return resp.Data, nil +} diff --git a/marketing-api/api/local/promotion/doc.go b/marketing-api/api/local/promotion/doc.go new file mode 100644 index 00000000..d93ed8e4 --- /dev/null +++ b/marketing-api/api/local/promotion/doc.go @@ -0,0 +1,2 @@ +// Package promotion 广告管理模块 +package promotion diff --git a/marketing-api/api/local/promotion/list.go b/marketing-api/api/local/promotion/list.go new file mode 100644 index 00000000..540f85a9 --- /dev/null +++ b/marketing-api/api/local/promotion/list.go @@ -0,0 +1,18 @@ +package promotion + +import ( + "context" + + "github.com/bububa/oceanengine/marketing-api/core" + "github.com/bububa/oceanengine/marketing-api/model/local/promotion" +) + +// List 获取广告列表 +// 该接口暂不支持拉取 推广目的为获取线索的项目下的广告 +func List(ctx context.Context, clt *core.SDKClient, accessToken string, req *promotion.ListRequest) (*promotion.ListResult, error) { + var resp promotion.ListResponse + if err := clt.GetAPI(ctx, "v3.0/local/promotion/list/", req, &resp, accessToken); err != nil { + return nil, err + } + return resp.Data, nil +} diff --git a/marketing-api/api/local/promotion/status_update.go b/marketing-api/api/local/promotion/status_update.go new file mode 100644 index 00000000..c235271c --- /dev/null +++ b/marketing-api/api/local/promotion/status_update.go @@ -0,0 +1,17 @@ +package promotion + +import ( + "context" + + "github.com/bububa/oceanengine/marketing-api/core" + "github.com/bububa/oceanengine/marketing-api/model/local/promotion" +) + +// StatusUpdate 批量更新广告状态 +func StatusUpdate(ctx context.Context, clt *core.SDKClient, accessToken string, req *promotion.StatusUpdateRequest) (*promotion.UpdateResult, error) { + var resp promotion.StatusUpdateResponse + if err := clt.PostAPI(ctx, "v3.0/local/promotion/status/update/", req, &resp, accessToken); err != nil { + return nil, err + } + return resp.Data, nil +} diff --git a/marketing-api/api/local/promotion/update.go b/marketing-api/api/local/promotion/update.go new file mode 100644 index 00000000..c35d008a --- /dev/null +++ b/marketing-api/api/local/promotion/update.go @@ -0,0 +1,14 @@ +package promotion + +import ( + "context" + + "github.com/bububa/oceanengine/marketing-api/core" + "github.com/bububa/oceanengine/marketing-api/model/local/promotion" +) + +// Update 更新广告 +// 本接口为全量更新,每次更新会对所有参数进行调整,若希望进行局部更新,请先通过获取广告列表接口前置获取广告的详情信息再进行更新 +func Update(ctx context.Context, clt *core.SDKClient, accessToken string, req *promotion.UpdateRequest) error { + return clt.PostAPI(ctx, "v3.0/local/promotion/update/", req, nil, accessToken) +} diff --git a/marketing-api/api/local/report/doc.go b/marketing-api/api/local/report/doc.go new file mode 100644 index 00000000..66d7b255 --- /dev/null +++ b/marketing-api/api/local/report/doc.go @@ -0,0 +1,2 @@ +// Package report 本地推数据报表相关 +package report diff --git a/marketing-api/api/local/report/material_get.go b/marketing-api/api/local/report/material_get.go new file mode 100644 index 00000000..f85cdf6d --- /dev/null +++ b/marketing-api/api/local/report/material_get.go @@ -0,0 +1,18 @@ +package report + +import ( + "context" + + "github.com/bububa/oceanengine/marketing-api/core" + "github.com/bububa/oceanengine/marketing-api/model/local/report" +) + +// MaterialGet 获取素材数据 +// 获取素材维度报表数据内容获取 +func MaterialGet(ctx context.Context, clt *core.SDKClient, accessToken string, req *report.MaterialGetRequest) (*report.MaterialGetResult, error) { + var resp report.MaterialGetResponse + if err := clt.GetAPI(ctx, "v3.0/local/report/material/get/", req, &resp, accessToken); err != nil { + return nil, err + } + return resp.Data, nil +} diff --git a/marketing-api/api/local/report/project_get.go b/marketing-api/api/local/report/project_get.go new file mode 100644 index 00000000..90274928 --- /dev/null +++ b/marketing-api/api/local/report/project_get.go @@ -0,0 +1,18 @@ +package report + +import ( + "context" + + "github.com/bububa/oceanengine/marketing-api/core" + "github.com/bububa/oceanengine/marketing-api/model/local/report" +) + +// ProjectGet 获取项目数据 +// 获取项目维度报表数据内容 +func ProjectGet(ctx context.Context, clt *core.SDKClient, accessToken string, req *report.ProjectGetRequest) (*report.ProjectGetResult, error) { + var resp report.ProjectGetResponse + if err := clt.GetAPI(ctx, "v3.0/local/report/project/get/", req, &resp, accessToken); err != nil { + return nil, err + } + return resp.Data, nil +} diff --git a/marketing-api/api/local/report/promotion_get.go b/marketing-api/api/local/report/promotion_get.go new file mode 100644 index 00000000..4aefd163 --- /dev/null +++ b/marketing-api/api/local/report/promotion_get.go @@ -0,0 +1,18 @@ +package report + +import ( + "context" + + "github.com/bububa/oceanengine/marketing-api/core" + "github.com/bububa/oceanengine/marketing-api/model/local/report" +) + +// PromotionGet 获取广告数据 +// 获取广告维度报表数据内容 +func PromotionGet(ctx context.Context, clt *core.SDKClient, accessToken string, req *report.PromotionGetRequest) (*report.PromotionGetResult, error) { + var resp report.PromotionGetResponse + if err := clt.GetAPI(ctx, "v3.0/local/report/promotion/get/", req, &resp, accessToken); err != nil { + return nil, err + } + return resp.Data, nil +} diff --git a/marketing-api/enum/holiday.go b/marketing-api/enum/holiday.go new file mode 100644 index 00000000..0f9c50ab --- /dev/null +++ b/marketing-api/enum/holiday.go @@ -0,0 +1,29 @@ +package enum + +// Holiday 节假日 +type Holiday string + +const ( + // NEW_YEAR 元旦 + NEW_YEAR Holiday = "NEW_YEAR" + // SPRING_FESTIVAL 春节 + SPRING_FESTIVAL Holiday = "SPRING_FESTIVAL" + // VALENTINES_DAY 情人节 + VALENTINES_DAY Holiday = "VALENTINES_DAY" + // LABOUR_DAY 五一 + LABOUR_DAY Holiday = "LABOUR_DAY" + // DRAGON_BOAT_FESTIVAL 端午 + DRAGON_BOAT_FESTIVAL Holiday = "DRAGON_BOAT_FESTIVAL" + // CHINESE_VALENTINES_DAY 七夕 + CHINESE_VALENTINES_DAY Holiday = "CHINESE_VALENTINES_DAY" + // MOON_FESTIVAL 中秋 + MOON_FESTIVAL Holiday = "MOON_FESTIVAL" + // NATIONAL_DAY 国庆 + NATIONAL_DAY Holiday = "NATIONAL_DAY" + // CHRISTMAS 圣诞节 + CHRISTMAS Holiday = "CHRISTMAS" + // SHOPPING_DAY_618 618 + SHOPPING_DAY_618 Holiday = "SHOPPING_DAY_618" + // SHOPPING_DAY_1111 双11 + SHOPPING_DAY_1111 Holiday = "SHOPPING_DAY_1111" +) diff --git a/marketing-api/enum/learning_phase.go b/marketing-api/enum/learning_phase.go index 813c58b2..0db73c84 100644 --- a/marketing-api/enum/learning_phase.go +++ b/marketing-api/enum/learning_phase.go @@ -12,4 +12,6 @@ const ( LearningPhase_LEARNED LearningPhase = "LEARNED" // LearningPhase_LEARN_FAILED 学习失败 LearningPhase_LEARN_FAILED LearningPhase = "LEARN_FAILED" + // LearningPhase_ALL 不限 + LearningPhase_ALL LearningPhase = "ALL" ) diff --git a/marketing-api/enum/local/ad_type.go b/marketing-api/enum/local/ad_type.go new file mode 100644 index 00000000..a110294a --- /dev/null +++ b/marketing-api/enum/local/ad_type.go @@ -0,0 +1,13 @@ +package local + +// AdType 广告类型 +type AdType string + +const ( + // AdType_ALL 不限 + AdType_ALL AdType = "ALL" + // AdType_GENERAL 通投广告 + AdType_GENERAL AdType = "GENERAL" + // AdType_SEARCHING 搜索广告 + AdType_SEARCHING AdType = "SEARCHING" +) diff --git a/marketing-api/enum/local/bid_type.go b/marketing-api/enum/local/bid_type.go new file mode 100644 index 00000000..fa2fb545 --- /dev/null +++ b/marketing-api/enum/local/bid_type.go @@ -0,0 +1,13 @@ +package local + +// BidType 出价方式 +type BidType string + +const ( + // BidType_ALL 不限 + BidType_ALL BidType = "ALL" + // BidType_MANUAL 手动出价 + BidType_MANUAL BidType = "MANUAL" + // BidType_SMART 智能出价 + BidType_SMART BidType = "SMART" +) diff --git a/marketing-api/enum/local/city_divide.go b/marketing-api/enum/local/city_divide.go new file mode 100644 index 00000000..90466b31 --- /dev/null +++ b/marketing-api/enum/local/city_divide.go @@ -0,0 +1,11 @@ +package local + +// CityDivide 城市划分类型 +type CityDivide string + +const ( + // CityDivide_BY_LEVEL 按发展等级划分 + CityDivide_BY_LEVEL CityDivide = "BY_LEVEL" + // CityDivide_BY_LOCATION 按地理划分(默认值) + CityDivide_BY_LOCATION CityDivide = "BY_LOCATION" +) diff --git a/marketing-api/enum/local/converted_time_duration.go b/marketing-api/enum/local/converted_time_duration.go new file mode 100644 index 00000000..5b967f6e --- /dev/null +++ b/marketing-api/enum/local/converted_time_duration.go @@ -0,0 +1,19 @@ +package local + +// ConvertedTimeDuration 过滤已转化投放时间 +type ConvertedTimeDuration string + +const ( + // ConvertedTimeDuration_SEVEN_DAY 七天(默认值) + ConvertedTimeDuration_SEVEN_DAY ConvertedTimeDuration = "SEVEN_DAY" + // ConvertedTimeDuration_ONE_MONTH 1个月 + ConvertedTimeDuration_ONE_MONTH ConvertedTimeDuration = "ONE_MONTH" + // ConvertedTimeDuration_THREE_MONTH 3个月 + ConvertedTimeDuration_THREE_MONTH ConvertedTimeDuration = "THREE_MONTH" + // ConvertedTimeDuration_SIX_MONTH 6个月 + ConvertedTimeDuration_SIX_MONTH ConvertedTimeDuration = "SIX_MONTH" + // ConvertedTimeDuration_TWELVE_MONTH 12个月 + ConvertedTimeDuration_TWELVE_MONTH ConvertedTimeDuration = "TWELVE_MONTH" + // ConvertedTimeDuration_TODAY 当天 + ConvertedTimeDuration_TODAY ConvertedTimeDuration = "TODAY" +) diff --git a/marketing-api/enum/local/custom_audience_tags_type.go b/marketing-api/enum/local/custom_audience_tags_type.go new file mode 100644 index 00000000..9c526d9c --- /dev/null +++ b/marketing-api/enum/local/custom_audience_tags_type.go @@ -0,0 +1,11 @@ +package local + +// CustomAudienceTagsType 人群包属性筛选 +type CustomAudienceTagsType string + +const ( + // CustomAudienceTagsType_CUSTOM 自定义人群包 + CustomAudienceTagsType_CUSTOM CustomAudienceTagsType = "CUSTOM" + // CustomAudienceTagsType_SYS_RECOMMEND 系统推荐人群包 + CustomAudienceTagsType_SYS_RECOMMEND CustomAudienceTagsType = "SYS_RECOMMEND" +) diff --git a/marketing-api/enum/local/delivery_goal.go b/marketing-api/enum/local/delivery_goal.go new file mode 100644 index 00000000..8c3ed4ec --- /dev/null +++ b/marketing-api/enum/local/delivery_goal.go @@ -0,0 +1,11 @@ +package local + +// DeliveryGoal 投放内容 +type DeliveryGoal string + +const ( + // DeliveryGoal_POI 门店 + DeliveryGoal_POI DeliveryGoal = "POI" + // DeliveryGoal_PRODUCT 商品 + DeliveryGoal_PRODUCT DeliveryGoal = "PRODUCT" +) diff --git a/marketing-api/enum/local/delivery_poi_model.go b/marketing-api/enum/local/delivery_poi_model.go new file mode 100644 index 00000000..b8774976 --- /dev/null +++ b/marketing-api/enum/local/delivery_poi_model.go @@ -0,0 +1,11 @@ +package local + +// DeliveryPoiMode 是否投放全部门店 +type DeliveryPoiMode string + +const ( + // DeliveryPoiMode_ALL 投放全部门店 + DeliveryPoiMode_ALL DeliveryPoiMode = "ALL" + // DeliveryPoiMode_PART 投放指定门店 + DeliveryPoiMode_PART DeliveryPoiMode = "PART" +) diff --git a/marketing-api/enum/local/external_action.go b/marketing-api/enum/local/external_action.go new file mode 100644 index 00000000..cc111efb --- /dev/null +++ b/marketing-api/enum/local/external_action.go @@ -0,0 +1,31 @@ +package local + +// ExternalAction 优化目标 +type ExternalAction string + +const ( + // ExternalAction_NATIVE_ACTION 用户互动 + ExternalAction_NATIVE_ACTION ExternalAction = "NATIVE_ACTION" + // ExternalAction_FOLLOW_ACTION 粉丝增长 + ExternalAction_FOLLOW_ACTION ExternalAction = "FOLLOW_ACTION" + // ExternalAction_SHOW 展示量 + ExternalAction_SHOW ExternalAction = "SHOW" + // ExternalAction_OTO_PAY 团购购买 + ExternalAction_OTO_PAY ExternalAction = "OTO_PAY" + // ExternalAction_POI_RECOMMEND 门店引流 + ExternalAction_POI_RECOMMEND ExternalAction = "POI_RECOMMEND" + // ExternalAction_LIVE_OTO_CLICK 商品点击 + ExternalAction_LIVE_OTO_CLICK ExternalAction = "LIVE_OTO_CLICK" + // ExternalAction_LIVE_OTO_GROUP_BUYING 直播间团购购买 + ExternalAction_LIVE_OTO_GROUP_BUYING ExternalAction = "LIVE_OTO_GROUP_BUYING" + // ExternalAction_LIVE_ENGAGE 直播加热 + ExternalAction_LIVE_ENGAGE ExternalAction = "LIVE_ENGAGE" + // ExternalAction_LIVE_ENGAGEMENT 直播加热 + ExternalAction_LIVE_ENGAGEMENT ExternalAction = "LIVE_ENGAGEMENT" + // ExternalAction_FOLLOWER_COUNT 粉丝增长 + ExternalAction_FOLLOWER_COUNT ExternalAction = "FOLLOWER_COUNT" + // ExternalAction_LIVE_ENTER_ACTION 直播间观看 + ExternalAction_LIVE_ENTER_ACTION ExternalAction = "LIVE_ENTER_ACTION" + // ExternalAction_LIVE_STAY_TIME 直播间停留 + ExternalAction_LIVE_STAY_TIME ExternalAction = "LIVE_STAY_TIME" +) diff --git a/marketing-api/enum/local/gender.go b/marketing-api/enum/local/gender.go new file mode 100644 index 00000000..ca126857 --- /dev/null +++ b/marketing-api/enum/local/gender.go @@ -0,0 +1,13 @@ +package local + +// Gender 性别 +type Gender string + +const ( + // Gender_FEMALE 女 + Gender_FEMALE Gender = "FEMALE" + // Gender_MALE 男 + Gender_MALE Gender = "MALE" + // Gender_NONE 不限 + Gender_NONE Gender = "NONE" +) diff --git a/marketing-api/enum/local/hide_if_converted.go b/marketing-api/enum/local/hide_if_converted.go new file mode 100644 index 00000000..7fa2963b --- /dev/null +++ b/marketing-api/enum/local/hide_if_converted.go @@ -0,0 +1,19 @@ +package local + +// HideIfConverted 过滤已转化的维度,可以避免该广告再次投放给已转化过的用户,不传默认不过滤 +type HideIfConverted string + +const ( + // HideIfConverted_NOT_EXCLUDE 不过滤 + HideIfConverted_NOT_EXCLUDE HideIfConverted = "NOT_EXCLUDE" + // HideIfConverted_ADVERTISER 广告主账户 + HideIfConverted_ADVERTISER HideIfConverted = "ADVERTISER" + // HideIfConverted_CC 组织账户 + HideIfConverted_CC HideIfConverted = "CC" + // HideIfConverted_CUSTOMER 公司账户 + HideIfConverted_CUSTOMER HideIfConverted = "CUSTOMER" + // HideIfConverted_PROJECT 项目 + HideIfConverted_PROJECT HideIfConverted = "PROJECT" + // HideIfConverted_PROMOTION 广告 + HideIfConverted_PROMOTION HideIfConverted = "PROMOTION" +) diff --git a/marketing-api/enum/local/image_mode.go b/marketing-api/enum/local/image_mode.go new file mode 100644 index 00000000..3ad598de --- /dev/null +++ b/marketing-api/enum/local/image_mode.go @@ -0,0 +1,11 @@ +package local + +// ImageMode 素材类型 +type ImageMode string + +const ( + // IMAGE_MODE_VIDEO 横版视频 + IMAGE_MODE_VIDEO ImageMode = "IMAGE_MODE_VIDEO" + // IMAGE_MODE_VIDEO_VERTICAL 竖版视频 + IMAGE_MODE_VIDEO_VERTICAL ImageMode = "IMAGE_MODE_VIDEO_VERTICAL" +) diff --git a/marketing-api/enum/local/local_delivery_scene.go b/marketing-api/enum/local/local_delivery_scene.go new file mode 100644 index 00000000..b1128e20 --- /dev/null +++ b/marketing-api/enum/local/local_delivery_scene.go @@ -0,0 +1,23 @@ +package local + +// LocalDeliveryScene 推广目的 +type LocalDeliveryScene string + +const ( + // LocalDeliveryScene_ALL 不限 + LocalDeliveryScene_ALL LocalDeliveryScene = "ALL" + // LocalDeliveryScene_CONTENT_HEAT 内容加热 + LocalDeliveryScene_CONTENT_HEAT LocalDeliveryScene = "CONTENT_HEAT" + // LocalDeliveryScene_POI_RECOMMEND 门店引流 + LocalDeliveryScene_POI_RECOMMEND LocalDeliveryScene = "POI_RECOMMEND" + // LocalDeliveryScene_PRODUCT_PAY 团购成交 + LocalDeliveryScene_PRODUCT_PAY LocalDeliveryScene = "PRODUCT_PAY" + // LocalDeliveryScene_EXTERNAL 销售线索收集 + LocalDeliveryScene_EXTERNAL LocalDeliveryScene = "EXTERNAL" + // LocalDeliveryScene_CLUE 线索 + LocalDeliveryScene_CLUE LocalDeliveryScene = "CLUE" + // LocalDeliveryScene_POI_CUSTOMER 门店引流 + LocalDeliveryScene_POI_CUSTOMER LocalDeliveryScene = "POI_CUSTOMER" + // LocalDeliveryScene_PURCHASE 团购成交 + LocalDeliveryScene_PURCHASE LocalDeliveryScene = "PURCHASE" +) diff --git a/marketing-api/enum/local/location_type.go b/marketing-api/enum/local/location_type.go new file mode 100644 index 00000000..390d7ac2 --- /dev/null +++ b/marketing-api/enum/local/location_type.go @@ -0,0 +1,15 @@ +package local + +// LocationType 区域内人群定向设置 +type LocationType string + +const ( + // LocationType_ALL 该地区的所有用户 + LocationType_ALL LocationType = "ALL" + // LocationType_CURRENT 正在该地区的用户(默认值) + LocationType_CURRENT LocationType = "CURRENT" + // LocationType_HOME 居住在该地区的用户 + LocationType_HOME LocationType = "HOME" + // LocationType_TRAVEL 到该地区旅行的用户 + LocationType_TRAVEL LocationType = "TRAVEL" +) diff --git a/marketing-api/enum/local/marketing_goal.go b/marketing-api/enum/local/marketing_goal.go new file mode 100644 index 00000000..02930ec4 --- /dev/null +++ b/marketing-api/enum/local/marketing_goal.go @@ -0,0 +1,13 @@ +package local + +// MarketingGoal 营销场景 +type MarketingGoal string + +const ( + // MarketingGoal_ALL 不限 + MarketingGoal_ALL MarketingGoal = "ALL" + // MarketingGoal_LIVE 直播 + MarketingGoal_LIVE MarketingGoal = "LIVE" + // MarketingGoal_VIDEO_IMAGE 短视频/图文 + MarketingGoal_VIDEO_IMAGE MarketingGoal = "VIDEO_IMAGE" +) diff --git a/marketing-api/enum/local/poi_around_radius.go b/marketing-api/enum/local/poi_around_radius.go new file mode 100644 index 00000000..5555547a --- /dev/null +++ b/marketing-api/enum/local/poi_around_radius.go @@ -0,0 +1,19 @@ +package local + +// PoiAroundRadius 半径,门店附近仅支持固定半径的设置 +type PoiAroundRadius string + +const ( + // PoiAroundRadius_KM_6 门店附近6km + PoiAroundRadius_KM_6 PoiAroundRadius = "KM_6" + // PoiAroundRadius_KM_8 门店附近8km + PoiAroundRadius_KM_8 PoiAroundRadius = "KM_8" + // PoiAroundRadius_KM_10 门店附近10km(默认值) + PoiAroundRadius_KM_10 PoiAroundRadius = "KM_10" + // PoiAroundRadius_KM_12 门店附近12km + PoiAroundRadius_KM_12 PoiAroundRadius = "KM_12" + // PoiAroundRadius_KM_15 门店附近15km + PoiAroundRadius_KM_15 PoiAroundRadius = "KM_15" + // PoiAroundRadius_KM_20 门店附近20km + PoiAroundRadius_KM_20 PoiAroundRadius = "KM_20" +) diff --git a/marketing-api/enum/local/project_status.go b/marketing-api/enum/local/project_status.go new file mode 100644 index 00000000..ff2a3004 --- /dev/null +++ b/marketing-api/enum/local/project_status.go @@ -0,0 +1,25 @@ +package local + +// ProjectStatus 项目状态 +type ProjectStatus string + +const ( + // PROJECT_STATUS_ALL 不限(包含已删除) + PROJECT_STATUS_ALL ProjectStatus = "PROJECT_STATUS_ALL" + // PROJECT_STATUS_DELETE 已删除 + PROJECT_STATUS_DELETE ProjectStatus = "PROJECT_STATUS_DELETE" + // PROJECT_STATUS_DISABLE 未投放 + PROJECT_STATUS_DISABLE ProjectStatus = "PROJECT_STATUS_DISABLE" + // PROJECT_STATUS_DONE 已完成 + PROJECT_STATUS_DONE ProjectStatus = "PROJECT_STATUS_DONE" + // PROJECT_STATUS_ENABLE 启用中 + PROJECT_STATUS_ENABLE ProjectStatus = "PROJECT_STATUS_ENABLE" + // PROJECT_STATUS_NOT_DELETE 不限(不包含已删除) + PROJECT_STATUS_NOT_DELETE ProjectStatus = "PROJECT_STATUS_NOT_DELETE" + // PROJECT_STATUS_BUDGET_EXCEED 项目超出预算 + PROJECT_STATUS_BUDGET_EXCEED ProjectStatus = "PROJECT_STATUS_BUDGET_EXCEED" + // PROJECT_STATUS_NOT_SCHEDULE 不在投放时段 + PROJECT_STATUS_NOT_SCHEDULE ProjectStatus = "PROJECT_STATUS_NOT_SCHEDULE" + // PROJECT_STATUS_NOT_START 未达投放时间 + PROJECT_STATUS_NOT_START ProjectStatus = "PROJECT_STATUS_NOT_START" +) diff --git a/marketing-api/enum/local/promotion_status.go b/marketing-api/enum/local/promotion_status.go new file mode 100644 index 00000000..433bea9f --- /dev/null +++ b/marketing-api/enum/local/promotion_status.go @@ -0,0 +1,57 @@ +package local + +// PromotionStatusFirst 广告一级状态 +type PromotionStatusFirst string + +const ( + // PROMOTION_STATUS_ALL 不限(包含已删除) + PROMOTION_STATUS_ALL PromotionStatusFirst = "PROMOTION_STATUS_ALL" + // PROMOTION_STATUS_DELETED 已删除: + PROMOTION_STATUS_DELETED PromotionStatusFirst = "PROMOTION_STATUS_DELETED" + // PROMOTION_STATUS_DISABLE 未投放 + PROMOTION_STATUS_DISABLE PromotionStatusFirst = "PROMOTION_STATUS_DISABLE" + // PROMOTION_STATUS_DONE 已完成 + PROMOTION_STATUS_DONE PromotionStatusFirst = "PROMOTION_STATUS_DONE" + // PROMOTION_STATUS_ENABLE 投放中 + PROMOTION_STATUS_ENABLE PromotionStatusFirst = "PROMOTION_STATUS_ENABLE" + // PROMOTION_STATUS_FROZEN 已终止 + PROMOTION_STATUS_FROZEN PromotionStatusFirst = "PROMOTION_STATUS_FROZEN" + // PROMOTION_STATUS_NOT_DELETE 不限(不包含已删除) + PROMOTION_STATUS_NOT_DELETE PromotionStatusFirst = "PROMOTION_STATUS_NOT_DELETE" +) + +// PromotionStatusSecond 广告二级状态 +type PromotionStatusSecond string + +const ( + // PromotionStatusSecond_AUDIT_DENY 审核不通过 + PromotionStatusSecond_AUDIT_DENY PromotionStatusSecond = "AUDIT_DENY" + // PromotionStatusSecond_AUDIT 新建审核中 + PromotionStatusSecond_AUDIT PromotionStatusSecond = "AUDIT" + // PromotionStatusSecond_REAUDIT 修改审核中 + PromotionStatusSecond_REAUDIT PromotionStatusSecond = "REAUDIT" + // PromotionStatusSecond_DISABLED 已暂停 + PromotionStatusSecond_DISABLED PromotionStatusSecond = "DISABLED" + // PromotionStatusSecond_DISABLE_BY_QUOTA 配额达限 + PromotionStatusSecond_DISABLE_BY_QUOTA PromotionStatusSecond = "DISABLE_BY_QUOTA" + // PromotionStatusSecond_PROJECT_DISABLED 项目已被暂停 + PromotionStatusSecond_PROJECT_DISABLED PromotionStatusSecond = "PROJECT_DISABLED" + // PromotionStatusSecond_NO_SCHEDULE 不在投放时段 + PromotionStatusSecond_NO_SCHEDULE PromotionStatusSecond = "NO_SCHEDULE" + // PromotionStatusSecond_TIME_NO_REACH 未到达投放时间 + PromotionStatusSecond_TIME_NO_REACH PromotionStatusSecond = "TIME_NO_REACH" + // PromotionStatusSecond_OFFLINE_BALANCE 账户余额不足 + PromotionStatusSecond_OFFLINE_BALANCE PromotionStatusSecond = "OFFLINE_BALANCE" + // PromotionStatusSecond_BALANCE_OFFLINE_BUDGET 账户超出预算 + PromotionStatusSecond_BALANCE_OFFLINE_BUDGET PromotionStatusSecond = "BALANCE_OFFLINE_BUDGET" + // PromotionStatusSecond_PROJECT_OFFLINE_BUDGET 项目超出预算 + PromotionStatusSecond_PROJECT_OFFLINE_BUDGET PromotionStatusSecond = "PROJECT_OFFLINE_BUDGET" + // PromotionStatusSecond_PROMOTION_OFFLINE_BUDGET 广告超出预算 + PromotionStatusSecond_PROMOTION_OFFLINE_BUDGET PromotionStatusSecond = "PROMOTION_OFFLINE_BUDGET" + // PromotionStatusSecond_LIVE_ROOM_OFF 直播间不可投放 + PromotionStatusSecond_LIVE_ROOM_OFF PromotionStatusSecond = "LIVE_ROOM_OFF" + // PromotionStatusSecond_AWEME_ACCOUNT_DISABLED 抖音账号不可投放 + PromotionStatusSecond_AWEME_ACCOUNT_DISABLED PromotionStatusSecond = "AWEME_ACCOUNT_DISABLED" + // PromotionStatusSecond_PRODUCT_OR_POI_OFFLINE 商品/门店不可投 + PromotionStatusSecond_PRODUCT_OR_POI_OFFLINE PromotionStatusSecond = "PRODUCT_OR_POI_OFFLINE" +) diff --git a/marketing-api/enum/local/schedule_type.go b/marketing-api/enum/local/schedule_type.go new file mode 100644 index 00000000..90ca4387 --- /dev/null +++ b/marketing-api/enum/local/schedule_type.go @@ -0,0 +1,13 @@ +package local + +// ScheduleType 投放日期类型设置 +type ScheduleType string + +const ( + // ScheduleType_FROM_NOW_ON 从今天起长期投放 + ScheduleType_FROM_NOW_ON ScheduleType = "FROM_NOW_ON" + // ScheduleType_START_TO_END 设置开始结束时间 + ScheduleType_START_TO_END ScheduleType = "START_TO_END" + // ScheduleType_FIXED_TIME 固定时长 + ScheduleType_FIXED_TIME ScheduleType = "FIXED_TIME" +) diff --git a/marketing-api/enum/material_mode.go b/marketing-api/enum/material_mode.go index 281e20a6..80b2c745 100644 --- a/marketing-api/enum/material_mode.go +++ b/marketing-api/enum/material_mode.go @@ -24,4 +24,6 @@ const ( MaterialMode_AWEME_LIVE_ROOM MaterialMode = "AWEME_LIVE_ROOM" // MaterialMode_CAROUSEL 图文 MaterialMode_CAROUSEL MaterialMode = "CAROUSEL" + // MaterialMode_VIDEO 视频 + MaterialMode_VIDEO MaterialMode = "VIDEO" ) diff --git a/marketing-api/enum/promotion_reject_reason_type.go b/marketing-api/enum/promotion_reject_reason_type.go index 0e14b4b9..59082168 100644 --- a/marketing-api/enum/promotion_reject_reason_type.go +++ b/marketing-api/enum/promotion_reject_reason_type.go @@ -18,4 +18,6 @@ const ( PromotionRejectReasonType_EXAGGERATION PromotionRejectReasonType = "EXAGGERATION" // PromotionRejectReasonType_ELSE 其他 PromotionRejectReasonType_ELSE PromotionRejectReasonType = "ELSE" + // PromotionRejectReasonType_ALL 不限 + PromotionRejectReasonType_ALL PromotionRejectReasonType = "ALL" ) diff --git a/marketing-api/enum/stat_time_granularity.go b/marketing-api/enum/stat_time_granularity.go index 36435389..35c23aa0 100644 --- a/marketing-api/enum/stat_time_granularity.go +++ b/marketing-api/enum/stat_time_granularity.go @@ -26,4 +26,6 @@ const ( TIME_GRANULARITY_WEEK TimeGranularity = "TIME_GRANULARITY_WEEK" // TIME_GRANULARITY_MONTH 按月粒度 TIME_GRANULARITY_MONTH TimeGranularity = "TIME_GRANULARITY_MONTH" + // TIME_GRANULARITY_TOTAL 汇总 + TIME_GRANULARITY_TOTAL TimeGranularity = "TIME_GRANULARITY_TOTAL" ) diff --git a/marketing-api/enum/weekday.go b/marketing-api/enum/weekday.go new file mode 100644 index 00000000..e91f739d --- /dev/null +++ b/marketing-api/enum/weekday.go @@ -0,0 +1,21 @@ +package enum + +// Weekday 自然周 +type Weekday string + +const ( + // MONDAY 周一 + MONDAY Weekday = "MONDAY" + // TUESDAY 周二 + TUESDAY Weekday = "TUESDAY" + // WEDNESDAY 周三 + WEDNESDAY Weekday = "WEDNESDAY" + // THURSDAY 周四 + THURSDAY Weekday = "THURSDAY" + // FRIDAY 周五 + FRIDAY Weekday = "FRIDAY" + // SATURDAY 周六 + SATURDAY Weekday = "SATURDAY" + // SUNDAY 周日 + SUNDAY Weekday = "SUNDAY" +) diff --git a/marketing-api/model/local/aweme/authorized_get.go b/marketing-api/model/local/aweme/authorized_get.go new file mode 100644 index 00000000..018771b4 --- /dev/null +++ b/marketing-api/model/local/aweme/authorized_get.go @@ -0,0 +1,65 @@ +package aweme + +import ( + "strconv" + + "github.com/bububa/oceanengine/marketing-api/enum/local" + "github.com/bububa/oceanengine/marketing-api/model" + "github.com/bububa/oceanengine/marketing-api/util" +) + +// AuthorizedGetRequest 获取本地推创编可用抖音号 API Request +type AuthorizedGetRequest struct { + // LocalAccountID 本地推广告主ID + LocalAccountID uint64 `json:"local_account_id,omitempty"` + // Filtering 过滤器 + Filtering *AuthorizedGetFilter `json:"filtering,omitempty"` + // Page 页码 + Page int `json:"page,omitempty"` + // PageSize 页面大小 + PageSize int `json:"page_size,omitempty"` + // MarketingGoal 抖音号使用场景,允许值 + // LIVE 直播 + // VIDEO_IMAGE 短视频/图文 + MarketingGoal local.MarketingGoal `json:"marketing_goal,omitempty"` +} + +type AuthorizedGetFilter struct { + // SearchKeyWord 根据抖音号id和名称进行搜索 + SearchKeyWord string `json:"search_key_word,omitempty"` +} + +// Encode implements GetRequest interface +func (r AuthorizedGetRequest) Encode() string { + values := util.GetUrlValues() + values.Set("local_account_id", strconv.FormatUint(r.LocalAccountID, 10)) + if r.Filtering != nil { + values.Set("filtering", string(util.JSONMarshal(r.Filtering))) + } + if r.Page > 0 { + values.Set("page", strconv.Itoa(r.Page)) + } + if r.PageSize > 0 { + values.Set("page_size", strconv.Itoa(r.PageSize)) + } + if r.MarketingGoal != "" { + values.Set("marketing_goal", string(r.MarketingGoal)) + } + ret := values.Encode() + util.PutUrlValues(values) + return ret +} + +// AuthorizedGetResponse 获取本地推创编可用抖音号 API Response +type AuthorizedGetResponse struct { + model.BaseResponse + // Data json返回值 + Data *AuthorizedGetResult `json:"data,omitempty"` +} + +type AuthorizedGetResult struct { + // PageInfo 分页信息 + PageInfo *model.PageInfo `json:"page_info,omitempty"` + // AwemeIDList 抖音号列表 + AwemeIDList []Aweme `json:"aweme_id_list,omitempty"` +} diff --git a/marketing-api/model/local/aweme/aweme.go b/marketing-api/model/local/aweme/aweme.go new file mode 100644 index 00000000..9f40cc9e --- /dev/null +++ b/marketing-api/model/local/aweme/aweme.go @@ -0,0 +1,28 @@ +package aweme + +import "github.com/bububa/oceanengine/marketing-api/enum" + +// Aweme 抖音号 +type Aweme struct { + // AwemeID 抖音号 + AwemeID string `json:"aweme_id,omitempty"` + // AwemeName 抖音号名称 + AwemeName string `json:"aweme_name,omitempty"` + // AwemeAvatar 抖音头像 + AwemeAvatar string `json:"aweme_avatar,omitempty"` + // AuthType 抖音号授权类型,枚举值: + // OFFICIAL 官方 + // SELF 自运营 + // AWEME_COOPERATOR 合作达人 + // 不同授权类型的抖音号权限说明: + // 官方:支持发布视频到主页(政媒号不支持)、支持选取主页视频投放、支持推广该抖音号的直播间 + // 自运营:支持发布视频到主页(政媒号不支持)、支持选取主页视频投放、支持推广该抖音号的直播间 + // 合作达人:支持选取主页视频投放、支持推广该抖音号的直播间 + AuthType enum.AwemeBindType `json:"auth_type,omitempty"` + // AwemeHasUniProm 该抖音号是否有直播roi2计划投放 + // 注意:如果该抖音号有直播roi2计划投放,那么该抖音号不可以创建 【标准推广-推直播间-直播间团购购买】 的直播广告 + AwemeHasUniProm bool `json:"aweme_has_uni_prom,omitempty"` + // CanCreateRoi2Ad 该抖音号是否能创建roi2广告 + // marketing_goal=LIVE时返回 + CanCreateRoi2Ad bool `json:"can_create_roi2_ad,omitempty"` +} diff --git a/marketing-api/model/local/aweme/doc.go b/marketing-api/model/local/aweme/doc.go new file mode 100644 index 00000000..ed37fe59 --- /dev/null +++ b/marketing-api/model/local/aweme/doc.go @@ -0,0 +1,2 @@ +// Package aweme 抖音号相关 +package aweme diff --git a/marketing-api/model/local/customaudience/custom_audience.go b/marketing-api/model/local/customaudience/custom_audience.go new file mode 100644 index 00000000..15443a50 --- /dev/null +++ b/marketing-api/model/local/customaudience/custom_audience.go @@ -0,0 +1,15 @@ +package customaudience + +import "github.com/bububa/oceanengine/marketing-api/enum/local" + +// CustomAudience 人群包 +type CustomAudience struct { + // CustomAudienceID 人群包ID + CustomAudienceID uint64 `json:"custom_audience_id,omitempty"` + // Name 人群包名称 + Name string `json:"name,omitempty"` + // TagsType 人群包属性 + TagsType local.CustomAudienceTagsType `json:"tags_type,omitempty"` + // CreateTime 人群包创建时间 + CreateTime string `json:"create_time,omitempty"` +} diff --git a/marketing-api/model/local/customaudience/doc.go b/marketing-api/model/local/customaudience/doc.go new file mode 100644 index 00000000..12081413 --- /dev/null +++ b/marketing-api/model/local/customaudience/doc.go @@ -0,0 +1,2 @@ +// Package customaudience 人群包相关 +package customaudience diff --git a/marketing-api/model/local/customaudience/get.go b/marketing-api/model/local/customaudience/get.go new file mode 100644 index 00000000..66eb9ee9 --- /dev/null +++ b/marketing-api/model/local/customaudience/get.go @@ -0,0 +1,54 @@ +package customaudience + +import ( + "strconv" + + "github.com/bububa/oceanengine/marketing-api/enum/local" + "github.com/bububa/oceanengine/marketing-api/model" + "github.com/bububa/oceanengine/marketing-api/util" +) + +// GetRequest 查询本地推创编可用人群包 API Request +type GetRequest struct { + // LocalAccountID 本地推广告主ID + LocalAccountID uint64 `json:"local_account_id,omitempty"` + // TagsType 按人群包属性筛选,允许值: + // CUSTOM 自定义人群包 + // SYS_RECOMMEND 系统推荐人群包 + TagsType local.CustomAudienceTagsType `json:"tags_type,omitempty"` + // Page 页码,默认值1 + Page int `json:"page,omitempty"` + // PageSize 页面大小,默认值20,最大值100 + PageSize int `json:"page_size,omitempty"` +} + +// Encode implements GetRequest interface +func (r GetRequest) Encode() string { + values := util.GetUrlValues() + values.Set("local_account_id", strconv.FormatUint(r.LocalAccountID, 10)) + if r.TagsType != "" { + values.Set("tags_type", string(r.TagsType)) + } + if r.Page > 0 { + values.Set("page", strconv.Itoa(r.Page)) + } + if r.PageSize > 0 { + values.Set("page_size", strconv.Itoa(r.PageSize)) + } + ret := values.Encode() + util.PutUrlValues(values) + return ret +} + +// GetResponse 查询本地推创编可用人群包 API Response +type GetResponse struct { + model.BaseResponse + Data *GetResult `json:"data,omitempty"` +} + +type GetResult struct { + // PageInfo 分页信息 + PageInfo *model.PageInfo `json:"page_info,omitempty"` + // CustomAudienceList 人群包列表 + CustomAudienceList []CustomAudience `json:"custom_audience_list,omitempty"` +} diff --git a/marketing-api/model/local/doc.go b/marketing-api/model/local/doc.go new file mode 100644 index 00000000..7251de81 --- /dev/null +++ b/marketing-api/model/local/doc.go @@ -0,0 +1,2 @@ +// Package local 本地推相关 +package local diff --git a/marketing-api/model/local/poi/doc.go b/marketing-api/model/local/poi/doc.go new file mode 100644 index 00000000..6ff24407 --- /dev/null +++ b/marketing-api/model/local/poi/doc.go @@ -0,0 +1,2 @@ +// Package poi 门店相关 +package poi diff --git a/marketing-api/model/local/poi/multi_poi.go b/marketing-api/model/local/poi/multi_poi.go new file mode 100644 index 00000000..84a6d046 --- /dev/null +++ b/marketing-api/model/local/poi/multi_poi.go @@ -0,0 +1,9 @@ +package poi + +// MultiPoi 多门店信息 +type MultiPoi struct { + // MultiPoiID 多门店id + MultiPoiID uint64 `json:"multi_poi_id,omitempty"` + // PoiIDs 门店id列表 + PoiIDs []uint64 `json:"poi_ids,omitempty"` +} diff --git a/marketing-api/model/local/poi/multi_poi_ids_get.go b/marketing-api/model/local/poi/multi_poi_ids_get.go new file mode 100644 index 00000000..6b4065dc --- /dev/null +++ b/marketing-api/model/local/poi/multi_poi_ids_get.go @@ -0,0 +1,47 @@ +package poi + +import ( + "strconv" + + "github.com/bububa/oceanengine/marketing-api/model" + "github.com/bububa/oceanengine/marketing-api/util" +) + +// MultiPoiIDsGetRequest 根据多门店ID拉取门店ID API Request +type MultiPoiIDsGetRequest struct { + // LocalAccountID 本地推广告主ID + LocalAccountID uint64 `json:"local_account_id,omitempty"` + // MultiPoiIDs 多门店id,可通过【获取项目详情】接口获取项目推广的多门店ID + // 数量上限:50 + MultiPoiIDs []uint64 `json:"multi_poi_ids,omitempty"` + // NeedEnable 是否仅查询当前在投门店,即过滤不在投放中的门店(可能存在部分门店,因门店已下线/门店下无团购/被全域推广转移,被从计划中剔除,不在投放中),允许值: + // true 仅查询在投放中的门店 + // false查询多门店ID对应的所有门店(默认值) + NeedEnable bool `json:"need_enable,omitempty"` +} + +// Encode implements GetRequest interface +func (r MultiPoiIDsGetRequest) Encode() string { + values := util.GetUrlValues() + values.Set("local_account_id", strconv.FormatUint(r.LocalAccountID, 10)) + values.Set("multi_poi_ids", string(util.JSONMarshal(r.MultiPoiIDs))) + if r.NeedEnable { + values.Set("need_enable", "true") + } + ret := values.Encode() + util.PutUrlValues(values) + return ret +} + +// MultiPoiIDsGetResponse 根据多门店ID拉取门店ID API Response +type MultiPoiIDsGetResponse struct { + model.BaseResponse + Data *MultiPoiIDsGetResult `json:"data,omitempty"` +} + +type MultiPoiIDsGetResult struct { + // PageInfo 分页信息 + PageInfo *model.PageInfo `json:"page_info,omitempty"` + // MultiPoiInfo 多门店信息 + MultiPoiInfo []MultiPoi `json:"multi_poi_info,omitempty"` +} diff --git a/marketing-api/model/local/product/doc.go b/marketing-api/model/local/product/doc.go new file mode 100644 index 00000000..77afca8a --- /dev/null +++ b/marketing-api/model/local/product/doc.go @@ -0,0 +1,2 @@ +// Package product 商品相关 +package product diff --git a/marketing-api/model/local/product/get.go b/marketing-api/model/local/product/get.go new file mode 100644 index 00000000..1d79127a --- /dev/null +++ b/marketing-api/model/local/product/get.go @@ -0,0 +1,66 @@ +package product + +import ( + "strconv" + + "github.com/bububa/oceanengine/marketing-api/enum/local" + "github.com/bububa/oceanengine/marketing-api/model" + "github.com/bububa/oceanengine/marketing-api/util" +) + +// GetRequest 获取可投商品列表 API Request +type GetRequest struct { + // LocalAccountID 本地推广告主ID + LocalAccountID uint64 `json:"local_account_id,omitempty"` + // LocalDeliveryScene 推广目的,允许值: + // CONTENT_HEAT 内容加热 + // EXTERNAL 销售线索收集 + // POI_RECOMMEND 门店引流 + // PRODUCT_PAY 团购成交 + LocalDeliveryScene local.LocalDeliveryScene `json:"local_delivery_scene,omitempty"` + // Filtering 过滤器 + Filtering *GetFilter `json:"filtering,omitempty"` + // Page 页码,默认值1 + Page int `json:"page,omitempty"` + // PageSize 页面大小,默认值20,最大值100 + PageSize int `json:"page_size,omitempty"` +} + +type GetFilter struct { + // SearchKeyWord 根据商品名称/商品ID搜索(商品名称支持模糊搜索,商品ID支持精确搜索) + SearchKeyWord string `json:"search_key_word,omitempty"` +} + +// Encode implements GetRequest interface +func (r GetRequest) Encode() string { + values := util.GetUrlValues() + values.Set("local_account_id", strconv.FormatUint(r.LocalAccountID, 10)) + if r.LocalDeliveryScene != "" { + values.Set("local_delivery_scene", string(r.LocalDeliveryScene)) + } + if r.Filtering != nil { + values.Set("filtering", string(util.JSONMarshal(r.Filtering))) + } + if r.Page > 0 { + values.Set("page", strconv.Itoa(r.Page)) + } + if r.PageSize > 0 { + values.Set("page_size", strconv.Itoa(r.PageSize)) + } + ret := values.Encode() + util.PutUrlValues(values) + return ret +} + +// GetResponse 获取可投商品列表 API Response +type GetResponse struct { + model.BaseResponse + Data *GetResult `json:"data,omitempty"` +} + +type GetResult struct { + // PageInfo 分页信息 + PageInfo *model.PageInfo `json:"page_info,omitempty"` + // Products 商品信息 + Products []Product `json:"products,omitempty"` +} diff --git a/marketing-api/model/local/product/get_by_poiids.go b/marketing-api/model/local/product/get_by_poiids.go new file mode 100644 index 00000000..0c68fdb5 --- /dev/null +++ b/marketing-api/model/local/product/get_by_poiids.go @@ -0,0 +1,35 @@ +package product + +import ( + "strconv" + + "github.com/bububa/oceanengine/marketing-api/model" + "github.com/bububa/oceanengine/marketing-api/util" +) + +// GetByPoiIDsRequest 根据门店ID查询门店下商品ID API Request +type GetByPoiIDsRequest struct { + // LocalAccountID 本地推广告账户ID + LocalAccountID uint64 `json:"local_account_id,omitempty"` + // PoiIDs 门店ID列表,这里需填入项目所推广的门店 + PoiIDs []uint64 `json:"poi_ids,omitempty"` +} + +// Encode implements GetRequest interface +func (r GetByPoiIDsRequest) Encode() string { + values := util.GetUrlValues() + values.Set("local_account_id", strconv.FormatUint(r.LocalAccountID, 10)) + values.Set("poi_ids", string(util.JSONMarshal(r.PoiIDs))) + ret := values.Encode() + util.PutUrlValues(values) + return ret +} + +// GetByPoiIDsResponse 根据门店ID查询门店下商品ID API Response +type GetByPoiIDsResponse struct { + model.BaseResponse + Data struct { + // ProductIDs 门店下商品ID列表 + ProductIDs []uint64 `json:"product_ids,omitempty"` + } `json:"data,omitempty"` +} diff --git a/marketing-api/model/local/product/product.go b/marketing-api/model/local/product/product.go new file mode 100644 index 00000000..1ae3caf9 --- /dev/null +++ b/marketing-api/model/local/product/product.go @@ -0,0 +1,17 @@ +package product + +// Product 商品信息 +type Product struct { + // ProductID 商品id + ProductID uint64 `json:"product_id,omitempty"` + // ProductName 商品名称 + ProductName string `json:"product_name,omitempty"` + // ProductImageURL 商品图片 + ProductImageURL string `json:"product_image_url,omitempty"` + // Price 商品价格,单位元 + Price float64 `json:"price,omitempty"` + // ProductPics 商品头图,有效期2h + ProductPics []string `json:"product_pics,omitempty"` + // ApplicablePoiNum 商品适用门店数 + ApplicablePoiNum int `json:"applicable_poi_num,omitempty"` +} diff --git a/marketing-api/model/local/project/audience.go b/marketing-api/model/local/project/audience.go new file mode 100644 index 00000000..3f11f663 --- /dev/null +++ b/marketing-api/model/local/project/audience.go @@ -0,0 +1,136 @@ +package project + +import ( + "github.com/bububa/oceanengine/marketing-api/enum" + "github.com/bububa/oceanengine/marketing-api/enum/local" +) + +// Audience 定向设置 +type Audience struct { + // District 地域类型,允许值: + // ALL 不限 + // LOCAL 自定义/商圈 + // POI 门店附近 + // 当delivery_content_type=POI&& 门店数量>2000家 时,不支持POI_AROUND门店附近 + // REGION 按行政区域划分 + // 使用行政区域示例:{"district":"REGION": "city":[31], "region_versio":"1.0.0"} + District enum.District `json:"district,omitempty"` + // Region 行政区域信息 + // 当district=REGION 行政区域划分时有效且必填 + Region *Region `json:"region,omitempty"` + // CustomArea 自定义区域设置 + // 当district=LOCAL时必填 + CustomArea *CustomArea `json:"custom_area,omitempty"` + // PoiAround 门店附近定向设置 + // 当district=POI门店附近时有效且必填 + PoiAround *PoiAround `json:"poi_around,omitempty"` + // Age 年龄,允许值: + // 年龄不可同时传入 5 分段枚举和 10 分段枚举 + // 5分段(age_5_part_set) + // AGE_BETWEEN_18_19 + // AGE_BETWEEN_20_23 + // AGE_BETWEEN_24_30 + // AGE_BETWEEN_31_35 + // AGE_BETWEEN_36_40 + // AGE_BETWEEN_41_45 + // AGE_BETWEEN_46_50 + // AGE_BETWEEN_51_55 + // AGE_BETWEEN_56_59 + // AGE_ABOVE_60 + // 10分段(age_10_part_set) + // AGE_BETWEEN_18_23 + // AGE_BETWEEN_24_30 + // AGE_BETWEEN_31_40 + // AGE_BETWEEN_41_49 + // AGE_ABOVE_50 + Age enum.AudienceAge `json:"age,omitempty"` + // Gender 性别,不传默认不限,允许值: + // FEMALE 女 + // MALE 男 + // NONE 不限 + Gender local.Gender `json:"gender,omitempty"` + // RetargetingTags 定向人群包ID,可通过【查询本地推创编可用人群包】接口获取 + // 数量上限:200 + RetargetingTags []uint64 `json:"retargeting_tags,omitempty"` + // RetargetingTagsExclude 排除人群包ID,可通过【查询本地推创编可用人群包】接口获取 + // 数量上限:200 + RetargetingTagsExclude []uint64 `json:"retargeting_tags_exclude,omitempty"` + // HideIfConverted 过滤已转化的维度,可以避免该广告再次投放给已转化过的用户,不传默认不过滤,允许值: + // NOT_EXCLUDE 不过滤 + // ADVERTISER 广告主账户 + // CC 组织账户 + // CUSTOMER 公司账户 + // PROJECT 项目 + // PROMOTION 广告 + // 当external_action=SHOW 展示量时,不支持该字段 + HideIfConverted local.HideIfConverted `json:"hide_if_converted,omitempty"` + // ConvertedTimeDuration 过滤已转化投放时间,允许值: + // SEVEN_DAY 七天(默认值) + // ONE_MONTH 1个月 + // THREE_MONTH 3个月 + // SIX_MONTH 6个月 + // TWELVE_MONTH 12个月 + // TODAY 当天 + // 仅当hide_if_converted设置为CUSTOMER或ORGANIZATION,该字段有效,不传默认7天,其余场景该字段无效。 + ConvertedTimeDuration local.ConvertedTimeDuration `json:"converted_time_duration,omitempty"` +} + +// Region 行政区域信息 +type Region struct { + // City 地域定向省市或者区县列表(当传递省份ID时,旗下市县ID可省略不传),通过【获取行政信息】接口获取 + City []uint64 `json:"city,omitempty"` + // CityDivide 城市划分类型,允许值: + // BY_LEVEL 按发展等级划分 + // BY_LOCATION 按地理划分(默认值) + CityDivide local.CityDivide `json:"city_divide,omitempty"` + // LocationType 区域内人群定向设置,允许值: + // ALL 该地区的所有用户 + // CURRENT 正在该地区的用户(默认值) + // HOME 居住在该地区的用户 + // TRAVEL 到该地区旅行的用户 + LocationType local.LocationType `json:"location_type,omitempty"` + // RegionVer 行政区域版本号,通过【获取行政信息】接口获取 + RegionVer string `json:"region_ver,omitempty"` +} + +// CustomArea 自定义区域设置 +type CustomArea struct { + // Geolocation 地理位置设置,数量上限:1000 + Geolocation []Geolocation `json:"geolocation,omitempty"` +} + +// Geolocation 地理位置信息 +type Geolocation struct { + // Name 地点名称 + Name string `json:"name,omitempty"` + // AreaRadius 半径 + AreaRadius int64 `json:"area_radius,omitempty"` + // Long 经度 + Long float64 `json:"long,omitempty"` + // Lat 纬度 + Lat float64 `json:"lat,omitempty"` +} + +// PoiAround 门店附近定向设置 +type PoiAround struct { + // PoiIDs 定向门店id列表,可通过【获取门店列表】接口查询 + // 数量上限:2000 + // 「短视频推门店」无需传入,自动定位至推广的门店附近 + // 填写说明: + // marketing_goal=LIVE直播 && district =POI_AROUND门店附近,该字段有效且必填 + // 门店id要求:传入门店id需为本广告账户下的门店ID + // marketing_goal=VIDEO_AND_IMAGE短视频/图文,且delivery_content_type=PRODUCT为商品,且district =POI_AROUND时,该字段有效。 + // 门店id要求:传入门店id必须为推广的商品适用门店 + // 所推广的商品适用门店数大于2000时必填,且最多传入2000个; + // 所推广的商品适用门店数不超过2000时,不传默认推商品适用门店附近 + // marketing_goal=VIDEO_AND_IMAGE短视频/图文 && delivery_content_type=POI门店时,该字段无效,无需传入。选择门店附近定向,则默认投所推广的门店附近(仅推广门店数不超过2000家时可选择门店附近定向) + PoiIDs []uint64 `json:"poi_ids,omitempty"` + // PoiAroundRadius 半径,门店附近仅支持固定半径的设置,允许值: + // KM_6 门店附近6km + // KM_8 门店附近8km + // KM_10 门店附近10km(默认值) + // KM_12 门店附近12km + // KM_15 门店附近15km + // KM_20 门店附近20km + PoiAroundRadius local.PoiAroundRadius `json:"poi_around_radius,omitempty"` +} diff --git a/marketing-api/model/local/project/create.go b/marketing-api/model/local/project/create.go new file mode 100644 index 00000000..cd1132c9 --- /dev/null +++ b/marketing-api/model/local/project/create.go @@ -0,0 +1,179 @@ +package project + +import ( + "github.com/bububa/oceanengine/marketing-api/enum" + "github.com/bububa/oceanengine/marketing-api/enum/local" + "github.com/bububa/oceanengine/marketing-api/model" + "github.com/bububa/oceanengine/marketing-api/util" +) + +// CreateRequest 创建项目 API Request +type CreateRequest struct { + // LocalAccountID 本地推广告账户ID + LocalAccountID uint64 `json:"local_account_id,omitempty"` + // Name 项目名称,长度是1-50个字(两个英文字符占1个字) + Name string `json:"name,omitempty"` + // MarketingGoal 营销场景,允许值: + // LIVE 直播 + // VIDEO_IMAGE 短视频/图文 + MarketingGoal local.MarketingGoal `json:"marketing_goal,omitempty"` + // LocalDeliveryScene 推广目的,允许值: + // CONTENT_HEAT 内容加热 + // POI_RECOMMEND 门店引流 + // 当marketing_goal =LIVE 直播时,不支持传入POI_RECOMMEND 门店引流 + // PRODUCT_PAY 团购成交 + LocalDeliveryScene local.LocalDeliveryScene `json:"local_delivery_scene,omitempty"` + // AdType 广告类型,允许值: + // GENERAL 通投广告 + // SEARCHING 搜索广告 + // 当marketing_goal=VIDEO_IMAGE 短视频/图文 && local_delivery_scene=CONTENT_HEAT 内容加热 时,不支持传入SEARCHING + AdType local.AdType `json:"ad_type,omitempty"` + // DeliveryGoal 投放内容,允许值: + // POI 门店 + // PRODUCT 商品 + // 填写说明: + // 仅marketing_goal=VIDEO_AND_IMAGE时,该字段生效且必填;当marketing_goal=LIVE时,该字段无效 + // 当marketing_goal=VIDEO_AND_IMAGE且 + // local_delivery_scene=POI_RECOMMEND 门店引流时,仅支持POI + DeliveryGoal local.DeliveryGoal `json:"delivery_goal,omitempty"` + // DeliveryPoiMode 是否投放全部门店,允许值: + // ALL 投放全部门店 + // PART 投放指定门店,需同时传入promotion_poi_ids + // 填写说明: + // 当 marketing_goal=VIDEO_AND_IMAGE且delivery_goal=POI时,有效且必传 + DeliveryPoiMode local.DeliveryPoiMode `json:"delivery_poi_mode,omitempty"` + // PromotionPoiIDs 推广门店ID列表 + // 填写说明: + // 当delivery_goal=POI且 delivery_poi_mode=CUSTOM 投放指定门店时,有效且必填 + PromotionPoiIDs []uint64 `json:"promotion_poi_ids,omitempty"` + // ProductID 推广商品ID,可通过【获取可投商品列表】接口查询获取 + // 填写说明: + // 当marketing_goal=VIDEO_AND_IMAGE 且 delivery_goal=PRODUCT 时有效且必填 + ProductID uint64 `json:"product_id,omitempty"` + // AwemeID 用于推广直播间的抖音号,可通过【获取本地推创编可用抖音号】接口获取 + // 填写说明: + // 当marketing_goal=LIVE时有效且必填 + AwemeID string `json:"aweme_id,omitempty"` + // ExternalAction 优化目标 + // 填写说明: + // 当marketing_goal=VIDEO_AND_IMAGE短视频时: + // local_delivery_scene=PRODUCT_PURCHASE团购成交或POI_ATTRACTION门店引流时,不支持传入优化目标 + // local_delivery_scene=CONTENT_HEAT内容加热时,允许值: + // NATIVE_ACTION 用户互动 + // FOLLOW_ACTION 粉丝增长 + // SHOW展示量 + // 当marketing_goal=LIVE 直播: + // local_delivery_scene=PRODUCT_PURCHASE团购成交时: + // 当ad_type= GENERAL 通投广告时,允许值: + // LIVE_OTO_GROUP_BUYING 直播间团购购买 + // LIVE_OTO_CLICK 商品点击 + // 当ad_type= SEARCHING搜索广告时,允许值: + // LIVE_OTO_GROUP_BUYING 直播间团购购买 + // local_delivery_scene=CONTENT_HEAT 内容加热时: + // 当ad_type= GENERAL 通投广告时,允许值: + // LIVE_ENGAGE 直播加热 + // FOLLOWER_COUNT 粉丝增长 + // SHOW 展示 + // 当ad_type= SEARCHING 搜索广告时,允许值: + // LIVE_ENTER_ACTION直播间观看 + // LIVE_STAY_TIME 直播间停留 + ExternalAction local.ExternalAction `json:"external_action,omitempty"` + // Audience 定向设置,接口暂不支持设置抖音达人定向,该定向默认不限 + Audience *Audience `json:"audience,omitempty"` + // ScheduleType 投放日期类型设置,允许值: + // FROM_NOW_ON 从今天起长期投放 + // START_TO_END 设置开始结束时间 + // FIXED_TIME 固定时长 + // 仅营销场景=LIVE直播时,该枚举值有效,否则传入报错 + ScheduleType local.ScheduleType `json:"schedule_type,omitempty"` + // ScheduleFixedSeconds 直播固定投放时长(单位:秒) + // 填写说明: + // 仅当营销场景=LIVE && schedule_type=FIXED_TIME 固定时长时有效且必填,其他情况传入报错 + // 输入值需不小于1800,且为1800的整数倍(即半个小时为最小粒度) + ScheduleFixedSeconds int64 `json:"schedule_fixed_seconds,omitempty"` + // StartTime 开始投放时间,精确到天,例如:2017-01-01 + // 当schedule_type=START_TO_END时,有效且必填 + // 广告投放起始时间不允许修改 + // 开始时间不得大于结束时间,且开始时间内不得小于今天 + StartTime string `json:"start_time,omitempty"` + // EndTime 结束投放时间,精确到天,例如:2017-01-01 + // 当schedule_type=START_TO_END时,有效且必填 + // 结束时间不得小于开始时间 + EndTime string `json:"end_time,omitempty"` + // ScheduleTime 投放时段,默认全时段投放。格式是48*7位字符串,且都是0或1,也就是以半个小时为最小粒度,周一至周日每天分为48个区段,0为不投放,1为投放,不传、全传0、全传1均代表全时段投放。 + // 当schedule_type=FIXED_TIME固定时长时,该字段无效,传入会报错 + // 例如:000000000000000000000001111000000000000000000000000000000000000000000001111000000000000000000000000000000000000000000001111000000000000000000000000000000000000000000001111000000000000000000000000000000000000000000001111000000000000000000000000000000000000000000001111000000000000000000000000000000000000000000001111000000000000000000000,则投放时段为周一到周日的11:30~13:30 + ScheduleTime string `json:"schedule_time,omitempty"` + // BidType 出价方式,允许值: + // MANUAL 手动出价 + // SMART 智能出价 + // 填写说明: + // 优化目标= SHOW 展示量 时,仅支持MANUAL 手动出价 + // 营销目标=LIVE && 推广目的= CONTENT_HEAT内容加热 && 优化目标=LIVE_ENGAGEMENT时,仅支持SMART 智能出价 + BidType local.BidType `json:"bid_type,omitempty"` + // Bid 出价,当出价方式=MANUAL 手动出价时有效 + // 出价单位:分 + // 展示量取值范围为[400,10000],其他场景取值范围为[1, 1000000] + // 【展示量】:分/千次曝光 + Bid int64 `json:"bid,omitempty"` + // BudgetMode 预算模式设置,允许值: + // BUDGET_MODE_DAY 日预算 + // BUDGET_MODE_TOTAL 总预算 + // 填写说明: + // 当sceduale_type=FIXED_TIME固定时长时,仅支持BUDGET_MODE_TOTAL总预算 + // 当sceduale_type=FROM_NOW_ON或START_TO_END时,仅支持BUDGET_MODE_DAY日预算 + BudgetMode enum.BudgetMode `json:"budget_mode,omitempty"` + // Budget 项目预算,单位为:分 + // 填写限制: + // 当budget_mode=BUDGET_MODE_DAY 日预算 && bid_type=SMART 智能出价时,取值范围为[10000, 999999999] + // 当budget_mode=BUDGET_MODE_DAY 日预算 && bid_type=MANUAL 手动出价时,取值范围为[30000, 999999999] + // 当budget_mode=BUDGET_MODE_TOTAL 总预算时,取值范围为[30000, 999999999] + Budget int64 `json:"budget,omitempty"` + // IsSetPeakBudget 高峰日预算设置,仅当营销场景为短视频,且推广目的=团购成交或门店引流时,该字段有效且必填,允许值: + // TURE 开启 + // FALSE 关闭 + // 该字段为FALSE时:高峰日(自然周、节假日)、高峰日预算上调比例 均不可填值 + IsSetPeakBudget string `json:"is_set_peak_budget,omitempty"` + // PeakWeekDays 高峰日-自然周,允许值: + // MONDAY 周一 + // TUESDAY 周二 + // WEDNESDAY 周三 + // THURSDAY 周四 + // FRIDAY 周五 + // SATURDAY 周六 + // SUNDAY 周日 + // 注意:peak_holidays和peak_week_days不可同时为空,必须传入至少一个高峰日 + PeakWeekDays []enum.Weekday `json:"peak_week_days,omitempty"` + // PeakHolidays 高峰日-节假日,允许值: + // NEW_YEAR 元旦 + // SPRING_FESTIVAL 春节 + // VALENTINES_DAY 情人节 + // LABOUR_DAY 五一 + // DRAGON_BOAT_FESTIVAL 端午 + // CHINESE_VALENTINES_DAY 七夕 + // MOON_FESTIVAL 中秋 + // NATIONAL_DAY 国庆 + // CHRISTMAS 圣诞节 + // SHOPPING_DAY_618 618 + // SHOPPING_DAY_1111 双11 + // 注意:peak_holidays和peak_week_days不可同时为空,必须传入至少一个高峰日 + PeakHolidays []enum.Holiday `json:"peak_holidays,omitempty"` + // HighBudgetRate 高峰日预算上调比例,单位为百分比,例如:传“40”表示高峰日时预算上调“40%” + // 当is_set_peak_budget = TURE开启高峰日预算时有效且必填 + // 区间限制: 20~200 + HighBudgetRate int `json:"high_budget_rate,omitempty"` +} + +// Encode implements PostRequest interface +func (r CreateRequest) Encode() []byte { + return util.JSONMarshal(r) +} + +// CreateResponse 创建项目 API Response +type CreateResponse struct { + model.BaseResponse + Data struct { + // ProjectID 项目ID + ProjectID uint64 `json:"project_id,omitempty"` + } `json:"data,omitempty"` +} diff --git a/marketing-api/model/local/project/detail.go b/marketing-api/model/local/project/detail.go new file mode 100644 index 00000000..53695fb1 --- /dev/null +++ b/marketing-api/model/local/project/detail.go @@ -0,0 +1,33 @@ +package project + +import ( + "strconv" + + "github.com/bububa/oceanengine/marketing-api/model" + "github.com/bububa/oceanengine/marketing-api/util" +) + +// DetailRequest 获取项目详情 API Request +type DetailRequest struct { + // LocalAccountID 本地推广告账户ID + LocalAccountID uint64 `json:"local_account_id,omitempty"` + // ProjectID 项目ID + ProjectID uint64 `json:"project_id,omitempty"` +} + +// Encode implements GetRequest interface +func (r DetailRequest) Encode() string { + values := util.GetUrlValues() + values.Set("local_account_id", strconv.FormatUint(r.LocalAccountID, 10)) + values.Set("project_id", strconv.FormatUint(r.ProjectID, 10)) + ret := values.Encode() + util.PutUrlValues(values) + return ret +} + +// DetailResponse 获取项目详情 API Response +type DetailResponse struct { + // Project 项目详情 + Data *ProjectDetail `json:"data,omitempty"` + model.BaseResponse +} diff --git a/marketing-api/model/local/project/doc.go b/marketing-api/model/local/project/doc.go new file mode 100644 index 00000000..bfffe81c --- /dev/null +++ b/marketing-api/model/local/project/doc.go @@ -0,0 +1,2 @@ +// Package project 项目管理模块 +package project diff --git a/marketing-api/model/local/project/list.go b/marketing-api/model/local/project/list.go new file mode 100644 index 00000000..529b4edb --- /dev/null +++ b/marketing-api/model/local/project/list.go @@ -0,0 +1,112 @@ +package project + +import ( + "strconv" + + "github.com/bububa/oceanengine/marketing-api/enum/local" + "github.com/bububa/oceanengine/marketing-api/model" + "github.com/bububa/oceanengine/marketing-api/util" +) + +// ListRequest 获取项目列表 API Request +type ListRequest struct { + // LocalAccountID 本地推广告账户ID + LocalAccountID uint64 `json:"local_account_id,omitempty"` + // Filtering 过滤字段 + Filtering *ListRequestFilter `json:"filtering,omitempty"` + // Page 页码,默认值1 + Page int `json:"page,omitempty"` + // PageSize 页面大小,最大值100,默认值20 + PageSize int `json:"page_size,omitempty"` +} + +type ListRequestFilter struct { + // ProjectIDs 项目IDs筛选,最多100个 + ProjectIDs []uint64 `json:"project_ids,omitempty"` + // ProjectStatusFirst 项目一级状态筛选,允许值: + // PROJECT_STATUS_ALL 不限(包含已删除) + // PROJECT_STATUS_DELETE 已删除 + // PROJECT_STATUS_DISABLE 未投放 + // PROJECT_STATUS_DONE 已完成 + // PROJECT_STATUS_ENABLE 启用中 + // PROJECT_STATUS_NOT_DELETE 不限(不包含已删除) + // 默认值: PROJECT_STATUS_NOT_DELETE 不限(不包含已删除) + ProjectStatusFirst local.ProjectStatus `json:"project_status_first,omitempty"` + // ProjectStatusSecond 项目二级状态筛选,允许值: + // PROJECT_STATUS_BUDGET_EXCEED 项目超出预算 + // PROJECT_STATUS_DISABLE 已暂停 + // PROJECT_STATUS_NOT_SCHEDULE 不在投放时段 + // PROJECT_STATUS_NOT_START 未达投放时间 + // 仅当status_first = PROJECT_STATUS_DISABLE 未投放时传入有效 + ProjectStatusSecond local.ProjectStatus `json:"project_status_second,omitempty"` + // ShopIDs 按门店IDs筛选,单次限制最多10个 + ShopIDs []uint64 `json:"shop_ids,omitempty"` + // ProductIDs 按商品IDs筛选,单次限制最多10个 + ProductIDs []uint64 `json:"product_ids,omitempty"` + // LocalDeliveryScene 推广目的筛选,默认不限,允许值: + // ALL 不限 + // CONTENT_HEAT 内容加热 + // POI_RECOMMEND 门店引流 + // PRODUCT_PAY 团购成交 + // 默认值: ALL + LocalDeliveryScene local.LocalDeliveryScene `json:"local_delivery_scene,omitempty"` + // MarketingGoal 营销场景筛选,默认不限 ,允许值: + // ALL 不限 + // LIVE 直播 + // VIDEO_IMAGE 短视频/图文 + // 默认值: ALL + MarketingGoal local.MarketingGoal `json:"marketing_goal,omitempty"` + // AdType 广告类型筛选,默认不限,允许值: + // ALL 不限 + // GENERAL 通投广告 + // SEARCHING 搜索广告 + // 默认值: ALL + AdType local.AdType `json:"ad_type,omitempty"` + // ProjectName 项目名称,模糊搜索 + ProjectName string `json:"project_name,omitempty"` + // ProjectCreateTimeStart 项目创建开始时间,格式yyyy-MM-dd HH:mm:ss,与project_create_time_end搭配使用 + ProjectCreateTimeStart string `json:"project_create_time_start,omitempty"` + // ProjectCreateTimeEnd 项目创建结束时间,格式yyyy-MM-dd HH:mm:ss,与project_create_time_start搭配使用 + ProjectCreateTimeEnd string `json:"project_create_time_end,omitempty"` + // ProjectModifyTimeStart 项目更新开始时间,格式yyyy-MM-dd HH:mm:ss,与project_modify_time_end搭配使用 + ProjectModifyTimeStart string `json:"project_modify_time_start,omitempty"` + // ProjectModifyTimeEnd 项目更新结束时间,格式yyyy-MM-dd HH:mm:ss,与project_modify_time_start搭配使用 + ProjectModifyTimeEnd string `json:"project_modify_time_end,omitempty"` + // BidType 出价方式,默认不限,允许值: + // ALL 不限 + // MANUAL 手动出价 + // SMART 智能出价 + // 默认值: ALL + BidType local.BidType `json:"bid_type,omitempty"` +} + +// Encode implements GetRequest interface +func (r ListRequest) Encode() string { + values := util.GetUrlValues() + values.Set("local_account_id", strconv.FormatUint(r.LocalAccountID, 10)) + if r.Filtering != nil { + values.Set("filtering", string(util.JSONMarshal(r.Filtering))) + } + if r.Page > 0 { + values.Set("page", strconv.Itoa(r.Page)) + } + if r.PageSize > 0 { + values.Set("page_size", strconv.Itoa(r.PageSize)) + } + ret := values.Encode() + util.PutUrlValues(values) + return ret +} + +// ListResponse 获取项目列表 API Response +type ListResponse struct { + Data *ListResult `json:"data,omitempty"` + model.BaseResponse +} + +type ListResult struct { + // PageInfo 分页信息 + PageInfo *model.PageInfo `json:"page_info,omitempty"` + // ProjectList 项目列表 + ProjectList []Project `json:"project_list,omitempty"` +} diff --git a/marketing-api/model/local/project/project.go b/marketing-api/model/local/project/project.go new file mode 100644 index 00000000..c5a74942 --- /dev/null +++ b/marketing-api/model/local/project/project.go @@ -0,0 +1,175 @@ +package project + +import ( + "github.com/bububa/oceanengine/marketing-api/enum" + "github.com/bububa/oceanengine/marketing-api/enum/local" + "github.com/bububa/oceanengine/marketing-api/model/local/product" +) + +// Project 项目 +type Project struct { + // ProjectID 项目ID + ProjectID uint64 `json:"project_id,omitempty"` + // ProjectStatusFirst 项目一级状态 + ProjectStatusFirst local.ProjectStatus `json:"project_status_first,omitempty"` + // ProjectStatusSecond 项目二级状态 + ProjectStatusSecond []local.ProjectStatus `json:"project_status_second,omitempty"` + // LocalAccountID 本地推广告账户ID + LocalAccountID uint64 `json:"local_account_id,omitempty"` + // AdType 广告类型 + AdType local.AdType `json:"ad_type,omitempty"` + // MarketingGoal 营销场景 + MarketingGoal local.MarketingGoal `json:"marketing_goal,omitempty"` + // Name 项目名称 + Name string `json:"name,omitempty"` + // ProjectCreateTime 项目创建时间,格式:yyyy-MM-dd HH:mm:ss + ProjectCreateTime string `json:"project_create_time,omitempty"` + // ProjectModifyTime 项目更新时间,格式:yyyy-MM-dd HH:mm:ss + ProjectModifyTime string `json:"project_modify_time,omitempty"` + // ExternalAction 优化目标,枚举值: + // FOLLOW_ACTION 粉丝增长 + // LIVE_ENGAGEMENT 直播加热 + // LIVE_ENTER_ACTION 直播间观看 + // LIVE_OTO_CLICK 直播间商品点击 + // LIVE_OTO_GROUP_BUYING 直播间团购购买 + // LIVE_STAY_TIME 直播间停留NATIVE_ACTION 用户互动 + // SHOW 展示量 + // OTO_PAY 团购购买 + // POI_RECOMMEND 门店引流 + ExternalAction local.ExternalAction `json:"external_action,omitempty"` + // DeliveryGoal 投放内容,枚举值: + // POI 门店 + // PRODUCT 商品 + DeliveryGoal local.DeliveryGoal `json:"delivery_goal,omitempty"` + // ProjectBudgetMode 项目预算类型,枚举值: + // BUDGET_MODE_DAY 日预算 + // BUDGET_MODE_TOTAL 总预算 + ProjectBudgetMode enum.BudgetMode `json:"project_budget_mode,omitempty"` + // ProjectBudget 项目预算,单位为:分 + ProjectBudget int64 `json:"project_budget,omitempty"` + // BidType 出价方式,枚举值: + // MANUAL 手动出价 + // SMART 智能出价 + BidType local.BidType `json:"bid_type,omitempty"` + // ProjectBid 项目出价,单位为:分 + ProjectBid int64 `json:"project_bid,omitempty"` + // StartTime 投放开始时间,如:2017-01-01 精确到天 + StartTime string `json:"start_time,omitempty"` + // EndTime 投放结束时间,如:2017-01-01 精确到天 + EndTime string `json:"end_time,omitempty"` + // PoiInfo 项目推广门店信息 + PoiInfo *PoiInfo `json:"poi_info,omitempty"` + // ProductInfo 商品信息 + ProductInfo *product.Product `json:"product_info,omitempty"` + // DeliveryPoiMode 本地投放模式 + DeliveryPoiMode local.DeliveryPoiMode `json:"delivery_poi_mode,omitempty"` +} + +// ProjectDetail 项目详情 +type ProjectDetail struct { + // ProjectID 项目ID + ProjectID uint64 `json:"project_id,omitempty"` + // ProjectStatusFirst 项目一级状态 + ProjectStatusFirst local.ProjectStatus `json:"project_status_first,omitempty"` + // ProjectStatusSecond 项目二级状态 + ProjectStatusSecond []local.ProjectStatus `json:"project_status_second,omitempty"` + // LocalAccountID 本地推广告账户ID + LocalAccountID uint64 `json:"local_account_id,omitempty"` + // AwemeID 抖音号ID + AwemeID string `json:"aweme_id,omitempty"` + // AdType 广告类型 + AdType local.AdType `json:"ad_type,omitempty"` + // LocalDeliveryScene 本地投放场景 + LocalDeliveryScene local.LocalDeliveryScene `json:"local_delivery_scene,omitempty"` + // MarketingGoal 营销场景 + MarketingGoal local.MarketingGoal `json:"marketing_goal,omitempty"` + // Name 项目名称 + Name string `json:"name,omitempty"` + // ExternalAction 优化目标,枚举值: + // FOLLOW_ACTION 粉丝增长 + // LIVE_ENGAGEMENT 直播加热 + // LIVE_ENTER_ACTION 直播间观看 + // LIVE_OTO_CLICK 直播间商品点击 + // LIVE_OTO_GROUP_BUYING 直播间团购购买 + // LIVE_STAY_TIME 直播间停留NATIVE_ACTION 用户互动 + // SHOW 展示量 + // OTO_PAY 团购购买 + // POI_RECOMMEND 门店引流 + ExternalAction local.ExternalAction `json:"external_action,omitempty"` + // DeliveryGoal 投放内容,枚举值: + // POI 门店 + // PRODUCT 商品 + DeliveryGoal local.DeliveryGoal `json:"delivery_goal,omitempty"` + // BudgetMode 项目预算类型,枚举值: + // BUDGET_MODE_DAY 日预算 + // BUDGET_MODE_TOTAL 总预算 + BudgetMode enum.BudgetMode `json:"budget_mode,omitempty"` + // Budget 项目预算,单位为:分 + Budget int64 `json:"budget,omitempty"` + // BidType 出价方式,枚举值: + // MANUAL 手动出价 + // SMART 智能出价 + BidType local.BidType `json:"bid_type,omitempty"` + // Bid 项目出价,单位为:分 + Bid int64 `json:"bid,omitempty"` + // StartTime 投放开始时间,如:2017-01-01 精确到天 + StartTime string `json:"start_time,omitempty"` + // EndTime 投放结束时间,如:2017-01-01 精确到天 + EndTime string `json:"end_time,omitempty"` + // DeliveryPoiMode 本地投放模式 + DeliveryPoiMode local.DeliveryPoiMode `json:"delivery_poi_mode,omitempty"` + // AutoUpdatePois 自动更新门店开启状态,仅推广全部门店项目返回,枚举值: + // OFF 不启用 + // ON 启用 + AutoUpdatePois string `json:"auto_update_pois,omitempty"` + // PoiID 门店id + // 当项目推广单个门店时返回 + PoiID uint64 `json:"poi_id,omitempty"` + // MultiPoiNum 推广门店数量 + MultiPoiNum int `json:"multi_poi_num,omitempty"` + // ProductID 商品ID + ProductID uint64 `json:"product_id,omitempty"` + // ScheduleType 投放日期类型 ,枚举值: + // FROM_NOW_ON 从今天起长期投放 + // START_TO_END 设置开始结束时间 + // FIXED_TIME 固定时长投放 + ScheduleType local.ScheduleType `json:"schedule_type,omitempty"` + // ScheduleFixedSeconds 投放时长,单位为秒 + ScheduleFixedSeconds int64 `json:"schedule_fixed_seconds,omitempty"` + // ScheduleTime 投放时段 + // 格式是48*7位字符串,且都是0或1。也就是以半个小时为最小粒度,周一至周日每天分为48个区段,0为不投放,1为投放,不传、全传0、全传1均代表全时段投放。 + // 例如:000000000000000000000001111000000000000000000000000000000000000000000001111000000000000000000000000000000000000000000001111000000000000000000000000000000000000000000001111000000000000000000000000000000000000000000001111000000000000000000000000000000000000000000001111000000000000000000000000000000000000000000001111000000000000000000000,则投放时段为周一到周日的11:30~13:30 + ScheduleTime string `json:"schedule_time,omitempty"` + // IsSetPeakBudget 是否设置峰值预算 + IsSetPeakBudget bool `json:"is_set_peak_budget,omitempty"` + // HighBudgetRate 上调高峰日预算比例 + // 注意:该字段为百分比,例如:传“40”表示高峰日时预算上调“40%” + HighBudgetRate int `json:"high_budget_rate,omitempty"` + // PeakWeekDays 高峰日-自然周 + PeakWeekDays []enum.Weekday `json:"peak_week_days,omitempty"` + // PeakHolidays 高峰日-节假日 + PeakHolidays []enum.Holiday `json:"peak_holidays,omitempty"` + // Audience 定向设置 + Audience *Audience `json:"audience,omitempty"` +} + +// PoiInfo 项目推广门店信息 +type PoiInfo struct { + // PoiID 门店id + // 仅推广单门店项目返回,推广多门店时不返回 + PoiID uint64 `json:"poi_id,omitempty"` + // PoiName 门店名称 + // 仅推广单门店项目返回,推广多门店时不返回 + PoiName string `json:"poi_name,omitempty"` + // PoiImageURL 门店头图 + // 仅推广单门店项目返回,推广多门店时不返回 + PoiImageURL string `json:"poi_image_url,omitempty"` + // MultiPoiNum 推广门店数量 + MultiPoiNum int `json:"multi_poi_num,omitempty"` + // AllPoiMod 推广门店类型,枚举值: + // ALL 全部门店 + // PART 指定门店 + AllPoiMode local.DeliveryPoiMode `json:"all_poi_mode,omitempty"` + // AutoUpdatePoi 是否自动更新门店,枚举值: + AutoUpdatePoi string `json:"auto_update_poi,omitempty"` +} diff --git a/marketing-api/model/local/project/status_update.go b/marketing-api/model/local/project/status_update.go new file mode 100644 index 00000000..0504a62d --- /dev/null +++ b/marketing-api/model/local/project/status_update.go @@ -0,0 +1,58 @@ +package project + +import ( + "strconv" + + "github.com/bububa/oceanengine/marketing-api/model" + "github.com/bububa/oceanengine/marketing-api/util" +) + +// StatusUpdateRequest 批量更新项目状态 API Request +type StatusUpdateRequest struct { + // LocalAccountID 本地推广告账户ID + LocalAccountID uint64 `json:"local_account_id,omitempty"` + // Data 批量更新项目状态,包含项目ID和目标操作,list长度限制1~50 + Data []StatusUpdateItem `json:"data,omitempty"` +} + +// StatusUpdateItem 批量更新项目 +type StatusUpdateItem struct { + // ProjectID 项目id + ProjectID uint64 `json:"project_id,omitempty"` + // OptStatus 目标操作 + // 目标操作,可选值: + // ENABLE 启用项目 + // PAUSED 暂停项目 + // 对于删除的广告项目不可进行任何操作,否则会报错 + OptStatus string `json:"opt_status,omitempty"` +} + +// Encode implements PostRequest interface +func (r StatusUpdateRequest) Encode() []byte { + return util.JSONMarshal(r) +} + +// StatusUpdateResponse 批量更新项目状态 API Response +type StatusUpdateResponse struct { + model.BaseResponse + Data *UpdateResult `json:"data,omitempty"` +} + +type UpdateResult struct { + // ProjectIDs 更新成功的项目ID + ProjectIDs []uint64 `json:"project_ids,omitempty"` + // Errors 更新失败的项目列表 + Errors []UpdateError `json:"errors,omitempty"` +} + +// UpdateError 更新失败的项目列表 +type UpdateError struct { + // ProjectID 项目ID + ProjectID uint64 `json:"project_id,omitempty"` + // ErrorMessage 失败信息 + ErrorMessage string `json:"error_message,omitempty"` +} + +func (e UpdateError) Error() string { + return util.StringsJoin("项目ID:", strconv.FormatUint(e.ProjectID, 10), ", ", e.ErrorMessage) +} diff --git a/marketing-api/model/local/project/update.go b/marketing-api/model/local/project/update.go new file mode 100644 index 00000000..3244a54a --- /dev/null +++ b/marketing-api/model/local/project/update.go @@ -0,0 +1,87 @@ +package project + +import ( + "github.com/bububa/oceanengine/marketing-api/enum" + "github.com/bububa/oceanengine/marketing-api/enum/local" + "github.com/bububa/oceanengine/marketing-api/util" +) + +// UpdateRequest 更新项目 API Request +type UpdateRequest struct { + // LocalAccountID 本地推广告账户ID + LocalAccountID uint64 `json:"local_account_id,omitempty"` + // ProjectID 项目ID + ProjectID uint64 `json:"project_id,omitempty"` + // Name 项目名称,长度是1-50个字(两个英文字符占1个字) + Name string `json:"name,omitempty"` + // Audience 定向设置,接口暂不支持设置抖音达人定向,该定向默认不限 + Audience *Audience `json:"audience,omitempty"` + // ScheduleType 投放日期类型设置,允许值: + // FROM_NOW_ON 从今天起长期投放 + // START_TO_END 设置开始结束时间 + // FIXED_TIME 固定时长 + // 仅营销场景=LIVE直播时,该枚举值有效,否则传入报错 + ScheduleType local.ScheduleType `json:"schedule_type,omitempty"` + // ScheduleFixedSeconds 直播固定投放时长(单位:秒) + // 填写说明: + // 仅当营销场景=LIVE && schedule_type=FIXED_TIME 固定时长时有效且必填,其他情况传入报错 + // 输入值需不小于1800,且为1800的整数倍(即半个小时为最小粒度) + ScheduleFixedSeconds int64 `json:"schedule_fixed_seconds,omitempty"` + // EndTime 结束投放时间,精确到天,例如:2017-01-01 + // 当schedule_type=START_TO_END时,有效且必填 + // 结束时间不得小于开始时间 + EndTime string `json:"end_time,omitempty"` + // ScheduleTime 投放时段,默认全时段投放。格式是48*7位字符串,且都是0或1,也就是以半个小时为最小粒度,周一至周日每天分为48个区段,0为不投放,1为投放,不传、全传0、全传1均代表全时段投放。 + // 当schedule_type=FIXED_TIME固定时长时,该字段无效,传入会报错 + // 例如:000000000000000000000001111000000000000000000000000000000000000000000001111000000000000000000000000000000000000000000001111000000000000000000000000000000000000000000001111000000000000000000000000000000000000000000001111000000000000000000000000000000000000000000001111000000000000000000000000000000000000000000001111000000000000000000000,则投放时段为周一到周日的11:30~13:30 + ScheduleTime string `json:"schedule_time,omitempty"` + // Bid 出价,当出价方式=MANUAL 手动出价时有效 + // 出价单位:分 + // 展示量取值范围为[400,10000],其他场景取值范围为[1, 1000000] + // 【展示量】:分/千次曝光 + Bid int64 `json:"bid,omitempty"` + // Budget 项目预算,单位为:分 + // 填写限制: + // 当budget_mode=BUDGET_MODE_DAY 日预算 && bid_type=SMART 智能出价时,取值范围为[10000, 999999999] + // 当budget_mode=BUDGET_MODE_DAY 日预算 && bid_type=MANUAL 手动出价时,取值范围为[30000, 999999999] + // 当budget_mode=BUDGET_MODE_TOTAL 总预算时,取值范围为[30000, 999999999] + Budget int64 `json:"budget,omitempty"` + // IsSetPeakBudget 高峰日预算设置,仅当营销场景为短视频,且推广目的=团购成交或门店引流时,该字段有效且必填,允许值: + // TURE 开启 + // FALSE 关闭 + // 该字段为FALSE时:高峰日(自然周、节假日)、高峰日预算上调比例 均不可填值 + IsSetPeakBudget string `json:"is_set_peak_budget,omitempty"` + // PeakWeekDays 高峰日-自然周,允许值: + // MONDAY 周一 + // TUESDAY 周二 + // WEDNESDAY 周三 + // THURSDAY 周四 + // FRIDAY 周五 + // SATURDAY 周六 + // SUNDAY 周日 + // 注意:peak_holidays和peak_week_days不可同时为空,必须传入至少一个高峰日 + PeakWeekDays []enum.Weekday `json:"peak_week_days,omitempty"` + // PeakHolidays 高峰日-节假日,允许值: + // NEW_YEAR 元旦 + // SPRING_FESTIVAL 春节 + // VALENTINES_DAY 情人节 + // LABOUR_DAY 五一 + // DRAGON_BOAT_FESTIVAL 端午 + // CHINESE_VALENTINES_DAY 七夕 + // MOON_FESTIVAL 中秋 + // NATIONAL_DAY 国庆 + // CHRISTMAS 圣诞节 + // SHOPPING_DAY_618 618 + // SHOPPING_DAY_1111 双11 + // 注意:peak_holidays和peak_week_days不可同时为空,必须传入至少一个高峰日 + PeakHolidays []enum.Holiday `json:"peak_holidays,omitempty"` + // HighBudgetRate 高峰日预算上调比例,单位为百分比,例如:传“40”表示高峰日时预算上调“40%” + // 当is_set_peak_budget = TURE开启高峰日预算时有效且必填 + // 区间限制: 20~200 + HighBudgetRate int `json:"high_budget_rate,omitempty"` +} + +// Encode implements PostRequest interface +func (r UpdateRequest) Encode() []byte { + return util.JSONMarshal(r) +} diff --git a/marketing-api/model/local/promotion/create.go b/marketing-api/model/local/promotion/create.go new file mode 100644 index 00000000..eac6aaa6 --- /dev/null +++ b/marketing-api/model/local/promotion/create.go @@ -0,0 +1,51 @@ +package promotion + +import ( + "github.com/bububa/oceanengine/marketing-api/enum" + "github.com/bububa/oceanengine/marketing-api/model" + "github.com/bububa/oceanengine/marketing-api/util" +) + +// CreateRequest 创建广告 API Request +type CreateRequest struct { + // LocalAccountID 本地推广告账户ID + LocalAccountID uint64 `json:"local_account_id,omitempty"` + // ProjectID 项目ID + ProjectID uint64 `json:"project_id,omitempty"` + // Name 广告名称,长度是1-50个字(两个英文字符占1个字) + Name string `json:"name,omitempty"` + // EnableGraphicDelivery 是否开启团购卡 + // 仅当项目marketing_goal = VIDEO_IMAGE 短视频/图文 && external_action = OTO_PAY 团购购买/POI_RECOMMEND 门店引流时 ,有效且必传 + EnableGraphicDelivery bool `json:"enable_graphic_delivery,omitempty"` + // AwemeID 用于推广的抖音号id + // 当营销场景为短视频,且选择素材库和上传视频投广时,该字段必填 + AwemeID string `json:"aweme_id,omitempty"` + // VideoHpVisibility 主页视频是否可见,默认单次展示可见 + // ALWAYS_VISIBLE 主页始终可见 + // HIDE_VIDEO_ON_HP 仅单次展示可见(默认值) + // 仅针对素材库和上传视频生效 + VideoHpVisibility enum.VideoHpVisibility `json:"video_hp_visibility,omitempty"` + // LiveMaterialType 直播素材类型设置 可选值: + // LIVE 直播间画面 + // VIDEO 短视频 + // 注意:当项目营销场景为直播间时,有效且必传。直播场景下仅支持设置其一,当选择直播间画面时,不支持传入customer_material_list + LiveMaterialType enum.MarketingGoal `json:"live_material_type,omitempty"` + // CustomerMaterialList 视频素材列表 + // 推直播:live_material_type=VIDEO短视频时必填,live_material_type=LIVE时不支持传入,传入会报错; + // 推短视频:未开启团购卡时,视频素材必传;开启团购卡时,可根据是否需要推广短视频素材选择传入 + CustomerMaterialList []CustomerMaterial `json:"customer_material_list,omitempty"` +} + +// Encode implement PostRequest interface +func (r CreateRequest) Encode() []byte { + return util.JSONMarshal(r) +} + +// CreateResponse 创建广告 API Response +type CreateResponse struct { + model.BaseResponse + Data struct { + // PromotionID 广告ID + PromotionID uint64 `json:"promotion_id,omitempty"` + } `json:"data,omitempty"` +} diff --git a/marketing-api/model/local/promotion/customer_material.go b/marketing-api/model/local/promotion/customer_material.go new file mode 100644 index 00000000..642827ad --- /dev/null +++ b/marketing-api/model/local/promotion/customer_material.go @@ -0,0 +1,61 @@ +package promotion + +import "github.com/bububa/oceanengine/marketing-api/enum/local" + +// CustomerMaterial 视频素材列表 +type CustomerMaterial struct { + // ImageMode 素材类型 可选值: + // IMAGE_MODE_VIDEO 横版视频 + // IMAGE_MODE_VIDEO_VERTICAL 竖版视频 + ImageMode local.ImageMode `json:"image_mode,omitempty"` + // TitleMaterial 标题素材 + // 仅针对素材库视频生效且必填,即传入video_id时,该字段生效且必填 + // 当传入item_id时,以抖音主页视频的标题为主,该字段不生效 + TitleMaterial *TitleMaterial `json:"title_material,omitempty"` + // VideoMaterial 视频素材 + VideoMaterial *VideoMaterial `json:"video_material,omitempty"` +} + +// TitleMaterial 标题素材 +type TitleMaterial struct { + // Title 标题,标题长度要求5-55个字(两个英文字符占1个字) + Title string `json:"title,omitempty"` + // LegoMaterialID 标题素材库id + LegoMaterialID uint64 `json:"lego_material_id,omitempty"` + // MaterialID 标题素材id + MaterialID uint64 `json:"material_id,omitempty"` +} + +// VideoMaterial 视频素材 +type VideoMaterial struct { + // VideoID 视频ID + VideoID string `json:"video_id,omitempty"` + // CoverWebURL 封面图片URI + CoverWebURL string `json:"cover_web_url,omitempty"` + // AwemeItemID 抖音短视频ID,推广抖音主页视频时传入 + // 注意:如果视频为抖音主页视频,则该字段必填 + // 如果和video_id同时传,以aweme_item_id为准 + AwemeItemID uint64 `json:"aweme_item_id,omitempty"` + // LegoMaterialID 视频素材库id + LegoMaterialID uint64 `json:"lego_material_id,omitempty"` + // MaterialID 视频素材id + MaterialID uint64 `json:"material_id,omitempty"` + // ImageMode 素材类型,枚举值: + // IMAGE_MODE_VIDEO 横版视频 + // IMAGE_MODE_VIDEO_VERTICAL 竖版视频 + ImageMode local.ImageMode `json:"image_mode,omitempty"` + // VideoDuration 视频长度 + VideoDuration int64 `json:"video_duration,omitempty"` + // VideoHeight 视频高度 + VideoHeight int64 `json:"video_height,omitempty"` + // VideoWidth 视频宽度 + VideoWidth int64 `json:"video_width,omitempty"` + // VideoPlayURL 视频播放链接 + VideoPlayURL string `json:"video_play_url,omitempty"` + // CoverImageHeight 封面图片高度 + CoverImageHeight int64 `json:"cover_image_height,omitempty"` + // CoverImageWidth 封面图片宽度 + CoverImageWidth int64 `json:"cover_image_width,omitempty"` + // CoverWebURI 封面图片uri + CoverWebURI string `json:"cover_web_uri,omitempty"` +} diff --git a/marketing-api/model/local/promotion/detail.go b/marketing-api/model/local/promotion/detail.go new file mode 100644 index 00000000..cefb3447 --- /dev/null +++ b/marketing-api/model/local/promotion/detail.go @@ -0,0 +1,32 @@ +package promotion + +import ( + "strconv" + + "github.com/bububa/oceanengine/marketing-api/model" + "github.com/bububa/oceanengine/marketing-api/util" +) + +// DetailRequest 获取广告详情 API Request +type DetailRequest struct { + // LocalAccountID 本地推广告账户ID + LocalAccountID uint64 `json:"local_account_id,omitempty"` + // PromotionID 广告ID + PromotionID uint64 `json:"promotion_id,omitempty"` +} + +// Encode implements GetRequest interface +func (r DetailRequest) Encode() string { + values := util.GetUrlValues() + values.Set("local_account_id", strconv.FormatUint(r.LocalAccountID, 10)) + values.Set("promotion_id", strconv.FormatUint(r.PromotionID, 10)) + ret := values.Encode() + util.PutUrlValues(values) + return ret +} + +// DetailResponse 获取广告详情 API Response +type DetailResponse struct { + Data *PromotionDetail `json:"data,omitempty"` + model.BaseResponse +} diff --git a/marketing-api/model/local/promotion/doc.go b/marketing-api/model/local/promotion/doc.go new file mode 100644 index 00000000..d93ed8e4 --- /dev/null +++ b/marketing-api/model/local/promotion/doc.go @@ -0,0 +1,2 @@ +// Package promotion 广告管理模块 +package promotion diff --git a/marketing-api/model/local/promotion/list.go b/marketing-api/model/local/promotion/list.go new file mode 100644 index 00000000..0bceaab0 --- /dev/null +++ b/marketing-api/model/local/promotion/list.go @@ -0,0 +1,140 @@ +package promotion + +import ( + "strconv" + + "github.com/bububa/oceanengine/marketing-api/enum" + "github.com/bububa/oceanengine/marketing-api/enum/local" + "github.com/bububa/oceanengine/marketing-api/model" + "github.com/bububa/oceanengine/marketing-api/util" +) + +// ListRequest 获取广告列表 API Request +type ListRequest struct { + // LocalAccountID 本地推广告账户ID + LocalAccountID uint64 `json:"local_account_id,omitempty"` + // Filtering 筛选项 + Filtering *ListFilter `json:"filtering,omitempty"` + // Page 页码,默认值1 + Page int `json:"page,omitempty"` + // PageSize 页面大小,最大值100,默认10 + PageSize int `json:"page_size,omitempty"` +} + +type ListFilter struct { + // PromotionIDs 按广告IDs筛选,单次最多100个 + PromotionIDs []uint64 `json:"promotion_ids,omitempty"` + // PromotionName 按广告名称模糊搜索 + PromotionName string `json:"promotion_name,omitempty"` + // ProjectID 项目ID筛选 + ProjectID uint64 `json:"project_id,omitempty"` + // PromotionStatusFirst 广告一级状态过滤,默认不限(不包含已删除),允许值: + // PROMOTION_STATUS_ALL 不限(包含已删除) + // PROMOTION_STATUS_DELETED 已删除: + // PROMOTION_STATUS_DISABLE 未投放 + // PROMOTION_STATUS_DONE 已完成 + // PROMOTION_STATUS_ENABLE 投放中 + // PROMOTION_STATUS_FROZEN 已终止 + // PROMOTION_STATUS_NOT_DELETE 不限(不包含已删除) + // 默认值: PROMOTION_STATUS_NOT_DELETE + PromotionStatusFirst local.PromotionStatusFirst `json:"promotion_status_first,omitempty"` + // PromotionStatusSecond 广告二级状态过滤,允许值: + // 仅当promotion_status_first=PROMOTION_STATUS_DISABLE未投放时传入有效且必填,不传会报错;其他情况下传入该字段无效。 + // AUDIT_DENY 审核不通过 + // AUDIT 新建审核中 + // REAUD/IT 修改审核中 + // DISABLED 已暂停 + // DISABLE_BY_QUOTA 配额达限 + // PROJECT_DISABLED 项目已被暂停 + // NO_SCHEDULE 不在投放时段 + // TIME_NO_REACH 未到达投放时间 + // OFFLINE_BALANCE 账户余额不足 + // BALANCE_OFFLINE_BUDGET 账户超出预算 + // PROJECT_OFFLINE_BUDGET 项目超出预算 + // PROMOTION_OFFLINE_BUDGET 广告超出预算 + // LIVE_ROOM_OFF 直播间不可投放 + // AWEME_ACCOUNT_DISABLED 抖音账号不可投放 + // PRODUCT_OR_POI_OFFLINE 商品/门店不可投 + PromotionStatusSecond local.PromotionStatusSecond `json:"promotion_status_second,omitempty"` + // AdType 广告类型筛选,默认不限,允许值: + // ALL 不限 + // GENERAL 通投广告 + // SEARCHING 搜索广告 + // 默认值: ALL + AdType local.AdType `json:"ad_type,omitempty"` + // MarketingGoal 营销场景筛选,默认不限,允许值: + // ALL 不限 + // LIVE 直播 + // VIDEO_IMAGE 短视频/图文 + // 默认值: ALL + MarketingGoal local.MarketingGoal `json:"marketing_goal,omitempty"` + // PromotionCreateTimeStart 广告创建开始时间,格式yyyy-MM-dd HH:mm:ss与time_end搭配使用 + PromotionCreateTimeStart string `json:"promotion_create_time_start,omitempty"` + // PromotionCreateTimeEnd 广告创建结束时间,格式yyyy-MM-dd HH:mm:ss与time_start搭配使用 + PromotionCreateTimeEnd string `json:"promotion_create_time_end,omitempty"` + // PromotionModifyTimeStart 广告更新开始时间,格式yyyy-MM-dd HH:mm:ss与time_end搭配使用 + PromotionModifyTimeStart string `json:"promotion_modify_time_start,omitempty"` + // PromotionModifyTimeEnd 广告更新结束时间,格式yyyy-MM-dd HH:mm:ss与time_start搭配使用 + PromotionModifyTimeEnd string `json:"promotion_modify_time_end,omitempty"` + // RejectReasonType 审核建议类型筛选,默认不限,允许值: + // ALL 不限 + // NONE 无建议 + // LOW_MATERAIL 低俗素材 + // QUALITY_POOR 素材质量低 + // EXAGGERATION 夸大宣传 + // ELSE 其他 + // DISCOMFORT 引人不适 + // REVIEW_REJECT 审核不通过 + // 默认值: ALL + RejectReasonType enum.PromotionRejectReasonType `json:"reject_reason_type,omitempty"` + // LearningPhase 学习期状态筛选,默认不限,允许值: + // ALL 不限 + // LEARNED 学习期结束 + // LEARNING 学习中 + // LEARN_FAILED 学习失败 + // 默认值: ALL + LearningPhase enum.LearningPhase `json:"learning_phase,omitempty"` + // BudgetMode 预算类型筛选,默认不限,允许值: + // ALL 不限 + // BUDGET_MODE_DAY 日预算 + // BUDGET_MODE_TOTAL 总预算 + // 默认值: ALL + BudgetMode enum.BudgetMode `json:"budget_mode,omitempty"` + // BidType 出价方式筛选,默认不限,允许值: + // ALL 不限 + // MANUAL 手动出价 + // SMART 智能出价 + // 默认值: ALL + BidType local.BidType `json:"bid_type,omitempty"` +} + +// Encode implements GetRequest interface +func (r ListRequest) Encode() string { + values := util.GetUrlValues() + values.Set("local_account_id", strconv.FormatUint(r.LocalAccountID, 10)) + if r.Filtering != nil { + values.Set("filtering", string(util.JSONMarshal(r.Filtering))) + } + if r.Page > 0 { + values.Set("page", strconv.Itoa(r.Page)) + } + if r.PageSize > 0 { + values.Set("page_size", strconv.Itoa(r.PageSize)) + } + ret := values.Encode() + util.PutUrlValues(values) + return ret +} + +// ListResponse 获取广告列表 API Response +type ListResponse struct { + Data *ListResult `json:"data,omitempty"` + model.BaseResponse +} + +type ListResult struct { + // PageInfo 分页信息 + PageInfo *model.PageInfo `json:"page_info,omitempty"` + // PromotionList 广告列表 + Promotion []Promotion `json:"promotion_list,omitempty"` +} diff --git a/marketing-api/model/local/promotion/promotion.go b/marketing-api/model/local/promotion/promotion.go new file mode 100644 index 00000000..44c4f10f --- /dev/null +++ b/marketing-api/model/local/promotion/promotion.go @@ -0,0 +1,57 @@ +package promotion + +import ( + "github.com/bububa/oceanengine/marketing-api/enum" + "github.com/bububa/oceanengine/marketing-api/enum/local" +) + +// Promotion 广告 +type Promotion struct { + // ProjectID 项目ID + ProjectID uint64 `json:"project_id,omitempty"` + // LocalAccountID 广告主ID + LocalAccountID uint64 `json:"local_account_id,omitempty"` + // AdType 广告类型,枚举值: + // GENERAL 通投广告 + // SEARCHING 搜索广告 + AdType local.AdType `json:"ad_type,omitempty"` + // PromotionID 广告ID + PromotionID uint64 `json:"promotion_id,omitempty"` + // PromotionName 广告名称 + PromotionName string `json:"promotion_name,omitempty"` + // PromotionCreateTime 广告创建时间,格式yyyy-MM-dd HH:mm:ss + PromotionCreateTime string `json:"promotion_create_time,omitempty"` + // PromotionModifyTime 广告修改时间,格式yyyy-MM-dd HH:mm:ss + PromotionModifyTime string `json:"promotion_modify_time,omitempty"` + // PromotionStatusFirst 广告一级状态 + PromotionStatusFirst local.PromotionStatusFirst `json:"promotion_status_first,omitempty"` + // PromotionStatusSecond 广告二级状态 + PromotionStatusSecond []local.PromotionStatusSecond `json:"promotion_status_second,omitempty"` + // LearningPhase 学习期状态,枚举值: + // LEARNED 学习期结束 + // LEARNING 学习中 + // LEARN_FAILED 学习失败 + LearningPhase enum.LearningPhase `json:"learning_phase,omitempty"` + // AwemeID 抖音号 + AwemeID string `json:"aweme_id,omitempty"` + // AwemeName 抖音号昵称 + AwemeName string `json:"aweme_name,omitempty"` +} + +// PromotionDetail 广告详情 +type PromotionDetail struct { + // PromotionID 广告ID + PromotionID uint64 `json:"promotion_id,omitempty"` + // AwemeID 抖音号 + AwemeID string `json:"aweme_id,omitempty"` + // EnableGraphicDelivery 是否开启团购卡 + EnableGraphicDelivery bool `json:"enable_graphic_delivery,omitempty"` + // VideoHpVisibility 视频曝光 + VideoHpVisibility enum.VideoHpVisibility `json:"video_hp_visibility,omitempty"` + // LiveMaterialType 直播素材类型,枚举值: + // LIVE 直播素材 + // VIDEO 广告素材 + LiveMaterialType enum.MarketingGoal `json:"live_material_type,omitempty"` + // CustomerMaterialList 自定义素材组合 + CustomerMaterialList []CustomerMaterial `json:"customer_material_list,omitempty"` +} diff --git a/marketing-api/model/local/promotion/status_update.go b/marketing-api/model/local/promotion/status_update.go new file mode 100644 index 00000000..ffe7780e --- /dev/null +++ b/marketing-api/model/local/promotion/status_update.go @@ -0,0 +1,58 @@ +package promotion + +import ( + "strconv" + + "github.com/bububa/oceanengine/marketing-api/model" + "github.com/bububa/oceanengine/marketing-api/util" +) + +// StatusUpdateRequest 批量更新广告状态 API Request +type StatusUpdateRequest struct { + // LocalAccountID 本地推广告账户ID + LocalAccountID uint64 `json:"local_account_id,omitempty"` + // Data 批量更新广告状态,包含广告ID和目标操作,list长度限制1~50 + Data []StatusUpdateItem `json:"data,omitempty"` +} + +// StatusUpdateItem 批量更新广告 +type StatusUpdateItem struct { + // PromotionID 广告id + PromotionID uint64 `json:"promotion_id,omitempty"` + // OptStatus 目标操作 + // 目标操作,可选值: + // ENABLE 启用广告 + // PAUSED 暂停广告 + // 对于删除的广告广告不可进行任何操作,否则会报错 + OptStatus string `json:"opt_status,omitempty"` +} + +// Encode implements PostRequest interface +func (r StatusUpdateRequest) Encode() []byte { + return util.JSONMarshal(r) +} + +// StatusUpdateResponse 批量更新广告状态 API Response +type StatusUpdateResponse struct { + model.BaseResponse + Data *UpdateResult `json:"data,omitempty"` +} + +type UpdateResult struct { + // PromotionIDs 更新成功的广告ID + PromotionIDs []uint64 `json:"promotion_ids,omitempty"` + // Errors 更新失败的广告列表 + Errors []UpdateError `json:"errors,omitempty"` +} + +// UpdateError 更新失败的广告列表 +type UpdateError struct { + // PromotionID 广告ID + PromotionID uint64 `json:"promotion_id,omitempty"` + // ErrorMessage 失败信息 + ErrorMessage string `json:"error_message,omitempty"` +} + +func (e UpdateError) Error() string { + return util.StringsJoin("广告ID:", strconv.FormatUint(e.PromotionID, 10), ", ", e.ErrorMessage) +} diff --git a/marketing-api/model/local/promotion/update.go b/marketing-api/model/local/promotion/update.go new file mode 100644 index 00000000..34f45c8b --- /dev/null +++ b/marketing-api/model/local/promotion/update.go @@ -0,0 +1,33 @@ +package promotion + +import ( + "github.com/bububa/oceanengine/marketing-api/enum" + "github.com/bububa/oceanengine/marketing-api/util" +) + +// UpdateRequest 更新广告 API Request +type UpdateRequest struct { + // LocalAccountID 本地推广告账户ID + LocalAccountID uint64 `json:"local_account_id,omitempty"` + // PromotionID 广告ID + PromotionID uint64 `json:"promotion_id,omitempty"` + // Name 广告名称,长度是1-50个字(两个英文字符占1个字) + Name string `json:"name,omitempty"` + // AwemeID 用于推广的抖音号id + // 当营销场景为短视频,且选择素材库和上传视频投广时,该字段必填 + AwemeID string `json:"aweme_id,omitempty"` + // VideoHpVisibility 主页视频是否可见,默认单次展示可见 + // ALWAYS_VISIBLE 主页始终可见 + // HIDE_VIDEO_ON_HP 仅单次展示可见(默认值) + // 仅针对素材库和上传视频生效 + VideoHpVisibility enum.VideoHpVisibility `json:"video_hp_visibility,omitempty"` + // CustomerMaterialList 视频素材列表 + // 推直播:live_material_type=VIDEO短视频时必填,live_material_type=LIVE时不支持传入,传入会报错; + // 推短视频:未开启团购卡时,视频素材必传;开启团购卡时,可根据是否需要推广短视频素材选择传入 + CustomerMaterialList []CustomerMaterial `json:"customer_material_list,omitempty"` +} + +// Encode implement PostRequest interface +func (r UpdateRequest) Encode() []byte { + return util.JSONMarshal(r) +} diff --git a/marketing-api/model/local/report/doc.go b/marketing-api/model/local/report/doc.go new file mode 100644 index 00000000..66d7b255 --- /dev/null +++ b/marketing-api/model/local/report/doc.go @@ -0,0 +1,2 @@ +// Package report 本地推数据报表相关 +package report diff --git a/marketing-api/model/local/report/material_get.go b/marketing-api/model/local/report/material_get.go new file mode 100644 index 00000000..9f16a151 --- /dev/null +++ b/marketing-api/model/local/report/material_get.go @@ -0,0 +1,97 @@ +package report + +import ( + "strconv" + + "github.com/bububa/oceanengine/marketing-api/enum" + "github.com/bububa/oceanengine/marketing-api/enum/local" + "github.com/bububa/oceanengine/marketing-api/model" + "github.com/bububa/oceanengine/marketing-api/util" +) + +// MaterialGetRequest 获取素材数据 API Request +type MaterialGetRequest struct { + // LocalAccountID 本地推广告账户ID + LocalAccountID uint64 `json:"local_account_id,omitempty"` + // TimeGranularity 时间粒度,允许值: + // TIME_GRANULARITY_DAILY 天维度(默认值) + // TIME_GRANULARITY_HOURLY 小时维度 + // TIME_GRANULARITY_TOTAL 汇总 + TimeGranularity enum.TimeGranularity `json:"time_granularity,omitempty"` + // StartDate 查询起始日期,格式:yyyy-mm-dd + StartDate string `json:"start_date,omitempty"` + // EndDate 查询结束日期,格式:yyyy-mm-dd + // 当time_granularity = TIME_GRANULARITY_DAILY/TIME_GRANULARITY_TOTAL时,时间跨度不能超过365天 + // 当time_granularity = TIME_GRANULARITY_HOURLY时,时间跨度不能超过7天 + EndDate string `json:"end_date,omitempty"` + // OrderType 排序方式,允许值: + // ASC 升序(默认值) + // DESC 降序 + OrderType enum.OrderType `json:"order_type,omitempty"` + // OrderField 排序字段,允许值可参考应答返回数据指标 + OrderField string `json:"order_field,omitempty"` + // Metrics 指标集,允许值可参考应答返回数据指标 + Metrics []string `json:"metrics,omitempty"` + // Filtering 过滤器 + Filtering *MaterialGetFilter `json:"filtering,omitempty"` + // Page 页码,默认值:1 + Page int `json:"page,omitempty"` + // PageSize 页面大小,允许值:10(默认值)、20、50、100 + PageSize int `json:"page_size,omitempty"` +} + +type MaterialGetFilter struct { + // MaterialIDs 素材ID + MaterialIDs []uint64 `json:"material_ids,omitempty"` + // MaterialType 素材类型,允许值: +// CASURAL 图文 +// VIDEO 视频 + MaterialType enum.MaterialMode `json:"material_type,omitempty"` + // CampaignType 广告类型,允许值: + // GENERAL 通投广告 + // SEARCHING 线索广告 + CampaignType local.AdType `json:"campaign_type,omitempty"` +} + +// Encode implements GetRequest interface +func (r MaterialGetRequest) Encode() string { + values := util.GetUrlValues() + values.Set("local_account_id", strconv.FormatUint(r.LocalAccountID, 10)) + if r.TimeGranularity != "" { + values.Set("time_granularity", string(r.TimeGranularity)) + } + values.Set("start_date", r.StartDate) + values.Set("end_date", r.EndDate) + if r.OrderType != "" { + values.Set("order_type", string(r.OrderType)) + } + if r.OrderField != "" { + values.Set("order_field", r.OrderField) + } + values.Set("metrics", string(util.JSONMarshal(r.Metrics))) + if r.Filtering != nil { + values.Set("filtering", string(util.JSONMarshal(r.Filtering))) + } + if r.Page > 0 { + values.Set("page", strconv.Itoa(r.Page)) + } + if r.PageSize > 0 { + values.Set("page_size", strconv.Itoa(r.PageSize)) + } + ret := values.Encode() + util.PutUrlValues(values) + return ret +} + +// MaterialGetResponse 获取素材数据 API Response +type MaterialGetResponse struct { + model.BaseResponse + Data *MaterialGetResult `json:"data,omitempty"` +} + +type MaterialGetResult struct { + // PageInfo 分页信息 + PageInfo *model.PageInfo `json:"page_info,omitempty"` + // MaterialList + MaterialList []Report `json:"material_list,omitempty"` +} diff --git a/marketing-api/model/local/report/project_get.go b/marketing-api/model/local/report/project_get.go new file mode 100644 index 00000000..d9a19666 --- /dev/null +++ b/marketing-api/model/local/report/project_get.go @@ -0,0 +1,105 @@ +package report + +import ( + "strconv" + + "github.com/bububa/oceanengine/marketing-api/enum" + "github.com/bububa/oceanengine/marketing-api/enum/local" + "github.com/bububa/oceanengine/marketing-api/model" + "github.com/bububa/oceanengine/marketing-api/util" +) + +// ProjectGetRequest 获取项目数据 API Request +type ProjectGetRequest struct { + // LocalAccountID 本地推广告账户ID + LocalAccountID uint64 `json:"local_account_id,omitempty"` + // TimeGranularity 时间粒度,允许值: + // TIME_GRANULARITY_DAILY 天维度(默认值) + // TIME_GRANULARITY_HOURLY 小时维度 + // TIME_GRANULARITY_TOTAL 汇总 + TimeGranularity enum.TimeGranularity `json:"time_granularity,omitempty"` + // StartDate 查询起始日期,格式:yyyy-mm-dd + StartDate string `json:"start_date,omitempty"` + // EndDate 查询结束日期,格式:yyyy-mm-dd + // 当time_granularity = TIME_GRANULARITY_DAILY/TIME_GRANULARITY_TOTAL时,时间跨度不能超过365天 + // 当time_granularity = TIME_GRANULARITY_HOURLY时,时间跨度不能超过7天 + EndDate string `json:"end_date,omitempty"` + // OrderType 排序方式,允许值: + // ASC 升序(默认值) + // DESC 降序 + OrderType enum.OrderType `json:"order_type,omitempty"` + // OrderField 排序字段,允许值可参考应答返回数据指标 + OrderField string `json:"order_field,omitempty"` + // Metrics 指标集,允许值可参考应答返回数据指标 + Metrics []string `json:"metrics,omitempty"` + // Filtering 过滤器 + Filtering *ProjectGetFilter `json:"filtering,omitempty"` + // Page 页码,默认值:1 + Page int `json:"page,omitempty"` + // PageSize 页面大小,允许值:10(默认值)、20、50、100 + PageSize int `json:"page_size,omitempty"` +} + +type ProjectGetFilter struct { + // CdpProjectIDs 项目ID + CdpProjectIDs []uint64 `json:"cdp_project_ids,omitempty"` + // LocalDeliveryScene 推广目的,允许值: + // CLUE 线索 + // CONTENT_HEATING 内容加热 + // POI_CUSTOMER 门店引流 + // PURCHASE 团购成交 + LocalDeliveryScene local.LocalDeliveryScene `json:"local_delivery_scene,omitempty"` + // MarketingGoal 营销场景,允许值: + // LIVE 直播 + // VIDEO_IMAGE 短视频/图文 + MarketingGoal local.MarketingGoal `json:"marketing_goal,omitempty"` + // CampaignType 广告类型,允许值: + // GENERAL 通投广告 + // SEARCHING 线索广告 + CampaignType local.AdType `json:"campaign_type,omitempty"` + // ExternalAction 优化目标 + ExternalAction local.ExternalAction `json:"external_action,omitempty"` +} + +// Encode implements GetRequest interface +func (r ProjectGetRequest) Encode() string { + values := util.GetUrlValues() + values.Set("local_account_id", strconv.FormatUint(r.LocalAccountID, 10)) + if r.TimeGranularity != "" { + values.Set("time_granularity", string(r.TimeGranularity)) + } + values.Set("start_date", r.StartDate) + values.Set("end_date", r.EndDate) + if r.OrderType != "" { + values.Set("order_type", string(r.OrderType)) + } + if r.OrderField != "" { + values.Set("order_field", r.OrderField) + } + values.Set("metrics", string(util.JSONMarshal(r.Metrics))) + if r.Filtering != nil { + values.Set("filtering", string(util.JSONMarshal(r.Filtering))) + } + if r.Page > 0 { + values.Set("page", strconv.Itoa(r.Page)) + } + if r.PageSize > 0 { + values.Set("page_size", strconv.Itoa(r.PageSize)) + } + ret := values.Encode() + util.PutUrlValues(values) + return ret +} + +// ProjectGetResponse 获取项目数据 API Response +type ProjectGetResponse struct { + model.BaseResponse + Data *ProjectGetResult `json:"data,omitempty"` +} + +type ProjectGetResult struct { + // PageInfo 分页信息 + PageInfo *model.PageInfo `json:"page_info,omitempty"` + // ProjectList + ProjectList []Report `json:"project_list,omitempty"` +} diff --git a/marketing-api/model/local/report/promotion_get.go b/marketing-api/model/local/report/promotion_get.go new file mode 100644 index 00000000..1f02e427 --- /dev/null +++ b/marketing-api/model/local/report/promotion_get.go @@ -0,0 +1,105 @@ +package report + +import ( + "strconv" + + "github.com/bububa/oceanengine/marketing-api/enum" + "github.com/bububa/oceanengine/marketing-api/enum/local" + "github.com/bububa/oceanengine/marketing-api/model" + "github.com/bububa/oceanengine/marketing-api/util" +) + +// PromotionGetRequest 获取广告数据 API Request +type PromotionGetRequest struct { + // LocalAccountID 本地推广告账户ID + LocalAccountID uint64 `json:"local_account_id,omitempty"` + // TimeGranularity 时间粒度,允许值: + // TIME_GRANULARITY_DAILY 天维度(默认值) + // TIME_GRANULARITY_HOURLY 小时维度 + // TIME_GRANULARITY_TOTAL 汇总 + TimeGranularity enum.TimeGranularity `json:"time_granularity,omitempty"` + // StartDate 查询起始日期,格式:yyyy-mm-dd + StartDate string `json:"start_date,omitempty"` + // EndDate 查询结束日期,格式:yyyy-mm-dd + // 当time_granularity = TIME_GRANULARITY_DAILY/TIME_GRANULARITY_TOTAL时,时间跨度不能超过365天 + // 当time_granularity = TIME_GRANULARITY_HOURLY时,时间跨度不能超过7天 + EndDate string `json:"end_date,omitempty"` + // OrderType 排序方式,允许值: + // ASC 升序(默认值) + // DESC 降序 + OrderType enum.OrderType `json:"order_type,omitempty"` + // OrderField 排序字段,允许值可参考应答返回数据指标 + OrderField string `json:"order_field,omitempty"` + // Metrics 指标集,允许值可参考应答返回数据指标 + Metrics []string `json:"metrics,omitempty"` + // Filtering 过滤器 + Filtering *PromotionGetFilter `json:"filtering,omitempty"` + // Page 页码,默认值:1 + Page int `json:"page,omitempty"` + // PageSize 页面大小,允许值:10(默认值)、20、50、100 + PageSize int `json:"page_size,omitempty"` +} + +type PromotionGetFilter struct { + // PromotionIDs 广告ID + PromotionIDs []uint64 `json:"promotion_ids,omitempty"` + // LocalDeliveryScene 推广目的,允许值: + // CLUE 线索 + // CONTENT_HEATING 内容加热 + // POI_CUSTOMER 门店引流 + // PURCHASE 团购成交 + LocalDeliveryScene local.LocalDeliveryScene `json:"local_delivery_scene,omitempty"` + // MarketingGoal 营销场景,允许值: + // LIVE 直播 + // VIDEO_IMAGE 短视频/图文 + MarketingGoal local.MarketingGoal `json:"marketing_goal,omitempty"` + // CampaignType 广告类型,允许值: + // GENERAL 通投广告 + // SEARCHING 线索广告 + CampaignType local.AdType `json:"campaign_type,omitempty"` + // ExternalAction 优化目标 + ExternalAction local.ExternalAction `json:"external_action,omitempty"` +} + +// Encode implements GetRequest interface +func (r PromotionGetRequest) Encode() string { + values := util.GetUrlValues() + values.Set("local_account_id", strconv.FormatUint(r.LocalAccountID, 10)) + if r.TimeGranularity != "" { + values.Set("time_granularity", string(r.TimeGranularity)) + } + values.Set("start_date", r.StartDate) + values.Set("end_date", r.EndDate) + if r.OrderType != "" { + values.Set("order_type", string(r.OrderType)) + } + if r.OrderField != "" { + values.Set("order_field", r.OrderField) + } + values.Set("metrics", string(util.JSONMarshal(r.Metrics))) + if r.Filtering != nil { + values.Set("filtering", string(util.JSONMarshal(r.Filtering))) + } + if r.Page > 0 { + values.Set("page", strconv.Itoa(r.Page)) + } + if r.PageSize > 0 { + values.Set("page_size", strconv.Itoa(r.PageSize)) + } + ret := values.Encode() + util.PutUrlValues(values) + return ret +} + +// PromotionGetResponse 获取广告数据 API Response +type PromotionGetResponse struct { + model.BaseResponse + Data *PromotionGetResult `json:"data,omitempty"` +} + +type PromotionGetResult struct { + // PageInfo 分页信息 + PageInfo *model.PageInfo `json:"page_info,omitempty"` + // PromotionList 广告列表 + PromotionList []Report `json:"promotion_list,omitempty"` +} diff --git a/marketing-api/model/local/report/report.go b/marketing-api/model/local/report/report.go new file mode 100644 index 00000000..3ac7d60b --- /dev/null +++ b/marketing-api/model/local/report/report.go @@ -0,0 +1,119 @@ +package report + +// Report 报表 +type Report struct { + // ProjectID 项目ID + ProjectID uint64 `json:"project_id,omitempty"` + // ProjectName 项目名称 + ProjectName string `json:"project_name,omitempty"` + // PromotionID 广告id + PromotionID uint64 `json:"promotion_id,omitempty"` + // PromotionName 广告名称 + PromotionName string `json:"promotion_name,omitempty"` + // MaterialID 素材ID + MaterialID uint64 `json:"material_id,omitempty"` + // MaterialName 素材名称 + MaterialName string `json:"material_name,omitempty"` + // StatTimeDay 时间-天 + StatTimeDay string `json:"stat_time_day,omitempty"` + // StatTimeHour 时间-小时 + StatTimeHour string `json:"stat_time_hour,omitempty"` + // StatCost 消耗(元) + StatCost float64 `json:"stat_cost,omitempty"` + // ShowCnt 展示次数 + ShowCnt int64 `json:"show_cnt,omitempty"` + // ClickCnt 点击次数 + ClickCnt int64 `json:"click_cnt,omitempty"` + // Ctr 点击率 + Crt float64 `json:"ctr,omitempty"` + // CpcPlatform 点击均价(元) + CpcPlatform float64 `json:"cpc_platform,omitempty"` + // CpmPlatform 平均千次展示费用(元) + CpmPlatform float64 `json:"cpm_platform,omitempty"` + // ConvertCnt 转化数 + ConvertCnt int64 `json:"convert_cnt,omitempty"` + // ConversionRate 转化率 + ConversionRate float64 `json:"conversion_rate,omitempty"` + // ConversionCost 转化成本(元) + ConversionCost float64 `json:"conversion_cost,omitempty"` + // AttributionConvertCnt 转化数(计费时间) + AttributionConvertCnt int64 `json:"attribution_convert_cnt,omitempty"` + // AttributionConversionRate 转化率(计费时间) + AttributionConversionRate float64 `json:"attribution_conversion_rate,omitempty"` + // AttributionConversionCost 转化成本(计费时间) + AttributionConversionCost float64 `json:"attribution_conversion_cost,omitempty"` + // FormCnt 表单提交数 + FormCnt int64 `json:"form_cnt,omitempty"` + // CluePayOrderCnt 团购线索数 + CluePayOrderCnt int64 `json:"clue_pay_order_cnt,omitempty"` + // ClueMessageCount 私信留资数 + ClueMessageCount int64 `json:"clue_message_count,omitempty"` + // PhoneConfirmCnt 电话拨打数 + PhoneConfirmCnt int64 `json:"phone_confirm_cnt,omitempty"` + // PhoneConnectCnt 电话接通数 + PhoneConnectCnt int64 `json:"phone_connect_cnt,omitempty"` + // MessageActionCnt 私信咨询数 + MessageActionCnt int64 `json:"message_action_cnt,omitempty"` + // IntentionFormCnt 意向表单数 + IntentionFormCnt int64 `json:"intention_form_cnt,omitempty"` + // IntentionPhoneCnt 意向话单数 + IntentionPhoneCnt int64 `json:"intention_phone_cnt,omitempty"` + // IntentionMessageClueCnt 意向咨询数 + IntentionMessageClueCnt int64 `json:"intention_message_clue_cnt,omitempty"` + // AttributionFormCnt 表单提交数(计费时间) + AttributionFormCnt int64 `json:"attribution_form_cnt,omitempty"` + // AttributionIntentionMessageClueCnt 团购线索数(计费时间) + AttributionCluePayOrderCnt int64 `json:"attribution_clue_pay_order_cnt,omitempty"` + // AttributeClueMessageCnt 私信留资数(计费时间) + AttributeClueMessageCnt int64 `json:"attribute_clue_message_count,omitempty"` + // AttributionPhoneConfirmCnt 电话拨打数(计费时间) + AttributionPhoneConfirmCnt int64 `json:"attribution_phone_confirm_cnt,omitempty"` + // AttributePhoneConnectCnt 电话接通数(计费时间) + AttributePhoneConnectCnt int64 `json:"attribute_phone_connect_cnt,omitempty"` + // AttributeMessactionActionCnt 私信咨询数(计费时间) + AttributeMessactionActionCnt int64 `json:"attribute_messaction_action_cnt,omitempty"` + // AttributeIntentionFormCnt 意向表单数(计费时间) + AttributionIntentionFormCnt int64 `json:"attribution_intention_form_cnt,omitempty"` + // AttributionIntentionPhoneCnt 意向话单数(计费时间) + AttributionIntentionPhoneCnt int64 `json:"attribution_intention_phone_cnt,omitempty"` + // AttributionIntentionMessageClueCnt 意向咨询数(计费时间) + AttributionIntentionMessageClueCnt int64 `json:"attribution_intention_message_clue_cnt,omitempty"` + // DyLike 视频点赞次数 + DyLike int64 `json:"dy_like,omitempty"` + // DyComment 视频评论次数 + DyComment int64 `json:"dy_comment,omitempty"` + // DyShare 视频分享次数 + DyShare int64 `json:"dy_share,omitempty"` + // DyCollect 视频收藏次数 + DyCollect int64 `json:"dy_collect,omitempty"` + // DyFollow 粉丝量 + DyFollow int64 `json:"dy_follow,omitempty"` + // TotalPlay 视频播放次数 + TotalPlay int64 `json:"total_play,omitempty"` + // PlayDuration3s 视频3s播放次数 + PlayDuration3s int64 `json:"play_duration_3s,omitempty"` + // PlayDuration5s 视频5s播放次数 + PlayDuration5s int64 `json:"play_duration_5s,omitempty"` + // Play25FeedBreak 视频25%进度播放次数 + Play25FeedBreak int64 `json:"play_25_feed_break,omitempty"` + // Play50FeedBreak 视频50%进度播放次数 + Play50FeedBreak int64 `json:"play_50_feed_break,omitempty"` + // Play75FeedBreak 视频75%进度播放次数 + Play75FeedBreak int64 `json:"play_75_feed_break,omitempty"` + // PlayOver 视频播放完成次数 + PlayOver int64 `json:"play_over,omitempty"` + // PlayDuration5sShowCntRate 视频5s播放率 + PlayDuration5sShowCntRate float64 `json:"play_duration_5s_show_cnt_rate,omitempty"` + // PlayOverRate 视频完播率 + PlayOverRate float64 `json:"play_over_rate,omitempty"` + // DyLikeRate 视频点赞率 + DyLikeRate float64 `json:"dy_like_rate,omitempty"` + // LubanLiveEnterCnt 直播间观看次数 + LubanLiveEnterCnt int64 `json:"luban_live_enter_cnt,omitempty"` + // LiveWatchOneMinuteCount 直播间超1分钟停留次数 + LiveWatchOneMinuteCount int64 `json:"live_watch_one_minute_count,omitempty"` + // LubanLiveCommentCnt 直播间评论次数 + LubanLiveCommentCnt int64 `json:"luban_live_comment_cnt,omitempty"` + // LubanLiveShareCnt 直播间分享次数 + LubanLiveShareCnt int64 `json:"luban_live_share_cnt,omitempty"` +} From aadb5555b1b4b8998c7ad1396eef7b0ff3332450 Mon Sep 17 00:00:00 2001 From: Syd Xu Date: Fri, 11 Oct 2024 18:15:11 +0800 Subject: [PATCH 2/2] =?UTF-8?q?feat(local):=20=E5=A2=9E=E5=8A=A0=E6=9C=AC?= =?UTF-8?q?=E5=9C=B0=E6=8E=A8=E7=B4=A0=E6=9D=90=E7=AE=A1=E7=90=86=E7=9B=B8?= =?UTF-8?q?=E5=85=B3API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- marketing-api/LOCAL.md | 6 + marketing-api/api/local/file/doc.go | 2 + .../api/local/file/upload_task_create.go | 19 ++++ .../api/local/file/video_aweme_get.go | 17 +++ marketing-api/api/local/file/video_get.go | 17 +++ marketing-api/api/local/file/video_upload.go | 17 +++ .../api/local/file/video_upload_task_list.go | 17 +++ marketing-api/core/client.go | 14 ++- .../enum/local/material_analysis_type.go | 13 +++ marketing-api/enum/local/material_source.go | 17 +++ .../enum/local/upload_task_status.go | 13 +++ marketing-api/model/local/file/doc.go | 2 + .../model/local/file/upload_task_create.go | 31 ++++++ marketing-api/model/local/file/video.go | 81 ++++++++++++++ .../model/local/file/video_aweme_get.go | 105 ++++++++++++++++++ marketing-api/model/local/file/video_get.go | 94 ++++++++++++++++ .../model/local/file/video_upload.go | 49 ++++++++ .../local/file/video_upload_task_list.go | 61 ++++++++++ marketing-api/model/page_info.go | 2 + 19 files changed, 574 insertions(+), 3 deletions(-) create mode 100644 marketing-api/api/local/file/doc.go create mode 100644 marketing-api/api/local/file/upload_task_create.go create mode 100644 marketing-api/api/local/file/video_aweme_get.go create mode 100644 marketing-api/api/local/file/video_get.go create mode 100644 marketing-api/api/local/file/video_upload.go create mode 100644 marketing-api/api/local/file/video_upload_task_list.go create mode 100644 marketing-api/enum/local/material_analysis_type.go create mode 100644 marketing-api/enum/local/material_source.go create mode 100644 marketing-api/enum/local/upload_task_status.go create mode 100644 marketing-api/model/local/file/doc.go create mode 100644 marketing-api/model/local/file/upload_task_create.go create mode 100644 marketing-api/model/local/file/video.go create mode 100644 marketing-api/model/local/file/video_aweme_get.go create mode 100644 marketing-api/model/local/file/video_get.go create mode 100644 marketing-api/model/local/file/video_upload.go create mode 100644 marketing-api/model/local/file/video_upload_task_list.go diff --git a/marketing-api/LOCAL.md b/marketing-api/LOCAL.md index 83b73fb9..5e2e0783 100644 --- a/marketing-api/LOCAL.md +++ b/marketing-api/LOCAL.md @@ -21,3 +21,9 @@ - 获取项目数据 [ ProjectGet(ctx context.Context, clt *core.SDKClient, accessToken string, req *report.ProjectGetRequest) (*report.ProjectGetResult, error) ] - 获取广告数据 [ PromotionGet(ctx context.Context, clt *core.SDKClient, accessToken string, req *report.PromotionGetRequest) (*report.PromotionGetResult, error) ] - 获取素材数据 [ MaterialGet(ctx context.Context, clt *core.SDKClient, accessToken string, req *report.MaterialGetRequest) (*report.MaterialGetResult, error) ] +- 本地推素材管理 (local/file) + - 异步上传本地推视频 [ UploadTaskCreate(ctx context.Context, clt *core.SDKClient, accessToken string, req *file.UploadTaskCreateRequest) (uint64, error) ] + - 查询异步上传本地推视频结果 [ VideoUploadTaskList(ctx context.Context, clt *core.SDKClient, accessToken string, req *file.VideoUploadTaskListRequest) ([]file.UploadTask, error) ] + - 上传视频 [ VideoUpload(ctx context.Context, clt *core.SDKClient, accessToken string, req *file.VideoUploadRequest) (*file.Video, error) ] + - 获取素材库视频 [ VideoGet(ctx context.Context, clt *core.SDKClient, accessToken string, req *file.VideoGetRequest) (*file.VideoGetResult, error) ] + - 获取抖音主页视频 [ VideoAwemeGet(ctx context.Context, clt *core.SDKClient, accessToken string, req *file.VideoAwemeGetRequest) (*file.VideoAwemeGetResult, error) ] diff --git a/marketing-api/api/local/file/doc.go b/marketing-api/api/local/file/doc.go new file mode 100644 index 00000000..7339833c --- /dev/null +++ b/marketing-api/api/local/file/doc.go @@ -0,0 +1,2 @@ +// Package file 本地推素材管理相关 +package file diff --git a/marketing-api/api/local/file/upload_task_create.go b/marketing-api/api/local/file/upload_task_create.go new file mode 100644 index 00000000..fea677e2 --- /dev/null +++ b/marketing-api/api/local/file/upload_task_create.go @@ -0,0 +1,19 @@ +package file + +import ( + "context" + + "github.com/bububa/oceanengine/marketing-api/core" + "github.com/bububa/oceanengine/marketing-api/model/local/file" +) + +// UploadTaskCreate 异步上传本地推视频 +// 将视频文件通过连山云素材服务上传后获取到视频文件链接,再将获取到的连山云视频文件url作为入参的video_url通过素材库提供的视频上传接口进行文件上传 +// 仅支持开发者购置连山云素材服务上传生成的tos链接上传,不支持其他三方链接地址 +func UploadTaskCreate(ctx context.Context, clt *core.SDKClient, accessToken string, req *file.UploadTaskCreateRequest) (uint64, error) { + var resp file.UploadTaskCreateResponse + if err := clt.PostAPI(ctx, "v3.0/local/file/upload_task/create/", req, &resp, accessToken); err != nil { + return 0, err + } + return resp.Data.TaskID, nil +} diff --git a/marketing-api/api/local/file/video_aweme_get.go b/marketing-api/api/local/file/video_aweme_get.go new file mode 100644 index 00000000..0de8c13b --- /dev/null +++ b/marketing-api/api/local/file/video_aweme_get.go @@ -0,0 +1,17 @@ +package file + +import ( + "context" + + "github.com/bububa/oceanengine/marketing-api/core" + "github.com/bububa/oceanengine/marketing-api/model/local/file" +) + +// VideoAwemeGet 获取素材库视频 +func VideoAwemeGet(ctx context.Context, clt *core.SDKClient, accessToken string, req *file.VideoAwemeGetRequest) (*file.VideoAwemeGetResult, error) { + var resp file.VideoAwemeGetResponse + if err := clt.GetAPI(ctx, "v3.0/local/file/video/aweme/get/", req, &resp, accessToken); err != nil { + return nil, err + } + return resp.Data, nil +} diff --git a/marketing-api/api/local/file/video_get.go b/marketing-api/api/local/file/video_get.go new file mode 100644 index 00000000..0ad9cb14 --- /dev/null +++ b/marketing-api/api/local/file/video_get.go @@ -0,0 +1,17 @@ +package file + +import ( + "context" + + "github.com/bububa/oceanengine/marketing-api/core" + "github.com/bububa/oceanengine/marketing-api/model/local/file" +) + +// VideoGet 获取素材库视频 +func VideoGet(ctx context.Context, clt *core.SDKClient, accessToken string, req *file.VideoGetRequest) (*file.VideoGetResult, error) { + var resp file.VideoGetResponse + if err := clt.GetAPI(ctx, "v3.0/local/file/video/get/", req, &resp, accessToken); err != nil { + return nil, err + } + return resp.Data, nil +} diff --git a/marketing-api/api/local/file/video_upload.go b/marketing-api/api/local/file/video_upload.go new file mode 100644 index 00000000..c8d4c788 --- /dev/null +++ b/marketing-api/api/local/file/video_upload.go @@ -0,0 +1,17 @@ +package file + +import ( + "context" + + "github.com/bububa/oceanengine/marketing-api/core" + "github.com/bububa/oceanengine/marketing-api/model/local/file" +) + +// VideoUpload 上传视频 +func VideoUpload(ctx context.Context, clt *core.SDKClient, accessToken string, req *file.VideoUploadRequest) (*file.Video, error) { + var resp file.VideoUploadResponse + if err := clt.Upload(ctx, "v3.0/local/file/video/upload/", req, &resp, accessToken); err != nil { + return nil, err + } + return resp.Data, nil +} diff --git a/marketing-api/api/local/file/video_upload_task_list.go b/marketing-api/api/local/file/video_upload_task_list.go new file mode 100644 index 00000000..0c74217b --- /dev/null +++ b/marketing-api/api/local/file/video_upload_task_list.go @@ -0,0 +1,17 @@ +package file + +import ( + "context" + + "github.com/bububa/oceanengine/marketing-api/core" + "github.com/bububa/oceanengine/marketing-api/model/local/file" +) + +// VideoUploadTaskList 查询异步上传本地推视频结果 +func VideoUploadTaskList(ctx context.Context, clt *core.SDKClient, accessToken string, req *file.VideoUploadTaskListRequest) ([]file.UploadTask, error) { + var resp file.VideoUploadTaskListResponse + if err := clt.GetAPI(ctx, "v3.0/local/file/video/upload_task/list/", req, &resp, accessToken); err != nil { + return nil, err + } + return resp.Data.List, nil +} diff --git a/marketing-api/core/client.go b/marketing-api/core/client.go index 3e0c49ca..f8b020ec 100644 --- a/marketing-api/core/client.go +++ b/marketing-api/core/client.go @@ -129,6 +129,15 @@ func (c *SDKClient) OpenGet(ctx context.Context, gw string, req model.GetRequest return c.get(ctx, OPEN_URL, gw, req, resp, accessToken) } +// Upload multipart/form-data post +func (c *SDKClient) Upload(ctx context.Context, gw string, req model.UploadRequest, resp model.Response, accessToken string) error { + return c.upload(ctx, BASE_URL, gw, req, resp, accessToken) +} + +func (c *SDKClient) UploadAPI(ctx context.Context, gw string, req model.UploadRequest, resp model.Response, accessToken string) error { + return c.upload(ctx, API_BASE_URL, gw, req, resp, accessToken) +} + func (c *SDKClient) post(ctx context.Context, base string, gw string, req model.PostRequest, resp model.Response, accessToken string) error { var reqBytes []byte if req != nil { @@ -217,8 +226,7 @@ func (c *SDKClient) GetBytes(ctx context.Context, gw string, req model.GetReques return ret, err } -// Upload multipart/form-data post -func (c *SDKClient) Upload(ctx context.Context, gw string, req model.UploadRequest, resp model.Response, accessToken string) error { +func (c *SDKClient) upload(ctx context.Context, base string, gw string, req model.UploadRequest, resp model.Response, accessToken string) error { buf := util.GetBufferPool() defer util.PutBufferPool(buf) mw := multipart.NewWriter(buf) @@ -252,7 +260,7 @@ func (c *SDKClient) Upload(ctx context.Context, gw string, req model.UploadReque } } mw.Close() - reqUrl := util.StringsJoin(BASE_URL, gw) + reqUrl := util.StringsJoin(base, gw) debug.PrintPostMultipartRequest(reqUrl, mp, c.debug) httpReq, err := http.NewRequestWithContext(ctx, http.MethodPost, reqUrl, buf) if err != nil { diff --git a/marketing-api/enum/local/material_analysis_type.go b/marketing-api/enum/local/material_analysis_type.go new file mode 100644 index 00000000..b75f050f --- /dev/null +++ b/marketing-api/enum/local/material_analysis_type.go @@ -0,0 +1,13 @@ +package local + +// MaterialAnalysisType 评估类型 +type MaterialAnalysisType string + +const ( + // MaterialAnalysisType_FIRST_PUBLISH 首发 + MaterialAnalysisType_FIRST_PUBLISH MaterialAnalysisType = "FIRST_PUBLISH" + // MaterialAnalysisType_FIRST_PUBLISH_AND_HIGH_QUALITY 首发&优质 + MaterialAnalysisType_FIRST_PUBLISH_AND_HIGH_QUALITY MaterialAnalysisType = "FIRST_PUBLISH_AND_HIGH_QUALITY" + // MaterialAnalysisType_HIGH_QUALITY 优质 + MaterialAnalysisType_HIGH_QUALITY MaterialAnalysisType = "HIGH_QUALITY" +) diff --git a/marketing-api/enum/local/material_source.go b/marketing-api/enum/local/material_source.go new file mode 100644 index 00000000..86839c61 --- /dev/null +++ b/marketing-api/enum/local/material_source.go @@ -0,0 +1,17 @@ +package local + +// MaterialSource 素材来源 +type MaterialSource string + +const ( + // MaterialSource_BP_PLATFORM 巨量引擎工作平台共享视频 + MaterialSource_BP_PLATFORM MaterialSource = "BP_PLATFORM" + // MaterialSource_CREATIVE_AIGC 即创 + MaterialSource_CREATIVE_AIGC MaterialSource = "CREATIVE_AIGC" + // MaterialSource_LOCAL_ADS_UPLOAD 本地上传 + MaterialSource_LOCAL_ADS_UPLOAD MaterialSource = "LOCAL_ADS_UPLOAD" + // MaterialSource_STAR 星图平台 + MaterialSource_STAR MaterialSource = "STAR" + // MaterialSource_MAPI MAPI上传 + MaterialSource_MAPI MaterialSource = "MAPI" +) diff --git a/marketing-api/enum/local/upload_task_status.go b/marketing-api/enum/local/upload_task_status.go new file mode 100644 index 00000000..062230c1 --- /dev/null +++ b/marketing-api/enum/local/upload_task_status.go @@ -0,0 +1,13 @@ +package local + +// UploadTaskStatus 任务处理状态 +type UploadTaskStatus string + +const ( + // UploadTaskStatus_PROCESS 处理中 + UploadTaskStatus_PROCESS UploadTaskStatus = "PROCESS" + // UploadTaskStatus_SUCCESS 成功 + UploadTaskStatus_SUCCESS UploadTaskStatus = "SUCCESS" + // UploadTaskStatus_FAILED 失败 + UploadTaskStatus_FAILED UploadTaskStatus = "FAILED" +) diff --git a/marketing-api/model/local/file/doc.go b/marketing-api/model/local/file/doc.go new file mode 100644 index 00000000..7339833c --- /dev/null +++ b/marketing-api/model/local/file/doc.go @@ -0,0 +1,2 @@ +// Package file 本地推素材管理相关 +package file diff --git a/marketing-api/model/local/file/upload_task_create.go b/marketing-api/model/local/file/upload_task_create.go new file mode 100644 index 00000000..a05061f2 --- /dev/null +++ b/marketing-api/model/local/file/upload_task_create.go @@ -0,0 +1,31 @@ +package file + +import ( + "github.com/bububa/oceanengine/marketing-api/model" + "github.com/bububa/oceanengine/marketing-api/util" +) + +// UploadTaskCreateRequest 异步上传本地推视频 API Request +type UploadTaskCreateRequest struct { + // LocalAccountID 本地推账户id + LocalAccountID uint64 `json:"local_account_id,omitempty"` + // Filename 素材的文件名 + Filename string `json:"filename,omitempty"` + // VideoURL 视频 url地址,最大支持上传文件大小:1000M + // 仅支持开发者购置连山云素材服务上传生成的tos链接上传,不支持其他三方链接地址,具体见接入指南 + VideoURL string `json:"video_url,omitempty"` +} + +// Encode implements PostRequest interface +func (r UploadTaskCreateRequest) Encode() []byte { + return util.JSONMarshal(r) +} + +// UploadTaskCreateResponse 异步上传本地推视频 API Response +type UploadTaskCreateResponse struct { + model.BaseResponse + Data struct { + // TaskID 本地推任务id + TaskID uint64 `json:"task_id,omitempty"` + } `json:"data,omitempty"` +} diff --git a/marketing-api/model/local/file/video.go b/marketing-api/model/local/file/video.go new file mode 100644 index 00000000..4a12c5c6 --- /dev/null +++ b/marketing-api/model/local/file/video.go @@ -0,0 +1,81 @@ +package file + +import "github.com/bububa/oceanengine/marketing-api/enum/local" + +// Video 视频信息 +type Video struct { + // VideoID 视频id + VideoID string `json:"video_id,omitempty"` + // MaterialID 素材id + MaterialID uint64 `json:"material_id,omitempty"` + // Size 视频大小 + Size int64 `json:"size,omitempty"` + // VideoSiganture 视频md5 + VideoSiganture string `json:"video_siganture,omitempty"` + // Width 视频宽 + Width int64 `json:"width,omitempty"` + // Height 视频高 + Height int64 `json:"height,omitempty"` + // VideoURL 视频地址 + VideoURL string `json:"video_url,omitempty"` + // Duration 视频时长 + Duration float64 `json:"duration,omitempty"` + // VideoName 视频名称 + VideoName string `json:"video_name,omitempty"` + // PosterURL 视频首帧截图 + PosterURL string `json:"poster_url,omitempty"` + // MaterialProperties 素材标签,枚举值: + // COPY 搬运风险 + // FIRST_PUBLISH 首发 + // HIGH_QUALITY 优质 + // LOW_QUALITY 低质 + // SIMILAR 同质化风险 + MaterialProperties []string `json:"material_properties,omitempty"` + // ImageMode 视频类型,枚举值: + // IMAGE_MODE_VIDEO 横版视频 + // IMAGE_MODE_VIDEO_VERTICAL 竖版视频 + ImageMode local.ImageMode `json:"image_mode,omitempty"` + // Source 视频来源,枚举值: + // BP_PLATFORM 巨量引擎工作平台共享视频 + // CREATIVE_AIGC 即创 + // LOCAL_ADS_UPLOAD 本地上传 + // STAR 星图平台 + // MAPI MAPI接口上传 + Source local.MaterialSource `json:"source,omitempty"` + // CreateTime 素材的上传时间,格式:yyyy-mm-dd HH:mm:ss + CreateTime string `json:"create_time,omitempty"` +} + +// VideoAweme 抖音视频 +type VideoAweme struct { + // ItemID 抖音视频ID + ItemID uint64 `json:"item_id,omitempty"` + // Title 视频标题 + Title string `json:"title,omitempty"` + // VideoID 视频ID + VideoID string `json:"video_id,omitempty"` + // AwemeID 抖音号ID + AwemeID string `json:"aweme_id,omitempty"` + // ImageMode 视频类型,枚举值: + // IMAGE_MODE_VIDEO 横版视频 + // IMAGE_MODE_VIDEO_VERTICAL 竖版视频 + ImageMode local.ImageMode `json:"image_mode,omitempty"` + // CoverImageURL 视频封面图片地址 + CoverImageURL string `json:"cover_image_url,omitempty"` + // AwemeVideoURL 视频播放地址 + AwemeVideoURL string `json:"aweme_video_url,omitempty"` + // NotDeliveryReason 不可投放原因 + NotDeliveryReason string `json:"not_delivery_reason,omitempty"` + // CanDelivery 视频是否可投放 + // true 可投放 + // false 不可投放 + CanDelivery bool `json:"can_delivery,omitempty"` + // LegoMaterialID 素材id + LegoMaterialID uint64 `json:"lego_material_id,omitempty"` + // VideoWidth 视频宽度 + VideoWidth int64 `json:"video_width,omitempty"` + // VideoHeight 视频高度 + VideoHeight int64 `json:"video_height,omitempty"` + // Duration 视频时长 + Duration string `json:"duration,omitempty"` +} diff --git a/marketing-api/model/local/file/video_aweme_get.go b/marketing-api/model/local/file/video_aweme_get.go new file mode 100644 index 00000000..ee73184f --- /dev/null +++ b/marketing-api/model/local/file/video_aweme_get.go @@ -0,0 +1,105 @@ +package file + +import ( + "strconv" + + "github.com/bububa/oceanengine/marketing-api/enum/local" + "github.com/bububa/oceanengine/marketing-api/model" + "github.com/bububa/oceanengine/marketing-api/util" +) + +// VideoAwemeGetRequest 获取抖音主页视频 API Request +type VideoAwemeGetRequest struct { + // LocalAccountID 本地推账户id + LocalAccountID uint64 `json:"local_account_id,omitempty"` + // Filtering 过滤字段 + Filtering *VideoAwemeGetFilter `json:"filtering,omitempty"` + // OrderField 排序字段,允许值: + // ARRIVE_SHOP 到店量排序 + // ESTIMATE 预估效果排序 + // LIKE_CNT 点赞量排序 + // PAY_ORDER_CNT 成交量排序 + // PUBLISH_TIME 发布时间排序 + OrderField string `json:"order_field,omitempty"` + // ExternalAction 转化目标,允许值: + // OTO_PAY 团购购买(默认值) + // POI_RECOMMEND 门店引流 + // 仅order_filed= ESTIMATE 预估效果排序时有效 + ExternalAction local.ExternalAction `json:"external_action,omitempty"` + // Count 页面数据量,默认10,最大值100,最小值1 + Count int `json:"count,omitempty"` + // Cursor 页码游标值,第一次传0,之后每次传上一次请求返回的游标值 + Cursor string `json:"cursor,omitempty"` +} + +type VideoAwemeGetFilter struct { + // AnchorInfo 视频挂载的锚点信息 + AnchorInfo *AnchorInfo `json:"anchor_info,omitempty"` + // AwemeIDs 抖音号ids筛选,当anchor_types=ALL_ANCHOR时必传 + AwemeIDs []string `json:"aweme_ids,omitempty"` + // ItemIDs 主页视频ids筛选,一次最大长度限制10 + ItemIDs []uint64 `json:"item_ids,omitempty"` + // ItemStatus 素材状态筛选,默认可用 可选值: + // ALL 全部状态(可用&不可用) + // VALID 可用状态 + // 默认值:VALID + ItemStatus string `json:"item_status,omitempty"` + // StartTime 根据视频发布时间进行过滤的起始时间,与end_time搭配使用,格式:yyyy-MM-dd HH:mm:ss + StartTime string `json:"start_time,omitempty"` + // EndTime 根据视频发布时间进行过滤的结束时间,与start_time搭配使用,格式:yyyy-MM-dd HH:mm:ss + EndTime string `json:"end_time,omitempty"` +} + +// AnchorInfo 视频挂载的锚点信息 +type AnchorInfo struct { + // AnchorType 根据视频所挂载的锚点类型筛选(注意:请按照项目设置和下方说明传入对应的锚点类型枚举),允许值: + // ALL_ANCHOR 不限制锚点 + // POI_ANCHOR 门店锚点 + // PRODUCT_ANCHOR 商品锚点 + // 本地推创编选择抖音主页视频范围说明: + // 营销场景=短视频/图文,且推广目的=团购成交/门店引流/内容加热时: + // 推广门店时,支持选择POI_ANCHOR门店锚点和PRODUCT_ANCHOR商品锚点的抖音主页视频;需同时传入anchor_types和poi_ids/product_ids,其中,门店锚点需为项目所推广的门店,商品锚点需为所推广门店下挂载的商品,门店下挂载的商品id可通过【根据门店ID查询门店下商品ID】接口获取。 + // 推广商品时,支持选择PRODUCT_ANCHOR商品锚点的抖音主页视频;需同时传入anchor_types和product_ids,其中商品锚点需为项目所推广的商品。 + // 营销场景=直播时,支持选择抖音主页下全部视频,即ALL_ANCHOR不限制锚点 + AnchorType []string `json:"anchor_type,omitempty"` + // PoiIDs 推广的门店ids,anchor_types=POI_ANCHOR时必传 + PoiIDs []uint64 `json:"poi_ids,omitempty"` + // ProductIDs 推广的商品ids,anchor_types=PRODUCT_ANCHOR时必传 + ProductIDs []uint64 `json:"product_ids,omitempty"` +} + +func (r VideoAwemeGetRequest) Encode() string { + values := util.GetUrlValues() + values.Set("local_account_id", strconv.FormatUint(r.LocalAccountID, 10)) + if r.Filtering != nil { + values.Set("filtering", string(util.JSONMarshal(r.Filtering))) + } + if r.OrderField != "" { + values.Set("order_field", r.OrderField) + } + if r.ExternalAction != "" { + values.Set("external_action", string(r.ExternalAction)) + } + if r.Count > 0 { + values.Set("count", strconv.Itoa(r.Count)) + } + if r.Cursor != "" { + values.Set("cursor", r.Cursor) + } + ret := values.Encode() + util.PutUrlValues(values) + return ret +} + +// VideoAwemeGetResponse 获取抖音主页视频 API Response +type VideoAwemeGetResponse struct { + model.BaseResponse + Data *VideoAwemeGetResult `json:"data,omitempty"` +} + +type VideoAwemeGetResult struct { + // PageInfo 分页信息 + PageInfo *model.CursorInfo `json:"page_info,omitempty"` + // VideoList 视频列表 + VideoList []VideoAweme `json:"video_list,omitempty"` +} diff --git a/marketing-api/model/local/file/video_get.go b/marketing-api/model/local/file/video_get.go new file mode 100644 index 00000000..ee6f1aac --- /dev/null +++ b/marketing-api/model/local/file/video_get.go @@ -0,0 +1,94 @@ +package file + +import ( + "strconv" + + "github.com/bububa/oceanengine/marketing-api/enum" + "github.com/bububa/oceanengine/marketing-api/enum/local" + "github.com/bububa/oceanengine/marketing-api/model" + "github.com/bububa/oceanengine/marketing-api/util" +) + +// VideoGetRequest 获取素材库视频 API Request +type VideoGetRequest struct { + // LocalAccountID 本地推账户id + LocalAccountID uint64 `json:"local_account_id,omitempty"` + // Filtering 过滤器 + Filtering *VideoGetFilter `json:"filtering,omitempty"` + // Page 页码 + Page int `json:"page,omitempty"` + // PageSize 每页大小,默认值:20,最大值:100 + PageSize int `json:"page_size,omitempty"` +} + +type VideoGetFilter struct { + // SearchKeyWord 根据视频名称或ID筛选 + SearchKeyWord string `json:"search_key_word,omitempty"` + // ImageMode 素材类型 允许值: + // IMAGE_MODE_VIDEO 横版视频 + // IMAGE_MODE_VIDEO_VERTICAL 竖版视频 + ImageMode local.ImageMode `json:"image_mode,omitempty"` + // MaterialSource 素材来源 允许值: + // BP_PLATFORM 巨量引擎工作平台共享视频 + // CREATIVE_AIGC 即创 + // LOCAL_ADS_UPLOAD 本地上传 + // STAR 星图平台 + // MAPI MAPI上传 + MaterialSource local.MaterialSource `json:"material_source,omitempty"` + // AnalysisType 评估类型 允许值: + // FIRST_PUBLISH 首发 + // FIRST_PUBLISH_AND_HIGH_QUALITY 首发&优质 + // HIGH_QUALITY 优质 + AnalysisType local.MaterialAnalysisType `json:"analysis_type,omitempty"` + // StartTime 根据视频上传时间进行过滤的起始时间,与end_time搭配使用,格式:yyyy-MM-dd HH:mm:ss + StartTime string `json:"start_time,omitempty"` + // EndTime 根据视频上传时间进行过滤的截止时间,与start_time搭配使用,格式:yyyy-MM-dd HH:mm:ss + EndTime string `json:"end_time,omitempty"` + // IsFilterUnqualified 是否过滤低质素材,允许值: + // false 不过滤 + // true 过滤(默认值) + IsFilterUnqualified *bool `json:"is_filter_unqualified,omitempty"` + // OrderField 排序字段,允许值: + // CONVERSION_COST 转化成本 + // CONVERSION_RATE 转化率 + // CREATE_TIME 创建时间(默认值) + // CTR 点击率 + // DURATION 视频时长 + // STAT_COST 消耗 + OrderField string `json:"order_field,omitempty"` + // OrderType 排序顺序,允许值: + // ASC 升序 + // DESC 降序(默认值) + OrderType enum.OrderType `json:"order_type,omitempty"` +} + +// Encode implements GetRequest interface +func (r VideoGetRequest) Encode() string { + values := util.GetUrlValues() + values.Set("local_account_id", strconv.FormatUint(r.LocalAccountID, 10)) + if r.Filtering != nil { + values.Set("filtering", string(util.JSONMarshal(r.Filtering))) + } + if r.Page > 0 { + values.Set("page", strconv.Itoa(r.Page)) + } + if r.PageSize > 0 { + values.Set("page_size", strconv.Itoa(r.PageSize)) + } + ret := values.Encode() + util.PutUrlValues(values) + return ret +} + +// VideoGetResponse 获取素材库视频 API Response +type VideoGetResponse struct { + model.BaseResponse + Data *VideoGetResult `json:"data,omitempty"` +} + +type VideoGetResult struct { + // PageInfo 分页信息 + PageInfo *model.PageInfo `json:"page_info,omitempty"` + // VideoList 素材库视频列表 + VideoList []Video `json:"video_list,omitempty"` +} diff --git a/marketing-api/model/local/file/video_upload.go b/marketing-api/model/local/file/video_upload.go new file mode 100644 index 00000000..684fd21c --- /dev/null +++ b/marketing-api/model/local/file/video_upload.go @@ -0,0 +1,49 @@ +package file + +import ( + "io" + "strconv" + + "github.com/bububa/oceanengine/marketing-api/model" +) + +// VideoUploadRequest 上传视频 API Request +type VideoUploadRequest struct { + // LocalAccountID 本地推账户id + LocalAccountID uint64 `json:"local_account_id,omitempty"` + // VideoFile 文件 + VideoFile io.Reader `json:"video_file,omitempty"` + // Filename 文件名 + Filename string `json:"filename,omitempty"` + // VideoSignature 文件MD5 + VideoSignature string `json:"video_signature,omitempty"` +} + +// Encode implement UploadReqeust interface +func (r VideoUploadRequest) Encode() []model.UploadField { + ret := make([]model.UploadField, 0, 3) + ret = append(ret, model.UploadField{ + Key: "local_account_id", + Value: strconv.FormatUint(r.LocalAccountID, 10), + }) + ret = append(ret, model.UploadField{ + Key: "video_file", + Value: r.Filename, + Reader: r.VideoFile, + }) + ret = append(ret, model.UploadField{ + Key: "filename", + Value: r.Filename, + }) + ret = append(ret, model.UploadField{ + Key: "video_signature", + Value: r.VideoSignature, + }) + return ret +} + +// VideoUploadResponse 上传视频 API Response +type VideoUploadResponse struct { + model.BaseResponse + Data *Video `json:"data,omitempty"` +} diff --git a/marketing-api/model/local/file/video_upload_task_list.go b/marketing-api/model/local/file/video_upload_task_list.go new file mode 100644 index 00000000..8dc95bf4 --- /dev/null +++ b/marketing-api/model/local/file/video_upload_task_list.go @@ -0,0 +1,61 @@ +package file + +import ( + "strconv" + + "github.com/bububa/oceanengine/marketing-api/enum/local" + "github.com/bububa/oceanengine/marketing-api/model" + "github.com/bububa/oceanengine/marketing-api/util" +) + +// VideoUploadTaskListRequest 查询异步上传本地推视频结果 API Request +type VideoUploadTaskListRequest struct { + // LocalAccountID 本地推账户id + LocalAccountID uint64 `json:"local_account_id,omitempty"` + // TaskIDs 任务id列表,单次最多支持100个任务id + TaskIDs []uint64 `json:"task_ids,omitempty"` +} + +// Encode implements GetRequest interface +func (r VideoUploadTaskListRequest) Encode() string { + values := util.GetUrlValues() + values.Set("local_account_id", strconv.FormatUint(r.LocalAccountID, 10)) + values.Set("task_ids", string(util.JSONMarshal(r.TaskIDs))) + ret := values.Encode() + util.PutUrlValues(values) + return ret +} + +// VideoUploadTaskListResponse 查询异步上传本地推视频结果 API Response +type VideoUploadTaskListResponse struct { + model.BaseResponse + Data struct { + // List 任务列表 + List []UploadTask `json:"list,omitempty"` + } `json:"data,omitempty"` +} + +// UploadTask 上传任务 +type UploadTask struct { + // Status 任务处理状态 可选值: + // PROCESS 处理中 + // SUCCESS 成功 + // FAILED 失败 + Status local.UploadTaskStatus `json:"status,omitempty"` + // ErrorMsg 当任务失败后,会返回失败信息 + ErrorMsg string `json:"error_msg,omitempty"` + // CreateTime 任务创建时间 + CreateTime string `json:"create_time,omitempty"` + // TaskID 任务id + TaskID uint64 `json:"task_id,omitempty"` + // VideoInfo 视频信息 + VideoInfo *Video `json:"video_info,omitempty"` +} + +func (t UploadTask) IsError() bool { + return t.Status == local.UploadTaskStatus_FAILED +} + +func (t UploadTask) Error() string { + return util.StringsJoin("任务ID:", strconv.FormatUint(t.TaskID, 10), ", ", t.ErrorMsg) +} diff --git a/marketing-api/model/page_info.go b/marketing-api/model/page_info.go index 6ae9c6a6..6023270b 100644 --- a/marketing-api/model/page_info.go +++ b/marketing-api/model/page_info.go @@ -24,4 +24,6 @@ type CursorInfo struct { Cursor string `json:"cursor,omitempty"` // Count Count int `json:"count,omitempty"` + // HasMore 是否有下一页 + HasMore bool `json:"has_more,omitempty"` }