analysis.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. package analysis
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "github.com/silenceper/wechat/miniprogram/context"
  6. "github.com/silenceper/wechat/util"
  7. )
  8. const (
  9. // 获取用户访问小程序日留存
  10. getAnalysisDailyRetainURL = "https://api.weixin.qq.com/datacube/getweanalysisappiddailyretaininfo?access_token=%s"
  11. // 获取用户访问小程序月留存
  12. getAnalysisMonthlyRetainURL = "https://api.weixin.qq.com/datacube/getweanalysisappidmonthlyretaininfo?access_token=%s"
  13. // 获取用户访问小程序周留存
  14. getAnalysisWeeklyRetainURL = "https://api.weixin.qq.com/datacube/getweanalysisappidweeklyretaininfo?access_token=%s"
  15. // 获取用户访问小程序数据概况
  16. getAnalysisDailySummaryURL = "https://api.weixin.qq.com/datacube/getweanalysisappiddailysummarytrend?access_token=%s"
  17. // 获取用户访问小程序数据日趋势
  18. getAnalysisDailyVisitTrendURL = "https://api.weixin.qq.com/datacube/getweanalysisappiddailyvisittrend?access_token=%s"
  19. // 获取用户访问小程序数据月趋势
  20. getAnalysisMonthlyVisitTrendURL = "https://api.weixin.qq.com/datacube/getweanalysisappidmonthlyvisittrend?access_token=%s"
  21. // 获取用户访问小程序数据周趋势
  22. getAnalysisWeeklyVisitTrendURL = "https://api.weixin.qq.com/datacube/getweanalysisappidweeklyvisittrend?access_token=%s"
  23. // 获取小程序新增或活跃用户的画像分布数据
  24. getAnalysisUserPortraitURL = "https://api.weixin.qq.com/datacube/getweanalysisappiduserportrait?access_token=%s"
  25. // 获取用户小程序访问分布数据
  26. getAnalysisVisitDistributionURL = "https://api.weixin.qq.com/datacube/getweanalysisappidvisitdistribution?access_token=%s"
  27. // 访问页面
  28. getAnalysisVisitPageURL = "https://api.weixin.qq.com/datacube/getweanalysisappidvisitpage?access_token=%s"
  29. )
  30. //Analysis analyis 数据分析
  31. type Analysis struct {
  32. *context.Context
  33. }
  34. //NewAnalysis new
  35. func NewAnalysis(ctx *context.Context) *Analysis {
  36. return &Analysis{ctx}
  37. }
  38. // fetchData 拉取统计数据
  39. func (analysis *Analysis) fetchData(urlStr string, body interface{}) (response []byte, err error) {
  40. var accessToken string
  41. accessToken, err = analysis.GetAccessToken()
  42. if err != nil {
  43. return
  44. }
  45. urlStr = fmt.Sprintf(urlStr, accessToken)
  46. response, err = util.PostJSON(urlStr, body)
  47. return
  48. }
  49. // RetainItem 留存项结构
  50. type RetainItem struct {
  51. Key int `json:"key"` // 标识,0开始表示当天,1表示1甜后,以此类推
  52. Value int `json:"value"` // key对应日期的新增用户数/活跃用户数(key=0时)或留存用户数(k>0时)
  53. }
  54. // ResAnalysisRetain 小程序留存数据返回
  55. type ResAnalysisRetain struct {
  56. util.CommonError
  57. RefDate string `json:"ref_date"` // 日期
  58. VisitUVNew []RetainItem `json:"visit_uv_new"` // 新增用户留存
  59. VisitUV []RetainItem `json:"visit_uv"` // 活跃用户留存
  60. }
  61. // getAnalysisRetain 获取用户访问小程序留存数据(日、月、周)
  62. func (analysis *Analysis) getAnalysisRetain(urlStr string, beginDate, endDate string) (result ResAnalysisRetain, err error) {
  63. body := map[string]string{
  64. "begin_date": beginDate,
  65. "end_date": endDate,
  66. }
  67. response, err := analysis.fetchData(urlStr, body)
  68. if err != nil {
  69. return
  70. }
  71. err = json.Unmarshal(response, &result)
  72. if err != nil {
  73. return
  74. }
  75. if result.ErrCode != 0 {
  76. err = fmt.Errorf("getAnalysisRetain error : errcode=%v , errmsg=%v", result.ErrCode, result.ErrMsg)
  77. return
  78. }
  79. return
  80. }
  81. // GetAnalysisDailyRetain 获取用户访问小程序日留存
  82. func (analysis *Analysis) GetAnalysisDailyRetain(beginDate, endDate string) (result ResAnalysisRetain, err error) {
  83. return analysis.getAnalysisRetain(getAnalysisDailyRetainURL, beginDate, endDate)
  84. }
  85. // GetAnalysisMonthlyRetain 获取用户访问小程序月留存
  86. func (analysis *Analysis) GetAnalysisMonthlyRetain(beginDate, endDate string) (result ResAnalysisRetain, err error) {
  87. return analysis.getAnalysisRetain(getAnalysisMonthlyRetainURL, beginDate, endDate)
  88. }
  89. // GetAnalysisWeeklyRetain 获取用户访问小程序周留存
  90. func (analysis *Analysis) GetAnalysisWeeklyRetain(beginDate, endDate string) (result ResAnalysisRetain, err error) {
  91. return analysis.getAnalysisRetain(getAnalysisWeeklyRetainURL, beginDate, endDate)
  92. }
  93. // ResAnalysisDailySummary 小程序访问数据概况
  94. type ResAnalysisDailySummary struct {
  95. util.CommonError
  96. List []struct {
  97. RefDate string `json:"ref_date"` // 日期
  98. VisitTotal int `json:"visit_total"` // 累计用户数
  99. SharePV int `json:"share_pv"` // 转发次数
  100. ShareUV int `json:"share_uv"` // 转发人数
  101. } `json:"list"`
  102. }
  103. // GetAnalysisDailySummary 获取用户访问小程序数据概况
  104. func (analysis *Analysis) GetAnalysisDailySummary(beginDate, endDate string) (result ResAnalysisDailySummary, err error) {
  105. body := map[string]string{
  106. "begin_date": beginDate,
  107. "end_date": endDate,
  108. }
  109. response, err := analysis.fetchData(getAnalysisDailySummaryURL, body)
  110. if err != nil {
  111. return
  112. }
  113. fmt.Println(string(response))
  114. err = json.Unmarshal(response, &result)
  115. if err != nil {
  116. return
  117. }
  118. if result.ErrCode != 0 {
  119. err = fmt.Errorf("GetAnalysisDailySummary error : errcode=%v , errmsg=%v", result.ErrCode, result.ErrMsg)
  120. return
  121. }
  122. return
  123. }
  124. // ResAnalysisVisitTrend 小程序访问数据趋势(日、月、周)
  125. type ResAnalysisVisitTrend struct {
  126. util.CommonError
  127. List []struct {
  128. RefDate string `json:"ref_date"` // 日期
  129. SessionCnt int `json:"session_cnt"` // 打开次数
  130. VisitPV int `json:"visit_pv"` // 访问次数
  131. VisitUV int `json:"visit_uv"` // 访问人数
  132. VisitUVNew int `json:"visit_uv_new"` // 新用户数
  133. StayTimeUV float64 `json:"stay_time_uv"` // 人均停留时长
  134. StayTimeSession float64 `json:"stay_time_session"` // 次均停留时常
  135. VisitDepth float64 `json:"visit_depth"` // 平均访问深度
  136. } `json:"list"`
  137. }
  138. // getAnalysisRetain 获取小程序访问数据趋势(日、月、周)
  139. func (analysis *Analysis) getAnalysisVisitTrend(urlStr string, beginDate, endDate string) (result ResAnalysisVisitTrend, err error) {
  140. body := map[string]string{
  141. "begin_date": beginDate,
  142. "end_date": endDate,
  143. }
  144. response, err := analysis.fetchData(urlStr, body)
  145. if err != nil {
  146. return
  147. }
  148. err = json.Unmarshal(response, &result)
  149. if err != nil {
  150. return
  151. }
  152. if result.ErrCode != 0 {
  153. err = fmt.Errorf("getAnalysisVisitTrend error : errcode=%v , errmsg=%v", result.ErrCode, result.ErrMsg)
  154. return
  155. }
  156. return
  157. }
  158. // GetAnalysisDailyVisitTrend 获取用户访问小程序数据日趋势
  159. func (analysis *Analysis) GetAnalysisDailyVisitTrend(beginDate, endDate string) (result ResAnalysisVisitTrend, err error) {
  160. return analysis.getAnalysisVisitTrend(getAnalysisDailyVisitTrendURL, beginDate, endDate)
  161. }
  162. // GetAnalysisMonthlyVisitTrend 获取用户访问小程序数据月趋势
  163. func (analysis *Analysis) GetAnalysisMonthlyVisitTrend(beginDate, endDate string) (result ResAnalysisVisitTrend, err error) {
  164. return analysis.getAnalysisVisitTrend(getAnalysisMonthlyVisitTrendURL, beginDate, endDate)
  165. }
  166. // GetAnalysisWeeklyVisitTrend 获取用户访问小程序数据周趋势
  167. func (analysis *Analysis) GetAnalysisWeeklyVisitTrend(beginDate, endDate string) (result ResAnalysisVisitTrend, err error) {
  168. return analysis.getAnalysisVisitTrend(getAnalysisWeeklyVisitTrendURL, beginDate, endDate)
  169. }
  170. // UserPortraitItem 用户画像项目
  171. type UserPortraitItem struct {
  172. ID int `json:"id"` // 属性值id
  173. Name string `json:"name"` // 属性值名称
  174. AccessSourceVisitUV int `json:"access_source_visit_uv"` // 该场景访问uv
  175. }
  176. // UserPortrait 用户画像
  177. type UserPortrait struct {
  178. Index int `json:"index"` // 分布类型
  179. Province []UserPortraitItem `json:"province"` // 省份,如北京、广东等
  180. City []UserPortraitItem `json:"city"` // 城市,如北京、广州等
  181. Genders []UserPortraitItem `json:"genders"` // 性别,包括男、女、未知
  182. Platforms []UserPortraitItem `json:"platforms"` // 终端类型,包括iPhone, android, 其他
  183. Devices []UserPortraitItem `json:"devices"` // 机型,如苹果iPhone 6, OPPO R9等
  184. Ages []UserPortraitItem `json:"ages"` // 年龄,包括17岁以下、18-24对等区间
  185. }
  186. // ResAnalysisUserPortrait 小程序新增或活跃用户的画像分布数据返回
  187. type ResAnalysisUserPortrait struct {
  188. util.CommonError
  189. RefDate string `json:"ref_date"` // 日期
  190. VisitUVNew UserPortrait `json:"visit_uv_new"` // 新用户画像
  191. VisitUV UserPortrait `json:"visit_uv"` // 活跃用户画像
  192. }
  193. // GetAnalysisUserPortrait 获取小程序新增或活跃用户的画像分布数据
  194. func (analysis *Analysis) GetAnalysisUserPortrait(beginDate, endDate string) (result ResAnalysisUserPortrait, err error) {
  195. body := map[string]string{
  196. "begin_date": beginDate,
  197. "end_date": endDate,
  198. }
  199. response, err := analysis.fetchData(getAnalysisUserPortraitURL, body)
  200. if err != nil {
  201. return
  202. }
  203. err = json.Unmarshal(response, &result)
  204. if err != nil {
  205. return
  206. }
  207. if result.ErrCode != 0 {
  208. err = fmt.Errorf("GetAnalysisUserPortrait error : errcode=%v , errmsg=%v", result.ErrCode, result.ErrMsg)
  209. return
  210. }
  211. return
  212. }
  213. // VisitDistributionIndexItem 访问分数数据结构
  214. type VisitDistributionIndexItem struct {
  215. Key int `json:"key"` // 场景id
  216. Value int `json:"value"` // 该场景id访问pv
  217. AccessSourceVisitUV int `json:"access_source_visit_uv"` // 该场景id访问uv
  218. }
  219. // VisitDistributionIndex 访问分布单分布类型数据
  220. type VisitDistributionIndex struct {
  221. Index string `json:"index"` // 分布类型
  222. ItemList []VisitDistributionIndexItem `json:"item_list"` // 分布数据列表
  223. }
  224. // ResAnalysisVisitDistribution 小程序访问分布数据返回
  225. type ResAnalysisVisitDistribution struct {
  226. util.CommonError
  227. RefDate string `json:"ref_date"` // 日期
  228. List []VisitDistributionIndex `json:"list"` // 数据列表
  229. }
  230. // GetAnalysisVisitDistribution 获取用户小程序访问分布数据
  231. func (analysis *Analysis) GetAnalysisVisitDistribution(beginDate, endDate string) (result ResAnalysisVisitDistribution, err error) {
  232. body := map[string]string{
  233. "begin_date": beginDate,
  234. "end_date": endDate,
  235. }
  236. response, err := analysis.fetchData(getAnalysisVisitDistributionURL, body)
  237. if err != nil {
  238. return
  239. }
  240. err = json.Unmarshal(response, &result)
  241. if err != nil {
  242. return
  243. }
  244. if result.ErrCode != 0 {
  245. err = fmt.Errorf("GetAnalysisVisitDistribution error : errcode=%v , errmsg=%v", result.ErrCode, result.ErrMsg)
  246. return
  247. }
  248. return
  249. }
  250. // VisitPageItem 访问单个页面的数据结构
  251. type VisitPageItem struct {
  252. PagePath string `json:"page_path"` // 页面路径
  253. PageVisitPV int `json:"page_visit_pv"` // 访问次数
  254. PageVisitUV int `json:"page_visit_uv"` // 访问人数
  255. PageStaytimePV float64 `json:"page_staytime_pv"` // 次均停留时常
  256. EntrypagePV int `json:"entrypage_pv"` // 进入页次数
  257. ExitpagePV int `json:"exitpage_pv"` // 退出页次数
  258. PageSharePV int `json:"page_share_pv"` // 转发次数
  259. PageShareUV int `json:"page_share_uv"` // 转发人数
  260. }
  261. // ResAnalysisVisitPage 访问小程序页面访问数据返回
  262. type ResAnalysisVisitPage struct {
  263. util.CommonError
  264. RefDate string `json:"ref_date"` // 日期
  265. List []VisitPageItem `json:"list"` // 数据列表
  266. }
  267. // GetAnalysisVisitPage 获取小程序页面访问数据
  268. func (analysis *Analysis) GetAnalysisVisitPage(beginDate, endDate string) (result ResAnalysisVisitPage, err error) {
  269. body := map[string]string{
  270. "begin_date": beginDate,
  271. "end_date": endDate,
  272. }
  273. response, err := analysis.fetchData(getAnalysisVisitPageURL, body)
  274. if err != nil {
  275. return
  276. }
  277. err = json.Unmarshal(response, &result)
  278. if err != nil {
  279. return
  280. }
  281. if result.ErrCode != 0 {
  282. err = fmt.Errorf("GetAnalysisVisitPage error : errcode=%v , errmsg=%v", result.ErrCode, result.ErrMsg)
  283. return
  284. }
  285. return
  286. }