customer_message.go 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  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. }
  36. // NewCustomerTextMessage 文本消息结构体构造方法
  37. func NewCustomerTextMessage(toUser, text string) *CustomerMessage {
  38. return &CustomerMessage{
  39. ToUser: toUser,
  40. Msgtype: MsgTypeText,
  41. Text: &MediaText{
  42. text,
  43. },
  44. }
  45. }
  46. // NewCustomerImgMessage 图片消息的构造方法
  47. func NewCustomerImgMessage(toUser, mediaID string) *CustomerMessage {
  48. return &CustomerMessage{
  49. ToUser: toUser,
  50. Msgtype: MsgTypeImage,
  51. Image: &MediaResource{
  52. mediaID,
  53. },
  54. }
  55. }
  56. // NewCustomerVoiceMessage 语音消息的构造方法
  57. func NewCustomerVoiceMessage(toUser, mediaID string) *CustomerMessage {
  58. return &CustomerMessage{
  59. ToUser: toUser,
  60. Msgtype: MsgTypeVoice,
  61. Voice: &MediaResource{
  62. mediaID,
  63. },
  64. }
  65. }
  66. // NewCustomerMiniprogrampageMessage 小程序卡片消息的构造方法
  67. func NewCustomerMiniprogrampageMessage(toUser, title, appID, pagePath, thumbMediaID string) *CustomerMessage {
  68. return &CustomerMessage{
  69. ToUser: toUser,
  70. Msgtype: MsgTypeMiniprogrampage,
  71. Miniprogrampage: &MediaMiniprogrampage{
  72. Title: title,
  73. AppID: appID,
  74. Pagepath: pagePath,
  75. ThumbMediaID: thumbMediaID,
  76. },
  77. }
  78. }
  79. // MediaText 文本消息的文字
  80. type MediaText struct {
  81. Content string `json:"content"`
  82. }
  83. // MediaResource 消息使用的永久素材id
  84. type MediaResource struct {
  85. MediaID string `json:"media_id"`
  86. }
  87. // MediaVideo 视频消息包含的内容
  88. type MediaVideo struct {
  89. MediaID string `json:"media_id"`
  90. ThumbMediaID string `json:"thumb_media_id"`
  91. Title string `json:"title"`
  92. Description string `json:"description"`
  93. }
  94. // MediaMusic 音乐消息包括的内容
  95. type MediaMusic struct {
  96. Title string `json:"title"`
  97. Description string `json:"description"`
  98. Musicurl string `json:"musicurl"`
  99. Hqmusicurl string `json:"hqmusicurl"`
  100. ThumbMediaID string `json:"thumb_media_id"`
  101. }
  102. // MediaNews 图文消息的内容
  103. type MediaNews struct {
  104. Articles []MediaArticles `json:"articles"`
  105. }
  106. // MediaArticles 图文消息的内容的文章列表中的单独一条
  107. type MediaArticles struct {
  108. Title string `json:"title"`
  109. Description string `json:"description"`
  110. URL string `json:"url"`
  111. Picurl string `json:"picurl"`
  112. }
  113. // MediaMsgmenu 菜单消息的内容
  114. type MediaMsgmenu struct {
  115. HeadContent string `json:"head_content"`
  116. List []MsgmenuItem `json:"list"`
  117. TailContent string `json:"tail_content"`
  118. }
  119. // MsgmenuItem 菜单消息的菜单按钮
  120. type MsgmenuItem struct {
  121. ID string `json:"id"`
  122. Content string `json:"content"`
  123. }
  124. // MediaWxcard 卡券的id
  125. type MediaWxcard struct {
  126. CardID string `json:"card_id"`
  127. }
  128. // MediaMiniprogrampage 小程序消息
  129. type MediaMiniprogrampage struct {
  130. Title string `json:"title"`
  131. AppID string `json:"appid"`
  132. Pagepath string `json:"pagepath"`
  133. ThumbMediaID string `json:"thumb_media_id"`
  134. }
  135. // Send 发送客服消息
  136. func (manager *Manager) Send(msg *CustomerMessage) error {
  137. accessToken, err := manager.Context.GetAccessToken()
  138. if err != nil {
  139. return err
  140. }
  141. uri := fmt.Sprintf("%s?access_token=%s", customerSendMessage, accessToken)
  142. response, err := util.PostJSON(uri, msg)
  143. if err != nil {
  144. return err
  145. }
  146. var result util.CommonError
  147. err = json.Unmarshal(response, &result)
  148. if err != nil {
  149. return err
  150. }
  151. if result.ErrCode != 0 {
  152. err = fmt.Errorf("customer msg send error : errcode=%v , errmsg=%v", result.ErrCode, result.ErrMsg)
  153. return err
  154. }
  155. return nil
  156. }