dingtalk.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  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. // GetUserNameByCode 通过临时code获取当前用户信息
  27. func (d *DingTalkAgent) GetUserNameByCode(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. username := rdata["name"].(string)
  56. return username, nil
  57. }
  58. // GetAccesstoken 获取钉钉请求Token
  59. func (d *DingTalkAgent) GetAccesstoken() (err error) {
  60. url := fmt.Sprintf("https://oapi.dingtalk.com/gettoken?appkey=%s&appsecret=%s", d.AppKey, d.AppSecret)
  61. resp, err := http.Get(url)
  62. if err != nil {
  63. return err
  64. }
  65. body, err := ioutil.ReadAll(resp.Body)
  66. if err != nil {
  67. return err
  68. }
  69. var i map[string]interface{}
  70. err = json.Unmarshal(body, &i)
  71. if err != nil {
  72. return err
  73. }
  74. if i["errcode"].(float64) == 0 {
  75. d.AccessToken = i["access_token"].(string)
  76. return nil
  77. }
  78. return errors.New("accesstoken获取错误:" + i["errmsg"].(string))
  79. }
  80. func (d *DingTalkAgent) encodeSHA256(message string) string {
  81. // 钉钉签名算法实现
  82. h := hmac.New(sha256.New, []byte(d.AppSecret))
  83. h.Write([]byte(message))
  84. sum := h.Sum(nil) // 二进制流
  85. tmpMsg := base64.StdEncoding.EncodeToString(sum)
  86. uv := url.Values{}
  87. uv.Add("0", tmpMsg)
  88. message = uv.Encode()[2:]
  89. return message
  90. }