template.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  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. templateSendURL = "https://api.weixin.qq.com/cgi-bin/message/template/send"
  10. templateListURL = "https://api.weixin.qq.com/cgi-bin/template/get_all_private_template"
  11. )
  12. //Template 模板消息
  13. type Template struct {
  14. *context.Context
  15. }
  16. //NewTemplate 实例化
  17. func NewTemplate(context *context.Context) *Template {
  18. tpl := new(Template)
  19. tpl.Context = context
  20. return tpl
  21. }
  22. //TemplateMessage 发送的模板消息内容
  23. type TemplateMessage struct {
  24. ToUser string `json:"touser"` // 必须, 接受者OpenID
  25. TemplateID string `json:"template_id"` // 必须, 模版ID
  26. URL string `json:"url,omitempty"` // 可选, 用户点击后跳转的URL, 该URL必须处于开发者在公众平台网站中设置的域中
  27. Color string `json:"color,omitempty"` // 可选, 整个消息的颜色, 可以不设置
  28. Data map[string]*TemplateDataItem `json:"data"` // 必须, 模板数据
  29. MiniProgram struct {
  30. AppID string `json:"appid"` //所需跳转到的小程序appid(该小程序appid必须与发模板消息的公众号是绑定关联关系)
  31. PagePath string `json:"pagepath"` //所需跳转到小程序的具体页面路径,支持带参数,(示例index?foo=bar)
  32. } `json:"miniprogram"` //可选,跳转至小程序地址
  33. }
  34. //TemplateDataItem 模版内某个 .DATA 的值
  35. type TemplateDataItem struct {
  36. Value string `json:"value"`
  37. Color string `json:"color,omitempty"`
  38. }
  39. type resTemplateSend struct {
  40. util.CommonError
  41. MsgID int64 `json:"msgid"`
  42. }
  43. //Send 发送模板消息
  44. func (tpl *Template) Send(msg *TemplateMessage) (msgID int64, err error) {
  45. var accessToken string
  46. accessToken, err = tpl.GetAccessToken()
  47. if err != nil {
  48. return
  49. }
  50. uri := fmt.Sprintf("%s?access_token=%s", templateSendURL, accessToken)
  51. response, err := util.PostJSON(uri, msg)
  52. if err != nil {
  53. return
  54. }
  55. var result resTemplateSend
  56. err = json.Unmarshal(response, &result)
  57. if err != nil {
  58. return
  59. }
  60. if result.ErrCode != 0 {
  61. err = fmt.Errorf("template msg send error : errcode=%v , errmsg=%v", result.ErrCode, result.ErrMsg)
  62. return
  63. }
  64. msgID = result.MsgID
  65. return
  66. }
  67. // TemplateItem 模板消息.
  68. type TemplateItem struct {
  69. TemplateID string `json:"template_id"`
  70. Title string `json:"title"`
  71. PrimaryIndustry string `json:"primary_industry"`
  72. DeputyIndustry string `json:"deputy_industry"`
  73. Content string `json:"content"`
  74. Example string `json:"example"`
  75. }
  76. type resTemplateList struct {
  77. util.CommonError
  78. TemplateList []*TemplateItem `json:"template_list"`
  79. }
  80. //List 获取模板列表
  81. func (tpl *Template) List() (templateList []*TemplateItem, err error) {
  82. var accessToken string
  83. accessToken, err = tpl.GetAccessToken()
  84. if err != nil {
  85. return
  86. }
  87. uri := fmt.Sprintf("%s?access_token=%s", templateListURL, accessToken)
  88. var response []byte
  89. response, err = util.HTTPGet(uri)
  90. if err != nil {
  91. return
  92. }
  93. var res resTemplateList
  94. err = util.DecodeWithError(response, &res, "ListTemplate")
  95. if err != nil {
  96. return
  97. }
  98. templateList = res.TemplateList
  99. return
  100. }