mirror of
https://github.com/silenceper/wechat.git
synced 2026-02-04 21:02:25 +08:00
增加微信公众号数据统计功能 (#279)
* * fix: 移除代码中的Println * 增加公众号数据统计 * fix code style
This commit is contained in:
@@ -125,7 +125,7 @@ func (analysis *Analysis) GetAnalysisDailySummary(beginDate, endDate string) (re
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
fmt.Println(string(response))
|
||||
|
||||
err = json.Unmarshal(response, &result)
|
||||
if err != nil {
|
||||
return
|
||||
|
||||
270
officialaccount/datacube/broadcast.go
Normal file
270
officialaccount/datacube/broadcast.go
Normal file
@@ -0,0 +1,270 @@
|
||||
package datacube
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/silenceper/wechat/v2/util"
|
||||
)
|
||||
|
||||
const (
|
||||
getArticleSummary = "https://api.weixin.qq.com/datacube/getarticlesummary"
|
||||
getArticleTotal = "https://api.weixin.qq.com/datacube/getarticletotal"
|
||||
getUserRead = "https://api.weixin.qq.com/datacube/getuserread"
|
||||
getUserReadHour = "https://api.weixin.qq.com/datacube/getuserreadhour"
|
||||
getUserShare = "https://api.weixin.qq.com/datacube/getusershare"
|
||||
getUserShareHour = "https://api.weixin.qq.com/datacube/getusersharehour"
|
||||
)
|
||||
|
||||
//ResArticleSummary 获取图文群发每日数据响应
|
||||
type ResArticleSummary struct {
|
||||
util.CommonError
|
||||
|
||||
List []struct {
|
||||
RefDate string `json:"ref_date"`
|
||||
MsgID string `json:"msgid"`
|
||||
Title string `json:"title"`
|
||||
IntPageReadUser int `json:"int_page_read_user"`
|
||||
IntPageReadCount int `json:"int_page_read_count"`
|
||||
OriPageReadUser int `json:"ori_page_read_user"`
|
||||
OriPageReadCount int `json:"ori_page_read_count"`
|
||||
ShareUser int `json:"share_user"`
|
||||
ShareCount int `json:"share_count"`
|
||||
AddToFavUser int `json:"add_to_fav_user"`
|
||||
AddToFavCount int `json:"add_to_fav_count"`
|
||||
} `json:"list"`
|
||||
}
|
||||
|
||||
//ResArticleTotal 获取图文群发总数据响应
|
||||
type ResArticleTotal struct {
|
||||
util.CommonError
|
||||
|
||||
List []struct {
|
||||
RefDate string `json:"ref_date"`
|
||||
MsgID string `json:"msgid"`
|
||||
Title string `json:"title"`
|
||||
Details []ArticleTotalDetails `json:"details"`
|
||||
} `json:"list"`
|
||||
}
|
||||
|
||||
//ArticleTotalDetails 获取图文群发总数据响应文字详情
|
||||
type ArticleTotalDetails struct {
|
||||
StatDate string `json:"stat_date"`
|
||||
TargetUser int `json:"target_user"`
|
||||
IntPageReadUser int `json:"int_page_read_user"`
|
||||
IntPageReadCount int `json:"int_page_read_count"`
|
||||
OriPageReadUser int `json:"ori_page_read_user"`
|
||||
OriPageReadCount int `json:"ori_page_read_count"`
|
||||
ShareUser int `json:"share_user"`
|
||||
ShareCount int `json:"share_count"`
|
||||
AddToFavUser int `json:"add_to_fav_user"`
|
||||
AddToFavCount int `json:"add_to_fav_count"`
|
||||
IntPageFromSessionReadUser int `json:"int_page_from_session_read_user"`
|
||||
IntPageFromSessionReadCount int `json:"int_page_from_session_read_count"`
|
||||
IntPageFromHistMsgReadUser int `json:"int_page_from_hist_msg_read_user"`
|
||||
IntPageFromHistMsgReadCount int `json:"int_page_from_hist_msg_read_count"`
|
||||
IntPageFromFeedReadUser int `json:"int_page_from_feed_read_user"`
|
||||
IntPageFromFeedReadCount int `json:"int_page_from_feed_read_count"`
|
||||
IntPageFromFriendsReadUser int `json:"int_page_from_friends_read_user"`
|
||||
IntPageFromFriendsReadCount int `json:"int_page_from_friends_read_count"`
|
||||
IntPageFromOtherReadUser int `json:"int_page_from_other_read_user"`
|
||||
IntPageFromOtherReadCount int `json:"int_page_from_other_read_count"`
|
||||
FeedShareFromSessionUser int `json:"feed_share_from_session_user"`
|
||||
FeedShareFromSessionCnt int `json:"feed_share_from_session_cnt"`
|
||||
FeedShareFromFeedUser int `json:"feed_share_from_feed_user"`
|
||||
FeedShareFromFeedCnt int `json:"feed_share_from_feed_cnt"`
|
||||
FeedShareFromOtherUser int `json:"feed_share_from_other_user"`
|
||||
FeedShareFromOtherCnt int `json:"feed_share_from_other_cnt"`
|
||||
}
|
||||
|
||||
//ResUserRead 获取图文统计数据响应
|
||||
type ResUserRead struct {
|
||||
util.CommonError
|
||||
|
||||
List []struct {
|
||||
RefDate string `json:"ref_date"`
|
||||
UserSource int `json:"user_source"`
|
||||
IntPageReadUser int `json:"int_page_read_user"`
|
||||
IntPageReadCount int `json:"int_page_read_count"`
|
||||
OriPageReadUser int `json:"ori_page_read_user"`
|
||||
OriPageReadCount int `json:"ori_page_read_count"`
|
||||
ShareUser int `json:"share_user"`
|
||||
ShareCount int `json:"share_count"`
|
||||
AddToFavUser int `json:"add_to_fav_user"`
|
||||
AddToFavCount int `json:"add_to_fav_count"`
|
||||
} `json:"list"`
|
||||
}
|
||||
|
||||
//ResUserReadHour 获取图文统计分时数据
|
||||
type ResUserReadHour struct {
|
||||
util.CommonError
|
||||
|
||||
List []struct {
|
||||
RefDate string `json:"ref_date"`
|
||||
RefHour int `json:"ref_hour"`
|
||||
UserSource int `json:"user_source"`
|
||||
IntPageReadUser int `json:"int_page_read_user"`
|
||||
IntPageReadCount int `json:"int_page_read_count"`
|
||||
OriPageReadUser int `json:"ori_page_read_user"`
|
||||
OriPageReadCount int `json:"ori_page_read_count"`
|
||||
ShareUser int `json:"share_user"`
|
||||
ShareCount int `json:"share_count"`
|
||||
AddToFavUser int `json:"add_to_fav_user"`
|
||||
AddToFavCount int `json:"add_to_fav_count"`
|
||||
} `json:"list"`
|
||||
}
|
||||
|
||||
//ResUserShare 获取图文分享转发数据
|
||||
type ResUserShare struct {
|
||||
util.CommonError
|
||||
|
||||
List []struct {
|
||||
RefDate string `json:"ref_date"`
|
||||
ShareScene int `json:"share_scene"`
|
||||
ShareCount int `json:"share_count"`
|
||||
ShareUser int `json:"share_user"`
|
||||
} `json:"list"`
|
||||
}
|
||||
|
||||
//ResUserShareHour 获取图文分享转发分时数据
|
||||
type ResUserShareHour struct {
|
||||
util.CommonError
|
||||
|
||||
List []struct {
|
||||
RefDate string `json:"ref_date"`
|
||||
RefHour int `json:"ref_hour"`
|
||||
ShareScene int `json:"share_scene"`
|
||||
ShareCount int `json:"share_count"`
|
||||
ShareUser int `json:"share_user"`
|
||||
} `json:"list"`
|
||||
}
|
||||
|
||||
//GetArticleSummary 获取图文群发每日数据
|
||||
func (cube *DataCube) GetArticleSummary(s string, e string) (resArticleSummary ResArticleSummary, err error) {
|
||||
accessToken, err := cube.GetAccessToken()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
uri := fmt.Sprintf("%s?access_token=%s", getArticleSummary, accessToken)
|
||||
reqDate := &reqDate{
|
||||
BeginDate: s,
|
||||
EndDate: e,
|
||||
}
|
||||
|
||||
response, err := util.PostJSON(uri, reqDate)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = util.DecodeWithError(response, &resArticleSummary, "GetArticleSummary")
|
||||
return
|
||||
}
|
||||
|
||||
//GetArticleTotal 获取图文群发总数据
|
||||
func (cube *DataCube) GetArticleTotal(s string, e string) (resArticleTotal ResArticleTotal, err error) {
|
||||
accessToken, err := cube.GetAccessToken()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
uri := fmt.Sprintf("%s?access_token=%s", getArticleTotal, accessToken)
|
||||
reqDate := &reqDate{
|
||||
BeginDate: s,
|
||||
EndDate: e,
|
||||
}
|
||||
|
||||
response, err := util.PostJSON(uri, reqDate)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = util.DecodeWithError(response, &resArticleTotal, "GetArticleTotal")
|
||||
return
|
||||
}
|
||||
|
||||
//GetUserRead 获取图文统计数据
|
||||
func (cube *DataCube) GetUserRead(s string, e string) (resUserRead ResUserRead, err error) {
|
||||
accessToken, err := cube.GetAccessToken()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
uri := fmt.Sprintf("%s?access_token=%s", getUserRead, accessToken)
|
||||
reqDate := &reqDate{
|
||||
BeginDate: s,
|
||||
EndDate: e,
|
||||
}
|
||||
|
||||
response, err := util.PostJSON(uri, reqDate)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = util.DecodeWithError(response, &resUserRead, "GetUserRead")
|
||||
return
|
||||
}
|
||||
|
||||
//GetUserReadHour 获取图文统计分时数据
|
||||
func (cube *DataCube) GetUserReadHour(s string, e string) (resUserReadHour ResUserReadHour, err error) {
|
||||
accessToken, err := cube.GetAccessToken()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
uri := fmt.Sprintf("%s?access_token=%s", getUserReadHour, accessToken)
|
||||
reqDate := &reqDate{
|
||||
BeginDate: s,
|
||||
EndDate: e,
|
||||
}
|
||||
|
||||
response, err := util.PostJSON(uri, reqDate)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = util.DecodeWithError(response, &resUserReadHour, "GetUserReadHour")
|
||||
return
|
||||
}
|
||||
|
||||
//GetUserShare 获取图文分享转发数据
|
||||
func (cube *DataCube) GetUserShare(s string, e string) (resUserShare ResUserShare, err error) {
|
||||
accessToken, err := cube.GetAccessToken()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
uri := fmt.Sprintf("%s?access_token=%s", getUserShare, accessToken)
|
||||
reqDate := &reqDate{
|
||||
BeginDate: s,
|
||||
EndDate: e,
|
||||
}
|
||||
|
||||
response, err := util.PostJSON(uri, reqDate)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = util.DecodeWithError(response, &resUserShare, "GetUserShare")
|
||||
return
|
||||
}
|
||||
|
||||
//GetUserShareHour 获取图文分享转发分时数据
|
||||
func (cube *DataCube) GetUserShareHour(s string, e string) (resUserShareHour ResUserShareHour, err error) {
|
||||
accessToken, err := cube.GetAccessToken()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
uri := fmt.Sprintf("%s?access_token=%s", getUserShareHour, accessToken)
|
||||
reqDate := &reqDate{
|
||||
BeginDate: s,
|
||||
EndDate: e,
|
||||
}
|
||||
|
||||
response, err := util.PostJSON(uri, reqDate)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = util.DecodeWithError(response, &resUserShareHour, "GetUserShareHour")
|
||||
return
|
||||
}
|
||||
22
officialaccount/datacube/datacube.go
Normal file
22
officialaccount/datacube/datacube.go
Normal file
@@ -0,0 +1,22 @@
|
||||
package datacube
|
||||
|
||||
import (
|
||||
"github.com/silenceper/wechat/v2/officialaccount/context"
|
||||
)
|
||||
|
||||
type reqDate struct {
|
||||
BeginDate string `json:"begin_date"`
|
||||
EndDate string `json:"end_date"`
|
||||
}
|
||||
|
||||
//DataCube 数据统计
|
||||
type DataCube struct {
|
||||
*context.Context
|
||||
}
|
||||
|
||||
//NewCube 数据统计
|
||||
func NewCube(context *context.Context) *DataCube {
|
||||
dataCube := new(DataCube)
|
||||
dataCube.Context = context
|
||||
return dataCube
|
||||
}
|
||||
82
officialaccount/datacube/interface.go
Normal file
82
officialaccount/datacube/interface.go
Normal file
@@ -0,0 +1,82 @@
|
||||
package datacube
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/silenceper/wechat/v2/util"
|
||||
)
|
||||
|
||||
const (
|
||||
getInterfaceSummary = "https://api.weixin.qq.com/datacube/getinterfacesummary"
|
||||
getInterfaceSummaryHour = "https://api.weixin.qq.com/datacube/getinterfacesummaryhour"
|
||||
)
|
||||
|
||||
//ResInterfaceSummary 接口分析数据响应
|
||||
type ResInterfaceSummary struct {
|
||||
util.CommonError
|
||||
|
||||
List []struct {
|
||||
RefDate string `json:"ref_date"`
|
||||
CallbackCount int `json:"callback_count"`
|
||||
FailCount int `json:"fail_count"`
|
||||
TotalTimeCost int `json:"total_time_cost"`
|
||||
MaxTimeCost int `json:"max_time_cost"`
|
||||
} `json:"list"`
|
||||
}
|
||||
|
||||
//ResInterfaceSummaryHour 接口分析分时数据响应
|
||||
type ResInterfaceSummaryHour struct {
|
||||
util.CommonError
|
||||
|
||||
List []struct {
|
||||
RefDate string `json:"ref_date"`
|
||||
RefHour int `json:"ref_hour"`
|
||||
CallbackCount int `json:"callback_count"`
|
||||
FailCount int `json:"fail_count"`
|
||||
TotalTimeCost int `json:"total_time_cost"`
|
||||
MaxTimeCost int `json:"max_time_cost"`
|
||||
} `json:"list"`
|
||||
}
|
||||
|
||||
//GetInterfaceSummary 获取接口分析数据
|
||||
func (cube *DataCube) GetInterfaceSummary(s string, e string) (resInterfaceSummary ResInterfaceSummary, err error) {
|
||||
accessToken, err := cube.GetAccessToken()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
uri := fmt.Sprintf("%s?access_token=%s", getInterfaceSummary, accessToken)
|
||||
reqDate := &reqDate{
|
||||
BeginDate: s,
|
||||
EndDate: e,
|
||||
}
|
||||
|
||||
response, err := util.PostJSON(uri, reqDate)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = util.DecodeWithError(response, &resInterfaceSummary, "GetInterfaceSummary")
|
||||
return
|
||||
}
|
||||
|
||||
//GetInterfaceSummaryHour 获取接口分析分时数据
|
||||
func (cube *DataCube) GetInterfaceSummaryHour(s string, e string) (resInterfaceSummaryHour ResInterfaceSummaryHour, err error) {
|
||||
accessToken, err := cube.GetAccessToken()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
uri := fmt.Sprintf("%s?access_token=%s", getInterfaceSummaryHour, accessToken)
|
||||
reqDate := &reqDate{
|
||||
BeginDate: s,
|
||||
EndDate: e,
|
||||
}
|
||||
|
||||
response, err := util.PostJSON(uri, reqDate)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = util.DecodeWithError(response, &resInterfaceSummaryHour, "GetInterfaceSummaryHour")
|
||||
return
|
||||
}
|
||||
252
officialaccount/datacube/message.go
Normal file
252
officialaccount/datacube/message.go
Normal file
@@ -0,0 +1,252 @@
|
||||
package datacube
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/silenceper/wechat/v2/util"
|
||||
)
|
||||
|
||||
const (
|
||||
getUpstreamMsg = "https://api.weixin.qq.com/datacube/getupstreammsg"
|
||||
getUpstreamMsgHour = "https://api.weixin.qq.com/datacube/getupstreammsghour"
|
||||
getUpstreamMsgWeek = "https://api.weixin.qq.com/datacube/getupstreammsgweek"
|
||||
getUpstreamMsgMonth = "https://api.weixin.qq.com/datacube/getupstreammsgmonth"
|
||||
getUpstreamMsgDist = "https://api.weixin.qq.com/datacube/getupstreammsgdist"
|
||||
getUpstreamMsgDistWeek = "https://api.weixin.qq.com/datacube/getupstreammsgdistweek"
|
||||
getUpstreamMsgDistMonth = "https://api.weixin.qq.com/datacube/getupstreammsgdistmonth"
|
||||
)
|
||||
|
||||
//ResUpstreamMsg 获取消息发送概况数据响应
|
||||
type ResUpstreamMsg struct {
|
||||
util.CommonError
|
||||
|
||||
List []struct {
|
||||
RefDate string `json:"ref_date"`
|
||||
MsgType int `json:"msg_type"`
|
||||
MsgUser int `json:"msg_user"`
|
||||
MsgCount int `json:"msg_count"`
|
||||
} `json:"list"`
|
||||
}
|
||||
|
||||
//ResUpstreamMsgHour 获取消息分送分时数据响应
|
||||
type ResUpstreamMsgHour struct {
|
||||
util.CommonError
|
||||
|
||||
List []struct {
|
||||
RefDate string `json:"ref_date"`
|
||||
RefHour int `json:"ref_hour"`
|
||||
MsgType int `json:"msg_type"`
|
||||
MsgUser int `json:"msg_user"`
|
||||
MsgCount int `json:"msg_count"`
|
||||
} `json:"list"`
|
||||
}
|
||||
|
||||
//ResUpstreamMsgWeek 获取消息发送周数据响应
|
||||
type ResUpstreamMsgWeek struct {
|
||||
util.CommonError
|
||||
|
||||
List []struct {
|
||||
RefDate string `json:"ref_date"`
|
||||
MsgType int `json:"msg_type"`
|
||||
MsgUser int `json:"msg_user"`
|
||||
MsgCount int `json:"msg_count"`
|
||||
} `json:"list"`
|
||||
}
|
||||
|
||||
//ResUpstreamMsgMonth 获取消息发送月数据响应
|
||||
type ResUpstreamMsgMonth struct {
|
||||
util.CommonError
|
||||
|
||||
List []struct {
|
||||
RefDate string `json:"ref_date"`
|
||||
MsgType int `json:"msg_type"`
|
||||
MsgUser int `json:"msg_user"`
|
||||
MsgCount int `json:"msg_count"`
|
||||
} `json:"list"`
|
||||
}
|
||||
|
||||
//ResUpstreamMsgDist 获取消息发送分布数据响应
|
||||
type ResUpstreamMsgDist struct {
|
||||
util.CommonError
|
||||
|
||||
List []struct {
|
||||
RefDate string `json:"ref_date"`
|
||||
CountInterval int `json:"count_interval"`
|
||||
MsgUser int `json:"msg_user"`
|
||||
} `json:"list"`
|
||||
}
|
||||
|
||||
//ResUpstreamMsgDistWeek 获取消息发送分布周数据响应
|
||||
type ResUpstreamMsgDistWeek struct {
|
||||
util.CommonError
|
||||
|
||||
List []struct {
|
||||
RefDate string `json:"ref_date"`
|
||||
CountInterval int `json:"count_interval"`
|
||||
MsgUser int `json:"msg_user"`
|
||||
} `json:"list"`
|
||||
}
|
||||
|
||||
//ResUpstreamMsgDistMonth 获取消息发送分布月数据响应
|
||||
type ResUpstreamMsgDistMonth struct {
|
||||
util.CommonError
|
||||
|
||||
List []struct {
|
||||
RefDate string `json:"ref_date"`
|
||||
CountInterval int `json:"count_interval"`
|
||||
MsgUser int `json:"msg_user"`
|
||||
} `json:"list"`
|
||||
}
|
||||
|
||||
//GetUpstreamMsg 获取消息发送概况数据
|
||||
func (cube *DataCube) GetUpstreamMsg(s string, e string) (resUpstreamMsg ResUpstreamMsg, err error) {
|
||||
accessToken, err := cube.GetAccessToken()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
uri := fmt.Sprintf("%s?access_token=%s", getUpstreamMsg, accessToken)
|
||||
reqDate := &reqDate{
|
||||
BeginDate: s,
|
||||
EndDate: e,
|
||||
}
|
||||
|
||||
response, err := util.PostJSON(uri, reqDate)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = util.DecodeWithError(response, &resUpstreamMsg, "GetUpstreamMsg")
|
||||
return
|
||||
}
|
||||
|
||||
//GetUpstreamMsgHour 获取消息分送分时数据
|
||||
func (cube *DataCube) GetUpstreamMsgHour(s string, e string) (resUpstreamMsgHour ResUpstreamMsgHour, err error) {
|
||||
accessToken, err := cube.GetAccessToken()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
uri := fmt.Sprintf("%s?access_token=%s", getUpstreamMsgHour, accessToken)
|
||||
reqDate := &reqDate{
|
||||
BeginDate: s,
|
||||
EndDate: e,
|
||||
}
|
||||
|
||||
response, err := util.PostJSON(uri, reqDate)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = util.DecodeWithError(response, &resUpstreamMsgHour, "GetUpstreamMsgHour")
|
||||
return
|
||||
}
|
||||
|
||||
//GetUpstreamMsgWeek 获取消息发送周数据
|
||||
func (cube *DataCube) GetUpstreamMsgWeek(s string, e string) (resUpstreamMsgWeek ResUpstreamMsgWeek, err error) {
|
||||
accessToken, err := cube.GetAccessToken()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
uri := fmt.Sprintf("%s?access_token=%s", getUpstreamMsgWeek, accessToken)
|
||||
reqDate := &reqDate{
|
||||
BeginDate: s,
|
||||
EndDate: e,
|
||||
}
|
||||
|
||||
response, err := util.PostJSON(uri, reqDate)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = util.DecodeWithError(response, &resUpstreamMsgWeek, "GetUpstreamMsgWeek")
|
||||
return
|
||||
}
|
||||
|
||||
//GetUpstreamMsgMonth 获取消息发送月数据
|
||||
func (cube *DataCube) GetUpstreamMsgMonth(s string, e string) (resUpstreamMsgMonth ResUpstreamMsgMonth, err error) {
|
||||
accessToken, err := cube.GetAccessToken()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
uri := fmt.Sprintf("%s?access_token=%s", getUpstreamMsgMonth, accessToken)
|
||||
reqDate := &reqDate{
|
||||
BeginDate: s,
|
||||
EndDate: e,
|
||||
}
|
||||
|
||||
response, err := util.PostJSON(uri, reqDate)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = util.DecodeWithError(response, &resUpstreamMsgMonth, "GetUpstreamMsgMonth")
|
||||
return
|
||||
}
|
||||
|
||||
//GetUpstreamMsgDist 获取消息发送分布数据
|
||||
func (cube *DataCube) GetUpstreamMsgDist(s string, e string) (resUpstreamMsgDist ResUpstreamMsgDist, err error) {
|
||||
accessToken, err := cube.GetAccessToken()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
uri := fmt.Sprintf("%s?access_token=%s", getUpstreamMsgDist, accessToken)
|
||||
reqDate := &reqDate{
|
||||
BeginDate: s,
|
||||
EndDate: e,
|
||||
}
|
||||
|
||||
response, err := util.PostJSON(uri, reqDate)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = util.DecodeWithError(response, &resUpstreamMsgDist, "GetUpstreamMsgDist")
|
||||
return
|
||||
}
|
||||
|
||||
//GetUpstreamMsgDistWeek 获取消息发送分布周数据
|
||||
func (cube *DataCube) GetUpstreamMsgDistWeek(s string, e string) (resUpstreamMsgDistWeek ResUpstreamMsgDistWeek, err error) {
|
||||
accessToken, err := cube.GetAccessToken()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
uri := fmt.Sprintf("%s?access_token=%s", getUpstreamMsgDistWeek, accessToken)
|
||||
reqDate := &reqDate{
|
||||
BeginDate: s,
|
||||
EndDate: e,
|
||||
}
|
||||
|
||||
response, err := util.PostJSON(uri, reqDate)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = util.DecodeWithError(response, &resUpstreamMsgDistWeek, "GetUpstreamMsgDistWeek")
|
||||
return
|
||||
}
|
||||
|
||||
//GetUpstreamMsgDistMonth 获取消息发送分布月数据
|
||||
func (cube *DataCube) GetUpstreamMsgDistMonth(s string, e string) (resUpstreamMsgDistMonth ResUpstreamMsgDistMonth, err error) {
|
||||
accessToken, err := cube.GetAccessToken()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
uri := fmt.Sprintf("%s?access_token=%s", getUpstreamMsgDistMonth, accessToken)
|
||||
reqDate := &reqDate{
|
||||
BeginDate: s,
|
||||
EndDate: e,
|
||||
}
|
||||
|
||||
response, err := util.PostJSON(uri, reqDate)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = util.DecodeWithError(response, &resUpstreamMsgDistMonth, "GetUpstreamMsgDistMonth")
|
||||
return
|
||||
}
|
||||
306
officialaccount/datacube/publisher.go
Normal file
306
officialaccount/datacube/publisher.go
Normal file
@@ -0,0 +1,306 @@
|
||||
package datacube
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/silenceper/wechat/v2/util"
|
||||
"net/url"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
//AdSlot 广告位类型
|
||||
type AdSlot string
|
||||
|
||||
const (
|
||||
//SlotIDBizBottom 公众号底部广告
|
||||
SlotIDBizBottom AdSlot = "SLOT_ID_BIZ_BOTTOM"
|
||||
//SlotIDBizMidContext 公众号文中广告
|
||||
SlotIDBizMidContext AdSlot = "SLOT_ID_BIZ_MID_CONTEXT"
|
||||
//SlotIDBizVideoEnd 公众号视频后贴
|
||||
SlotIDBizVideoEnd AdSlot = "SLOT_ID_BIZ_VIDEO_END"
|
||||
//SlotIDBizSponsor 公众号互选广告
|
||||
SlotIDBizSponsor AdSlot = "SLOT_ID_BIZ_SPONSOR"
|
||||
//SlotIDBizCps 公众号返佣商品
|
||||
SlotIDBizCps AdSlot = "SLOT_ID_BIZ_CPS"
|
||||
//SlotIDWeappBanner 小程序banner
|
||||
SlotIDWeappBanner AdSlot = "SLOT_ID_WEAPP_BANNER"
|
||||
//SlotIDWeappRewardVideo 小程序激励视频
|
||||
SlotIDWeappRewardVideo AdSlot = "SLOT_ID_WEAPP_REWARD_VIDEO"
|
||||
//SlotIDWeappInterstitial 小程序插屏广告
|
||||
SlotIDWeappInterstitial AdSlot = "SLOT_ID_WEAPP_INTERSTITIAL"
|
||||
//SlotIDWeappVideoFeeds 小程序视频广告
|
||||
SlotIDWeappVideoFeeds AdSlot = "SLOT_ID_WEAPP_VIDEO_FEEDS"
|
||||
//SlotIDWeappVideoBegin 小程序视频前贴
|
||||
SlotIDWeappVideoBegin AdSlot = "SLOT_ID_WEAPP_VIDEO_BEGIN"
|
||||
//SlotIDWeappBox 小程序格子广告
|
||||
SlotIDWeappBox AdSlot = "SLOT_ID_WEAPP_BOX"
|
||||
)
|
||||
|
||||
const (
|
||||
publisherURL = "https://api.weixin.qq.com/publisher/stat"
|
||||
)
|
||||
|
||||
const (
|
||||
actionPublisherAdPosGeneral = "publisher_adpos_general"
|
||||
actionPublisherCpsGeneral = "publisher_cps_general"
|
||||
actionPublisherSettlement = "publisher_settlement"
|
||||
)
|
||||
|
||||
//BaseResp 错误信息
|
||||
type BaseResp struct {
|
||||
ErrMsg string `json:"err_msg"`
|
||||
Ret int `json:"ret"`
|
||||
}
|
||||
|
||||
//ResPublisherAdPos 公众号分广告位数据响应
|
||||
type ResPublisherAdPos struct {
|
||||
util.CommonError
|
||||
BaseResp
|
||||
|
||||
Base BaseResp `json:"base_resp"`
|
||||
List []ResAdPosList `json:"list"`
|
||||
Summary ResAdPosSummary `json:"summary"`
|
||||
TotalNum int `json:"total_num"`
|
||||
}
|
||||
|
||||
//ResAdPosList 公众号分广告位列表
|
||||
type ResAdPosList struct {
|
||||
SlotID int64 `json:"slot_id"`
|
||||
AdSlot string `json:"ad_slot"`
|
||||
Date string `json:"date"`
|
||||
ReqSuccCount int `json:"req_succ_count"`
|
||||
ExposureCount int `json:"exposure_count"`
|
||||
ExposureRate float64 `json:"exposure_rate"`
|
||||
ClickCount int `json:"click_count"`
|
||||
ClickRate float64 `json:"click_rate"`
|
||||
Income int `json:"income"`
|
||||
Ecpm float64 `json:"ecpm"`
|
||||
}
|
||||
|
||||
//ResAdPosSummary 公众号分广告位概览
|
||||
type ResAdPosSummary struct {
|
||||
ReqSuccCount int `json:"req_succ_count"`
|
||||
ExposureCount int `json:"exposure_count"`
|
||||
ExposureRate float64 `json:"exposure_rate"`
|
||||
ClickCount int `json:"click_count"`
|
||||
ClickRate float64 `json:"click_rate"`
|
||||
Income int `json:"income"`
|
||||
Ecpm float64 `json:"ecpm"`
|
||||
}
|
||||
|
||||
//ResPublisherCps 公众号返佣商品数据响应
|
||||
type ResPublisherCps struct {
|
||||
util.CommonError
|
||||
BaseResp
|
||||
|
||||
Base BaseResp `json:"base_resp"`
|
||||
List []ResCpsList `json:"list"`
|
||||
Summary ResCpsSummary `json:"summary"`
|
||||
TotalNum int `json:"total_num"`
|
||||
}
|
||||
|
||||
//ResCpsList 公众号返佣商品列表
|
||||
type ResCpsList struct {
|
||||
Date string `json:"date"`
|
||||
ExposureCount int `json:"exposure_count"`
|
||||
ClickCount int `json:"click_count"`
|
||||
ClickRate float64 `json:"click_rate"`
|
||||
OrderCount int `json:"order_count"`
|
||||
OrderRate float64 `json:"order_rate"`
|
||||
TotalFee int `json:"total_fee"`
|
||||
TotalCommission int `json:"total_commission"`
|
||||
}
|
||||
|
||||
//ResCpsSummary 公众号返佣概览
|
||||
type ResCpsSummary struct {
|
||||
ExposureCount int `json:"exposure_count"`
|
||||
ClickCount int `json:"click_count"`
|
||||
ClickRate float64 `json:"click_rate"`
|
||||
OrderCount int `json:"order_count"`
|
||||
OrderRate float64 `json:"order_rate"`
|
||||
TotalFee int `json:"total_fee"`
|
||||
TotalCommission int `json:"total_commission"`
|
||||
}
|
||||
|
||||
//ResPublisherSettlement 公众号结算收入数据及结算主体信息响应
|
||||
type ResPublisherSettlement struct {
|
||||
util.CommonError
|
||||
BaseResp
|
||||
|
||||
Base BaseResp `json:"base_resp"`
|
||||
Body string `json:"body"`
|
||||
PenaltyAll int `json:"penalty_all"`
|
||||
RevenueAll int64 `json:"revenue_all"`
|
||||
SettledRevenueAll int64 `json:"settled_revenue_all"`
|
||||
SettlementList []SettlementList `json:"settlement_list"`
|
||||
TotalNum int `json:"total_num"`
|
||||
}
|
||||
|
||||
//SettlementList 结算单列表
|
||||
type SettlementList struct {
|
||||
Date string `json:"date"`
|
||||
Zone string `json:"zone"`
|
||||
Month string `json:"month"`
|
||||
Order int `json:"order"`
|
||||
SettStatus int `json:"sett_status"`
|
||||
SettledRevenue int `json:"settled_revenue"`
|
||||
SettNo string `json:"sett_no"`
|
||||
MailSendCnt string `json:"mail_send_cnt"`
|
||||
SlotRevenue []SlotRevenue `json:"slot_revenue"`
|
||||
}
|
||||
|
||||
//SlotRevenue 产生收入的广告
|
||||
type SlotRevenue struct {
|
||||
SlotID string `json:"slot_id"`
|
||||
SlotSettledRevenue int `json:"slot_settled_revenue"`
|
||||
}
|
||||
|
||||
//ParamsPublisher 拉取数据参数
|
||||
type ParamsPublisher struct {
|
||||
Action string `json:"action"`
|
||||
StartDate string `json:"start_date"`
|
||||
EndDate string `json:"end_date"`
|
||||
Page int `json:"page"`
|
||||
PageSize int `json:"page_size"`
|
||||
AdSlot AdSlot `json:"ad_slot"`
|
||||
}
|
||||
|
||||
// fetchData 拉取统计数据
|
||||
func (cube *DataCube) fetchData(params ParamsPublisher) (response []byte, err error) {
|
||||
accessToken, err := cube.GetAccessToken()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
v := url.Values{}
|
||||
v.Add("action", params.Action)
|
||||
v.Add("access_token", accessToken)
|
||||
v.Add("page", strconv.Itoa(params.Page))
|
||||
v.Add("page_size", strconv.Itoa(params.PageSize))
|
||||
v.Add("start_date", params.StartDate)
|
||||
v.Add("end_date", params.EndDate)
|
||||
if params.AdSlot != "" {
|
||||
v.Add("ad_slot", string(params.AdSlot))
|
||||
}
|
||||
|
||||
uri := fmt.Sprintf("%s?%s", publisherURL, v.Encode())
|
||||
|
||||
response, err = util.HTTPGet(uri)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//GetPublisherAdPosGeneral 获取公众号分广告位数据
|
||||
func (cube *DataCube) GetPublisherAdPosGeneral(startDate, endDate string, page, pageSize int, adSlot AdSlot) (resPublisherAdPos ResPublisherAdPos, err error) {
|
||||
params := ParamsPublisher{
|
||||
Action: actionPublisherAdPosGeneral,
|
||||
StartDate: startDate,
|
||||
EndDate: endDate,
|
||||
Page: page,
|
||||
PageSize: pageSize,
|
||||
AdSlot: adSlot,
|
||||
}
|
||||
|
||||
response, err := cube.fetchData(params)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = json.Unmarshal(response, &resPublisherAdPos)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if resPublisherAdPos.CommonError.ErrCode != 0 {
|
||||
err = fmt.Errorf("GetPublisherAdPosGeneral Error , errcode=%d , errmsg=%s", resPublisherAdPos.CommonError.ErrCode, resPublisherAdPos.CommonError.ErrMsg)
|
||||
return
|
||||
}
|
||||
|
||||
if resPublisherAdPos.BaseResp.Ret != 0 {
|
||||
err = fmt.Errorf("GetPublisherAdPosGeneral Error , errcode=%d , errmsg=%s", resPublisherAdPos.BaseResp.Ret, resPublisherAdPos.BaseResp.ErrMsg)
|
||||
return
|
||||
}
|
||||
|
||||
if resPublisherAdPos.Base.Ret != 0 {
|
||||
err = fmt.Errorf("GetPublisherAdPosGeneral Error , errcode=%d , errmsg=%s", resPublisherAdPos.Base.Ret, resPublisherAdPos.Base.ErrMsg)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//GetPublisherCpsGeneral 获取公众号返佣商品数据
|
||||
func (cube *DataCube) GetPublisherCpsGeneral(startDate, endDate string, page, pageSize int) (resPublisherCps ResPublisherCps, err error) {
|
||||
params := ParamsPublisher{
|
||||
Action: actionPublisherCpsGeneral,
|
||||
StartDate: startDate,
|
||||
EndDate: endDate,
|
||||
Page: page,
|
||||
PageSize: pageSize,
|
||||
}
|
||||
|
||||
response, err := cube.fetchData(params)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = json.Unmarshal(response, &resPublisherCps)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if resPublisherCps.CommonError.ErrCode != 0 {
|
||||
err = fmt.Errorf("GetPublisherCpsGeneral Error , errcode=%d , errmsg=%s", resPublisherCps.CommonError.ErrCode, resPublisherCps.CommonError.ErrMsg)
|
||||
return
|
||||
}
|
||||
|
||||
if resPublisherCps.BaseResp.Ret != 0 {
|
||||
err = fmt.Errorf("GetPublisherCpsGeneral Error , errcode=%d , errmsg=%s", resPublisherCps.BaseResp.Ret, resPublisherCps.BaseResp.ErrMsg)
|
||||
return
|
||||
}
|
||||
|
||||
if resPublisherCps.Base.Ret != 0 {
|
||||
err = fmt.Errorf("GetPublisherCpsGeneral Error , errcode=%d , errmsg=%s", resPublisherCps.Base.Ret, resPublisherCps.Base.ErrMsg)
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
//GetPublisherSettlement 获取公众号结算收入数据及结算主体信息
|
||||
func (cube *DataCube) GetPublisherSettlement(startDate, endDate string, page, pageSize int) (resPublisherSettlement ResPublisherSettlement, err error) {
|
||||
params := ParamsPublisher{
|
||||
Action: actionPublisherSettlement,
|
||||
StartDate: startDate,
|
||||
EndDate: endDate,
|
||||
Page: page,
|
||||
PageSize: pageSize,
|
||||
}
|
||||
|
||||
response, err := cube.fetchData(params)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = json.Unmarshal(response, &resPublisherSettlement)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if resPublisherSettlement.CommonError.ErrCode != 0 {
|
||||
err = fmt.Errorf("GetPublisherSettlement Error , errcode=%d , errmsg=%s", resPublisherSettlement.CommonError.ErrCode, resPublisherSettlement.CommonError.ErrMsg)
|
||||
return
|
||||
}
|
||||
|
||||
if resPublisherSettlement.BaseResp.Ret != 0 {
|
||||
err = fmt.Errorf("GetPublisherSettlement Error , errcode=%d , errmsg=%s", resPublisherSettlement.BaseResp.Ret, resPublisherSettlement.BaseResp.ErrMsg)
|
||||
return
|
||||
}
|
||||
|
||||
if resPublisherSettlement.Base.Ret != 0 {
|
||||
err = fmt.Errorf("GetPublisherSettlement Error , errcode=%d , errmsg=%s", resPublisherSettlement.Base.Ret, resPublisherSettlement.Base.ErrMsg)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
77
officialaccount/datacube/user.go
Normal file
77
officialaccount/datacube/user.go
Normal file
@@ -0,0 +1,77 @@
|
||||
package datacube
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/silenceper/wechat/v2/util"
|
||||
)
|
||||
|
||||
const (
|
||||
getUserSummary = "https://api.weixin.qq.com/datacube/getusersummary"
|
||||
getUserAccumulate = "https://api.weixin.qq.com/datacube/getusercumulate"
|
||||
)
|
||||
|
||||
//ResUserSummary 获取用户增减数据响应
|
||||
type ResUserSummary struct {
|
||||
util.CommonError
|
||||
|
||||
List []struct {
|
||||
RefDate string `json:"ref_date"`
|
||||
UserSource int `json:"user_source"`
|
||||
NewUser int `json:"new_user"`
|
||||
CancelUser int `json:"cancel_user"`
|
||||
} `json:"list"`
|
||||
}
|
||||
|
||||
//ResUserAccumulate 获取累计用户数据响应
|
||||
type ResUserAccumulate struct {
|
||||
util.CommonError
|
||||
|
||||
List []struct {
|
||||
RefDate string `json:"ref_date"`
|
||||
CumulateUser int `json:"cumulate_user"`
|
||||
} `json:"list"`
|
||||
}
|
||||
|
||||
//GetUserSummary 获取用户增减数据
|
||||
func (cube *DataCube) GetUserSummary(s string, e string) (resUserSummary ResUserSummary, err error) {
|
||||
accessToken, err := cube.GetAccessToken()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
uri := fmt.Sprintf("%s?access_token=%s", getUserSummary, accessToken)
|
||||
reqDate := &reqDate{
|
||||
BeginDate: s,
|
||||
EndDate: e,
|
||||
}
|
||||
|
||||
response, err := util.PostJSON(uri, reqDate)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = util.DecodeWithError(response, &resUserSummary, "GetUserSummary")
|
||||
return
|
||||
}
|
||||
|
||||
//GetUserAccumulate 获取累计用户数据
|
||||
func (cube *DataCube) GetUserAccumulate(s string, e string) (resUserAccumulate ResUserAccumulate, err error) {
|
||||
accessToken, err := cube.GetAccessToken()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
uri := fmt.Sprintf("%s?access_token=%s", getUserAccumulate, accessToken)
|
||||
reqDate := &reqDate{
|
||||
BeginDate: s,
|
||||
EndDate: e,
|
||||
}
|
||||
|
||||
response, err := util.PostJSON(uri, reqDate)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = util.DecodeWithError(response, &resUserAccumulate, "GetUserAccumulate")
|
||||
return
|
||||
}
|
||||
@@ -60,7 +60,7 @@ func (d *Device) VerifyQRCode(ticket string) (res ResVerifyQRCode, err error) {
|
||||
req := map[string]interface{}{
|
||||
"ticket": ticket,
|
||||
}
|
||||
fmt.Println(req)
|
||||
|
||||
var response []byte
|
||||
if response, err = util.PostJSON(uri, req); err != nil {
|
||||
return
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package officialaccount
|
||||
|
||||
import (
|
||||
"github.com/silenceper/wechat/v2/officialaccount/datacube"
|
||||
"net/http"
|
||||
|
||||
"github.com/silenceper/wechat/v2/credential"
|
||||
@@ -101,3 +102,8 @@ func (officialAccount *OfficialAccount) GetDevice() *device.Device {
|
||||
func (officialAccount *OfficialAccount) GetBroadcast() *broadcast.Broadcast {
|
||||
return broadcast.NewBroadcast(officialAccount.ctx)
|
||||
}
|
||||
|
||||
//GetDataCube 数据统计
|
||||
func (officialAccount *OfficialAccount) GetDataCube() *datacube.DataCube {
|
||||
return datacube.NewCube(officialAccount.ctx)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user