init
This commit is contained in:
commit
829259f72f
|
|
@ -0,0 +1,2 @@
|
|||
*.sum
|
||||
*.yaml
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
// 使用 IntelliSense 了解相关属性。
|
||||
// 悬停以查看现有属性的描述。
|
||||
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Launch Package",
|
||||
"type": "go",
|
||||
"request": "launch",
|
||||
"mode": "auto",
|
||||
"program": "E://dingd"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
package dingtalk
|
||||
|
||||
import (
|
||||
"github.com/hugozhu/godingtalk"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
var _client *godingtalk.DingTalkClient
|
||||
var _appkey = viper.GetString("app.AppKey")
|
||||
var _appsecret = viper.GetString("app.AppSecret")
|
||||
var _agentid = viper.GetString("app.AgentId")
|
||||
|
||||
//getDingtalkClient 获取钉钉client
|
||||
func getDingtalkClient(appkey *string, appsecret *string, agentid *string) *godingtalk.DingTalkClient {
|
||||
if _client != nil {
|
||||
_client.RefreshAccessToken()
|
||||
return _client
|
||||
}
|
||||
_client = godingtalk.NewDingTalkClient(*appkey, *appsecret)
|
||||
_client.AgentID = *agentid
|
||||
_client.RefreshAccessToken()
|
||||
return _client
|
||||
}
|
||||
|
||||
func GET() *godingtalk.DingTalkClient {
|
||||
return getDingtalkClient(&_appkey, &_appsecret, &_agentid)
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
module myschools.me/wyh/dingd.git
|
||||
|
||||
go 1.17
|
||||
|
||||
require (
|
||||
github.com/hugozhu/godingtalk v1.0.6
|
||||
github.com/sirupsen/logrus v1.8.1
|
||||
github.com/spf13/viper v1.9.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/fsnotify/fsnotify v1.5.1 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/magiconair/properties v1.8.5 // indirect
|
||||
github.com/mitchellh/mapstructure v1.4.2 // indirect
|
||||
github.com/pelletier/go-toml v1.9.4 // indirect
|
||||
github.com/spf13/afero v1.6.0 // indirect
|
||||
github.com/spf13/cast v1.4.1 // indirect
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/subosito/gotenv v1.2.0 // indirect
|
||||
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf // indirect
|
||||
golang.org/x/text v0.3.6 // indirect
|
||||
gopkg.in/ini.v1 v1.63.2 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
)
|
||||
|
|
@ -0,0 +1,176 @@
|
|||
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×tamp=%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
|
||||
}
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
package model
|
||||
|
||||
type DingtalkUserInfoResponse struct {
|
||||
RequestID string `json:"request_id"`
|
||||
ErrCode int `json:"errcode"`
|
||||
ErrMsg string `json:"errmsg"`
|
||||
Result DingtalkUserGetResponse
|
||||
}
|
||||
|
||||
type DingtalkUserGetResponse struct {
|
||||
UserID string `json:"userid"`
|
||||
Unionid string `json:"unionid"`
|
||||
Name string `json:"name"`
|
||||
Avatar string `json:"avatar"`
|
||||
StateCode string `json:"state_code"`
|
||||
ManagerUserID string `json:"manager_userid"`
|
||||
Mobile string `json:"mobile"`
|
||||
HideMobile bool `json:"hide_mobile"`
|
||||
Telephone string `json:"telephone"`
|
||||
JobNumber string `json:"job_number"`
|
||||
Title string `json:"title"`
|
||||
Email string `json:"email"`
|
||||
WorkPlace string `json:"work_place"`
|
||||
Remark string `json:"remark"`
|
||||
LoginID string `json:"login_id"`
|
||||
ExclusiveAccountType string `json:"exclusive_account_type"`
|
||||
ExclusiveAccount bool `json:"exclusive_account"`
|
||||
DeptIDList []int `json:"dept_id_list"`
|
||||
DeptOrderList []DingtalkDeptOrder
|
||||
Extension string `json:"extension"`
|
||||
HiredDate int `json:"hired_date"`
|
||||
Active bool `json:"active"`
|
||||
RealAuthed bool `json:"real_authed"`
|
||||
OrgEmail string `json:"org_email"`
|
||||
OrgEmailType string `json:"org_email_type"`
|
||||
Senior bool `json:"senior"`
|
||||
Admin bool `json:"admin"`
|
||||
Boss bool `json:"boss"`
|
||||
LeaderInDept []DingtalkDeptLeader
|
||||
RoleList []DingtalkUserRole
|
||||
UnionEmpExt UnionEmpExt
|
||||
}
|
||||
|
||||
type DingtalkDeptOrder struct {
|
||||
DeptID int `json:"dept_id"`
|
||||
Order int `json:"order"`
|
||||
}
|
||||
|
||||
type DingtalkDeptLeader struct {
|
||||
DeptID int `json:"dept_id"`
|
||||
Leader bool `json:"leader"`
|
||||
}
|
||||
|
||||
type DingtalkUserRole struct {
|
||||
ID int
|
||||
Name string
|
||||
GroupName string
|
||||
}
|
||||
|
||||
type UnionEmpExt struct {
|
||||
UserID string `json:"userid"`
|
||||
UnionEmpMapList []DingtalkUnionEmpMapVo
|
||||
CorpId string `json:"corp_id"`
|
||||
}
|
||||
|
||||
type DingtalkUnionEmpMapVo struct {
|
||||
UserID string `json:"userid"`
|
||||
CorpID string `json:"corpid"`
|
||||
}
|
||||
Loading…
Reference in New Issue