package analysis import ( "encoding/json" "fmt" "github.com/silenceper/wechat/v2/miniprogram/context" "github.com/silenceper/wechat/v2/util" ) const ( // 获取用户访问小程序日留存 getAnalysisDailyRetainURL = "https://api.weixin.qq.com/datacube/getweanalysisappiddailyretaininfo?access_token=%s" // 获取用户访问小程序月留存 getAnalysisMonthlyRetainURL = "https://api.weixin.qq.com/datacube/getweanalysisappidmonthlyretaininfo?access_token=%s" // 获取用户访问小程序周留存 getAnalysisWeeklyRetainURL = "https://api.weixin.qq.com/datacube/getweanalysisappidweeklyretaininfo?access_token=%s" // 获取用户访问小程序数据概况 getAnalysisDailySummaryURL = "https://api.weixin.qq.com/datacube/getweanalysisappiddailysummarytrend?access_token=%s" // 获取用户访问小程序数据日趋势 getAnalysisDailyVisitTrendURL = "https://api.weixin.qq.com/datacube/getweanalysisappiddailyvisittrend?access_token=%s" // 获取用户访问小程序数据月趋势 getAnalysisMonthlyVisitTrendURL = "https://api.weixin.qq.com/datacube/getweanalysisappidmonthlyvisittrend?access_token=%s" // 获取用户访问小程序数据周趋势 getAnalysisWeeklyVisitTrendURL = "https://api.weixin.qq.com/datacube/getweanalysisappidweeklyvisittrend?access_token=%s" // 获取小程序新增或活跃用户的画像分布数据 getAnalysisUserPortraitURL = "https://api.weixin.qq.com/datacube/getweanalysisappiduserportrait?access_token=%s" // 获取用户小程序访问分布数据 getAnalysisVisitDistributionURL = "https://api.weixin.qq.com/datacube/getweanalysisappidvisitdistribution?access_token=%s" // 访问页面 getAnalysisVisitPageURL = "https://api.weixin.qq.com/datacube/getweanalysisappidvisitpage?access_token=%s" ) // Analysis analyis 数据分析 type Analysis struct { *context.Context } // NewAnalysis new func NewAnalysis(ctx *context.Context) *Analysis { return &Analysis{ctx} } // fetchData 拉取统计数据 func (analysis *Analysis) fetchData(urlStr string, body interface{}) (response []byte, err error) { var accessToken string accessToken, err = analysis.GetAccessToken() if err != nil { return } urlStr = fmt.Sprintf(urlStr, accessToken) response, err = util.PostJSON(urlStr, body) return } // RetainItem 留存项结构 type RetainItem struct { Key int `json:"key"` // 标识,0开始表示当天,1表示1甜后,以此类推 Value int `json:"value"` // key对应日期的新增用户数/活跃用户数(key=0时)或留存用户数(k>0时) } // ResAnalysisRetain 小程序留存数据返回 type ResAnalysisRetain struct { util.CommonError RefDate string `json:"ref_date"` // 日期 VisitUVNew []RetainItem `json:"visit_uv_new"` // 新增用户留存 VisitUV []RetainItem `json:"visit_uv"` // 活跃用户留存 } // getAnalysisRetain 获取用户访问小程序留存数据(日、月、周) func (analysis *Analysis) getAnalysisRetain(urlStr string, beginDate, endDate string) (result ResAnalysisRetain, err error) { body := map[string]string{ "begin_date": beginDate, "end_date": endDate, } response, err := analysis.fetchData(urlStr, body) if err != nil { return } err = json.Unmarshal(response, &result) if err != nil { return } if result.ErrCode != 0 { err = fmt.Errorf("getAnalysisRetain error : errcode=%v , errmsg=%v", result.ErrCode, result.ErrMsg) return } return } // GetAnalysisDailyRetain 获取用户访问小程序日留存 func (analysis *Analysis) GetAnalysisDailyRetain(beginDate, endDate string) (result ResAnalysisRetain, err error) { return analysis.getAnalysisRetain(getAnalysisDailyRetainURL, beginDate, endDate) } // GetAnalysisMonthlyRetain 获取用户访问小程序月留存 func (analysis *Analysis) GetAnalysisMonthlyRetain(beginDate, endDate string) (result ResAnalysisRetain, err error) { return analysis.getAnalysisRetain(getAnalysisMonthlyRetainURL, beginDate, endDate) } // GetAnalysisWeeklyRetain 获取用户访问小程序周留存 func (analysis *Analysis) GetAnalysisWeeklyRetain(beginDate, endDate string) (result ResAnalysisRetain, err error) { return analysis.getAnalysisRetain(getAnalysisWeeklyRetainURL, beginDate, endDate) } // ResAnalysisDailySummary 小程序访问数据概况 type ResAnalysisDailySummary struct { util.CommonError List []struct { RefDate string `json:"ref_date"` // 日期 VisitTotal int `json:"visit_total"` // 累计用户数 SharePV int `json:"share_pv"` // 转发次数 ShareUV int `json:"share_uv"` // 转发人数 } `json:"list"` } // GetAnalysisDailySummary 获取用户访问小程序数据概况 func (analysis *Analysis) GetAnalysisDailySummary(beginDate, endDate string) (result ResAnalysisDailySummary, err error) { body := map[string]string{ "begin_date": beginDate, "end_date": endDate, } response, err := analysis.fetchData(getAnalysisDailySummaryURL, body) if err != nil { return } err = json.Unmarshal(response, &result) if err != nil { return } if result.ErrCode != 0 { err = fmt.Errorf("GetAnalysisDailySummary error : errcode=%v , errmsg=%v", result.ErrCode, result.ErrMsg) return } return } // ResAnalysisVisitTrend 小程序访问数据趋势(日、月、周) type ResAnalysisVisitTrend struct { util.CommonError List []struct { RefDate string `json:"ref_date"` // 日期 SessionCnt int `json:"session_cnt"` // 打开次数 VisitPV int `json:"visit_pv"` // 访问次数 VisitUV int `json:"visit_uv"` // 访问人数 VisitUVNew int `json:"visit_uv_new"` // 新用户数 StayTimeUV float64 `json:"stay_time_uv"` // 人均停留时长 StayTimeSession float64 `json:"stay_time_session"` // 次均停留时常 VisitDepth float64 `json:"visit_depth"` // 平均访问深度 } `json:"list"` } // getAnalysisRetain 获取小程序访问数据趋势(日、月、周) func (analysis *Analysis) getAnalysisVisitTrend(urlStr string, beginDate, endDate string) (result ResAnalysisVisitTrend, err error) { body := map[string]string{ "begin_date": beginDate, "end_date": endDate, } response, err := analysis.fetchData(urlStr, body) if err != nil { return } err = json.Unmarshal(response, &result) if err != nil { return } if result.ErrCode != 0 { err = fmt.Errorf("getAnalysisVisitTrend error : errcode=%v , errmsg=%v", result.ErrCode, result.ErrMsg) return } return } // GetAnalysisDailyVisitTrend 获取用户访问小程序数据日趋势 func (analysis *Analysis) GetAnalysisDailyVisitTrend(beginDate, endDate string) (result ResAnalysisVisitTrend, err error) { return analysis.getAnalysisVisitTrend(getAnalysisDailyVisitTrendURL, beginDate, endDate) } // GetAnalysisMonthlyVisitTrend 获取用户访问小程序数据月趋势 func (analysis *Analysis) GetAnalysisMonthlyVisitTrend(beginDate, endDate string) (result ResAnalysisVisitTrend, err error) { return analysis.getAnalysisVisitTrend(getAnalysisMonthlyVisitTrendURL, beginDate, endDate) } // GetAnalysisWeeklyVisitTrend 获取用户访问小程序数据周趋势 func (analysis *Analysis) GetAnalysisWeeklyVisitTrend(beginDate, endDate string) (result ResAnalysisVisitTrend, err error) { return analysis.getAnalysisVisitTrend(getAnalysisWeeklyVisitTrendURL, beginDate, endDate) } // UserPortraitItem 用户画像项目 type UserPortraitItem struct { ID int `json:"id"` // 属性值id Name string `json:"name"` // 属性值名称 AccessSourceVisitUV int `json:"access_source_visit_uv"` // 该场景访问uv } // UserPortrait 用户画像 type UserPortrait struct { Index int `json:"index"` // 分布类型 Province []UserPortraitItem `json:"province"` // 省份,如北京、广东等 City []UserPortraitItem `json:"city"` // 城市,如北京、广州等 Genders []UserPortraitItem `json:"genders"` // 性别,包括男、女、未知 Platforms []UserPortraitItem `json:"platforms"` // 终端类型,包括iPhone, android, 其他 Devices []UserPortraitItem `json:"devices"` // 机型,如苹果iPhone 6, OPPO R9等 Ages []UserPortraitItem `json:"ages"` // 年龄,包括17岁以下、18-24对等区间 } // ResAnalysisUserPortrait 小程序新增或活跃用户的画像分布数据返回 type ResAnalysisUserPortrait struct { util.CommonError RefDate string `json:"ref_date"` // 日期 VisitUVNew UserPortrait `json:"visit_uv_new"` // 新用户画像 VisitUV UserPortrait `json:"visit_uv"` // 活跃用户画像 } // GetAnalysisUserPortrait 获取小程序新增或活跃用户的画像分布数据 func (analysis *Analysis) GetAnalysisUserPortrait(beginDate, endDate string) (result ResAnalysisUserPortrait, err error) { body := map[string]string{ "begin_date": beginDate, "end_date": endDate, } response, err := analysis.fetchData(getAnalysisUserPortraitURL, body) if err != nil { return } err = json.Unmarshal(response, &result) if err != nil { return } if result.ErrCode != 0 { err = fmt.Errorf("GetAnalysisUserPortrait error : errcode=%v , errmsg=%v", result.ErrCode, result.ErrMsg) return } return } // VisitDistributionIndexItem 访问分数数据结构 type VisitDistributionIndexItem struct { Key int `json:"key"` // 场景id Value int `json:"value"` // 该场景id访问pv AccessSourceVisitUV int `json:"access_source_visit_uv"` // 该场景id访问uv } // VisitDistributionIndex 访问分布单分布类型数据 type VisitDistributionIndex struct { Index string `json:"index"` // 分布类型 ItemList []VisitDistributionIndexItem `json:"item_list"` // 分布数据列表 } // ResAnalysisVisitDistribution 小程序访问分布数据返回 type ResAnalysisVisitDistribution struct { util.CommonError RefDate string `json:"ref_date"` // 日期 List []VisitDistributionIndex `json:"list"` // 数据列表 } // GetAnalysisVisitDistribution 获取用户小程序访问分布数据 func (analysis *Analysis) GetAnalysisVisitDistribution(beginDate, endDate string) (result ResAnalysisVisitDistribution, err error) { body := map[string]string{ "begin_date": beginDate, "end_date": endDate, } response, err := analysis.fetchData(getAnalysisVisitDistributionURL, body) if err != nil { return } err = json.Unmarshal(response, &result) if err != nil { return } if result.ErrCode != 0 { err = fmt.Errorf("GetAnalysisVisitDistribution error : errcode=%v , errmsg=%v", result.ErrCode, result.ErrMsg) return } return } // VisitPageItem 访问单个页面的数据结构 type VisitPageItem struct { PagePath string `json:"page_path"` // 页面路径 PageVisitPV int `json:"page_visit_pv"` // 访问次数 PageVisitUV int `json:"page_visit_uv"` // 访问人数 PageStaytimePV float64 `json:"page_staytime_pv"` // 次均停留时常 EntrypagePV int `json:"entrypage_pv"` // 进入页次数 ExitpagePV int `json:"exitpage_pv"` // 退出页次数 PageSharePV int `json:"page_share_pv"` // 转发次数 PageShareUV int `json:"page_share_uv"` // 转发人数 } // ResAnalysisVisitPage 访问小程序页面访问数据返回 type ResAnalysisVisitPage struct { util.CommonError RefDate string `json:"ref_date"` // 日期 List []VisitPageItem `json:"list"` // 数据列表 } // GetAnalysisVisitPage 获取小程序页面访问数据 func (analysis *Analysis) GetAnalysisVisitPage(beginDate, endDate string) (result ResAnalysisVisitPage, err error) { body := map[string]string{ "begin_date": beginDate, "end_date": endDate, } response, err := analysis.fetchData(getAnalysisVisitPageURL, body) if err != nil { return } err = json.Unmarshal(response, &result) if err != nil { return } if result.ErrCode != 0 { err = fmt.Errorf("GetAnalysisVisitPage error : errcode=%v , errmsg=%v", result.ErrCode, result.ErrMsg) return } return }