-
Notifications
You must be signed in to change notification settings - Fork 0
/
dingtalk.go
168 lines (143 loc) · 3.15 KB
/
dingtalk.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
package dingtalk
import (
"fmt"
"net/http"
"sync"
"time"
)
type ClientType int32
const (
CORP ClientType = 0
ISV ClientType = 1
PERSON ClientType = 2
)
type CorpConfig struct {
CorpId string
CorpSecret string
ApiToken string
AgentId string
AppKey string
AppSecret string
}
type ISVConfig struct {
CorpId string
CorpSecret string
ApiToken string
MiniAppId string
AppId string
SuiteId string
SuiteKey string
SuiteSecret string
AESKey string
Token string
}
type PersonConfig struct {
CorpId string
CorpSecret string
ApiToken string
MiniAppId string
AppId string
AppSecret string
}
type config struct {
corpId string
corpSecret string // SSOSecret
apiToken string
agentId string
appKey string
suiteId string
suiteKey string
suiteSecret string
miniAppId string
appId string
appSecret string
token string
aesKey string
}
type DingTalkClient struct {
config config
httpClient *http.Client
pushCryptoSuit *PushCryptoSuit
clientType ClientType
cache Cache
persist Persist
suiteAccessTokenLocker sync.Mutex
}
type Option func(*options)
func WithCache(cache Cache) Option {
return func(o *options) {
o.cache = cache
}
}
func WithPersist(persist Persist) Option {
return func(o *options) {
o.persist = persist
}
}
func newDingTalkClient(clientType ClientType, cfg config, opts ...Option) *DingTalkClient {
o := defaultOptions(clientType)
for _, opt := range opts {
opt(o)
}
c := &DingTalkClient{
config: cfg,
httpClient: &http.Client{
Timeout: 10 * time.Second,
},
clientType: clientType,
cache: o.cache,
persist: o.persist,
}
if cfg.aesKey != "" && cfg.token != "" {
suit, err := NewPushCryptoSuit(cfg.token, cfg.aesKey, cfg.suiteKey)
if err != nil {
panic(err)
}
c.pushCryptoSuit = suit
}
return c
}
func NewISVClient(cfg ISVConfig, opts ...Option) *DingTalkClient {
return newDingTalkClient(ISV, config{
corpId: cfg.CorpId,
corpSecret: cfg.CorpSecret,
apiToken: cfg.ApiToken,
token: cfg.Token,
aesKey: cfg.AESKey,
miniAppId: cfg.MiniAppId,
appId: cfg.AppId,
suiteId: cfg.SuiteId,
suiteKey: cfg.SuiteKey,
suiteSecret: cfg.SuiteSecret,
}, opts...)
}
func NewCorpClient(cfg CorpConfig, opts ...Option) *DingTalkClient {
return newDingTalkClient(CORP, config{
corpId: cfg.CorpId,
corpSecret: cfg.CorpSecret,
apiToken: cfg.ApiToken,
agentId: cfg.AgentId,
appKey: cfg.AppKey,
appSecret: cfg.AppSecret,
}, opts...)
}
func NewPersonClient(cfg PersonConfig, opts ...Option) *DingTalkClient {
return newDingTalkClient(PERSON, config{
corpId: cfg.CorpId,
corpSecret: cfg.CorpSecret,
apiToken: cfg.ApiToken,
miniAppId: cfg.MiniAppId,
appId: cfg.AppId,
appSecret: cfg.AppSecret,
}, opts...)
}
type options struct {
cache Cache
persist Persist
}
func defaultOptions(clientType ClientType) *options {
return &options{
cache: NewFileCache(fmt.Sprintf(".dingtalk_cache_%d", clientType)),
persist: NewFileCache(fmt.Sprintf(".dingtalk_persist_%d", clientType)),
}
}