mirror of
https://github.com/silenceper/wechat.git
synced 2026-02-04 12:52:27 +08:00
规范目录
This commit is contained in:
218
officialaccount/material/material.go
Normal file
218
officialaccount/material/material.go
Normal file
@@ -0,0 +1,218 @@
|
||||
package material
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/silenceper/wechat/officialaccount/context"
|
||||
"github.com/silenceper/wechat/util"
|
||||
)
|
||||
|
||||
const (
|
||||
addNewsURL = "https://api.weixin.qq.com/cgi-bin/material/add_news"
|
||||
addMaterialURL = "https://api.weixin.qq.com/cgi-bin/material/add_material"
|
||||
delMaterialURL = "https://api.weixin.qq.com/cgi-bin/material/del_material"
|
||||
getMaterialURL = "https://api.weixin.qq.com/cgi-bin/material/get_material"
|
||||
)
|
||||
|
||||
//Material 素材管理
|
||||
type Material struct {
|
||||
*context.Context
|
||||
}
|
||||
|
||||
//NewMaterial init
|
||||
func NewMaterial(context *context.Context) *Material {
|
||||
material := new(Material)
|
||||
material.Context = context
|
||||
return material
|
||||
}
|
||||
|
||||
//Article 永久图文素材
|
||||
type Article struct {
|
||||
Title string `json:"title"`
|
||||
ThumbMediaID string `json:"thumb_media_id"`
|
||||
ThumbURL string `json:"thumb_url"`
|
||||
Author string `json:"author"`
|
||||
Digest string `json:"digest"`
|
||||
ShowCoverPic int `json:"show_cover_pic"`
|
||||
Content string `json:"content"`
|
||||
ContentSourceURL string `json:"content_source_url"`
|
||||
URL string `json:"url"`
|
||||
DownURL string `json:"down_url"`
|
||||
}
|
||||
|
||||
// GetNews 获取/下载永久素材
|
||||
func (material *Material) GetNews(id string) ([]*Article, error) {
|
||||
accessToken, err := material.GetAccessToken()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
uri := fmt.Sprintf("%s?access_token=%s", getMaterialURL, accessToken)
|
||||
|
||||
var req struct {
|
||||
MediaID string `json:"media_id"`
|
||||
}
|
||||
req.MediaID = id
|
||||
responseBytes, err := util.PostJSON(uri, req)
|
||||
|
||||
var res struct {
|
||||
NewsItem []*Article `json:"news_item"`
|
||||
}
|
||||
err = json.Unmarshal(responseBytes, &res)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return res.NewsItem, nil
|
||||
}
|
||||
|
||||
//reqArticles 永久性图文素材请求信息
|
||||
type reqArticles struct {
|
||||
Articles []*Article `json:"articles"`
|
||||
}
|
||||
|
||||
//resArticles 永久性图文素材返回结果
|
||||
type resArticles struct {
|
||||
util.CommonError
|
||||
|
||||
MediaID string `json:"media_id"`
|
||||
}
|
||||
|
||||
//AddNews 新增永久图文素材
|
||||
func (material *Material) AddNews(articles []*Article) (mediaID string, err error) {
|
||||
req := &reqArticles{articles}
|
||||
|
||||
var accessToken string
|
||||
accessToken, err = material.GetAccessToken()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
uri := fmt.Sprintf("%s?access_token=%s", addNewsURL, accessToken)
|
||||
responseBytes, err := util.PostJSON(uri, req)
|
||||
var res resArticles
|
||||
err = json.Unmarshal(responseBytes, &res)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
mediaID = res.MediaID
|
||||
return
|
||||
}
|
||||
|
||||
//resAddMaterial 永久性素材上传返回的结果
|
||||
type resAddMaterial struct {
|
||||
util.CommonError
|
||||
|
||||
MediaID string `json:"media_id"`
|
||||
URL string `json:"url"`
|
||||
}
|
||||
|
||||
//AddMaterial 上传永久性素材(处理视频需要单独上传)
|
||||
func (material *Material) AddMaterial(mediaType MediaType, filename string) (mediaID string, url string, err error) {
|
||||
if mediaType == MediaTypeVideo {
|
||||
err = errors.New("永久视频素材上传使用 AddVideo 方法")
|
||||
}
|
||||
var accessToken string
|
||||
accessToken, err = material.GetAccessToken()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
uri := fmt.Sprintf("%s?access_token=%s&type=%s", addMaterialURL, accessToken, mediaType)
|
||||
var response []byte
|
||||
response, err = util.PostFile("media", filename, uri)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
var resMaterial resAddMaterial
|
||||
err = json.Unmarshal(response, &resMaterial)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if resMaterial.ErrCode != 0 {
|
||||
err = fmt.Errorf("AddMaterial error : errcode=%v , errmsg=%v", resMaterial.ErrCode, resMaterial.ErrMsg)
|
||||
return
|
||||
}
|
||||
mediaID = resMaterial.MediaID
|
||||
url = resMaterial.URL
|
||||
return
|
||||
}
|
||||
|
||||
type reqVideo struct {
|
||||
Title string `json:"title"`
|
||||
Introduction string `json:"introduction"`
|
||||
}
|
||||
|
||||
//AddVideo 永久视频素材文件上传
|
||||
func (material *Material) AddVideo(filename, title, introduction string) (mediaID string, url string, err error) {
|
||||
var accessToken string
|
||||
accessToken, err = material.GetAccessToken()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
uri := fmt.Sprintf("%s?access_token=%s&type=video", addMaterialURL, accessToken)
|
||||
|
||||
videoDesc := &reqVideo{
|
||||
Title: title,
|
||||
Introduction: introduction,
|
||||
}
|
||||
var fieldValue []byte
|
||||
fieldValue, err = json.Marshal(videoDesc)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
fields := []util.MultipartFormField{
|
||||
{
|
||||
IsFile: true,
|
||||
Fieldname: "media",
|
||||
Filename: filename,
|
||||
},
|
||||
{
|
||||
IsFile: false,
|
||||
Fieldname: "description",
|
||||
Value: fieldValue,
|
||||
},
|
||||
}
|
||||
|
||||
var response []byte
|
||||
response, err = util.PostMultipartForm(fields, uri)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var resMaterial resAddMaterial
|
||||
err = json.Unmarshal(response, &resMaterial)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if resMaterial.ErrCode != 0 {
|
||||
err = fmt.Errorf("AddMaterial error : errcode=%v , errmsg=%v", resMaterial.ErrCode, resMaterial.ErrMsg)
|
||||
return
|
||||
}
|
||||
mediaID = resMaterial.MediaID
|
||||
url = resMaterial.URL
|
||||
return
|
||||
}
|
||||
|
||||
type reqDeleteMaterial struct {
|
||||
MediaID string `json:"media_id"`
|
||||
}
|
||||
|
||||
//DeleteMaterial 删除永久素材
|
||||
func (material *Material) DeleteMaterial(mediaID string) error {
|
||||
accessToken, err := material.GetAccessToken()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
uri := fmt.Sprintf("%s?access_token=%s", delMaterialURL, accessToken)
|
||||
response, err := util.PostJSON(uri, reqDeleteMaterial{mediaID})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return util.DecodeWithCommonError(response, "DeleteMaterial")
|
||||
}
|
||||
110
officialaccount/material/media.go
Normal file
110
officialaccount/material/media.go
Normal file
@@ -0,0 +1,110 @@
|
||||
package material
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/silenceper/wechat/util"
|
||||
)
|
||||
|
||||
//MediaType 媒体文件类型
|
||||
type MediaType string
|
||||
|
||||
const (
|
||||
//MediaTypeImage 媒体文件:图片
|
||||
MediaTypeImage MediaType = "image"
|
||||
//MediaTypeVoice 媒体文件:声音
|
||||
MediaTypeVoice = "voice"
|
||||
//MediaTypeVideo 媒体文件:视频
|
||||
MediaTypeVideo = "video"
|
||||
//MediaTypeThumb 媒体文件:缩略图
|
||||
MediaTypeThumb = "thumb"
|
||||
)
|
||||
|
||||
const (
|
||||
mediaUploadURL = "https://api.weixin.qq.com/cgi-bin/media/upload"
|
||||
mediaUploadImageURL = "https://api.weixin.qq.com/cgi-bin/media/uploadimg"
|
||||
mediaGetURL = "https://api.weixin.qq.com/cgi-bin/media/get"
|
||||
)
|
||||
|
||||
//Media 临时素材上传返回信息
|
||||
type Media struct {
|
||||
util.CommonError
|
||||
|
||||
Type MediaType `json:"type"`
|
||||
MediaID string `json:"media_id"`
|
||||
ThumbMediaID string `json:"thumb_media_id"`
|
||||
CreatedAt int64 `json:"created_at"`
|
||||
}
|
||||
|
||||
//MediaUpload 临时素材上传
|
||||
func (material *Material) MediaUpload(mediaType MediaType, filename string) (media Media, err error) {
|
||||
var accessToken string
|
||||
accessToken, err = material.GetAccessToken()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
uri := fmt.Sprintf("%s?access_token=%s&type=%s", mediaUploadURL, accessToken, mediaType)
|
||||
var response []byte
|
||||
response, err = util.PostFile("media", filename, uri)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = json.Unmarshal(response, &media)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if media.ErrCode != 0 {
|
||||
err = fmt.Errorf("MediaUpload error : errcode=%v , errmsg=%v", media.ErrCode, media.ErrMsg)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//GetMediaURL 返回临时素材的下载地址供用户自己处理
|
||||
//NOTICE: URL 不可公开,因为含access_token 需要立即另存文件
|
||||
func (material *Material) GetMediaURL(mediaID string) (mediaURL string, err error) {
|
||||
var accessToken string
|
||||
accessToken, err = material.GetAccessToken()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
mediaURL = fmt.Sprintf("%s?access_token=%s&media_id=%s", mediaGetURL, accessToken, mediaID)
|
||||
return
|
||||
}
|
||||
|
||||
//resMediaImage 图片上传返回结果
|
||||
type resMediaImage struct {
|
||||
util.CommonError
|
||||
|
||||
URL string `json:"url"`
|
||||
}
|
||||
|
||||
//ImageUpload 图片上传
|
||||
func (material *Material) ImageUpload(filename string) (url string, err error) {
|
||||
var accessToken string
|
||||
accessToken, err = material.GetAccessToken()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
uri := fmt.Sprintf("%s?access_token=%s", mediaUploadImageURL, accessToken)
|
||||
var response []byte
|
||||
response, err = util.PostFile("media", filename, uri)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
var image resMediaImage
|
||||
err = json.Unmarshal(response, &image)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if image.ErrCode != 0 {
|
||||
err = fmt.Errorf("UploadImage error : errcode=%v , errmsg=%v", image.ErrCode, image.ErrMsg)
|
||||
return
|
||||
}
|
||||
url = image.URL
|
||||
return
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user