dingding/main.go

177 lines
4.5 KiB
Go
Raw Normal View History

2021-11-17 03:17:31 +00:00
package main
import (
"crypto/hmac"
"crypto/sha256"
"encoding/base64"
"encoding/json"
"errors"
"flag"
"fmt"
"io/ioutil"
"log"
"net/http"
"net/url"
"strconv"
"strings"
"time"
"github.com/sirupsen/logrus"
"github.com/spf13/viper"
"myschools.me/wyh/dingd.git/model"
)
const (
AuthCode = "bdbc74ebecaf30259895b145d3c48d35"
Appkey = "dinguipztmzpv8sog933"
AppSecret = "kUYbKHxNixdMhTmW6IrdTE-yVnWfQLs1C7RQIAsrlwz8BYlVmceFs-3JRBmU32rQ"
)
func main() {
cf := flag.String("config", "config.yaml", "file of config")
flag.Parse()
viper.SetConfigFile(*cf)
if err := viper.ReadInConfig(); err != nil {
logrus.WithFields(logrus.Fields{
"func": "main",
}).Errorf("%s", err.Error())
return
}
timestamp := strconv.FormatInt(time.Now().UnixNano()/1000000, 10) // 毫秒时间戳
signature := EncodeSHA256(timestamp, AppSecret) // 加密签名 加密算法见我另一个函数
url := fmt.Sprintf("https://oapi.dingtalk.com/sns/getuserinfo_bycode?accessKey=%s&timestamp=%s&signature=%s",
Appkey, timestamp, signature)
p := struct {
Tmp_auth_code string `json:"tmp_auth_code"`
}{AuthCode} // post数据
p1, _ := json.Marshal(p)
p2 := string(p1)
p3 := strings.NewReader(p2) //构建post数据
resp, err := http.Post(url, "application/json;charset=UTF-8", p3)
if err != nil {
log.Fatal(err)
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
i := make(map[string]interface{})
_ = json.Unmarshal(body, &i)
fmt.Println(i)
errcode := i["errcode"].(float64)
if errcode != 0 {
log.Fatal("errcode ==0")
}
unionid := i["user_info"].(map[string]interface{})["unionid"].(string)
accesstoken, err := GetAccesstoken()
if err != nil {
log.Fatal(err)
}
userid, err := GetUseridByUnionid(accesstoken, unionid)
if err != nil {
log.Fatal(err)
}
userinfo, err := GETUserInfo(accesstoken, userid)
if err != nil {
log.Fatal(err)
}
fmt.Println(userinfo)
}
func EncodeSHA256(message, secret string) string {
// 钉钉签名算法实现
h := hmac.New(sha256.New, []byte(secret))
h.Write([]byte(message))
sum := h.Sum(nil) // 二进制流
message1 := base64.StdEncoding.EncodeToString(sum)
uv := url.Values{}
uv.Add("0", message1)
message2 := uv.Encode()[2:]
return message2
}
func GetAccesstoken() (accesstoken string, err error) {
var resp *http.Response
//var AppKey, AppSecret string
//获取access_token
url := fmt.Sprintf("https://oapi.dingtalk.com/gettoken?appkey=%s&appsecret=%s", Appkey, AppSecret)
resp, err = http.Get(url)
if err != nil {
return "", err
}
//fmt.Println(resp)
//fmt.Println(err)
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return "", err
}
var i map[string]interface{}
_ = json.Unmarshal(body, &i)
//fmt.Println(1, string(body), i["errmsg"])
if i["errcode"].(float64) == 0 {
return i["access_token"].(string), nil
}
return "", errors.New("accesstoken获取错误" + i["errmsg"].(string))
}
func GetUseridByUnionid(accesstoken, unionid string) (userid string, err error) {
//根据unionid获取userid
var resp *http.Response
url := fmt.Sprintf("https://oapi.dingtalk.com/topapi/user/getbyunionid?access_token=%s", accesstoken)
p := struct {
Unionid string `json:"unionid"`
}{unionid} // post数据
p1, _ := json.Marshal(p)
p2 := string(p1)
p3 := strings.NewReader(p2) //构建post数据
resp, err = http.Post(url, "application/json;charset=UTF-8", p3)
if err != nil {
return "", nil
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return "", nil
}
//fmt.Println(1, string(body), err)
var i map[string]interface{}
_ = json.Unmarshal(body, &i)
errcode := i["errcode"].(float64)
if errcode != 0 {
return "", fmt.Errorf("userid获取错误: %f, %s", errcode, i["errmsg"].(string))
}
return i["result"].(map[string]interface{})["userid"].(string), nil
}
func GETUserInfo(accesstoken, userid string) (*model.DingtalkUserInfoResponse, error) {
var resp *http.Response
url := fmt.Sprintf("https://oapi.dingtalk.com/topapi/v2/user/get?access_token=%s", accesstoken)
p := struct {
UserID string `json:"userid"`
Language string `json:"language"`
}{
UserID: userid,
Language: "zh_CN",
}
p1, _ := json.Marshal(p)
p2 := string(p1)
p3 := strings.NewReader(p2) //构建post数据
resp, err := http.Post(url, "application/json;charset=UTF-8", p3)
if err != nil {
return nil, err
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
userinfo := &model.DingtalkUserInfoResponse{}
_ = json.Unmarshal(body, userinfo)
errcode := userinfo.ErrCode
if errcode != 0 {
log.Fatal("errcode!=0")
}
return userinfo, nil
}