| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279 |
- 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
- }
|