publisher.go 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. package datacube
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "github.com/silenceper/wechat/v2/util"
  6. "net/url"
  7. "strconv"
  8. )
  9. //AdSlot 广告位类型
  10. type AdSlot string
  11. const (
  12. //SlotIDBizBottom 公众号底部广告
  13. SlotIDBizBottom AdSlot = "SLOT_ID_BIZ_BOTTOM"
  14. //SlotIDBizMidContext 公众号文中广告
  15. SlotIDBizMidContext AdSlot = "SLOT_ID_BIZ_MID_CONTEXT"
  16. //SlotIDBizVideoEnd 公众号视频后贴
  17. SlotIDBizVideoEnd AdSlot = "SLOT_ID_BIZ_VIDEO_END"
  18. //SlotIDBizSponsor 公众号互选广告
  19. SlotIDBizSponsor AdSlot = "SLOT_ID_BIZ_SPONSOR"
  20. //SlotIDBizCps 公众号返佣商品
  21. SlotIDBizCps AdSlot = "SLOT_ID_BIZ_CPS"
  22. //SlotIDWeappBanner 小程序banner
  23. SlotIDWeappBanner AdSlot = "SLOT_ID_WEAPP_BANNER"
  24. //SlotIDWeappRewardVideo 小程序激励视频
  25. SlotIDWeappRewardVideo AdSlot = "SLOT_ID_WEAPP_REWARD_VIDEO"
  26. //SlotIDWeappInterstitial 小程序插屏广告
  27. SlotIDWeappInterstitial AdSlot = "SLOT_ID_WEAPP_INTERSTITIAL"
  28. //SlotIDWeappVideoFeeds 小程序视频广告
  29. SlotIDWeappVideoFeeds AdSlot = "SLOT_ID_WEAPP_VIDEO_FEEDS"
  30. //SlotIDWeappVideoBegin 小程序视频前贴
  31. SlotIDWeappVideoBegin AdSlot = "SLOT_ID_WEAPP_VIDEO_BEGIN"
  32. //SlotIDWeappBox 小程序格子广告
  33. SlotIDWeappBox AdSlot = "SLOT_ID_WEAPP_BOX"
  34. )
  35. const (
  36. publisherURL = "https://api.weixin.qq.com/publisher/stat"
  37. )
  38. const (
  39. actionPublisherAdPosGeneral = "publisher_adpos_general"
  40. actionPublisherCpsGeneral = "publisher_cps_general"
  41. actionPublisherSettlement = "publisher_settlement"
  42. )
  43. //BaseResp 错误信息
  44. type BaseResp struct {
  45. ErrMsg string `json:"err_msg"`
  46. Ret int `json:"ret"`
  47. }
  48. //ResPublisherAdPos 公众号分广告位数据响应
  49. type ResPublisherAdPos struct {
  50. util.CommonError
  51. BaseResp
  52. Base BaseResp `json:"base_resp"`
  53. List []ResAdPosList `json:"list"`
  54. Summary ResAdPosSummary `json:"summary"`
  55. TotalNum int `json:"total_num"`
  56. }
  57. //ResAdPosList 公众号分广告位列表
  58. type ResAdPosList struct {
  59. SlotID int64 `json:"slot_id"`
  60. AdSlot string `json:"ad_slot"`
  61. Date string `json:"date"`
  62. ReqSuccCount int `json:"req_succ_count"`
  63. ExposureCount int `json:"exposure_count"`
  64. ExposureRate float64 `json:"exposure_rate"`
  65. ClickCount int `json:"click_count"`
  66. ClickRate float64 `json:"click_rate"`
  67. Income int `json:"income"`
  68. Ecpm float64 `json:"ecpm"`
  69. }
  70. //ResAdPosSummary 公众号分广告位概览
  71. type ResAdPosSummary struct {
  72. ReqSuccCount int `json:"req_succ_count"`
  73. ExposureCount int `json:"exposure_count"`
  74. ExposureRate float64 `json:"exposure_rate"`
  75. ClickCount int `json:"click_count"`
  76. ClickRate float64 `json:"click_rate"`
  77. Income int `json:"income"`
  78. Ecpm float64 `json:"ecpm"`
  79. }
  80. //ResPublisherCps 公众号返佣商品数据响应
  81. type ResPublisherCps struct {
  82. util.CommonError
  83. BaseResp
  84. Base BaseResp `json:"base_resp"`
  85. List []ResCpsList `json:"list"`
  86. Summary ResCpsSummary `json:"summary"`
  87. TotalNum int `json:"total_num"`
  88. }
  89. //ResCpsList 公众号返佣商品列表
  90. type ResCpsList struct {
  91. Date string `json:"date"`
  92. ExposureCount int `json:"exposure_count"`
  93. ClickCount int `json:"click_count"`
  94. ClickRate float64 `json:"click_rate"`
  95. OrderCount int `json:"order_count"`
  96. OrderRate float64 `json:"order_rate"`
  97. TotalFee int `json:"total_fee"`
  98. TotalCommission int `json:"total_commission"`
  99. }
  100. //ResCpsSummary 公众号返佣概览
  101. type ResCpsSummary struct {
  102. ExposureCount int `json:"exposure_count"`
  103. ClickCount int `json:"click_count"`
  104. ClickRate float64 `json:"click_rate"`
  105. OrderCount int `json:"order_count"`
  106. OrderRate float64 `json:"order_rate"`
  107. TotalFee int `json:"total_fee"`
  108. TotalCommission int `json:"total_commission"`
  109. }
  110. //ResPublisherSettlement 公众号结算收入数据及结算主体信息响应
  111. type ResPublisherSettlement struct {
  112. util.CommonError
  113. BaseResp
  114. Base BaseResp `json:"base_resp"`
  115. Body string `json:"body"`
  116. PenaltyAll int `json:"penalty_all"`
  117. RevenueAll int64 `json:"revenue_all"`
  118. SettledRevenueAll int64 `json:"settled_revenue_all"`
  119. SettlementList []SettlementList `json:"settlement_list"`
  120. TotalNum int `json:"total_num"`
  121. }
  122. //SettlementList 结算单列表
  123. type SettlementList struct {
  124. Date string `json:"date"`
  125. Zone string `json:"zone"`
  126. Month string `json:"month"`
  127. Order int `json:"order"`
  128. SettStatus int `json:"sett_status"`
  129. SettledRevenue int `json:"settled_revenue"`
  130. SettNo string `json:"sett_no"`
  131. MailSendCnt string `json:"mail_send_cnt"`
  132. SlotRevenue []SlotRevenue `json:"slot_revenue"`
  133. }
  134. //SlotRevenue 产生收入的广告
  135. type SlotRevenue struct {
  136. SlotID string `json:"slot_id"`
  137. SlotSettledRevenue int `json:"slot_settled_revenue"`
  138. }
  139. //ParamsPublisher 拉取数据参数
  140. type ParamsPublisher struct {
  141. Action string `json:"action"`
  142. StartDate string `json:"start_date"`
  143. EndDate string `json:"end_date"`
  144. Page int `json:"page"`
  145. PageSize int `json:"page_size"`
  146. AdSlot AdSlot `json:"ad_slot"`
  147. }
  148. // fetchData 拉取统计数据
  149. func (cube *DataCube) fetchData(params ParamsPublisher) (response []byte, err error) {
  150. accessToken, err := cube.GetAccessToken()
  151. if err != nil {
  152. return
  153. }
  154. v := url.Values{}
  155. v.Add("action", params.Action)
  156. v.Add("access_token", accessToken)
  157. v.Add("page", strconv.Itoa(params.Page))
  158. v.Add("page_size", strconv.Itoa(params.PageSize))
  159. v.Add("start_date", params.StartDate)
  160. v.Add("end_date", params.EndDate)
  161. if params.AdSlot != "" {
  162. v.Add("ad_slot", string(params.AdSlot))
  163. }
  164. uri := fmt.Sprintf("%s?%s", publisherURL, v.Encode())
  165. response, err = util.HTTPGet(uri)
  166. if err != nil {
  167. return
  168. }
  169. return
  170. }
  171. //GetPublisherAdPosGeneral 获取公众号分广告位数据
  172. func (cube *DataCube) GetPublisherAdPosGeneral(startDate, endDate string, page, pageSize int, adSlot AdSlot) (resPublisherAdPos ResPublisherAdPos, err error) {
  173. params := ParamsPublisher{
  174. Action: actionPublisherAdPosGeneral,
  175. StartDate: startDate,
  176. EndDate: endDate,
  177. Page: page,
  178. PageSize: pageSize,
  179. AdSlot: adSlot,
  180. }
  181. response, err := cube.fetchData(params)
  182. if err != nil {
  183. return
  184. }
  185. err = json.Unmarshal(response, &resPublisherAdPos)
  186. if err != nil {
  187. return
  188. }
  189. if resPublisherAdPos.CommonError.ErrCode != 0 {
  190. err = fmt.Errorf("GetPublisherAdPosGeneral Error , errcode=%d , errmsg=%s", resPublisherAdPos.CommonError.ErrCode, resPublisherAdPos.CommonError.ErrMsg)
  191. return
  192. }
  193. if resPublisherAdPos.BaseResp.Ret != 0 {
  194. err = fmt.Errorf("GetPublisherAdPosGeneral Error , errcode=%d , errmsg=%s", resPublisherAdPos.BaseResp.Ret, resPublisherAdPos.BaseResp.ErrMsg)
  195. return
  196. }
  197. if resPublisherAdPos.Base.Ret != 0 {
  198. err = fmt.Errorf("GetPublisherAdPosGeneral Error , errcode=%d , errmsg=%s", resPublisherAdPos.Base.Ret, resPublisherAdPos.Base.ErrMsg)
  199. return
  200. }
  201. return
  202. }
  203. //GetPublisherCpsGeneral 获取公众号返佣商品数据
  204. func (cube *DataCube) GetPublisherCpsGeneral(startDate, endDate string, page, pageSize int) (resPublisherCps ResPublisherCps, err error) {
  205. params := ParamsPublisher{
  206. Action: actionPublisherCpsGeneral,
  207. StartDate: startDate,
  208. EndDate: endDate,
  209. Page: page,
  210. PageSize: pageSize,
  211. }
  212. response, err := cube.fetchData(params)
  213. if err != nil {
  214. return
  215. }
  216. err = json.Unmarshal(response, &resPublisherCps)
  217. if err != nil {
  218. return
  219. }
  220. if resPublisherCps.CommonError.ErrCode != 0 {
  221. err = fmt.Errorf("GetPublisherCpsGeneral Error , errcode=%d , errmsg=%s", resPublisherCps.CommonError.ErrCode, resPublisherCps.CommonError.ErrMsg)
  222. return
  223. }
  224. if resPublisherCps.BaseResp.Ret != 0 {
  225. err = fmt.Errorf("GetPublisherCpsGeneral Error , errcode=%d , errmsg=%s", resPublisherCps.BaseResp.Ret, resPublisherCps.BaseResp.ErrMsg)
  226. return
  227. }
  228. if resPublisherCps.Base.Ret != 0 {
  229. err = fmt.Errorf("GetPublisherCpsGeneral Error , errcode=%d , errmsg=%s", resPublisherCps.Base.Ret, resPublisherCps.Base.ErrMsg)
  230. return
  231. }
  232. return
  233. }
  234. //GetPublisherSettlement 获取公众号结算收入数据及结算主体信息
  235. func (cube *DataCube) GetPublisherSettlement(startDate, endDate string, page, pageSize int) (resPublisherSettlement ResPublisherSettlement, err error) {
  236. params := ParamsPublisher{
  237. Action: actionPublisherSettlement,
  238. StartDate: startDate,
  239. EndDate: endDate,
  240. Page: page,
  241. PageSize: pageSize,
  242. }
  243. response, err := cube.fetchData(params)
  244. if err != nil {
  245. return
  246. }
  247. err = json.Unmarshal(response, &resPublisherSettlement)
  248. if err != nil {
  249. return
  250. }
  251. if resPublisherSettlement.CommonError.ErrCode != 0 {
  252. err = fmt.Errorf("GetPublisherSettlement Error , errcode=%d , errmsg=%s", resPublisherSettlement.CommonError.ErrCode, resPublisherSettlement.CommonError.ErrMsg)
  253. return
  254. }
  255. if resPublisherSettlement.BaseResp.Ret != 0 {
  256. err = fmt.Errorf("GetPublisherSettlement Error , errcode=%d , errmsg=%s", resPublisherSettlement.BaseResp.Ret, resPublisherSettlement.BaseResp.ErrMsg)
  257. return
  258. }
  259. if resPublisherSettlement.Base.Ret != 0 {
  260. err = fmt.Errorf("GetPublisherSettlement Error , errcode=%d , errmsg=%s", resPublisherSettlement.Base.Ret, resPublisherSettlement.Base.ErrMsg)
  261. return
  262. }
  263. return
  264. }