mirror of
https://github.com/silenceper/wechat.git
synced 2026-02-04 12:52:27 +08:00
群发消息接口 (#259)
* 添加TODO:待完善接口 * 【模板消息】将message.DataItem改为message.TemplateDataItem * 【群发消息】基本框架 * 群发消息-基本方法 * fix golint * fix:SendWxCard log
This commit is contained in:
279
officialaccount/broadcast/broadcast.go
Normal file
279
officialaccount/broadcast/broadcast.go
Normal file
@@ -0,0 +1,279 @@
|
||||
package broadcast
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/silenceper/wechat/v2/officialaccount/context"
|
||||
"github.com/silenceper/wechat/v2/util"
|
||||
)
|
||||
|
||||
const (
|
||||
sendURLByTag = "https://api.weixin.qq.com/cgi-bin/message/mass/sendall"
|
||||
sendURLByOpenID = "https://api.weixin.qq.com/cgi-bin/message/mass/send"
|
||||
deleteSendURL ="https://api.weixin.qq.com/cgi-bin/message/mass/delete"
|
||||
)
|
||||
|
||||
//MsgType 发送消息类型
|
||||
type MsgType string
|
||||
|
||||
const (
|
||||
//MsgTypeNews 图文消息
|
||||
MsgTypeNews MsgType = "mpnews"
|
||||
//MsgTypeText 文本
|
||||
MsgTypeText MsgType = "text"
|
||||
//MsgTypeVoice 语音/音频
|
||||
MsgTypeVoice MsgType = "voice"
|
||||
//MsgTypeImage 图片
|
||||
MsgTypeImage MsgType = "image"
|
||||
//MsgTypeVideo 视频
|
||||
MsgTypeVideo MsgType = "mpvideo"
|
||||
//MsgTypeWxCard 卡券
|
||||
MsgTypeWxCard MsgType = "wxcard"
|
||||
)
|
||||
|
||||
//Broadcast 群发消息
|
||||
type Broadcast struct {
|
||||
*context.Context
|
||||
}
|
||||
|
||||
//NewBroadcast new
|
||||
func NewBroadcast(ctx *context.Context) *Broadcast {
|
||||
return &Broadcast{ctx}
|
||||
}
|
||||
|
||||
//User 发送的用户
|
||||
type User struct {
|
||||
TagID int64
|
||||
OpenID []string
|
||||
}
|
||||
|
||||
//Result 群发返回结果
|
||||
type Result struct {
|
||||
util.CommonError
|
||||
MsgID int64 `json:"msg_id"`
|
||||
MsgDataID int64 `json:"msg_data_id"`
|
||||
}
|
||||
|
||||
//sendRequest 发送请求的数据
|
||||
type sendRequest struct {
|
||||
//根据tag获全部发送
|
||||
Filter map[string]interface{} `json:"filter,omitempty"`
|
||||
//根据OpenID发送
|
||||
ToUser interface{} `json:"touser,omitempty"`
|
||||
//发送文本
|
||||
Text map[string]interface{} `json:"text,omitempty"`
|
||||
//发送图文消息
|
||||
Mpnews map[string]interface{} `json:"mpnews,omitempty"`
|
||||
//发送语音
|
||||
Voice map[string]interface{} `json:"voice,omitempty"`
|
||||
//发送图片
|
||||
Images *Image `json:"images,omitempty"`
|
||||
//发送卡券
|
||||
WxCard map[string]interface{} `json:"wxcard,omitempty"`
|
||||
MsgType MsgType `json:"msgtype"`
|
||||
SendIgnoreReprint int32 `json:"send_ignore_reprint,omitempty"`
|
||||
}
|
||||
|
||||
//Image 发送图片
|
||||
type Image struct{
|
||||
MediaIDs []string `json:"media_ids"`
|
||||
Recommend string `json:"recommend"`
|
||||
NeedOpenComment int32 `json:"need_open_comment"`
|
||||
OnlyFansCanComment int32 `json:"only_fans_can_comment"`
|
||||
}
|
||||
|
||||
//SendText 群发文本
|
||||
//user 为nil,表示全员发送
|
||||
//&User{TagID:2} 根据tag发送
|
||||
//&User{OpenID:[]string("xxx","xxx")} 根据openid发送
|
||||
func (broadcast *Broadcast) SendText(user *User, content string) (*Result, error) {
|
||||
ak, err := broadcast.GetAccessToken()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req := &sendRequest{
|
||||
ToUser: nil,
|
||||
MsgType: MsgTypeText,
|
||||
}
|
||||
req.Text=map[string]interface{}{
|
||||
"content":content,
|
||||
}
|
||||
req,sendURL:=broadcast.chooseTagOrOpenID(user,req)
|
||||
url := fmt.Sprintf("%s?access_token=%s", sendURL, ak)
|
||||
data, err := util.PostJSON(url, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res := &Result{}
|
||||
err = util.DecodeWithError(data, res, "SendText")
|
||||
return res, err
|
||||
}
|
||||
|
||||
//SendNews 发送图文
|
||||
func (broadcast *Broadcast) SendNews(user *User, mediaID string,ignoreReprint bool) (*Result, error) {
|
||||
ak, err := broadcast.GetAccessToken()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req := &sendRequest{
|
||||
ToUser: nil,
|
||||
MsgType: MsgTypeNews,
|
||||
}
|
||||
if ignoreReprint{
|
||||
req.SendIgnoreReprint=1
|
||||
}
|
||||
req.Mpnews=map[string]interface{}{
|
||||
"media_id":mediaID,
|
||||
}
|
||||
req,sendURL:=broadcast.chooseTagOrOpenID(user,req)
|
||||
url := fmt.Sprintf("%s?access_token=%s", sendURL, ak)
|
||||
data, err := util.PostJSON(url, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res := &Result{}
|
||||
err = util.DecodeWithError(data, res, "SendNews")
|
||||
return res, err
|
||||
}
|
||||
|
||||
|
||||
//SendVoice 发送语音
|
||||
func (broadcast *Broadcast) SendVoice(user *User, mediaID string) (*Result, error) {
|
||||
ak, err := broadcast.GetAccessToken()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req := &sendRequest{
|
||||
ToUser: nil,
|
||||
MsgType: MsgTypeVoice,
|
||||
}
|
||||
req.Voice=map[string]interface{}{
|
||||
"media_id":mediaID,
|
||||
}
|
||||
req,sendURL:=broadcast.chooseTagOrOpenID(user,req)
|
||||
url := fmt.Sprintf("%s?access_token=%s", sendURL, ak)
|
||||
data, err := util.PostJSON(url, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res := &Result{}
|
||||
err = util.DecodeWithError(data, res, "SendVoice")
|
||||
return res, err
|
||||
}
|
||||
|
||||
//SendImage 发送图片
|
||||
func (broadcast *Broadcast) SendImage(user *User, images *Image) (*Result, error) {
|
||||
ak, err := broadcast.GetAccessToken()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req := &sendRequest{
|
||||
ToUser: nil,
|
||||
MsgType: MsgTypeImage,
|
||||
}
|
||||
req.Images=images
|
||||
req,sendURL:=broadcast.chooseTagOrOpenID(user,req)
|
||||
url := fmt.Sprintf("%s?access_token=%s", sendURL, ak)
|
||||
data, err := util.PostJSON(url, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res := &Result{}
|
||||
err = util.DecodeWithError(data, res, "SendImage")
|
||||
return res, err
|
||||
}
|
||||
|
||||
|
||||
//SendVideo 发送视频
|
||||
func (broadcast *Broadcast) SendVideo(user *User, mediaID string,title,description string) (*Result, error) {
|
||||
ak, err := broadcast.GetAccessToken()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req := &sendRequest{
|
||||
ToUser: nil,
|
||||
MsgType: MsgTypeVideo,
|
||||
}
|
||||
req.Voice=map[string]interface{}{
|
||||
"media_id":mediaID,
|
||||
"title":title,
|
||||
"description":description,
|
||||
}
|
||||
req,sendURL:=broadcast.chooseTagOrOpenID(user,req)
|
||||
url := fmt.Sprintf("%s?access_token=%s", sendURL, ak)
|
||||
data, err := util.PostJSON(url, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res := &Result{}
|
||||
err = util.DecodeWithError(data, res, "SendVideo")
|
||||
return res, err
|
||||
}
|
||||
|
||||
|
||||
//SendWxCard 发送卡券
|
||||
func (broadcast *Broadcast) SendWxCard(user *User, cardID string) (*Result, error) {
|
||||
ak, err := broadcast.GetAccessToken()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req := &sendRequest{
|
||||
ToUser: nil,
|
||||
MsgType: MsgTypeWxCard,
|
||||
}
|
||||
req.WxCard=map[string]interface{}{
|
||||
"card_id":cardID,
|
||||
}
|
||||
req,sendURL:=broadcast.chooseTagOrOpenID(user,req)
|
||||
url := fmt.Sprintf("%s?access_token=%s", sendURL, ak)
|
||||
data, err := util.PostJSON(url, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res := &Result{}
|
||||
err = util.DecodeWithError(data, res, "SendWxCard")
|
||||
return res, err
|
||||
}
|
||||
//Delete 删除群发消息
|
||||
func (broadcast *Broadcast) Delete(msgID int64 ,articleIDx int64) error {
|
||||
ak, err := broadcast.GetAccessToken()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req := map[string]interface{}{
|
||||
"msg_id": msgID,
|
||||
"article_idx": articleIDx,
|
||||
}
|
||||
url := fmt.Sprintf("%s?access_token=%s", deleteSendURL, ak)
|
||||
data, err := util.PostJSON(url, req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return util.DecodeWithCommonError(data, "Delete")
|
||||
}
|
||||
|
||||
|
||||
//TODO 发送预览,群发消息状态,发送速度
|
||||
|
||||
func (broadcast *Broadcast) chooseTagOrOpenID(user *User,req *sendRequest)(ret *sendRequest,url string){
|
||||
sendURL:=""
|
||||
if user == nil {
|
||||
req.Filter=map[string]interface{}{
|
||||
"is_to_all":true,
|
||||
}
|
||||
sendURL=sendURLByTag
|
||||
} else {
|
||||
if user.TagID != 0 {
|
||||
req.Filter=map[string]interface{}{
|
||||
"is_to_all":false,
|
||||
"tag_id":user.TagID,
|
||||
}
|
||||
sendURL=sendURLByTag
|
||||
}
|
||||
if len(user.OpenID) != 0 {
|
||||
req.ToUser = user.OpenID
|
||||
sendURL=sendURLByOpenID
|
||||
}
|
||||
}
|
||||
return req,sendURL
|
||||
}
|
||||
Reference in New Issue
Block a user