@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,178 @@
1
+ /**
2
+ * 会议室模块
3
+ * API 章节:二十五 - 会议室
4
+ * 包含:会议室管理、会议室预定管理
5
+ * 注意:与会议模块(meeting)的Rooms不同,这里是独立的会议室系统
6
+ */
7
+
8
+ const WeComSDK = require('../../sdk');
9
+
10
+ class Room extends WeComSDK {
11
+ constructor(config) {
12
+ super(config);
13
+ }
14
+
15
+ // ========== 会议室管理 ==========
16
+
17
+ /**
18
+ * 获取会议室列表
19
+ * @param {number} offset 偏移量
20
+ * @param {number} size 每页数量
21
+ */
22
+ async getMeetingRoomList(offset = 0, size = 100) {
23
+ return this.post('/meetingroom/list', { offset, limit: size });
24
+ }
25
+
26
+ /**
27
+ * 获取会议室详情
28
+ * @param {string} meetingRoomId 会议室 ID
29
+ */
30
+ async getMeetingRoomDetail(meetingRoomId) {
31
+ return this.post('/meetingroom/get', { meetingroom_id: meetingRoomId });
32
+ }
33
+
34
+ /**
35
+ * 添加会议室
36
+ * @param {object} room 会议室信息
37
+ */
38
+ async addMeetingRoom(room) {
39
+ return this.post('/meetingroom/add', room);
40
+ }
41
+
42
+ /**
43
+ * 修改会议室
44
+ * @param {string} meetingRoomId 会议室 ID
45
+ * @param {object} room 会议室信息
46
+ */
47
+ async updateMeetingRoom(meetingRoomId, room) {
48
+ return this.post('/meetingroom/edit', {
49
+ meetingroom_id: meetingRoomId,
50
+ ...room
51
+ });
52
+ }
53
+
54
+ /**
55
+ * 删除会议室
56
+ * @param {string} meetingRoomId 会议室 ID
57
+ */
58
+ async deleteMeetingRoom(meetingRoomId) {
59
+ return this.post('/meetingroom/del', { meetingroom_id: meetingRoomId });
60
+ }
61
+
62
+ // ========== 会议室预定管理 ==========
63
+
64
+ /**
65
+ * 预定会议室
66
+ * @param {string} meetingRoomId 会议室 ID
67
+ * @param {number} startTime 开始时间戳
68
+ * @param {number} endTime 结束时间戳
69
+ * @param {string} userId 预定人 ID
70
+ * @param {string} subject 会议主题
71
+ */
72
+ async bookMeetingRoom(meetingRoomId, startTime, endTime, userId, subject = '') {
73
+ return this.post('/meetingroom/book', {
74
+ meetingroom_id: meetingRoomId,
75
+ start_time: startTime,
76
+ end_time: endTime,
77
+ userid: userId,
78
+ subject
79
+ });
80
+ }
81
+
82
+ /**
83
+ * 取消预定会议室
84
+ * @param {string} meetingRoomId 会议室 ID
85
+ * @param {string} bookingId 预定记录 ID
86
+ */
87
+ async cancelMeetingRoomBooking(meetingRoomId, bookingId) {
88
+ return this.post('/meetingroom/cancel_book', {
89
+ meetingroom_id: meetingRoomId,
90
+ booking_id: bookingId
91
+ });
92
+ }
93
+
94
+ /**
95
+ * 获取会议室预定情况
96
+ * @param {string} meetingRoomId 会议室 ID
97
+ * @param {number} startTime 开始时间戳
98
+ * @param {number} endTime 结束时间戳
99
+ */
100
+ async getMeetingRoomBookings(meetingRoomId, startTime, endTime) {
101
+ return this.post('/meetingroom/get_booking_info', {
102
+ meetingroom_id: meetingRoomId,
103
+ start_time: startTime,
104
+ end_time: endTime
105
+ });
106
+ }
107
+
108
+ /**
109
+ * 获取用户预定列表
110
+ * @param {string} userId 用户 ID
111
+ * @param {number} offset 偏移量
112
+ * @param {number} size 每页数量
113
+ */
114
+ async getUserBookings(userId, offset = 0, size = 100) {
115
+ return this.post('/meetingroom/user_booking_list', {
116
+ userid: userId,
117
+ offset,
118
+ limit: size
119
+ });
120
+ }
121
+
122
+ /**
123
+ * 获取会议室可用时间
124
+ * @param {string} meetingRoomId 会议室 ID
125
+ * @param {number} startTime 开始时间戳
126
+ * @param {number} endTime 结束时间戳
127
+ */
128
+ async getMeetingRoomAvailableTime(meetingRoomId, startTime, endTime) {
129
+ return this.post('/meetingroom/get_available_time', {
130
+ meetingroom_id: meetingRoomId,
131
+ start_time: startTime,
132
+ end_time: endTime
133
+ });
134
+ }
135
+
136
+ /**
137
+ * 设置会议室管理员
138
+ * @param {string} meetingRoomId 会议室 ID
139
+ * @param {string[]} userIds 管理员 userid 列表
140
+ */
141
+ async setMeetingRoomAdmins(meetingRoomId, userIds) {
142
+ return this.post('/meetingroom/set_admins', {
143
+ meetingroom_id: meetingRoomId,
144
+ userids: userIds
145
+ });
146
+ }
147
+
148
+ // ========== 会议室分组管理 ==========
149
+
150
+ /**
151
+ * 获取会议室分组列表
152
+ */
153
+ async getMeetingRoomGroupList() {
154
+ return this.post('/meetingroom/group_list', {});
155
+ }
156
+
157
+ /**
158
+ * 创建会议室分组
159
+ * @param {string} groupName 分组名称
160
+ * @param {string[]} roomIds 会议室 ID 列表
161
+ */
162
+ async createMeetingRoomGroup(groupName, roomIds) {
163
+ return this.post('/meetingroom/group_add', {
164
+ group_name: groupName,
165
+ meetingroom_ids: roomIds
166
+ });
167
+ }
168
+
169
+ /**
170
+ * 删除会议室分组
171
+ * @param {string} groupId 分组 ID
172
+ */
173
+ async deleteMeetingRoomGroup(groupId) {
174
+ return this.post('/meetingroom/group_del', { group_id: groupId });
175
+ }
176
+ }
177
+
178
+ module.exports = Room;
@@ -0,0 +1,246 @@
1
+ /**
2
+ * 日程管理模块
3
+ * API 章节:十六 - 日程
4
+ * 包含:管理日历、管理日程
5
+ */
6
+
7
+ const WeComSDK = require('../../sdk');
8
+
9
+ class Schedule extends WeComSDK {
10
+ constructor(config) {
11
+ super(config);
12
+ }
13
+
14
+ // ========== 管理日历 ==========
15
+
16
+ /**
17
+ * 创建日历
18
+ * @param {object} params 日历参数
19
+ */
20
+ async createCalendar(params) {
21
+ const { title, color, description, shares, calendarIds } = params;
22
+ return this.post('/oa/calendar/add', {
23
+ calendar: {
24
+ title,
25
+ color,
26
+ description,
27
+ shares,
28
+ calendar_ids: calendarIds
29
+ }
30
+ });
31
+ }
32
+
33
+ /**
34
+ * 更新日历
35
+ * @param {string} calendarId 日历 id
36
+ * @param {object} params 更新参数
37
+ */
38
+ async updateCalendar(calendarId, { title, color, description, shares }) {
39
+ return this.post('/oa/calendar/update', {
40
+ calendar: {
41
+ calendar_id: calendarId,
42
+ title,
43
+ color,
44
+ description,
45
+ shares
46
+ }
47
+ });
48
+ }
49
+
50
+ /**
51
+ * 获取日历详情
52
+ * @param {string} calendarId 日历 id
53
+ */
54
+ async getCalendar(calendarId) {
55
+ return this.post('/oa/calendar/get', { calendar_id: calendarId });
56
+ }
57
+
58
+ /**
59
+ * 删除日历
60
+ * @param {string} calendarId 日历 id
61
+ */
62
+ async deleteCalendar(calendarId) {
63
+ return this.post('/oa/calendar/del', { calendar_id: calendarId });
64
+ }
65
+
66
+ // ========== 管理日程 ==========
67
+
68
+ /**
69
+ * 创建日程
70
+ * @param {object} params 日程参数
71
+ */
72
+ async createEvent(params) {
73
+ const {
74
+ organizer, title, startTime, endTime, attendees,
75
+ description, location, reminders, meetingId, roomId
76
+ } = params;
77
+
78
+ const event = {
79
+ organizer,
80
+ title,
81
+ start: {
82
+ timestamp: Math.floor(new Date(startTime).getTime() / 1000),
83
+ timezone: 'Asia/Shanghai'
84
+ },
85
+ end: {
86
+ timestamp: Math.floor(new Date(endTime).getTime() / 1000),
87
+ timezone: 'Asia/Shanghai'
88
+ }
89
+ };
90
+
91
+ if (attendees) event.attendees = attendees;
92
+ if (description) event.description = description;
93
+ if (location) event.location = { name: location };
94
+ if (reminders) event.reminders = reminders;
95
+ if (meetingId) event.meeting_id = meetingId;
96
+ if (roomId) event.room_id = roomId;
97
+
98
+ return this.post('/oa/schedule/add', { schedule: event });
99
+ }
100
+
101
+ /**
102
+ * 更新日程
103
+ * @param {string} scheduleId 日程 id
104
+ * @param {object} params 更新参数
105
+ */
106
+ async updateEvent(scheduleId, params) {
107
+ const { title, startTime, endTime, attendees, description, location, reminders } = params;
108
+
109
+ const event = {
110
+ schedule_id: scheduleId
111
+ };
112
+
113
+ if (title) event.title = title;
114
+ if (startTime) {
115
+ event.start = {
116
+ timestamp: Math.floor(new Date(startTime).getTime() / 1000),
117
+ timezone: 'Asia/Shanghai'
118
+ };
119
+ }
120
+ if (endTime) {
121
+ event.end = {
122
+ timestamp: Math.floor(new Date(endTime).getTime() / 1000),
123
+ timezone: 'Asia/Shanghai'
124
+ };
125
+ }
126
+ if (attendees) event.attendees = attendees;
127
+ if (description) event.description = description;
128
+ if (location) event.location = { name: location };
129
+ if (reminders) event.reminders = reminders;
130
+
131
+ return this.post('/oa/schedule/update', { schedule: event });
132
+ }
133
+
134
+ /**
135
+ * 更新重复日程
136
+ * @param {string} scheduleId 日程 id
137
+ * @param {string} seriesId 重复系列 id
138
+ * @param {object} params 更新参数
139
+ */
140
+ async updateRecurringEvent(scheduleId, seriesId, params) {
141
+ const { title, startTime, endTime, attendees, description, location, reminders } = params;
142
+
143
+ const event = {
144
+ schedule_id: scheduleId,
145
+ series_id: seriesId
146
+ };
147
+
148
+ if (title) event.title = title;
149
+ if (startTime) {
150
+ event.start = {
151
+ timestamp: Math.floor(new Date(startTime).getTime() / 1000),
152
+ timezone: 'Asia/Shanghai'
153
+ };
154
+ }
155
+ if (endTime) {
156
+ event.end = {
157
+ timestamp: Math.floor(new Date(endTime).getTime() / 1000),
158
+ timezone: 'Asia/Shanghai'
159
+ };
160
+ }
161
+ if (attendees) event.attendees = attendees;
162
+ if (description) event.description = description;
163
+ if (location) event.location = { name: location };
164
+ if (reminders) event.reminders = reminders;
165
+
166
+ return this.post('/oa/schedule/update', { schedule: event });
167
+ }
168
+
169
+ /**
170
+ * 删除日程
171
+ * @param {string} scheduleId 日程 id
172
+ */
173
+ async deleteEvent(scheduleId) {
174
+ return this.post('/oa/schedule/del', { schedule_id: scheduleId });
175
+ }
176
+
177
+ /**
178
+ * 删除重复日程
179
+ * @param {string} scheduleId 日程 id
180
+ * @param {string} seriesId 重复系列 id
181
+ * @param {number} type 删除类型: 1-单日 2-后续 3-全部
182
+ */
183
+ async deleteRecurringEvent(scheduleId, seriesId, type = 1) {
184
+ return this.post('/oa/schedule/del', {
185
+ schedule_id: scheduleId,
186
+ series_id: seriesId,
187
+ type
188
+ });
189
+ }
190
+
191
+ /**
192
+ * 新增日程参与者
193
+ * @param {string} scheduleId 日程 id
194
+ * @param {string[]} attendees 参与者 userid 列表
195
+ */
196
+ async addEventAttendees(scheduleId, attendees) {
197
+ return this.post('/oa/schedule/addattendees', {
198
+ schedule_id: scheduleId,
199
+ attendees
200
+ });
201
+ }
202
+
203
+ /**
204
+ * 删除日程参与者
205
+ * @param {string} scheduleId 日程 id
206
+ * @param {string[]} attendees 参与者 userid 列表
207
+ */
208
+ async removeEventAttendees(scheduleId, attendees) {
209
+ return this.post('/oa/schedule/delattendees', {
210
+ schedule_id: scheduleId,
211
+ attendees
212
+ });
213
+ }
214
+
215
+ /**
216
+ * 获取日历下的日程列表
217
+ * @param {string} calendarId 日历 id
218
+ * @param {number} startTime 开始时间戳
219
+ * @param {number} endTime 结束时间戳
220
+ */
221
+ async getCalendarEvents(calendarId, startTime, endTime) {
222
+ return this.post('/oa/schedule/list', {
223
+ calendar_id: calendarId,
224
+ start_time: startTime,
225
+ end_time: endTime
226
+ });
227
+ }
228
+
229
+ /**
230
+ * 获取日程详情
231
+ * @param {string} scheduleId 日程 id
232
+ */
233
+ async getEventDetail(scheduleId) {
234
+ return this.post('/oa/schedule/get', { schedule_id: scheduleId });
235
+ }
236
+
237
+ /**
238
+ * 取消日程
239
+ * @param {string} scheduleId 日程 id
240
+ */
241
+ async cancelEvent(scheduleId) {
242
+ return this.deleteEvent(scheduleId);
243
+ }
244
+ }
245
+
246
+ module.exports = Schedule;
@@ -0,0 +1,199 @@
1
+ /**
2
+ * 家校消息模块
3
+ * API 章节:八 - 家校消息
4
+ * 包含:学校通知
5
+ */
6
+
7
+ const WeComSDK = require('../../sdk');
8
+
9
+ class School extends WeComSDK {
10
+ constructor(config) {
11
+ super(config);
12
+ }
13
+
14
+ // ========== 学校通知 ==========
15
+
16
+ /**
17
+ * 发送学校通知
18
+ * @param {string} userId 老师 ID
19
+ * @param {string} studentUserId 学生 userid(家校通知时必填)
20
+ * @param {object} content 通知内容
21
+ */
22
+ async sendSchoolNotice(userId, studentUserId, content) {
23
+ const { title, content: text, mediaId, msgType = 'text' } = content;
24
+
25
+ const params = {
26
+ userid: userId,
27
+ msgtype: msgType
28
+ };
29
+
30
+ // 如果是家校通知,需要传入学生信息
31
+ if (studentUserId) {
32
+ params.student_userid = studentUserId;
33
+ }
34
+
35
+ switch (msgType) {
36
+ case 'text':
37
+ params.text = { content: text };
38
+ break;
39
+ case 'image':
40
+ params.image = { media_id: mediaId };
41
+ break;
42
+ case 'voice':
43
+ params.voice = { media_id: mediaId };
44
+ break;
45
+ case 'video':
46
+ params.video = { media_id: mediaId };
47
+ break;
48
+ case 'file':
49
+ params.file = { media_id: mediaId };
50
+ break;
51
+ case 'news':
52
+ params.news = { articles: content.articles };
53
+ break;
54
+ case 'mpnews':
55
+ params.mpnews = { articles: content.articles };
56
+ break;
57
+ }
58
+
59
+ return this.post('/school/send_notice', params);
60
+ }
61
+
62
+ /**
63
+ * 获取学校通知发送结果
64
+ * @param {string} msgId 消息 ID
65
+ */
66
+ async getSchoolNoticeResult(msgId) {
67
+ return this.post('/school/get_notice_result', { msg_id: msgId });
68
+ }
69
+
70
+ /**
71
+ * 撤回学校通知
72
+ * @param {string} msgId 消息 ID
73
+ */
74
+ async recallSchoolNotice(msgId) {
75
+ return this.post('/school/recall_notice', { msg_id: msgId });
76
+ }
77
+
78
+ // ========== 家校通讯录 ==========
79
+
80
+ /**
81
+ * 获取班级列表
82
+ * @param {string} schoolId 学校 ID
83
+ * @param {number} offset 偏移量
84
+ * @param {number} size 每页数量
85
+ */
86
+ async getClassList(schoolId, offset = 0, size = 100) {
87
+ return this.post('/school/get_class_list', {
88
+ schoolid: schoolId,
89
+ offset,
90
+ limit: size
91
+ });
92
+ }
93
+
94
+ /**
95
+ * 获取学生列表
96
+ * @param {string} classId 班级 ID
97
+ * @param {number} offset 偏移量
98
+ * @param {number} size 每页数量
99
+ */
100
+ async getStudentList(classId, offset = 0, size = 100) {
101
+ return this.post('/school/get_student_list', {
102
+ classid: classId,
103
+ offset,
104
+ limit: size
105
+ });
106
+ }
107
+
108
+ /**
109
+ * 获取家长列表
110
+ * @param {string} studentUserId 学生 userid
111
+ */
112
+ async getParentList(studentUserId) {
113
+ return this.post('/school/get_parent_list', { student_userid: studentUserId });
114
+ }
115
+
116
+ /**
117
+ * 获取老师列表
118
+ * @param {string} schoolId 学校 ID
119
+ * @param {number} offset 偏移量
120
+ * @param {number} size 每页数量
121
+ */
122
+ async getTeacherList(schoolId, offset = 0, size = 100) {
123
+ return this.post('/school/get_teacher_list', {
124
+ schoolid: schoolId,
125
+ offset,
126
+ limit: size
127
+ });
128
+ }
129
+
130
+ // ========== 健康上报 ==========
131
+
132
+ /**
133
+ * 创建健康上报任务
134
+ * @param {string} schoolId 学校 ID
135
+ * @param {string} classId 班级 ID
136
+ * @param {object} task 上报任务配置
137
+ */
138
+ async createHealthReportTask(schoolId, classId, task) {
139
+ return this.post('/school/add_health_report_task', {
140
+ schoolid: schoolId,
141
+ classid: classId,
142
+ ...task
143
+ });
144
+ }
145
+
146
+ /**
147
+ * 获取健康上报统计
148
+ * @param {string} taskId 任务 ID
149
+ */
150
+ async getHealthReportStat(taskId) {
151
+ return this.post('/school/get_health_report_stat', { task_id: taskId });
152
+ }
153
+
154
+ /**
155
+ * 获取健康上报详情
156
+ * @param {string} taskId 任务 ID
157
+ * @param {string} studentUserId 学生 userid
158
+ */
159
+ async getHealthReportDetail(taskId, studentUserId) {
160
+ return this.post('/school/get_health_report_detail', {
161
+ task_id: taskId,
162
+ student_userid: studentUserId
163
+ });
164
+ }
165
+
166
+ // ========== 成绩管理 ==========
167
+
168
+ /**
169
+ * 发布成绩
170
+ * @param {string} schoolId 学校 ID
171
+ * @param {string} studentUserId 学生 userid
172
+ * @param {object} score 成绩信息
173
+ */
174
+ async publishScore(schoolId, studentUserId, score) {
175
+ return this.post('/school/publish_score', {
176
+ schoolid: schoolId,
177
+ student_userid: studentUserId,
178
+ ...score
179
+ });
180
+ }
181
+
182
+ /**
183
+ * 获取成绩列表
184
+ * @param {string} schoolId 学校 ID
185
+ * @param {string} studentUserId 学生 userid
186
+ * @param {number} offset 偏移量
187
+ * @param {number} size 每页数量
188
+ */
189
+ async getScoreList(schoolId, studentUserId, offset = 0, size = 100) {
190
+ return this.post('/school/get_score_list', {
191
+ schoolid: schoolId,
192
+ student_userid: studentUserId,
193
+ offset,
194
+ limit: size
195
+ });
196
+ }
197
+ }
198
+
199
+ module.exports = School;