@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.
Files changed (58) hide show
  1. package/README.md +228 -0
  2. package/config.example.json +7 -0
  3. package/config.js +76 -0
  4. package/docs/approval-templates.example.json +11 -0
  5. package/docs/nginx-mirror.md +193 -0
  6. package/openclaw.plugin.json +15 -0
  7. package/package.json +34 -0
  8. package/plugin.cjs +172 -0
  9. package/plugin.ts +136 -0
  10. package/skills/wecom-api/SKILL.md +40 -0
  11. package/skills/wecom-api/index.js +288 -0
  12. package/skills/wecom-api/openclaw.plugin.json +10 -0
  13. package/src/callback-helper.js +198 -0
  14. package/src/config.cjs +286 -0
  15. package/src/core/permission.js +479 -0
  16. package/src/crypto.js +130 -0
  17. package/src/index.js +199 -0
  18. package/src/modules/addressbook/index.js +413 -0
  19. package/src/modules/addressbook_cache/index.js +365 -0
  20. package/src/modules/advanced/index.js +159 -0
  21. package/src/modules/app/index.js +102 -0
  22. package/src/modules/approval/index.js +146 -0
  23. package/src/modules/auth/index.js +103 -0
  24. package/src/modules/callback/index.js +1180 -0
  25. package/src/modules/chain/index.js +193 -0
  26. package/src/modules/checkin/index.js +142 -0
  27. package/src/modules/checkin_rules/index.js +251 -0
  28. package/src/modules/contact/index.js +481 -0
  29. package/src/modules/contact_stats/index.js +349 -0
  30. package/src/modules/custom/index.js +140 -0
  31. package/src/modules/customer/index.js +51 -0
  32. package/src/modules/disk/index.js +245 -0
  33. package/src/modules/document/index.js +282 -0
  34. package/src/modules/hr/index.js +93 -0
  35. package/src/modules/intelligence/index.js +346 -0
  36. package/src/modules/kf/index.js +74 -0
  37. package/src/modules/live/index.js +122 -0
  38. package/src/modules/media/index.js +183 -0
  39. package/src/modules/meeting/index.js +665 -0
  40. package/src/modules/message/index.js +402 -0
  41. package/src/modules/messenger/index.js +208 -0
  42. package/src/modules/moments/index.js +161 -0
  43. package/src/modules/msgaudit/index.js +24 -0
  44. package/src/modules/notify/index.js +81 -0
  45. package/src/modules/oceanengine/index.js +199 -0
  46. package/src/modules/openchat/index.js +197 -0
  47. package/src/modules/phone/index.js +45 -0
  48. package/src/modules/room/index.js +178 -0
  49. package/src/modules/schedule/index.js +246 -0
  50. package/src/modules/school/index.js +199 -0
  51. package/src/modules/security/index.js +223 -0
  52. package/src/modules/sensitive/index.js +170 -0
  53. package/src/modules/thirdparty/index.js +145 -0
  54. package/src/sdk/index.js +269 -0
  55. package/src/utils/callback-helper.js +198 -0
  56. package/test/callback-crypto.test.js +55 -0
  57. package/test/crypto.test.js +85 -0
  58. package/test/permission.test.js +115 -0
