Skip to content

Commit 42c730a

Browse files
author
yanghaijian
committed
init
1 parent 08b271f commit 42c730a

13 files changed

+7829
-0
lines changed

.eslintignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node_modules

.eslintrc

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"root": true,
3+
"parser": "esprima",
4+
"extends": "airbnb-base",
5+
"globals": {},
6+
"env": {
7+
"node": true
8+
},
9+
"plugins": [],
10+
"rules": {
11+
"comma-dangle": "off",
12+
"no-bitwise": "off",
13+
"no-param-reassign": ["error", { "props": false }]
14+
}
15+
}

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules
2+
*.log

index.js

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
const WeworkApp = require('./lib/wework_app');
2+
const WeworkAppCorp = require('./lib/wework_app_corp');
3+
const WeworkCorp = require('./lib/wework_corp');
4+
const WeworkProvider = require('./lib/wework_provider');
5+
6+
module.exports = {
7+
WeworkApp,
8+
WeworkAppCorp,
9+
WeworkCorp,
10+
WeworkProvider
11+
};

lib/wework_app.js

+268
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,268 @@
1+
const request = require('request-promise');
2+
3+
const WeworkAppCorp = require('./wework_app_corp');
4+
5+
/**
6+
* 第三方应用相关API
7+
*/
8+
class WeworkApp {
9+
/**
10+
* @param config { corpid, appid, secret }
11+
* @param store
12+
*/
13+
constructor(config, store) {
14+
this.config = config;
15+
this.store = store;
16+
this.prefix = 'https://qyapi.weixin.qq.com/cgi-bin';
17+
}
18+
19+
createCorpInstance(corpid, permanentCode) {
20+
return new WeworkAppCorp({ corpid }, this, permanentCode);
21+
}
22+
23+
/* 第三方接口 */
24+
25+
async setSuiteTicket(ticket) {
26+
await this.store.set(`wework:app:${this.config.appid}:ticket`, ticket);
27+
}
28+
29+
async getSuiteTicket() {
30+
const ticket = await this.store.get(`wework:app:${this.config.appid}:ticket`);
31+
32+
return ticket;
33+
}
34+
35+
async getSuiteAccessToken() {
36+
let suiteAccessToken = await this.store.get(`wework:app:${this.config.appid}:token`);
37+
if (suiteAccessToken) {
38+
suiteAccessToken = JSON.parse(suiteAccessToken);
39+
if (Date.now() < suiteAccessToken.expires) {
40+
return suiteAccessToken.token;
41+
}
42+
}
43+
44+
const suiteTicket = await this.getSuiteTicket();
45+
const res = await request({
46+
method: 'POST',
47+
uri: `${this.prefix}/service/get_suite_token`,
48+
body: {
49+
suite_id: this.config.appid,
50+
suite_secret: this.config.secret,
51+
suite_ticket: suiteTicket
52+
},
53+
json: true
54+
});
55+
56+
if (res.errcode) {
57+
throw new Error(`获取SuiteAccessToken失败 ${res.errcode} ${res.errmsg}`);
58+
}
59+
60+
suiteAccessToken = {
61+
token: res.suite_access_token,
62+
expires: (Date.now() + ((res.expires_in - 10) * 1000))
63+
};
64+
65+
await this.store.setex(
66+
`wework:app:${this.config.appid}:token`,
67+
res.expires_in - 10,
68+
JSON.stringify(suiteAccessToken)
69+
);
70+
71+
return suiteAccessToken.token;
72+
}
73+
74+
async getPreAuthCode() {
75+
const suiteAccessToken = await this.getSuiteAccessToken();
76+
const res = await request({
77+
method: 'POST',
78+
uri: `${this.prefix}/service/get_pre_auth_code?suite_access_token=${suiteAccessToken}`,
79+
body: {
80+
suite_id: this.config.appid
81+
},
82+
json: true
83+
});
84+
85+
if (res.errcode) {
86+
throw new Error(`获取预授权码失败 ${res.errcode} ${res.errmsg}`);
87+
}
88+
89+
// for test app
90+
// await this.setSessionInfo(res.pre_auth_code);
91+
92+
return res;
93+
}
94+
95+
async setSessionInfo(preAuthCode, appid, authType = 1) {
96+
const suiteAccessToken = await this.getSuiteAccessToken();
97+
const res = await request({
98+
method: 'POST',
99+
uri: `${this.prefix}/service/set_session_info?suite_access_token=${suiteAccessToken}`,
100+
body: {
101+
pre_auth_code: preAuthCode,
102+
session_info: {
103+
appid,
104+
auth_type: authType
105+
}
106+
},
107+
json: true
108+
});
109+
110+
if (res.errcode) {
111+
throw new Error(`设置授权配置失败 ${res.errcode} ${res.errmsg}`);
112+
}
113+
}
114+
115+
async getPermanentCode(authCode) {
116+
const suiteAccessToken = await this.getSuiteAccessToken();
117+
const res = await request({
118+
method: 'POST',
119+
uri: `${this.prefix}/service/get_permanent_code?suite_access_token=${suiteAccessToken}`,
120+
body: {
121+
suite_id: this.config.appid,
122+
auth_code: authCode
123+
},
124+
json: true
125+
});
126+
127+
if (res.errcode) {
128+
throw new Error(`获取PermanentCode失败 ${res.errcode} ${res.errmsg}`);
129+
}
130+
131+
return res;
132+
}
133+
134+
async getAuthInfo(corpid, permanentCode) {
135+
const suiteAccessToken = await this.getSuiteAccessToken();
136+
const res = await request({
137+
method: 'POST',
138+
uri: `${this.prefix}/service/get_auth_info?suite_access_token=${suiteAccessToken}`,
139+
body: {
140+
suite_id: this.config.appid,
141+
auth_corpid: corpid,
142+
permanent_code: permanentCode
143+
},
144+
json: true
145+
});
146+
147+
if (res.errcode) {
148+
throw new Error(`获取企业授权信息失败 ${res.errcode} ${res.errmsg}`);
149+
}
150+
151+
return res;
152+
}
153+
154+
async deleteCorpAccessToken(corpid) {
155+
await this.store.del(`wework:app:${this.config.appid}:corp:${corpid}:token`);
156+
}
157+
158+
async getCorpAccessToken(corpid, permanentCode) {
159+
let corpAccessToken = await this.store.get(`wework:app:${this.config.appid}:corp:${corpid}:token`);
160+
if (corpAccessToken) {
161+
corpAccessToken = JSON.parse(corpAccessToken);
162+
if (Date.now() < corpAccessToken.expires) {
163+
return corpAccessToken.token;
164+
}
165+
}
166+
167+
const suiteAccessToken = await this.getSuiteAccessToken();
168+
const res = await request({
169+
method: 'POST',
170+
uri: `${this.prefix}/service/get_corp_token?suite_access_token=${suiteAccessToken}`,
171+
body: {
172+
suite_id: this.config.appid,
173+
auth_corpid: corpid,
174+
permanent_code: permanentCode
175+
},
176+
json: true
177+
});
178+
179+
if (res.errcode) {
180+
throw new Error(`获取企业AccessToken失败 ${res.errcode} ${res.errmsg}`);
181+
}
182+
183+
corpAccessToken = {
184+
token: res.access_token,
185+
expires: (Date.now() + ((res.expires_in - 10) * 1000))
186+
};
187+
188+
await this.store.setex(
189+
`wework:app:${this.config.appid}:corp:${corpid}:token`,
190+
res.expires_in - 10,
191+
JSON.stringify(corpAccessToken)
192+
);
193+
194+
return corpAccessToken.token;
195+
}
196+
197+
async getAdminList(corpid, agentid) {
198+
const suiteAccessToken = await this.getSuiteAccessToken();
199+
const res = await request({
200+
method: 'POST',
201+
uri: `${this.prefix}/service/get_admin_list?suite_access_token=${suiteAccessToken}`,
202+
body: {
203+
auth_corpid: corpid,
204+
agentid
205+
},
206+
json: true
207+
});
208+
209+
if (res.errcode !== 0) {
210+
throw new Error(`获取管理员列表失败 ${res.errcode} ${res.errmsg}`);
211+
}
212+
213+
return res.admin;
214+
}
215+
216+
/* auth user */
217+
218+
async getUserInfo3rd(code) {
219+
const accessToken = await this.getSuiteAccessToken();
220+
const res = await request({
221+
method: 'GET',
222+
uri: `${this.prefix}/service/getuserinfo3rd`,
223+
qs: {
224+
code,
225+
access_token: accessToken
226+
},
227+
json: true
228+
});
229+
230+
if (res.errcode) {
231+
throw new Error(`wework_app_${res.errcode}-获取企业成员信息失败 ${res.errmsg}`);
232+
}
233+
234+
return res;
235+
}
236+
237+
async getUserDetail3rd(userTicket) {
238+
const accessToken = await this.getSuiteAccessToken();
239+
const res = await request({
240+
method: 'POST',
241+
uri: `${this.prefix}/service/getuserdetail3rd?access_token=${accessToken}`,
242+
body: {
243+
user_ticket: userTicket
244+
},
245+
json: true
246+
});
247+
248+
if (res.errcode) {
249+
throw new Error(`获取成员详情失败 ${res.errcode} ${res.errmsg}`);
250+
}
251+
252+
return res;
253+
}
254+
255+
/* install */
256+
257+
get3rdAppInstallUrl(preAuthCode, redirectUri, state) {
258+
return `https://open.work.weixin.qq.com/3rdapp/install?suite_id=${this.config.appid}&pre_auth_code=${preAuthCode}&redirect_uri=${redirectUri}&state=${state}`;
259+
}
260+
261+
/* auth */
262+
263+
get3rdQrConnectUrl(redirectUri, state, usertype = 'member') {
264+
return `https://open.work.weixin.qq.com/wwopen/sso/3rd_qrConnect?appid=${this.config.corpid}&redirect_uri=${redirectUri}&state=${state}&usertype=${usertype}`;
265+
}
266+
}
267+
268+
module.exports = WeworkApp;

lib/wework_app_corp.js

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
const WeworkCorp = require('./wework_corp');
2+
3+
/**
4+
* 第三方应用企业相关API
5+
*/
6+
class WeworkAppCorp extends WeworkCorp {
7+
/**
8+
* @param {*} config { corpid, agentid }
9+
* @param {*} permanentCode
10+
* @param {*} app
11+
*/
12+
constructor(config, permanentCode, app) {
13+
super(config, app.store);
14+
15+
this.app = app;
16+
this.permanentCode = permanentCode;
17+
}
18+
19+
async getAccessToken() {
20+
return this.app.getCorpAccessToken(this.config.corpid, this.permanentCode);
21+
}
22+
}
23+
24+
module.exports = WeworkAppCorp;

0 commit comments

Comments
 (0)