qr.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. package qr
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "reflect"
  6. "time"
  7. "github.com/silenceper/wechat/context"
  8. "github.com/silenceper/wechat/util"
  9. )
  10. const (
  11. qrCreateURL = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=%s"
  12. getQRImgURL = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=%s"
  13. )
  14. const (
  15. actionID = "QR_SCENE"
  16. actionStr = "QR_STR_SCENE"
  17. actionLimitID = "QR_LIMIT_SCENE"
  18. actionLimitStr = "QR_LIMIT_STR_SCENE"
  19. )
  20. // QR 二维码
  21. type QR struct {
  22. *context.Context
  23. }
  24. //NewQR 二维码实例
  25. func NewQR(context *context.Context) *QR {
  26. q := new(QR)
  27. q.Context = context
  28. return q
  29. }
  30. // Request 临时二维码
  31. type Request struct {
  32. ExpireSeconds int64 `json:"expire_seconds,omitempty"`
  33. ActionName string `json:"action_name"`
  34. ActionInfo struct {
  35. Scene struct {
  36. SceneStr string `json:"scene_str,omitempty"`
  37. SceneID int `json:"scene_id,omitempty"`
  38. } `json:"scene"`
  39. } `json:"action_info"`
  40. }
  41. // Ticket 二维码ticket
  42. type Ticket struct {
  43. util.CommonError `json:",inline"`
  44. Ticket string `json:"ticket"`
  45. ExpireSeconds int64 `json:"expire_seconds"`
  46. URL string `json:"url"`
  47. }
  48. // GetQRTicket 获取二维码 Ticket
  49. func (q *QR) GetQRTicket(tq *Request) (t *Ticket, err error) {
  50. accessToken, err := q.GetAccessToken()
  51. if err != nil {
  52. return
  53. }
  54. uri := fmt.Sprintf(qrCreateURL, accessToken)
  55. response, err := util.PostJSON(uri, tq)
  56. if err != nil {
  57. err = fmt.Errorf("get qr ticket failed, %s", err)
  58. return
  59. }
  60. t = new(Ticket)
  61. err = json.Unmarshal(response, &t)
  62. if err != nil {
  63. return
  64. }
  65. return
  66. }
  67. // ShowQRCode 通过ticket换取二维码
  68. func ShowQRCode(tk *Ticket) string {
  69. return fmt.Sprintf(getQRImgURL, tk.Ticket)
  70. }
  71. // NewTmpQrRequest 新建临时二维码请求实例
  72. func NewTmpQrRequest(exp time.Duration, scene interface{}) *Request {
  73. tq := &Request{
  74. ExpireSeconds: int64(exp.Seconds()),
  75. }
  76. switch reflect.ValueOf(scene).Kind() {
  77. case reflect.String:
  78. tq.ActionName = actionStr
  79. tq.ActionInfo.Scene.SceneStr = scene.(string)
  80. case reflect.Int, reflect.Int8, reflect.Int16,
  81. reflect.Int32, reflect.Int64,
  82. reflect.Uint, reflect.Uint8, reflect.Uint16,
  83. reflect.Uint32, reflect.Uint64:
  84. tq.ActionName = actionID
  85. tq.ActionInfo.Scene.SceneID = scene.(int)
  86. }
  87. return tq
  88. }
  89. // NewLimitQrRequest 新建永久二维码请求实例
  90. func NewLimitQrRequest(scene interface{}) *Request {
  91. tq := &Request{}
  92. switch reflect.ValueOf(scene).Kind() {
  93. case reflect.String:
  94. tq.ActionName = actionLimitStr
  95. tq.ActionInfo.Scene.SceneStr = scene.(string)
  96. case reflect.Int, reflect.Int8, reflect.Int16,
  97. reflect.Int32, reflect.Int64,
  98. reflect.Uint, reflect.Uint8, reflect.Uint16,
  99. reflect.Uint32, reflect.Uint64:
  100. tq.ActionName = actionLimitID
  101. tq.ActionInfo.Scene.SceneID = scene.(int)
  102. }
  103. return tq
  104. }