@jiexiaoyin/wecom-api 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +228 -0
- package/config.example.json +7 -0
- package/config.js +76 -0
- package/docs/approval-templates.example.json +11 -0
- package/docs/nginx-mirror.md +193 -0
- package/openclaw.plugin.json +15 -0
- package/package.json +34 -0
- package/plugin.cjs +172 -0
- package/plugin.ts +136 -0
- package/skills/wecom-api/SKILL.md +40 -0
- package/skills/wecom-api/index.js +288 -0
- package/skills/wecom-api/openclaw.plugin.json +10 -0
- package/src/callback-helper.js +198 -0
- package/src/config.cjs +286 -0
- package/src/core/permission.js +479 -0
- package/src/crypto.js +130 -0
- package/src/index.js +199 -0
- package/src/modules/addressbook/index.js +413 -0
- package/src/modules/addressbook_cache/index.js +365 -0
- package/src/modules/advanced/index.js +159 -0
- package/src/modules/app/index.js +102 -0
- package/src/modules/approval/index.js +146 -0
- package/src/modules/auth/index.js +103 -0
- package/src/modules/callback/index.js +1180 -0
- package/src/modules/chain/index.js +193 -0
- package/src/modules/checkin/index.js +142 -0
- package/src/modules/checkin_rules/index.js +251 -0
- package/src/modules/contact/index.js +481 -0
- package/src/modules/contact_stats/index.js +349 -0
- package/src/modules/custom/index.js +140 -0
- package/src/modules/customer/index.js +51 -0
- package/src/modules/disk/index.js +245 -0
- package/src/modules/document/index.js +282 -0
- package/src/modules/hr/index.js +93 -0
- package/src/modules/intelligence/index.js +346 -0
- package/src/modules/kf/index.js +74 -0
- package/src/modules/live/index.js +122 -0
- package/src/modules/media/index.js +183 -0
- package/src/modules/meeting/index.js +665 -0
- package/src/modules/message/index.js +402 -0
- package/src/modules/messenger/index.js +208 -0
- package/src/modules/moments/index.js +161 -0
- package/src/modules/msgaudit/index.js +24 -0
- package/src/modules/notify/index.js +81 -0
- package/src/modules/oceanengine/index.js +199 -0
- package/src/modules/openchat/index.js +197 -0
- package/src/modules/phone/index.js +45 -0
- package/src/modules/room/index.js +178 -0
- package/src/modules/schedule/index.js +246 -0
- package/src/modules/school/index.js +199 -0
- package/src/modules/security/index.js +223 -0
- package/src/modules/sensitive/index.js +170 -0
- package/src/modules/thirdparty/index.js +145 -0
- package/src/sdk/index.js +269 -0
- package/src/utils/callback-helper.js +198 -0
- package/test/callback-crypto.test.js +55 -0
- package/test/crypto.test.js +85 -0
- package/test/permission.test.js +115 -0
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 通讯录缓存模块
|
|
3
|
+
*
|
|
4
|
+
* 功能:
|
|
5
|
+
* 1. 本地缓存部门树和员工列表
|
|
6
|
+
* 2. 事件驱动的自动更新
|
|
7
|
+
* 3. 快速查询接口
|
|
8
|
+
*
|
|
9
|
+
* 数据文件:data/addressbook_cache.json
|
|
10
|
+
*
|
|
11
|
+
* 首次使用会检查是否需要同步,用户确认后才同步
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
const fs = require('fs');
|
|
15
|
+
const path = require('path');
|
|
16
|
+
|
|
17
|
+
class AddressBookCache {
|
|
18
|
+
constructor(config, options = {}) {
|
|
19
|
+
this.config = config;
|
|
20
|
+
this.cachePath = path.join(process.cwd(), 'data', 'addressbook_cache.json');
|
|
21
|
+
this.cache = this._loadCache();
|
|
22
|
+
this.syncConfirmed = false; // 是否已确认同步
|
|
23
|
+
this.onConfirmCallback = options.onConfirm; // 确认回调
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* 检查是否需要同步
|
|
28
|
+
* @returns {boolean}
|
|
29
|
+
*/
|
|
30
|
+
needsSync() {
|
|
31
|
+
// 没有缓存数据,需要同步
|
|
32
|
+
if (!this.cache.updatedAt) {
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
// 缓存超过7天,建议重新同步
|
|
36
|
+
const cacheDate = new Date(this.cache.updatedAt);
|
|
37
|
+
const now = new Date();
|
|
38
|
+
const daysDiff = (now - cacheDate) / (1000 * 60 * 60 * 24);
|
|
39
|
+
return daysDiff > 7;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* 获取同步状态信息
|
|
44
|
+
*/
|
|
45
|
+
getSyncStatus() {
|
|
46
|
+
return {
|
|
47
|
+
needsSync: this.needsSync(),
|
|
48
|
+
lastSyncTime: this.cache.updatedAt,
|
|
49
|
+
departmentCount: this.cache.departments?.length || 0,
|
|
50
|
+
userCount: this.cache.users?.length || 0
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* 请求同步(首次或用户主动触发)
|
|
56
|
+
* @returns {object} 状态信息
|
|
57
|
+
*/
|
|
58
|
+
requestSync() {
|
|
59
|
+
const status = this.getSyncStatus();
|
|
60
|
+
|
|
61
|
+
if (!status.needsSync && this.syncConfirmed) {
|
|
62
|
+
return {
|
|
63
|
+
needConfirm: false,
|
|
64
|
+
alreadySynced: true,
|
|
65
|
+
status: status
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return {
|
|
70
|
+
needConfirm: true,
|
|
71
|
+
confirmed: this.syncConfirmed,
|
|
72
|
+
status: status,
|
|
73
|
+
message: status.lastSyncTime
|
|
74
|
+
? `通讯录缓存已过期(上一次同步:${status.lastSyncTime}),是否重新同步?`
|
|
75
|
+
: '通讯录缓存尚未初始化,是否立即同步?'
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* 确认同步
|
|
81
|
+
*/
|
|
82
|
+
confirmSync() {
|
|
83
|
+
this.syncConfirmed = true;
|
|
84
|
+
if (this.onConfirmCallback) {
|
|
85
|
+
this.onConfirmCallback();
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* 跳过同步
|
|
91
|
+
*/
|
|
92
|
+
skipSync() {
|
|
93
|
+
this.syncConfirmed = false;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* 加载本地缓存
|
|
98
|
+
*/
|
|
99
|
+
_loadCache() {
|
|
100
|
+
try {
|
|
101
|
+
if (fs.existsSync(this.cachePath)) {
|
|
102
|
+
const data = JSON.parse(fs.readFileSync(this.cachePath, 'utf8'));
|
|
103
|
+
console.log('[AddressBookCache] 已加载本地缓存');
|
|
104
|
+
return data;
|
|
105
|
+
}
|
|
106
|
+
} catch (e) {
|
|
107
|
+
console.log('[AddressBookCache] 加载缓存失败:', e.message);
|
|
108
|
+
}
|
|
109
|
+
return this._createEmptyCache();
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* 创建空缓存结构
|
|
114
|
+
*/
|
|
115
|
+
_createEmptyCache() {
|
|
116
|
+
return {
|
|
117
|
+
updatedAt: null,
|
|
118
|
+
departments: [],
|
|
119
|
+
users: [],
|
|
120
|
+
userMap: {}, // userId -> user
|
|
121
|
+
departmentMap: {} // deptId -> department
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* 保存缓存到文件
|
|
127
|
+
*/
|
|
128
|
+
_saveCache() {
|
|
129
|
+
try {
|
|
130
|
+
const dir = path.dirname(this.cachePath);
|
|
131
|
+
if (!fs.existsSync(dir)) {
|
|
132
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
133
|
+
}
|
|
134
|
+
this.cache.updatedAt = new Date().toISOString();
|
|
135
|
+
fs.writeFileSync(this.cachePath, JSON.stringify(this.cache, null, 2));
|
|
136
|
+
console.log('[AddressBookCache] 缓存已保存');
|
|
137
|
+
} catch (e) {
|
|
138
|
+
console.log('[AddressBookCache] 保存缓存失败:', e.message);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* 初始化/更新完整通讯录
|
|
144
|
+
*
|
|
145
|
+
* ⚠️ 注意:只需获取根部门(id=1)并设置 fetch_child=true
|
|
146
|
+
* 因为它会递归获取所有子部门成员,避免重复获取
|
|
147
|
+
*/
|
|
148
|
+
async syncFromAPI(addressbook) {
|
|
149
|
+
console.log('[AddressBookCache] 从 API 同步通讯录...');
|
|
150
|
+
|
|
151
|
+
try {
|
|
152
|
+
// 获取部门列表
|
|
153
|
+
const deptResult = await addressbook.getDepartmentList();
|
|
154
|
+
this.cache.departments = deptResult.department || [];
|
|
155
|
+
|
|
156
|
+
// 构建部门 map
|
|
157
|
+
this.cache.departmentMap = {};
|
|
158
|
+
for (const dept of this.cache.departments) {
|
|
159
|
+
this.cache.departmentMap[dept.id] = dept;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// 获取所有员工(只需获取根部门,fetch_child=true 会递归获取子部门)
|
|
163
|
+
this.cache.users = [];
|
|
164
|
+
this.cache.userMap = {};
|
|
165
|
+
|
|
166
|
+
try {
|
|
167
|
+
// 只获取根部门,fetch_child=true 会递归获取所有子部门成员
|
|
168
|
+
const users = await addressbook.getDepartmentUsers(1, true);
|
|
169
|
+
if (users.userlist) {
|
|
170
|
+
for (const user of users.userlist) {
|
|
171
|
+
// 根据用户所在的部门设置信息
|
|
172
|
+
const dept = this.cache.departmentMap[user.department?.[0] || 1];
|
|
173
|
+
user.departmentId = user.department?.[0] || 1;
|
|
174
|
+
user.departmentName = dept?.name || '未知部门';
|
|
175
|
+
|
|
176
|
+
// 使用 userId 去重
|
|
177
|
+
if (!this.cache.userMap[user.userid]) {
|
|
178
|
+
this.cache.users.push(user);
|
|
179
|
+
this.cache.userMap[user.userid] = user;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
console.log(`[AddressBookCache] 获取成员成功: ${users.userlist?.length || 0} 人`);
|
|
184
|
+
} catch (e) {
|
|
185
|
+
console.log('[AddressBookCache] 获取成员失败:', e.message);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
this._saveCache();
|
|
189
|
+
console.log(`[AddressBookCache] 同步完成: ${this.cache.departments.length} 部门, ${this.cache.users.length} 员工`);
|
|
190
|
+
|
|
191
|
+
} catch (e) {
|
|
192
|
+
console.log('[AddressBookCache] 同步失败:', e.message);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// ========== 事件驱动的更新 ==========
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* 处理成员新增事件
|
|
200
|
+
*/
|
|
201
|
+
onUserAdd(user) {
|
|
202
|
+
console.log('[AddressBookCache] 成员新增:', user.name || user.userid);
|
|
203
|
+
|
|
204
|
+
// 检查是否已存在
|
|
205
|
+
if (!this.cache.userMap[user.userid]) {
|
|
206
|
+
this.cache.users.push(user);
|
|
207
|
+
this.cache.userMap[user.userid] = user;
|
|
208
|
+
this._saveCache();
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* 处理成员删除事件
|
|
214
|
+
*/
|
|
215
|
+
onUserDelete(userId) {
|
|
216
|
+
console.log('[AddressBookCache] 成员删除:', userId);
|
|
217
|
+
|
|
218
|
+
if (this.cache.userMap[userId]) {
|
|
219
|
+
const user = this.cache.userMap[userId];
|
|
220
|
+
this.cache.users = this.cache.users.filter(u => u.userid !== userId);
|
|
221
|
+
delete this.cache.userMap[userId];
|
|
222
|
+
this._saveCache();
|
|
223
|
+
return user;
|
|
224
|
+
}
|
|
225
|
+
return null;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* 处理成员更新事件
|
|
230
|
+
*/
|
|
231
|
+
onUserUpdate(user) {
|
|
232
|
+
console.log('[AddressBookCache] 成员更新:', user.userid);
|
|
233
|
+
|
|
234
|
+
if (this.cache.userMap[user.userid]) {
|
|
235
|
+
Object.assign(this.cache.userMap[user.userid], user);
|
|
236
|
+
const index = this.cache.users.findIndex(u => u.userid === user.userid);
|
|
237
|
+
if (index >= 0) {
|
|
238
|
+
Object.assign(this.cache.users[index], user);
|
|
239
|
+
}
|
|
240
|
+
this._saveCache();
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* 处理部门新增事件
|
|
246
|
+
*/
|
|
247
|
+
onDepartmentAdd(dept) {
|
|
248
|
+
console.log('[AddressBookCache] 部门新增:', dept.name);
|
|
249
|
+
|
|
250
|
+
if (!this.cache.departmentMap[dept.id]) {
|
|
251
|
+
this.cache.departments.push(dept);
|
|
252
|
+
this.cache.departmentMap[dept.id] = dept;
|
|
253
|
+
this._saveCache();
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* 处理部门删除事件
|
|
259
|
+
*/
|
|
260
|
+
onDepartmentDelete(deptId) {
|
|
261
|
+
console.log('[AddressBookCache] 部门删除:', deptId);
|
|
262
|
+
|
|
263
|
+
if (this.cache.departmentMap[deptId]) {
|
|
264
|
+
this.cache.departments = this.cache.departments.filter(d => d.id !== deptId);
|
|
265
|
+
delete this.cache.departmentMap[deptId];
|
|
266
|
+
this._saveCache();
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* 处理部门更新事件
|
|
272
|
+
*/
|
|
273
|
+
onDepartmentUpdate(dept) {
|
|
274
|
+
console.log('[AddressBookCache] 部门更新:', dept.id);
|
|
275
|
+
|
|
276
|
+
if (this.cache.departmentMap[dept.id]) {
|
|
277
|
+
Object.assign(this.cache.departmentMap[dept.id], dept);
|
|
278
|
+
const index = this.cache.departments.findIndex(d => d.id === dept.id);
|
|
279
|
+
if (index >= 0) {
|
|
280
|
+
Object.assign(this.cache.departments[index], dept);
|
|
281
|
+
}
|
|
282
|
+
this._saveCache();
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// ========== 查询接口 ==========
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* 获取所有部门
|
|
290
|
+
*/
|
|
291
|
+
getDepartments() {
|
|
292
|
+
return this.cache.departments;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* 获取所有员工
|
|
297
|
+
*/
|
|
298
|
+
getUsers() {
|
|
299
|
+
return this.cache.users;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* 根据 ID 获取员工
|
|
304
|
+
*/
|
|
305
|
+
getUser(userId) {
|
|
306
|
+
return this.cache.userMap[userId];
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* 根据部门 ID 获取员工
|
|
311
|
+
*/
|
|
312
|
+
getUsersByDepartment(deptId) {
|
|
313
|
+
return this.cache.users.filter(u => u.departmentId === deptId);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* 根据部门 ID 获取子部门(包括自己)
|
|
318
|
+
*/
|
|
319
|
+
getSubDepartments(deptId) {
|
|
320
|
+
const result = [];
|
|
321
|
+
const addDeptAndChildren = (id) => {
|
|
322
|
+
result.push(this.cache.departmentMap[id]);
|
|
323
|
+
for (const dept of this.cache.departments) {
|
|
324
|
+
if (dept.parentid === id) {
|
|
325
|
+
addDeptAndChildren(dept.id);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
};
|
|
329
|
+
addDeptAndChildren(deptId);
|
|
330
|
+
return result;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* 获取部门树
|
|
335
|
+
*/
|
|
336
|
+
getDepartmentTree() {
|
|
337
|
+
const buildTree = (parentId) => {
|
|
338
|
+
return this.cache.departments
|
|
339
|
+
.filter(d => d.parentid === parentId)
|
|
340
|
+
.map(d => ({
|
|
341
|
+
...d,
|
|
342
|
+
children: buildTree(d.id)
|
|
343
|
+
}));
|
|
344
|
+
};
|
|
345
|
+
return buildTree(0);
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* 获取统计信息
|
|
350
|
+
*/
|
|
351
|
+
getStats() {
|
|
352
|
+
return {
|
|
353
|
+
updatedAt: this.cache.updatedAt,
|
|
354
|
+
departmentCount: this.cache.departments.length,
|
|
355
|
+
userCount: this.cache.users.length,
|
|
356
|
+
usersByDepartment: this.cache.departments.map(d => ({
|
|
357
|
+
id: d.id,
|
|
358
|
+
name: d.name,
|
|
359
|
+
userCount: this.getUsersByDepartment(d.id).length
|
|
360
|
+
}))
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
module.exports = AddressBookCache;
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 高级功能模块
|
|
3
|
+
* API 章节:二十六 - 高级功能
|
|
4
|
+
* 包含:成员申请回调、审批单设置、批量获取申请单
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const WeComSDK = require('../../sdk');
|
|
8
|
+
|
|
9
|
+
class Advanced extends WeComSDK {
|
|
10
|
+
constructor(config) {
|
|
11
|
+
super(config);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// ========== 成员申请的提交回调 ==========
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* 获取成员申请列表
|
|
18
|
+
* @param {number} startTime 开始时间戳
|
|
19
|
+
* @param {number} endTime 结束时间戳
|
|
20
|
+
* @param {number} cursor 分页游标
|
|
21
|
+
* @param {number} size 每页数量
|
|
22
|
+
*/
|
|
23
|
+
async getMemberApplicationList(startTime, endTime, cursor = 0, size = 100) {
|
|
24
|
+
return this.post('/member_application/list', {
|
|
25
|
+
start_time: startTime,
|
|
26
|
+
end_time: endTime,
|
|
27
|
+
cursor,
|
|
28
|
+
limit: size
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* 获取成员申请详情
|
|
34
|
+
* @param {string} applicationId 申请 ID
|
|
35
|
+
*/
|
|
36
|
+
async getMemberApplicationDetail(applicationId) {
|
|
37
|
+
return this.post('/member_application/get', { application_id: applicationId });
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// ========== 审批单相关 ==========
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* 设置审批单审批信息
|
|
44
|
+
* @param {string} spNo 审批单号
|
|
45
|
+
* @param {object} params 审批信息
|
|
46
|
+
*/
|
|
47
|
+
async setApprovalInfo(spNo, { approver, status, remark }) {
|
|
48
|
+
return this.post('/approval/spinfo/set', {
|
|
49
|
+
sp_no: spNo,
|
|
50
|
+
approver,
|
|
51
|
+
status,
|
|
52
|
+
remark
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* 批量获取审批单 ID
|
|
58
|
+
* @param {number} startTime 开始时间戳
|
|
59
|
+
* @param {number} endTime 结束时间戳
|
|
60
|
+
* @param {number} cursor 分页游标
|
|
61
|
+
* @param {number} size 每页数量
|
|
62
|
+
*/
|
|
63
|
+
async getApprovalIdList(startTime, endTime, cursor = 0, size = 100) {
|
|
64
|
+
return this.post('/approval/spno/list', {
|
|
65
|
+
start_time: startTime,
|
|
66
|
+
end_time: endTime,
|
|
67
|
+
cursor,
|
|
68
|
+
limit: size
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* 获取审批单详细信息
|
|
74
|
+
* @param {string} spNo 审批单号
|
|
75
|
+
*/
|
|
76
|
+
async getApprovalDetail(spNo) {
|
|
77
|
+
return this.post('/approval/spno/get', { sp_no: spNo });
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// ========== 企业标签高级管理 ==========
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* 创建企业标签组
|
|
84
|
+
* @param {string} groupName 组名称
|
|
85
|
+
* @param {string[]} tags 标签列表
|
|
86
|
+
*/
|
|
87
|
+
async createCorpTagGroup(groupName, tags = []) {
|
|
88
|
+
return this.post('/corpgroup/tag/add', {
|
|
89
|
+
group_name: groupName,
|
|
90
|
+
tags
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* 获取企业标签组列表
|
|
96
|
+
*/
|
|
97
|
+
async getCorpTagGroupList() {
|
|
98
|
+
return this.post('/corpgroup/tag/list', {});
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* 更新企业标签
|
|
103
|
+
* @param {string} tagId 标签 ID
|
|
104
|
+
* @param {string} tagName 新标签名
|
|
105
|
+
*/
|
|
106
|
+
async updateCorpTag(tagId, tagName) {
|
|
107
|
+
return this.post('/corpgroup/tag/update', {
|
|
108
|
+
id: tagId,
|
|
109
|
+
name: tagName
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* 删除企业标签
|
|
115
|
+
* @param {string} tagId 标签 ID
|
|
116
|
+
*/
|
|
117
|
+
async deleteCorpTag(tagId) {
|
|
118
|
+
return this.post('/corpgroup/tag/del', { tag_id: tagId });
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// ========== 企业群聊管理 ==========
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* 获取企业群聊列表
|
|
125
|
+
* @param {string} cursor 分页游标
|
|
126
|
+
* @param {number} size 每页数量
|
|
127
|
+
*/
|
|
128
|
+
async getCorpGroupChatList(cursor = '', size = 100) {
|
|
129
|
+
return this.post('/corpgroup/chat/list', { cursor, limit: size });
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* 获取企业群聊详情
|
|
134
|
+
* @param {string} chatId 群聊 ID
|
|
135
|
+
*/
|
|
136
|
+
async getCorpGroupChatDetail(chatId) {
|
|
137
|
+
return this.post('/corpgroup/chat/get', { chat_id: chatId });
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// ========== 互联企业消息推送 ==========
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* 给互联企业发送消息
|
|
144
|
+
* @param {string} corpId 目标企业 ID
|
|
145
|
+
* @param {string} toUser 接收成员
|
|
146
|
+
* @param {object} content 消息内容
|
|
147
|
+
* @param {string} msgType 消息类型
|
|
148
|
+
*/
|
|
149
|
+
async sendToLinkedCorp(corpId, toUser, content, msgType = 'text') {
|
|
150
|
+
return this.post('/corpgroup/message/send', {
|
|
151
|
+
corp_id: corpId,
|
|
152
|
+
touser: toUser,
|
|
153
|
+
msgtype: msgType,
|
|
154
|
+
[msgType]: content
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
module.exports = Advanced;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 应用管理模块
|
|
3
|
+
* API 章节:九 - 应用管理
|
|
4
|
+
* 包含:应用管理、自定义菜单
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const WeComSDK = require('../../sdk');
|
|
8
|
+
|
|
9
|
+
class App extends WeComSDK {
|
|
10
|
+
constructor(config) {
|
|
11
|
+
super(config);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// ========== 应用管理 ==========
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* 获取应用
|
|
18
|
+
* @param {number} agentId 应用 id
|
|
19
|
+
*/
|
|
20
|
+
async getAgent(agentId) {
|
|
21
|
+
return this.get('/agent/get', { agentid: agentId });
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* 设置应用
|
|
26
|
+
* @param {number} agentId 应用 id
|
|
27
|
+
* @param {object} params 应用参数
|
|
28
|
+
*/
|
|
29
|
+
async setAgent(agentId, { name, description, squareLogoUrl, redirectDomain, reportLocationFlag, isreportenter, homeUrl }) {
|
|
30
|
+
return this.post('/agent/set', {
|
|
31
|
+
agentid: agentId,
|
|
32
|
+
name,
|
|
33
|
+
description,
|
|
34
|
+
square_logo_url: squareLogoUrl,
|
|
35
|
+
redirect_domain: redirectDomain,
|
|
36
|
+
report_location_flag: reportLocationFlag,
|
|
37
|
+
isreportenter,
|
|
38
|
+
home_url: homeUrl
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* 获取应用列表
|
|
44
|
+
*/
|
|
45
|
+
async getAgentList() {
|
|
46
|
+
return this.get('/agent/list', {});
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// ========== 自定义菜单 ==========
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* 创建菜单
|
|
53
|
+
* @param {number} agentId 应用 id
|
|
54
|
+
* @param {object} menu 菜单配置
|
|
55
|
+
*/
|
|
56
|
+
async createMenu(agentId, menu) {
|
|
57
|
+
return this.post('/menu/create', {
|
|
58
|
+
agentid: agentId,
|
|
59
|
+
button: menu.button || menu
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* 获取菜单
|
|
65
|
+
* @param {number} agentId 应用 id
|
|
66
|
+
*/
|
|
67
|
+
async getMenu(agentId) {
|
|
68
|
+
return this.get('/menu/get', { agentid: agentId });
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* 删除菜单
|
|
73
|
+
* @param {number} agentId 应用 id
|
|
74
|
+
*/
|
|
75
|
+
async deleteMenu(agentId) {
|
|
76
|
+
return this.post('/menu/delete', { agentid: agentId });
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// ========== 工作台自定义展示 ==========
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* 设置工作台自定义展示
|
|
83
|
+
* @param {number} agentId 应用 id
|
|
84
|
+
* @param {object} config 工作台配置
|
|
85
|
+
*/
|
|
86
|
+
async setWorkbench(agentId, config) {
|
|
87
|
+
return this.post('/agent/set_workbench', {
|
|
88
|
+
agentid: agentId,
|
|
89
|
+
...config
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* 获取工作台自定义展示
|
|
95
|
+
* @param {number} agentId 应用 id
|
|
96
|
+
*/
|
|
97
|
+
async getWorkbench(agentId) {
|
|
98
|
+
return this.post('/agent/get_workbench', { agentid: agentId });
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
module.exports = App;
|