forked from chanxuehong/wechat
-
Notifications
You must be signed in to change notification settings - Fork 1
/
material.go
192 lines (165 loc) · 4.91 KB
/
material.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
package material
import (
"fmt"
"github.com/charsunny/wechat/mp/core"
)
// 删除永久素材.
func Delete(clt *core.Client, mediaId string) (err error) {
const incompleteURL = "https://api.weixin.qq.com/cgi-bin/material/del_material?access_token="
var request = struct {
MediaId string `json:"media_id"`
}{
MediaId: mediaId,
}
var result core.Error
if err = clt.PostJSON(incompleteURL, &request, &result); err != nil {
return
}
if result.ErrCode != core.ErrCodeOK {
err = &result
return
}
return
}
// 公众号永久素材总数信息
type MaterialCountInfo struct {
VoiceCount int `json:"voice_count"`
VideoCount int `json:"video_count"`
ImageCount int `json:"image_count"`
NewsCount int `json:"news_count"`
}
// 获取素材总数数据.
func GetMaterialCount(clt *core.Client) (info *MaterialCountInfo, err error) {
const incompleteURL = "https://api.weixin.qq.com/cgi-bin/material/get_materialcount?access_token="
var result struct {
core.Error
MaterialCountInfo
}
if err = clt.GetJSON(incompleteURL, &result); err != nil {
return
}
if result.ErrCode != core.ErrCodeOK {
err = &result.Error
return
}
info = &result.MaterialCountInfo
return
}
type BatchGetResult struct {
TotalCount int `json:"total_count"` // 该类型的素材的总数
ItemCount int `json:"item_count"` // 本次调用获取的素材的数量
Items []MaterialInfo `json:"item"` // 本次调用获取的素材列表
}
type MaterialInfo struct {
MediaId string `json:"media_id"` // 素材id
Name string `json:"name"` // 文件名称
UpdateTime int64 `json:"update_time"` // 最后更新时间
URL string `json:"url"` // 当获取的列表是图片素材列表时, 该字段是图片的URL
}
// 获取素材列表.
// materialType: 素材的类型, 图片(image), 视频(video), 语音 (voice)
// offset: 从全部素材的该偏移位置开始返回, 0表示从第一个素材
// count: 返回素材的数量, 取值在1到20之间
func BatchGet(clt *core.Client, materialType string, offset, count int) (rslt *BatchGetResult, err error) {
const incompleteURL = "https://api.weixin.qq.com/cgi-bin/material/batchget_material?access_token="
switch materialType {
case MaterialTypeImage, MaterialTypeVideo, MaterialTypeVoice, MaterialTypeNews:
default:
err = fmt.Errorf("Incorrect materialType: %s", materialType)
return
}
if offset < 0 {
err = fmt.Errorf("Incorrect offset: %d", offset)
return
}
if count <= 0 {
err = fmt.Errorf("Incorrect count: %d", count)
return
}
var request = struct {
MaterialType string `json:"type"`
Offset int `json:"offset"`
Count int `json:"count"`
}{
MaterialType: materialType,
Offset: offset,
Count: count,
}
var result struct {
core.Error
BatchGetResult
}
if err = clt.PostJSON(incompleteURL, &request, &result); err != nil {
return
}
if result.ErrCode != core.ErrCodeOK {
err = &result.Error
return
}
rslt = &result.BatchGetResult
return
}
// =====================================================================================================================
// MaterialIterator
//
// iter, err := NewMaterialIterator(clt, MaterialTypeImage, 0, 10)
// if err != nil {
// // TODO: 增加你的代码
// }
//
// for iter.HasNext() {
// items, err := iter.NextPage()
// if err != nil {
// // TODO: 增加你的代码
// }
// // TODO: 增加你的代码
// }
type MaterialIterator struct {
clt *core.Client
materialType string
nextOffset int
count int
lastBatchGetResult *BatchGetResult
nextPageCalled bool
}
func (iter *MaterialIterator) TotalCount() int {
return iter.lastBatchGetResult.TotalCount
}
func (iter *MaterialIterator) HasNext() bool {
if !iter.nextPageCalled {
return iter.lastBatchGetResult.ItemCount > 0 || iter.nextOffset < iter.lastBatchGetResult.TotalCount
}
return iter.nextOffset < iter.lastBatchGetResult.TotalCount
}
func (iter *MaterialIterator) NextPage() (items []MaterialInfo, err error) {
if !iter.nextPageCalled {
iter.nextPageCalled = true
items = iter.lastBatchGetResult.Items
return
}
rslt, err := BatchGet(iter.clt, iter.materialType, iter.nextOffset, iter.count)
if err != nil {
return
}
iter.lastBatchGetResult = rslt
iter.nextOffset += rslt.ItemCount
items = rslt.Items
return
}
func NewMaterialIterator(clt *core.Client, materialType string, offset, count int) (iter *MaterialIterator, err error) {
// 逻辑上相当于第一次调用 MaterialIterator.NextPage,
// 因为第一次调用 MaterialIterator.HasNext 需要数据支撑, 所以提前获取了数据
rslt, err := BatchGet(clt, materialType, offset, count)
if err != nil {
return
}
iter = &MaterialIterator{
clt: clt,
materialType: materialType,
nextOffset: offset + rslt.ItemCount,
count: count,
lastBatchGetResult: rslt,
nextPageCalled: false,
}
return
}