customer_message.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. package message
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "github.com/silenceper/wechat/v2/officialaccount/context"
  6. "github.com/silenceper/wechat/v2/util"
  7. )
  8. const (
  9. customerSendMessage = "https://api.weixin.qq.com/cgi-bin/message/custom/send"
  10. )
  11. // Manager 消息管理者,可以发送消息
  12. type Manager struct {
  13. *context.Context
  14. }
  15. // NewMessageManager 实例化消息管理者
  16. func NewMessageManager(context *context.Context) *Manager {
  17. return &Manager{
  18. context,
  19. }
  20. }
  21. // CustomerMessage 客服消息
  22. type CustomerMessage struct {
  23. ToUser string `json:"touser"` // 接受者 OpenID
  24. Msgtype MsgType `json:"msgtype"` // 客服消息类型
  25. Text *MediaText `json:"text,omitempty"` // 可选
  26. Image *MediaResource `json:"image,omitempty"` // 可选
  27. Voice *MediaResource `json:"voice,omitempty"` // 可选
  28. Video *MediaVideo `json:"video,omitempty"` // 可选
  29. Music *MediaMusic `json:"music,omitempty"` // 可选
  30. News *MediaNews `json:"news,omitempty"` // 可选
  31. Mpnews *MediaResource `json:"mpnews,omitempty"` // 可选
  32. Wxcard *MediaWxcard `json:"wxcard,omitempty"` // 可选
  33. Msgmenu *MediaMsgmenu `json:"msgmenu,omitempty"` // 可选
  34. Miniprogrampage *MediaMiniprogrampage `json:"miniprogrampage,omitempty"` // 可选
  35. Mpnewsarticle *MediaArticle `json:"mpnewsarticle,omitempty"` // 可选
  36. }
  37. // NewCustomerTextMessage 文本消息结构体构造方法
  38. func NewCustomerTextMessage(toUser, text string) *CustomerMessage {
  39. return &CustomerMessage{
  40. ToUser: toUser,
  41. Msgtype: MsgTypeText,
  42. Text: &MediaText{
  43. text,
  44. },
  45. }
  46. }
  47. // NewCustomerImgMessage 图片消息的构造方法
  48. func NewCustomerImgMessage(toUser, mediaID string) *CustomerMessage {
  49. return &CustomerMessage{
  50. ToUser: toUser,
  51. Msgtype: MsgTypeImage,
  52. Image: &MediaResource{
  53. mediaID,
  54. },
  55. }
  56. }
  57. // NewCustomerVoiceMessage 语音消息的构造方法
  58. func NewCustomerVoiceMessage(toUser, mediaID string) *CustomerMessage {
  59. return &CustomerMessage{
  60. ToUser: toUser,
  61. Msgtype: MsgTypeVoice,
  62. Voice: &MediaResource{
  63. mediaID,
  64. },
  65. }
  66. }
  67. // NewCustomerMiniprogrampageMessage 小程序卡片消息的构造方法
  68. func NewCustomerMiniprogrampageMessage(toUser, title, appID, pagePath, thumbMediaID string) *CustomerMessage {
  69. return &CustomerMessage{
  70. ToUser: toUser,
  71. Msgtype: MsgTypeMiniprogrampage,
  72. Miniprogrampage: &MediaMiniprogrampage{
  73. Title: title,
  74. AppID: appID,
  75. Pagepath: pagePath,
  76. ThumbMediaID: thumbMediaID,
  77. },
  78. }
  79. }
  80. // MediaText 文本消息的文字
  81. type MediaText struct {
  82. Content string `json:"content"`
  83. }
  84. // MediaResource 消息使用的永久素材 id
  85. type MediaResource struct {
  86. MediaID string `json:"media_id"`
  87. }
  88. // MediaArticle 消息使用的已发布文章 id
  89. type MediaArticle struct {
  90. ArticleID string `json:"article_id"`
  91. }
  92. // MediaVideo 视频消息包含的内容
  93. type MediaVideo struct {
  94. MediaID string `json:"media_id"`
  95. ThumbMediaID string `json:"thumb_media_id"`
  96. Title string `json:"title"`
  97. Description string `json:"description"`
  98. }
  99. // MediaMusic 音乐消息包括的内容
  100. type MediaMusic struct {
  101. Title string `json:"title"`
  102. Description string `json:"description"`
  103. Musicurl string `json:"musicurl"`
  104. Hqmusicurl string `json:"hqmusicurl"`
  105. ThumbMediaID string `json:"thumb_media_id"`
  106. }
  107. // MediaNews 图文消息的内容
  108. type MediaNews struct {
  109. Articles []MediaArticles `json:"articles"`
  110. }
  111. // MediaArticles 图文消息的内容的文章列表中的单独一条
  112. type MediaArticles struct {
  113. Title string `json:"title"`
  114. Description string `json:"description"`
  115. URL string `json:"url"`
  116. Picurl string `json:"picurl"`
  117. }
  118. // MediaMsgmenu 菜单消息的内容
  119. type MediaMsgmenu struct {
  120. HeadContent string `json:"head_content"`
  121. List []MsgmenuItem `json:"list"`
  122. TailContent string `json:"tail_content"`
  123. }
  124. // MsgmenuItem 菜单消息的菜单按钮
  125. type MsgmenuItem struct {
  126. ID string `json:"id"`
  127. Content string `json:"content"`
  128. }
  129. // MediaWxcard 卡券的 id
  130. type MediaWxcard struct {
  131. CardID string `json:"card_id"`
  132. }
  133. // MediaMiniprogrampage 小程序消息
  134. type MediaMiniprogrampage struct {
  135. Title string `json:"title"`
  136. AppID string `json:"appid"`
  137. Pagepath string `json:"pagepath"`
  138. ThumbMediaID string `json:"thumb_media_id"`
  139. }
  140. // Send 发送客服消息
  141. func (manager *Manager) Send(msg *CustomerMessage) error {
  142. accessToken, err := manager.Context.GetAccessToken()
  143. if err != nil {
  144. return err
  145. }
  146. uri := fmt.Sprintf("%s?access_token=%s", customerSendMessage, accessToken)
  147. response, err := util.PostJSON(uri, msg)
  148. if err != nil {
  149. return err
  150. }
  151. var result util.CommonError
  152. err = json.Unmarshal(response, &result)
  153. if err != nil {
  154. return err
  155. }
  156. if result.ErrCode != 0 {
  157. err = fmt.Errorf("customer msg send error : errcode=%v , errmsg=%v", result.ErrCode, result.ErrMsg)
  158. return err
  159. }
  160. return nil
  161. }