material.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. package material
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "fmt"
  6. "github.com/silenceper/wechat/context"
  7. "github.com/silenceper/wechat/util"
  8. )
  9. const (
  10. addNewsURL = "https://api.weixin.qq.com/cgi-bin/material/add_news"
  11. addMaterialURL = "https://api.weixin.qq.com/cgi-bin/material/add_material"
  12. delMaterialURL = "https://api.weixin.qq.com/cgi-bin/material/del_material"
  13. getMaterialURL = "https://api.weixin.qq.com/cgi-bin/material/get_material"
  14. )
  15. //Material 素材管理
  16. type Material struct {
  17. *context.Context
  18. }
  19. //NewMaterial init
  20. func NewMaterial(context *context.Context) *Material {
  21. material := new(Material)
  22. material.Context = context
  23. return material
  24. }
  25. //Article 永久图文素材
  26. type Article struct {
  27. Title string `json:"title"`
  28. ThumbMediaID string `json:"thumb_media_id"`
  29. Author string `json:"author"`
  30. Digest string `json:"digest"`
  31. ShowCoverPic int `json:"show_cover_pic"`
  32. Content string `json:"content"`
  33. ContentSourceURL string `json:"content_source_url"`
  34. URL string `json:"url"`
  35. DownURL string `json:"down_url"`
  36. }
  37. // GetNews 获取/下载永久素材
  38. func (material *Material) GetNews(id string) ([]*Article, error) {
  39. accessToken, err := material.GetAccessToken()
  40. if err != nil {
  41. return nil, err
  42. }
  43. uri := fmt.Sprintf("%s?access_token=%s", getMaterialURL, accessToken)
  44. var req struct {
  45. MediaID string `json:"media_id"`
  46. }
  47. req.MediaID = id
  48. responseBytes, err := util.PostJSON(uri, req)
  49. var res struct {
  50. NewsItem []*Article `json:"news_item"`
  51. }
  52. err = json.Unmarshal(responseBytes, &res)
  53. if err != nil {
  54. return nil, err
  55. }
  56. return res.NewsItem, nil
  57. }
  58. //reqArticles 永久性图文素材请求信息
  59. type reqArticles struct {
  60. Articles []*Article `json:"articles"`
  61. }
  62. //resArticles 永久性图文素材返回结果
  63. type resArticles struct {
  64. util.CommonError
  65. MediaID string `json:"media_id"`
  66. }
  67. //AddNews 新增永久图文素材
  68. func (material *Material) AddNews(articles []*Article) (mediaID string, err error) {
  69. req := &reqArticles{articles}
  70. var accessToken string
  71. accessToken, err = material.GetAccessToken()
  72. if err != nil {
  73. return
  74. }
  75. uri := fmt.Sprintf("%s?access_token=%s", addNewsURL, accessToken)
  76. responseBytes, err := util.PostJSON(uri, req)
  77. var res resArticles
  78. err = json.Unmarshal(responseBytes, &res)
  79. if err != nil {
  80. return
  81. }
  82. mediaID = res.MediaID
  83. return
  84. }
  85. //resAddMaterial 永久性素材上传返回的结果
  86. type resAddMaterial struct {
  87. util.CommonError
  88. MediaID string `json:"media_id"`
  89. URL string `json:"url"`
  90. }
  91. //AddMaterial 上传永久性素材(处理视频需要单独上传)
  92. func (material *Material) AddMaterial(mediaType MediaType, filename string) (mediaID string, url string, err error) {
  93. if mediaType == MediaTypeVideo {
  94. err = errors.New("永久视频素材上传使用 AddVideo 方法")
  95. }
  96. var accessToken string
  97. accessToken, err = material.GetAccessToken()
  98. if err != nil {
  99. return
  100. }
  101. uri := fmt.Sprintf("%s?access_token=%s&type=%s", addMaterialURL, accessToken, mediaType)
  102. var response []byte
  103. response, err = util.PostFile("media", filename, uri)
  104. if err != nil {
  105. return
  106. }
  107. var resMaterial resAddMaterial
  108. err = json.Unmarshal(response, &resMaterial)
  109. if err != nil {
  110. return
  111. }
  112. if resMaterial.ErrCode != 0 {
  113. err = fmt.Errorf("AddMaterial error : errcode=%v , errmsg=%v", resMaterial.ErrCode, resMaterial.ErrMsg)
  114. return
  115. }
  116. mediaID = resMaterial.MediaID
  117. url = resMaterial.URL
  118. return
  119. }
  120. type reqVideo struct {
  121. Title string `json:"title"`
  122. Introduction string `json:"introduction"`
  123. }
  124. //AddVideo 永久视频素材文件上传
  125. func (material *Material) AddVideo(filename, title, introduction string) (mediaID string, url string, err error) {
  126. var accessToken string
  127. accessToken, err = material.GetAccessToken()
  128. if err != nil {
  129. return
  130. }
  131. uri := fmt.Sprintf("%s?access_token=%s&type=video", addMaterialURL, accessToken)
  132. videoDesc := &reqVideo{
  133. Title: title,
  134. Introduction: introduction,
  135. }
  136. var fieldValue []byte
  137. fieldValue, err = json.Marshal(videoDesc)
  138. if err != nil {
  139. return
  140. }
  141. fields := []util.MultipartFormField{
  142. {
  143. IsFile: true,
  144. Fieldname: "media",
  145. Filename: filename,
  146. },
  147. {
  148. IsFile: false,
  149. Fieldname: "description",
  150. Value: fieldValue,
  151. },
  152. }
  153. var response []byte
  154. response, err = util.PostMultipartForm(fields, uri)
  155. if err != nil {
  156. return
  157. }
  158. var resMaterial resAddMaterial
  159. err = json.Unmarshal(response, &resMaterial)
  160. if err != nil {
  161. return
  162. }
  163. if resMaterial.ErrCode != 0 {
  164. err = fmt.Errorf("AddMaterial error : errcode=%v , errmsg=%v", resMaterial.ErrCode, resMaterial.ErrMsg)
  165. return
  166. }
  167. mediaID = resMaterial.MediaID
  168. url = resMaterial.URL
  169. return
  170. }
  171. type reqDeleteMaterial struct {
  172. MediaID string `json:"media_id"`
  173. }
  174. //DeleteMaterial 删除永久素材
  175. func (material *Material) DeleteMaterial(mediaID string) error {
  176. accessToken, err := material.GetAccessToken()
  177. if err != nil {
  178. return err
  179. }
  180. uri := fmt.Sprintf("%s?access_token=%s", delMaterialURL, accessToken)
  181. response, err := util.PostJSON(uri, reqDeleteMaterial{mediaID})
  182. if err != nil {
  183. return err
  184. }
  185. return util.DecodeWithCommonError(response, "DeleteMaterial")
  186. }