This repository has been archived by the owner on Jun 2, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
wecom.go
259 lines (219 loc) · 8.05 KB
/
wecom.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
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
package wecom
import (
"encoding/json"
"fmt"
badger "github.com/dgraph-io/badger/v2"
"github.com/go-laoji/wecom-app-sdk/internal"
"net/url"
"os"
"time"
)
type IWeCom interface {
getContactsAccessToken() string
getAppAccessToken() string
GetCorpId() string
//通讯录管理-成员管理 ↓
UserCreate(User) internal.BizResponse
UserGet(string) UserGetResponse
UserUpdate(User) internal.BizResponse
UserDelete(string) internal.BizResponse
UserBatchDelete([]string) internal.BizResponse
UserSimpleList(int32, int) UserSimpleListResponse
UserList(int32, int) UserListResponse
UserId2OpenId(string) UserId2OpenIdResponse
GetUserInfo(code string) (resp UserInfoResponse)
//通讯录管理-部门管理 ↓
DepartmentCreate(Department) DepartmentCreateResponse
DepartmentUpdate(Department) internal.BizResponse
DepartmentDelete(int32) internal.BizResponse
DepartmentList(int32) DepartmentListResponse
DepartmentSimpleList(id int32) (resp DepartmentSimpleListResponse)
DepartmentGet(id int32) (resp DepartmentGetResponse)
//通讯录管理-标签管理 ↓
TagCreate(Tag) TagCreateResponse
TagUpdate(Tag) internal.BizResponse
TagDelete(int) internal.BizResponse
TagList() TagListResponse
TagUserList(int) TagUserListResponse
TagAddUsers(int, []string, []int32) TagAddOrDelUsersResponse
TagDelUsers(int, []string, []int32) TagAddOrDelUsersResponse
//客户联系-联系我 ↓
ExternalAddContactWay(ContactMe) ContactMeAddResponse
ExternalUpdateContactWay(ContactMe) internal.BizResponse
ExternalGetContactWay(string) ContactMeGetResponse
ExternalListContactWay(int64, int64, string, int) ContactMeListResponse
ExternalDeleteContactWay(string) internal.BizResponse
ExternalCloseTempChat(string, string) internal.BizResponse
ExternalContactGetFollowUserList() ExternalContactGetFollowUserListResponse
//客户联系-规则组管理 ↓
ExternalContactCustomerStrategyList(string, int) ExternalContactCustomerStrategyListResponse
ExternalContactCustomerStrategyGet(int) ExternalContactCustomerStrategyGetResponse
ExternalContactCustomerStrategyGetRange(int, string, int) ExternalContactCustomerStrategyGetRangeResponse
ExternalContactCustomerStrategyCreate(ExternalContactCustomerStrategyCreateRequest) ExternalContactCustomerStrategyCreateResponse
ExternalContactCustomerStrategyEdit(ExternalContactCustomerStrategyEditRequest) internal.BizResponse
ExternalContactCustomerStrategyDelete(int) internal.BizResponse
//应用管理 ↓
AgentGet() AgentGetResponse
AgentList() (resp AgentListResponse)
//企业标签管理(客户) ↓
CorpTagList([]string, []string) CorpTagListResponse
CorpTagAdd(CorpTagGroup) CorpTagAddResponse
CorpTagUpdate(CorpTag) internal.BizResponse
CorpTagDelete([]string, []string) internal.BizResponse
//在职继承 ↓
TransferCustomer(TransferCustomerRequest) TransferCustomerResponse
TransferResult(TransferResultRequest) TransferResultResponse
//离职继承 ↓
GetUnassignedList(request UnAssignedRequest) (resp UnAssignedResponse)
TransferCustomerResigned(request TransferCustomerRequest) (resp TransferCustomerResponse)
TransferResultResigned(request TransferResultRequest) (resp TransferResultResponse)
TransferGroupChat(request GroupChatTransferRequest) (resp GroupChatTransferResponse)
//客户群管理 ↓
GroupChatList(GroupChatListFilter) GroupChatListResponse
GroupChat(GroupChatRequest) GroupChatResponse
GroupOpengId2ChatId(string) GroupOpengId2ChatIdResponse
GroupChatAddJoinWay(request GroupChatJoinWayRequest) (resp GroupChatAddJoinWayResponse)
GroupChatGetJoinWay(configId string) (resp GetJoinWayResponse)
GroupChatUpdateJoinWay(request GroupChatJoinWayRequest) (resp internal.BizResponse)
GroupChatDeleteJoinWay(configId string) (resp internal.BizResponse)
//客户朋友圈 ↓
// TODO: 测试未完成,接口不完整
AddMomentTask(task MomentTask) (resp AddMomentTaskResponse)
GetMomentTaskResult(jobId string) (resp GetMomentTaskResultResponse)
GetMomentList(filter MomentListFilter) (resp GetMomentListResponse)
GetMomentTask(filter MomentTaskFilter) (resp GetMomentTaskResponse)
//素材管理 ↓
MediaUploadAttachment(Media) MediaUploadResponse
MediaUpload(fileType MediaType, filePath string, fileName string) (resp MediaUploadResponse)
MediaUploadImg(filePath string, fileName string) (resp MediaUploadImgResponse)
//消息推送-客户群发 ↓
AddMsgTemplate(msg ExternalMsg) (resp AddMsgTemplateResponse)
GetGroupMsgListV2(filter GroupMsgListFilter) (resp GetGroupMsgListV2Response)
GetGroupMsgTask(filter GroupMsgTaskFilter) (resp GetGroupMsgTaskResponse)
GetGroupMsgSendResult(filter GroupMsgSendResultFilter) (resp GetGroupMsgSendResultResponse)
//消息推送(内部成员) ↓
MessageSend(msg interface{}) (resp MessageSendResponse)
MessageReCall(msgId string) (resp internal.BizResponse)
MessageUpdateTemplateCard(msg TemplateCardUpdateMessage) (resp MessageUpdateTemplateCardResponse)
AppChatCreate(request AppChatCreateRequest) (resp AppChatCreateResponse)
AppChatUpdate(request AppChatUpdateRequest) (resp internal.BizResponse)
AppChatGet(chatId string) (resp AppChatGetResponse)
AppChatSend(msg interface{}, chatId string) (resp internal.BizResponse)
}
type WorkChatConfig struct {
CorpId string
ContactSecret string
AppId string
AppSecret string
}
type weCom struct {
IWeCom
corpId string
contactSecret string
appId string
appSecret string
cache *badger.DB
}
func NewWeComApp(c WorkChatConfig) IWeCom {
app := new(weCom)
app.corpId = c.CorpId
app.contactSecret = c.ContactSecret
app.appId = c.AppId
app.appSecret = c.AppSecret
app.cache, _ = badger.Open(badger.DefaultOptions("").WithInMemory(true))
return app
}
func (app weCom) GetCorpId() string {
return app.corpId
}
type accessTokenResponse struct {
internal.BizResponse
AccessToken string `json:"access_token"`
ExpiresIn int `json:"expires_in"`
}
func (app weCom) requestAccessToken(secret string) (resp accessTokenResponse) {
apiUrl := fmt.Sprintf("/cgi-bin/gettoken?corpid=%s&corpsecret=%s", app.corpId, secret)
var data []byte
var err error
if data, err = internal.HttpGet(apiUrl); err != nil {
resp.ErrCode = 400
resp.ErrorMsg = err.Error()
return
}
if err = json.Unmarshal(data, &resp); err != nil {
resp.ErrCode = 400
resp.ErrorMsg = err.Error()
return
}
return resp
}
func (app *weCom) getContactsAccessToken() (token string) {
mutex.Lock()
defer mutex.Unlock()
var err error
var item *badger.Item
err = app.cache.View(func(txn *badger.Txn) error {
item, err = txn.Get([]byte("contactToken"))
if err == badger.ErrKeyNotFound {
return err
}
item.Value(func(val []byte) error {
token = string(val)
return nil
})
return err
})
if err == badger.ErrKeyNotFound {
if resp := app.requestAccessToken(app.contactSecret); resp.ErrCode != 0 {
panic(resp)
//logger.Error(err.Error())
} else {
token = resp.AccessToken
app.cache.Update(func(txn *badger.Txn) error {
entry := badger.NewEntry([]byte("contactToken"), []byte(token)).WithTTL(time.Second * 7200)
err = txn.SetEntry(entry)
return err
})
}
}
return token
}
func (app *weCom) getAppAccessToken() (token string) {
mutex.Lock()
defer mutex.Unlock()
var err error
var item *badger.Item
err = app.cache.View(func(txn *badger.Txn) error {
item, err = txn.Get([]byte("appToken"))
if err == badger.ErrKeyNotFound {
return err
}
item.Value(func(val []byte) error {
token = string(val)
return nil
})
return err
})
if err == badger.ErrKeyNotFound {
if resp := app.requestAccessToken(app.appSecret); resp.ErrCode != 0 {
panic(resp)
//logger.Error(err.Error())
} else {
token = resp.AccessToken
app.cache.Update(func(txn *badger.Txn) error {
entry := badger.NewEntry([]byte("appToken"), []byte(token)).WithTTL(time.Second * 7200)
err = txn.SetEntry(entry)
return err
})
}
}
return token
}
func (app weCom) buildBasicTokenQuery(token string) url.Values {
queryParams := url.Values{}
queryParams.Add("access_token", token)
if os.Getenv("debug") != "" {
queryParams.Add("debug", "1")
}
return queryParams
}