@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,183 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 素材管理模块
|
|
3
|
+
* API 章节:十 - 素材管理
|
|
4
|
+
* 包含:临时素材、图片、高清语音
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const WeComSDK = require('../../sdk');
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
|
|
11
|
+
class Media extends WeComSDK {
|
|
12
|
+
constructor(config) {
|
|
13
|
+
super(config);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* 上传临时素材
|
|
18
|
+
* @param {string} filePath 文件路径
|
|
19
|
+
* @param {string} type 媒体类型: image, voice, video, file
|
|
20
|
+
*/
|
|
21
|
+
async uploadMedia(filePath, type = 'image') {
|
|
22
|
+
if (!fs.existsSync(filePath)) {
|
|
23
|
+
throw new Error(`File not found: ${filePath}`);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const fileName = path.basename(filePath);
|
|
27
|
+
const fileBuffer = fs.readFileSync(filePath);
|
|
28
|
+
|
|
29
|
+
const formData = {
|
|
30
|
+
media: {
|
|
31
|
+
value: fileBuffer,
|
|
32
|
+
options: {
|
|
33
|
+
filename: fileName,
|
|
34
|
+
contentType: this.getContentType(fileName)
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
return this.post('/media/upload', { media: formData }, {
|
|
40
|
+
type,
|
|
41
|
+
apiType: 'upload'
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* 获取临时素材
|
|
47
|
+
* @param {string} mediaId 媒体 id
|
|
48
|
+
* @param {string} savePath 保存路径
|
|
49
|
+
*/
|
|
50
|
+
async getMedia(mediaId, savePath) {
|
|
51
|
+
const response = await this.request({
|
|
52
|
+
method: 'GET',
|
|
53
|
+
url: '/media/get',
|
|
54
|
+
params: { media_id: mediaId },
|
|
55
|
+
responseType: 'stream'
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
if (savePath) {
|
|
59
|
+
const writer = fs.createWriteStream(savePath);
|
|
60
|
+
response.data.pipe(writer);
|
|
61
|
+
return new Promise((resolve, reject) => {
|
|
62
|
+
writer.on('finish', () => resolve({ savePath }));
|
|
63
|
+
writer.on('error', reject);
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return response.data;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* 上传图片
|
|
72
|
+
* @param {string} filePath 图片路径
|
|
73
|
+
*/
|
|
74
|
+
async uploadImage(filePath) {
|
|
75
|
+
if (!fs.existsSync(filePath)) {
|
|
76
|
+
throw new Error(`File not found: ${filePath}`);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const fileName = path.basename(filePath);
|
|
80
|
+
const fileBuffer = fs.readFileSync(filePath);
|
|
81
|
+
|
|
82
|
+
const formData = {
|
|
83
|
+
media: {
|
|
84
|
+
value: fileBuffer,
|
|
85
|
+
options: {
|
|
86
|
+
filename: fileName,
|
|
87
|
+
contentType: 'image/jpeg'
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
return this.post('/media/uploadimg', { media: formData }, {
|
|
93
|
+
apiType: 'upload'
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* 获取高清语音素材
|
|
99
|
+
* @param {string} mediaId 媒体 id
|
|
100
|
+
* @param {string} savePath 保存路径
|
|
101
|
+
*/
|
|
102
|
+
async getHighDefinitionVoice(mediaId, savePath) {
|
|
103
|
+
const response = await this.request({
|
|
104
|
+
method: 'GET',
|
|
105
|
+
url: '/media/get/fcvoice',
|
|
106
|
+
params: { media_id: mediaId },
|
|
107
|
+
responseType: 'stream'
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
if (savePath) {
|
|
111
|
+
const writer = fs.createWriteStream(savePath);
|
|
112
|
+
response.data.pipe(writer);
|
|
113
|
+
return new Promise((resolve, reject) => {
|
|
114
|
+
writer.on('finish', () => resolve({ savePath }));
|
|
115
|
+
writer.on('error', reject);
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return response.data;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* 异步上传临时素材
|
|
124
|
+
* @param {string} filePath 文件路径
|
|
125
|
+
* @param {string} type 媒体类型
|
|
126
|
+
*/
|
|
127
|
+
async asyncUploadMedia(filePath, type = 'image') {
|
|
128
|
+
if (!fs.existsSync(filePath)) {
|
|
129
|
+
throw new Error(`File not found: ${filePath}`);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const fileName = path.basename(filePath);
|
|
133
|
+
const fileBuffer = fs.readFileSync(filePath);
|
|
134
|
+
|
|
135
|
+
const formData = {
|
|
136
|
+
media: {
|
|
137
|
+
value: fileBuffer,
|
|
138
|
+
options: {
|
|
139
|
+
filename: fileName,
|
|
140
|
+
contentType: this.getContentType(fileName)
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
return this.post('/media/async_upload', { media: formData }, {
|
|
146
|
+
type,
|
|
147
|
+
apiType: 'upload'
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* 根据文件扩展名获取 Content-Type
|
|
153
|
+
* @param {string} fileName 文件名
|
|
154
|
+
*/
|
|
155
|
+
getContentType(fileName) {
|
|
156
|
+
const ext = path.extname(fileName).toLowerCase();
|
|
157
|
+
const types = {
|
|
158
|
+
'.jpg': 'image/jpeg',
|
|
159
|
+
'.jpeg': 'image/jpeg',
|
|
160
|
+
'.png': 'image/png',
|
|
161
|
+
'.gif': 'image/gif',
|
|
162
|
+
'.bmp': 'image/bmp',
|
|
163
|
+
'.webp': 'image/webp',
|
|
164
|
+
'.mp3': 'audio/mpeg',
|
|
165
|
+
'.wma': 'audio/x-wav',
|
|
166
|
+
'.wav': 'audio/x-wav',
|
|
167
|
+
'.amr': 'audio/amr',
|
|
168
|
+
'.mp4': 'video/mp4',
|
|
169
|
+
'.avi': 'video/x-msvideo',
|
|
170
|
+
'.pdf': 'application/pdf',
|
|
171
|
+
'.doc': 'application/msword',
|
|
172
|
+
'.docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
|
173
|
+
'.xls': 'application/vnd.ms-excel',
|
|
174
|
+
'.xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
|
175
|
+
'.ppt': 'application/vnd.ms-powerpoint',
|
|
176
|
+
'.pptx': 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
|
|
177
|
+
'.zip': 'application/zip'
|
|
178
|
+
};
|
|
179
|
+
return types[ext] || 'application/octet-stream';
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
module.exports = Media;
|