dingtalk.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. package dingtalk
  2. import (
  3. "crypto/hmac"
  4. "crypto/sha256"
  5. "encoding/base64"
  6. "encoding/json"
  7. "errors"
  8. "fmt"
  9. "io/ioutil"
  10. "net/http"
  11. "net/url"
  12. )
  13. // DingTalkAgent 用于钉钉交互
  14. type DingTalkAgent struct {
  15. AppSecret string
  16. AppKey string
  17. AccessToken string
  18. }
  19. // NewDingTalkAgent 钉钉交互构造函数
  20. func NewDingTalkAgent(appSecret, appKey string) *DingTalkAgent {
  21. return &DingTalkAgent{
  22. AppSecret: appSecret,
  23. AppKey: appKey,
  24. }
  25. }
  26. // GetUserIDByCode 通过临时code获取当前用户ID
  27. func (d *DingTalkAgent) GetUserIDByCode(code string) (string, error) {
  28. urlEndpoint, err := url.Parse("https://oapi.dingtalk.com/user/getuserinfo")
  29. if err != nil {
  30. return "", err
  31. }
  32. query := url.Values{}
  33. query.Set("access_token", d.AccessToken)
  34. query.Set("code", code)
  35. urlEndpoint.RawQuery = query.Encode()
  36. urlPath := urlEndpoint.String()
  37. resp, err := http.Get(urlPath)
  38. if err != nil {
  39. return "", err
  40. }
  41. body, err := ioutil.ReadAll(resp.Body)
  42. if err != nil {
  43. return "", err
  44. }
  45. // 解析钉钉返回数据
  46. var rdata map[string]interface{}
  47. err = json.Unmarshal(body, &rdata)
  48. if err != nil {
  49. return "", err
  50. }
  51. errcode := rdata["errcode"].(float64)
  52. if errcode != 0 {
  53. return "", errors.New(fmt.Sprintf("登录错误: %.0f, %s", errcode, rdata["errmsg"].(string)))
  54. }
  55. userid := rdata["userid"].(string)
  56. return userid, nil
  57. }
  58. // GetUserNameAndAvatarByUserID 通过userid获取当前用户姓名和头像
  59. func (d *DingTalkAgent) GetUserNameAndAvatarByUserID(userid string) (string, string, error) {
  60. urlEndpoint, err := url.Parse("https://oapi.dingtalk.com/topapi/v2/user/get")
  61. if err != nil {
  62. return "", "", err
  63. }
  64. query := url.Values{}
  65. query.Set("access_token", d.AccessToken)
  66. urlEndpoint.RawQuery = query.Encode()
  67. urlPath := urlEndpoint.String()
  68. resp, err := http.PostForm(urlPath, url.Values{"userid": {userid}})
  69. if err != nil {
  70. return "", "", err
  71. }
  72. body, err := ioutil.ReadAll(resp.Body)
  73. if err != nil {
  74. return "", "", err
  75. }
  76. // 解析钉钉返回数据
  77. var rdata map[string]interface{}
  78. err = json.Unmarshal(body, &rdata)
  79. if err != nil {
  80. return "", "", err
  81. }
  82. errcode := rdata["errcode"].(float64)
  83. if errcode != 0 {
  84. return "", "", errors.New(fmt.Sprintf("登录错误: %.0f, %s", errcode, rdata["errmsg"].(string)))
  85. }
  86. userinfo := rdata["result"].(map[string]interface{})
  87. username := userinfo["name"].(string)
  88. avatar := userinfo["avatar"].(string)
  89. return username, avatar, nil
  90. }
  91. // GetAccesstoken 获取钉钉请求Token
  92. func (d *DingTalkAgent) GetAccesstoken() (err error) {
  93. url := fmt.Sprintf("https://oapi.dingtalk.com/gettoken?appkey=%s&appsecret=%s", d.AppKey, d.AppSecret)
  94. resp, err := http.Get(url)
  95. if err != nil {
  96. return err
  97. }
  98. body, err := ioutil.ReadAll(resp.Body)
  99. if err != nil {
  100. return err
  101. }
  102. var i map[string]interface{}
  103. err = json.Unmarshal(body, &i)
  104. if err != nil {
  105. return err
  106. }
  107. if i["errcode"].(float64) == 0 {
  108. d.AccessToken = i["access_token"].(string)
  109. return nil
  110. }
  111. return errors.New("accesstoken获取错误:" + i["errmsg"].(string))
  112. }
  113. func (d *DingTalkAgent) encodeSHA256(message string) string {
  114. // 钉钉签名算法实现
  115. h := hmac.New(sha256.New, []byte(d.AppSecret))
  116. h.Write([]byte(message))
  117. sum := h.Sum(nil) // 二进制流
  118. tmpMsg := base64.StdEncoding.EncodeToString(sum)
  119. uv := url.Values{}
  120. uv.Add("0", tmpMsg)
  121. message = uv.Encode()[2:]
  122. return message
  123. }