@@ -0,0 +1,245 @@
1
+ /**
2
+ * 微盘管理模块
3
+ * API 章节:十八
4
+ */
5
+
6
+ const WeComSDK = require('../../sdk');
7
+ const fs = require('fs');
8
+ const path = require('path');
9
+
10
+ class Disk extends WeComSDK {
11
+ constructor(config) {
12
+ super(config);
13
+ }
14
+
15
+ // ========== 空间管理 ==========
16
+
17
+ /**
18
+ * 新建空间
19
+ * @param {string} spaceName 空间名称
20
+ * @param {string} spaceOwner 空间负责人 userid
21
+ * @param {number} spaceType 空间类型: 0-企业空间 1-公共空间 2-共享空间
22
+ */
23
+ async createSpace(spaceName, spaceOwner, spaceType = 0) {
24
+ return this.post('/disk/create_space', {
25
+ space_name: spaceName,
26
+ space_owner: spaceOwner,
27
+ space_type: spaceType
28
+ });
29
+ }
30
+
31
+ /**
32
+ * 重命名空间
33
+ * @param {string} spaceId 空间 id
34
+ * @param {string} newName 新名称
35
+ */
36
+ async renameSpace(spaceId, newName) {
37
+ return this.post('/disk/rename_space', { spaceid: spaceId, new_name: newName });
38
+ }
39
+
40
+ /**
41
+ * 解散空间
42
+ * @param {string} spaceId 空间 id
43
+ */
44
+ async deleteSpace(spaceId) {
45
+ return this.post('/disk/delete_space', { spaceid: spaceId });
46
+ }
47
+
48
+ /**
49
+ * 获取空间信息
50
+ * @param {string} spaceId 空间 id
51
+ */
52
+ async getSpaceInfo(spaceId) {
53
+ return this.post('/disk/get_space_info', { spaceid: spaceId });
54
+ }
55
+
56
+ // ========== 空间权限管理 ==========
57
+
58
+ /**
59
+ * 添加成员/部门
60
+ * @param {string} spaceId 空间 id
61
+ * @param {string} type 成员类型: 1-成员 2-部门
62
+ * @param {string} id 成员或部门 id
63
+ * @param {number} permission 权限: 1-可查看 2-可编辑
64
+ */
65
+ async addSpaceMember(spaceId, type, id, permission = 1) {
66
+ return this.post('/disk/add_space_member', {
67
+ spaceid: spaceId,
68
+ type,
69
+ id,
70
+ permission
71
+ });
72
+ }
73
+
74
+ /**
75
+ * 移除成员/部门
76
+ * @param {string} spaceId 空间 id
77
+ * @param {string} type 成员类型: 1-成员 2-部门
78
+ * @param {string} id 成员或部门 id
79
+ */
80
+ async removeSpaceMember(spaceId, type, id) {
81
+ return this.post('/disk/remove_space_member', { spaceid: spaceId, type, id });
82
+ }
83
+
84
+ /**
85
+ * 获取邀请链接
86
+ * @param {string} spaceId 空间 id
87
+ */
88
+ async getShareLink(spaceId) {
89
+ return this.post('/disk/get_share_link', { spaceid: spaceId });
90
+ }
91
+
92
+ // ========== 文件管理 ==========
93
+
94
+ /**
95
+ * 获取文件列表
96
+ * @param {string} spaceId 空间 id
97
+ * @param {string} folderId 文件夹 id
98
+ * @param {number} start 分页起始位置
99
+ * @param {number} limit 每页数量
100
+ */
101
+ async getFileList(spaceId, folderId, start = 0, limit = 100) {
102
+ return this.post('/disk/get_file_list', {
103
+ spaceid: spaceId,
104
+ folder_id: folderId,
105
+ start,
106
+ limit
107
+ });
108
+ }
109
+
110
+ /**
111
+ * 上传文件
112
+ * @param {string} spaceId 空间 id
113
+ * @param {string} folderId 上级文件夹 id
114
+ * @param {string} fileName 文件名
115
+ * @param {string} filePath 本地文件路径
116
+ */
117
+ async uploadFile(spaceId, folderId, fileName, filePath) {
118
+ const token = await this.getAccessToken();
119
+ const url = `${this.baseUrl}/disk/upload_file?access_token=${token}`;
120
+
121
+ const FormData = require('form-data');
122
+ const form = new FormData();
123
+ form.append('spaceid', spaceId);
124
+ form.append('folder_id', folderId);
125
+ form.append('file_name', fileName);
126
+ form.append('file', fs.createReadStream(filePath));
127
+
128
+ const response = await axios.post(url, form, {
129
+ headers: form.getHeaders()
130
+ });
131
+
132
+ if (response.data.errcode !== 0) {
133
+ throw new Error(`上传文件失败: ${response.data.errmsg}`);
134
+ }
135
+ return response.data;
136
+ }
137
+
138
+ /**
139
+ * 下载文件
140
+ * @param {string} fileId 文件 id
141
+ * @param {string} savePath 保存路径
142
+ */
143
+ async downloadFile(fileId, savePath) {
144
+ const token = await this.getAccessToken();
145
+ const url = `${this.baseUrl}/disk/download_file?access_token=${token}`;
146
+
147
+ const response = await axios.post(url, { fileid: fileId }, {
148
+ responseType: 'arraybuffer'
149
+ });
150
+
151
+ fs.writeFileSync(savePath, response.data);
152
+ return { savePath };
153
+ }
154
+
155
+ /**
156
+ * 新建文件夹
157
+ * @param {string} spaceId 空间 id
158
+ * @param {string} parentFolderId 上级文件夹 id
159
+ * @param {string} folderName 文件夹名
160
+ */
161
+ async createFolder(spaceId, parentFolderId, folderName) {
162
+ return this.post('/disk/create_folder', {
163
+ spaceid: spaceId,
164
+ parent_folder_id: parentFolderId,
165
+ folder_name: folderName
166
+ });
167
+ }
168
+
169
+ /**
170
+ * 重命名文件
171
+ * @param {string} fileId 文件 id
172
+ * @param {string} newName 新名称
173
+ */
174
+ async renameFile(fileId, newName) {
175
+ return this.post('/disk/rename_file', { fileid: fileId, new_name: newName });
176
+ }
177
+
178
+ /**
179
+ * 移动文件
180
+ * @param {string} fileId 文件 id
181
+ * @param {string} spaceId 目标空间 id
182
+ * @param {string} targetFolderId 目标文件夹 id
183
+ */
184
+ async moveFile(fileId, spaceId, targetFolderId) {
185
+ return this.post('/disk/move_file', {
186
+ fileid: fileId,
187
+ spaceid: spaceId,
188
+ target_folder_id: targetFolderId
189
+ });
190
+ }
191
+
192
+ /**
193
+ * 删除文件
194
+ * @param {string} fileId 文件 id
195
+ */
196
+ async deleteFile(fileId) {
197
+ return this.post('/disk/delete_file', { fileid: fileId });
198
+ }
199
+
200
+ /**
201
+ * 获取文件信息
202
+ * @param {string} fileId 文件 id
203
+ */
204
+ async getFileInfo(fileId) {
205
+ return this.post('/disk/get_file_info', { fileid: fileId });
206
+ }
207
+
208
+ // ========== 文件权限管理 ==========
209
+
210
+ /**
211
+ * 新增成员
212
+ * @param {string} fileId 文件 id
213
+ * @param {string} type 成员类型: 1-成员 2-部门
214
+ * @param {string} id 成员或部门 id
215
+ * @param {number} permission 权限: 1-可查看 2-可编辑
216
+ */
217
+ async addFileMember(fileId, type, id, permission = 1) {
218
+ return this.post('/disk/add_file_member', {
219
+ fileid: fileId,
220
+ type,
221
+ id,
222
+ permission
223
+ });
224
+ }
225
+
226
+ /**
227
+ * 删除成员
228
+ * @param {string} fileId 文件 id
229
+ * @param {string} type 成员类型: 1-成员 2-部门
230
+ * @param {string} id 成员或部门 id
231
+ */
232
+ async removeFileMember(fileId, type, id) {
233
+ return this.post('/disk/remove_file_member', { fileid: fileId, type, id });
234
+ }
235
+
236
+ /**
237
+ * 获取文件权限信息
238
+ * @param {string} fileId 文件 id
239
+ */
240
+ async getFilePermission(fileId) {
241
+ return this.post('/disk/get_file_permission', { fileid: fileId });
242
+ }
243
+ }
244
+
245
+ module.exports = Disk;
@@ -0,0 +1,282 @@
1
+ /**
2
+ * 文档管理模块
3
+ * API 章节:十五 - 文档
4
+ * 包含:文档管理、收集表、素材管理
5
+ */
6
+
7
+ const WeComSDK = require('../../sdk');
8
+
9
+ class Document extends WeComSDK {
10
+ constructor(config) {
11
+ super(config);
12
+ }
13
+
14
+ // ========== 文档管理 ==========
15
+
16
+ /**
17
+ * 创建文档
18
+ * @param {string} spaceId 空间 ID
19
+ * @param {string} folderId 文件夹 ID
20
+ * @param {string} title 文档标题
21
+ * @param {string} docType 文档类型: doc, sheet, mindmap, docx, ppt, bitable
22
+ */
23
+ async createDocument(spaceId, folderId, title, docType = 'doc') {
24
+ return this.post('/doc/create', {
25
+ spaceid: spaceId,
26
+ folderid: folderId,
27
+ title,
28
+ doc_type: docType
29
+ });
30
+ }
31
+
32
+ /**
33
+ * 重命名文档
34
+ * @param {string} spaceId 空间 ID
35
+ * @param {string} objId 文档或文件夹 ID
36
+ * @param {string} title 新标题
37
+ */
38
+ async renameDocument(spaceId, objId, title) {
39
+ return this.post('/doc/rename', {
40
+ spaceid: spaceId,
41
+ obj_id: objId,
42
+ title
43
+ });
44
+ }
45
+
46
+ /**
47
+ * 删除文档
48
+ * @param {string} spaceId 空间 ID
49
+ * @param {string} objId 文档或文件夹 ID
50
+ */
51
+ async deleteDocument(spaceId, objId) {
52
+ return this.post('/doc/delete', {
53
+ spaceid: spaceId,
54
+ obj_id: objId
55
+ });
56
+ }
57
+
58
+ /**
59
+ * 获取文档信息
60
+ * @param {string} spaceId 空间 ID
61
+ * @param {string} objId 文档 ID
62
+ */
63
+ async getDocumentInfo(spaceId, objId) {
64
+ return this.post('/doc/get', {
65
+ spaceid: spaceId,
66
+ obj_id: objId
67
+ });
68
+ }
69
+
70
+ /**
71
+ * 获取文档权限信息
72
+ * @param {string} spaceId 空间 ID
73
+ * @param {string} objId 文档或文件夹 ID
74
+ */
75
+ async getDocumentAuth(spaceId, objId) {
76
+ return this.post('/doc/get_auth', {
77
+ spaceid: spaceId,
78
+ obj_id: objId
79
+ });
80
+ }
81
+
82
+ /**
83
+ * 修改文档安全设置
84
+ * @param {string} spaceId 空间 ID
85
+ * @param {string} objId 文档 ID
86
+ * @param {object} security 安全设置
87
+ */
88
+ async updateDocumentSecurity(spaceId, objId, security) {
89
+ return this.post('/doc/set_security', {
90
+ spaceid: spaceId,
91
+ obj_id: objId,
92
+ security
93
+ });
94
+ }
95
+
96
+ // ========== 管理收集表 ==========
97
+
98
+ /**
99
+ * 创建收集表
100
+ * @param {string} spaceId 空间 ID
101
+ * @param {string} title 收集表标题
102
+ * @param {string} description 描述
103
+ * @param {object[]} questions 问题列表
104
+ */
105
+ async createSurvey(spaceId, title, description = '', questions = []) {
106
+ return this.post('/doc/survey/create', {
107
+ spaceid: spaceId,
108
+ title,
109
+ description,
110
+ questions
111
+ });
112
+ }
113
+
114
+ /**
115
+ * 编辑收集表
116
+ * @param {string} surveyId 收集表 ID
117
+ * @param {object} params 更新参数
118
+ */
119
+ async updateSurvey(surveyId, { title, description, questions, status }) {
120
+ return this.post('/doc/survey/update', {
121
+ survey_id: surveyId,
122
+ title,
123
+ description,
124
+ questions,
125
+ status
126
+ });
127
+ }
128
+
129
+ /**
130
+ * 获取收集表信息
131
+ * @param {string} surveyId 收集表 ID
132
+ */
133
+ async getSurveyInfo(surveyId) {
134
+ return this.post('/doc/survey/get', { survey_id: surveyId });
135
+ }
136
+
137
+ /**
138
+ * 获取收集表的统计信息
139
+ * @param {string} surveyId 收集表 ID
140
+ */
141
+ async getSurveyStats(surveyId) {
142
+ return this.post('/doc/survey/stats', { survey_id: surveyId });
143
+ }
144
+
145
+ /**
146
+ * 读取收集表答案
147
+ * @param {string} surveyId 收集表 ID
148
+ * @param {string} token 答案 token
149
+ */
150
+ async getSurveyAnswer(surveyId, token) {
151
+ return this.post('/doc/survey/get_answer', {
152
+ survey_id: surveyId,
153
+ token
154
+ });
155
+ }
156
+
157
+ /**
158
+ * 获取收集表答案列表
159
+ * @param {string} surveyId 收集表 ID
160
+ * @param {number} offset 偏移量
161
+ * @param {number} size 每页数量
162
+ */
163
+ async listSurveyAnswers(surveyId, offset = 0, size = 100) {
164
+ return this.post('/doc/survey/list_answer', {
165
+ survey_id: surveyId,
166
+ offset,
167
+ limit: size
168
+ });
169
+ }
170
+
171
+ // ========== 接收外部数据到智能表格 ==========
172
+
173
+ /**
174
+ * 添加记录
175
+ * @param {string} spaceId 空间 ID
176
+ * @param {string} tableId 表格 ID
177
+ * @param {object[]} records 记录列表
178
+ */
179
+ async addBitableRecords(spaceId, tableId, records) {
180
+ return this.post('/doc/bitable/record/add', {
181
+ spaceid: spaceId,
182
+ table_id: tableId,
183
+ records
184
+ });
185
+ }
186
+
187
+ /**
188
+ * 更新记录
189
+ * @param {string} spaceId 空间 ID
190
+ * @param {string} tableId 表格 ID
191
+ * @param {object[]} records 记录列表
192
+ */
193
+ async updateBitableRecords(spaceId, tableId, records) {
194
+ return this.post('/doc/bitable/record/update', {
195
+ spaceid: spaceId,
196
+ table_id: tableId,
197
+ records
198
+ });
199
+ }
200
+
201
+ /**
202
+ * 删除记录
203
+ * @param {string} spaceId 空间 ID
204
+ * @param {string} tableId 表格 ID
205
+ * @param {string[]} recordIds 记录 ID 列表
206
+ */
207
+ async deleteBitableRecords(spaceId, tableId, recordIds) {
208
+ return this.post('/doc/bitable/record/delete', {
209
+ spaceid: spaceId,
210
+ table_id: tableId,
211
+ record_ids: recordIds
212
+ });
213
+ }
214
+
215
+ // ========== 素材管理 ==========
216
+
217
+ /**
218
+ * 上传文档图片
219
+ * @param {string} spaceId 空间 ID
220
+ * @param {string} filePath 文件路径
221
+ */
222
+ async uploadDocImage(spaceId, filePath) {
223
+ const fs = require('fs');
224
+ if (!fs.existsSync(filePath)) {
225
+ throw new Error(`File not found: ${filePath}`);
226
+ }
227
+
228
+ const fileName = require('path').basename(filePath);
229
+ const fileBuffer = fs.readFileSync(filePath);
230
+
231
+ const formData = {
232
+ media: {
233
+ value: fileBuffer,
234
+ options: {
235
+ filename: fileName,
236
+ contentType: 'image/jpeg'
237
+ }
238
+ }
239
+ };
240
+
241
+ return this.post('/doc/media/upload_image', { media: formData }, {
242
+ spaceid: spaceId,
243
+ apiType: 'upload'
244
+ });
245
+ }
246
+
247
+ // ========== 高级功能账号管理 ==========
248
+
249
+ /**
250
+ * 分配高级功能账号
251
+ * @param {string} userId 成员 userid
252
+ * @param {string} type 高级功能类型
253
+ */
254
+ async assignAdvancedAccount(userId, type) {
255
+ return this.post('/doc/advanced_account/assign', {
256
+ userid: userId,
257
+ type
258
+ });
259
+ }
260
+
261
+ /**
262
+ * 取消高级功能账号
263
+ * @param {string} userId 成员 userid
264
+ * @param {string} type 高级功能类型
265
+ */
266
+ async cancelAdvancedAccount(userId, type) {
267
+ return this.post('/doc/advanced_account/cancel', {
268
+ userid: userId,
269
+ type
270
+ });
271
+ }
272
+
273
+ /**
274
+ * 获取高级功能账号列表
275
+ * @param {string} type 高级功能类型
276
+ */
277
+ async getAdvancedAccountList(type) {
278
+ return this.post('/doc/advanced_account/list', { type });
279
+ }
280
+ }
281
+
282
+ module.exports = Document;
@@ -0,0 +1,93 @@
1
+ /**
2
+ * 人事助手模块
3
+ * API 章节:二十四 - 人事助手
4
+ * 包含:花名册管理
5
+ */
6
+
7
+ const WeComSDK = require('../../sdk');
8
+
9
+ class HR extends WeComSDK {
10
+ constructor(config) {
11
+ super(config);
12
+ }
13
+
14
+ // ========== 花名册 ==========
15
+
16
+ /**
17
+ * 获取员工字段配置
18
+ * @param {number} fieldType 字段类型: 1-系统字段 2-自定义字段
19
+ */
20
+ async getUserFields(fieldType = 1) {
21
+ return this.post('/hr/getuserfieldconfig', { field_type: fieldType });
22
+ }
23
+
24
+ /**
25
+ * 获取员工花名册信息
26
+ * @param {string} userId 员工 userid
27
+ * @param {string[]} fieldIds 字段 ID 列表
28
+ */
29
+ async getUserProfile(userId, fieldIds = []) {
30
+ return this.post('/hr/getuserprofile', {
31
+ userid: userId,
32
+ field_ids: fieldIds
33
+ });
34
+ }
35
+
36
+ /**
37
+ * 批量获取员工花名册信息
38
+ * @param {string[]} userIds 员工 userid 列表
39
+ * @param {string[]} fieldIds 字段 ID 列表
40
+ */
41
+ async batchGetUserProfiles(userIds, fieldIds = []) {
42
+ return this.post('/hr/batchgetuserprofile', {
43
+ userids: userIds,
44
+ field_ids: fieldIds
45
+ });
46
+ }
47
+
48
+ /**
49
+ * 更新员工花名册信息
50
+ * @param {string} userId 员工 userid
51
+ * @param {object} fieldData 字段数据
52
+ */
53
+ async updateUserProfile(userId, fieldData) {
54
+ return this.post('/hr/updateuserprofile', {
55
+ userid: userId,
56
+ field_data: fieldData
57
+ });
58
+ }
59
+
60
+ // ========== 员工入职管理 ==========
61
+
62
+ /**
63
+ * 获取入职登记表 ID
64
+ * @param {string} groupId 登记表模板组 ID
65
+ */
66
+ async getRegisterId(groupId) {
67
+ return this.post('/hr/get_register_id', { group_id: groupId });
68
+ }
69
+
70
+ /**
71
+ * 获取员工登记信息
72
+ * @param {string} registerId 登记表 ID
73
+ * @param {string} userId 员工 userid
74
+ */
75
+ async getRegisterInfo(registerId, userId) {
76
+ return this.post('/hr/get_register_info', {
77
+ register_id: registerId,
78
+ userid: userId
79
+ });
80
+ }
81
+
82
+ // ========== 员工离职管理 ==========
83
+
84
+ /**
85
+ * 获取离职交接人员列表
86
+ * @param {string} userId 离职员工 userid
87
+ */
88
+ async getDimissionHandoverList(userId) {
89
+ return this.post('/hr/get_dimission_handover_list', { userid: userId });
90
+ }
91
+ }
92
+
93
+ module.exports = HR;