UNPKG

10.1 kBJavaScriptView Raw
1'use strict';
2
3var path = require('path');
4var fs = require('fs');
5
6var formstream = require('formstream');
7
8var util = require('./util');
9var wrapper = util.wrapper;
10var postJSON = util.postJSON;
11var make = util.make;
12
13/**
14 * 上传永久素材,分别有图片(image)、语音(voice)、和缩略图(thumb)
15 * 详情请见:<http://mp.weixin.qq.com/wiki/14/7e6c03263063f4813141c3e17dd4350a.html>
16 * Examples:
17 * ```
18 * api.uploadMaterial('filepath', type, callback);
19 * ```
20 * Callback:
21 *
22 * - `err`, 调用失败时得到的异常
23 * - `result`, 调用正常时得到的对象
24 *
25 * Result:
26 * ```
27 * {"type":"TYPE","media_id":"MEDIA_ID","created_at":123456789}
28 * ```
29 * Shortcut:
30 *
31 * - `exports.uploadImageMaterial(filepath, callback);`
32 * - `exports.uploadVoiceMaterial(filepath, callback);`
33 * - `exports.uploadThumbMaterial(filepath, callback);`
34 *
35 * @param {String} filepath 文件路径
36 * @param {String} type 媒体类型,可用值有image、voice、video、thumb
37 * @param {Function} callback 回调函数
38 */
39make(exports, 'uploadMaterial', function (filepath, type, callback) {
40 var that = this;
41 fs.stat(filepath, function (err, stat) {
42 if (err) {
43 return callback(err);
44 }
45 var form = formstream();
46 form.file('media', filepath, path.basename(filepath), stat.size);
47 var url = that.endpoint + '/cgi-bin/material/add_material?access_token=' + that.token.accessToken + '&type=' + type;
48 var opts = {
49 dataType: 'json',
50 type: 'POST',
51 timeout: 60000, // 60秒超时
52 headers: form.headers(),
53 stream: form
54 };
55 that.request(url, opts, wrapper(callback));
56 });
57});
58
59['image', 'voice', 'thumb'].forEach(function (type) {
60 var method = 'upload' + type[0].toUpperCase() + type.substring(1) + 'Material';
61 exports[method] = function (filepath, callback) {
62 this.uploadMaterial(filepath, type, callback);
63 };
64});
65
66/**
67 * 上传永久素材,视频(video)
68 * 详情请见:<http://mp.weixin.qq.com/wiki/14/7e6c03263063f4813141c3e17dd4350a.html>
69 * Examples:
70 * ```
71 * var description = {
72 * "title":VIDEO_TITLE,
73 * "introduction":INTRODUCTION
74 * };
75 * api.uploadVideoMaterial('filepath', description, callback);
76 * ```
77 * Callback:
78 *
79 * - `err`, 调用失败时得到的异常
80 * - `result`, 调用正常时得到的对象
81 *
82 * Result:
83 * ```
84 * {"media_id":"MEDIA_ID"}
85 * ```
86 *
87 * @param {String} filepath 视频文件路径
88 * @param {Object} description 描述
89 * @param {Function} callback 回调函数
90 */
91make(exports, 'uploadVideoMaterial', function (filepath, description, callback) {
92 var that = this;
93 fs.stat(filepath, function (err, stat) {
94 if (err) {
95 return callback(err);
96 }
97 var form = formstream();
98 form.file('media', filepath, path.basename(filepath), stat.size);
99 form.field('description', JSON.stringify(description));
100 var url = that.endpoint + '/cgi-bin/material/add_material?access_token=' + that.token.accessToken + '&type=video';
101 var opts = {
102 dataType: 'json',
103 type: 'POST',
104 timeout: 60000, // 60秒超时
105 headers: form.headers(),
106 stream: form
107 };
108 that.request(url, opts, wrapper(callback));
109 });
110});
111
112/**
113 * 新增永久图文素材
114 *
115 * News:
116 * ```
117 * {
118 * "articles": [
119 * {
120 * "title": TITLE,
121 * "thumb_media_id": THUMB_MEDIA_ID,
122 * "author": AUTHOR,
123 * "digest": DIGEST,
124 * "show_cover_pic": SHOW_COVER_PIC(0 / 1),
125 * "content": CONTENT,
126 * "content_source_url": CONTENT_SOURCE_URL
127 * },
128 * //若新增的是多图文素材,则此处应还有几段articles结构
129 * ]
130 * }
131 * ```
132 * Examples:
133 * ```
134 * api.uploadNewsMaterial(news, callback);
135 * ```
136 * Callback:
137 *
138 * - `err`, 调用失败时得到的异常
139 * - `result`, 调用正常时得到的对象
140 *
141 * Result:
142 * ```
143 * {"errcode":0,"errmsg":"ok"}
144 * ```
145 * @param {Object} news 图文对象
146 * @param {Function} callback 回调函数
147 */
148exports.uploadNewsMaterial = function (news, callback) {
149 this.preRequest(this._uploadNewsMaterial, arguments);
150};
151
152/*!
153 * 新增永久图文素材的未封装版本
154 */
155exports._uploadNewsMaterial = function (news, callback) {
156 var url = this.endpoint + '/cgi-bin/material/add_news?access_token=' + this.token.accessToken;
157 this.request(url, postJSON(news), wrapper(callback));
158};
159
160
161/**
162 * 更新永久图文素材
163 * 详情请见:<http://mp.weixin.qq.com/wiki/14/7e6c03263063f4813141c3e17dd4350a.html>
164 * News:
165 * ```
166 * {
167 * "media_id":MEDIA_ID,
168 * "index":INDEX,
169 * "articles": {
170 * "title": TITLE,
171 * "thumb_media_id": THUMB_MEDIA_ID,
172 * "author": AUTHOR,
173 * "digest": DIGEST,
174 * "show_cover_pic": SHOW_COVER_PIC(0 / 1),
175 * "content": CONTENT,
176 * "content_source_url": CONTENT_SOURCE_URL
177 * }
178 * }
179 * ```
180 * Examples:
181 * ```
182 * api.updateNewsMaterial(news, callback);
183 * ```
184 * Callback:
185 *
186 * - `err`, 调用失败时得到的异常
187 * - `result`, 调用正常时得到的对象
188 *
189 * Result:
190 * ```
191 * {"errcode":0,"errmsg":"ok"}
192 * ```
193 * @param {Object} news 图文对象
194 * @param {Function} callback 回调函数
195 */
196exports.updateNewsMaterial = function (news, callback) {
197 this.preRequest(this._updateNewsMaterial, arguments);
198};
199
200/*!
201 * 更新永久图文素材的未封装版本
202 */
203exports._updateNewsMaterial = function (news, callback) {
204 var url = this.endpoint + '/cgi-bin/material/update_news?access_token=' + this.token.accessToken;
205 this.request(url, postJSON(news), wrapper(callback));
206};
207
208
209/**
210 * 根据媒体ID获取永久素材
211 * 详情请见:<http://mp.weixin.qq.com/wiki/4/b3546879f07623cb30df9ca0e420a5d0.html>
212 * Examples:
213 * ```
214 * api.getMaterial('media_id', callback);
215 * ```
216 * Callback:
217 *
218 * - `err`, 调用失败时得到的异常
219 * - `result`, 调用正常时得到的文件Buffer对象
220 * - `res`, HTTP响应对象
221 *
222 * @param {String} mediaId 媒体文件的ID
223 * @param {Function} callback 回调函数
224 */
225exports.getMaterial = function (mediaId, callback) {
226 this.preRequest(this._getMaterial, arguments);
227};
228
229/*!
230 * 下载永久素材的未封装版本
231 */
232exports._getMaterial = function (mediaId, callback) {
233 var url = this.endpoint + '/cgi-bin/material/get_material?access_token=' + this.token.accessToken;
234 var opts = {
235 type: 'POST',
236 data: {'media_id': mediaId},
237 headers: {
238 'Content-Type': 'application/json'
239 }
240 };
241 opts.timeout = 60000; // 60秒超时
242 this.request(url, opts, wrapper(function (err, data, res) {
243 // handle some err
244 if (err) {
245 return callback(err);
246 }
247 var contentType = res.headers['content-type'];
248 if (contentType === 'application/json') {
249 var ret;
250 try {
251 ret = JSON.parse(data);
252 if (ret.errcode) {
253 err = new Error(ret.errmsg);
254 err.name = 'WeChatAPIError';
255 }
256 } catch (ex) {
257 return callback(ex, data, res);
258 }
259 return callback(err, ret, res);
260 }
261 // 输出Buffer对象
262 callback(null, data, res);
263 }));
264};
265
266/**
267 * 删除永久素材
268 * 详情请见:<http://mp.weixin.qq.com/wiki/5/e66f61c303db51a6c0f90f46b15af5f5.html>
269 * Examples:
270 * ```
271 * api.removeMaterial('media_id', callback);
272 * ```
273 * Callback:
274 *
275 * - `err`, 调用失败时得到的异常
276 * - `result`, 调用正常时得到的文件Buffer对象
277 * - `res`, HTTP响应对象
278 *
279 * @param {String} mediaId 媒体文件的ID
280 * @param {Function} callback 回调函数
281 */
282exports.removeMaterial = function (mediaId, callback) {
283 this.preRequest(this._removeMaterial, arguments);
284};
285
286/*!
287 * 删除永久素材的未封装版本
288 */
289exports._removeMaterial = function (mediaId, callback) {
290 var url = this.endpoint + '/cgi-bin/material/del_material?access_token=' + this.token.accessToken;
291 this.request(url, postJSON({'media_id': mediaId}), wrapper(callback));
292};
293
294
295/**
296 * 获取素材总数
297 * 详情请见:<http://mp.weixin.qq.com/wiki/16/8cc64f8c189674b421bee3ed403993b8.html>
298 * Examples:
299 * ```
300 * api.getMaterialCount(callback);
301 * ```
302 * Callback:
303 *
304 * - `err`, 调用失败时得到的异常
305 * - `result`, 调用正常时得到的文件Buffer对象
306 * - `res`, HTTP响应对象
307 *
308 * Result:
309 * ```
310 * {
311 * "voice_count":COUNT,
312 * "video_count":COUNT,
313 * "image_count":COUNT,
314 * "news_count":COUNT
315 * }
316 * ```
317 * @param {Function} callback 回调函数
318 */
319exports.getMaterialCount = function (callback) {
320 this.preRequest(this._getMaterialCount, arguments);
321};
322
323
324
325/*!
326 * 删除永久素材的未封装版本
327 */
328exports._getMaterialCount = function (callback) {
329 var url = this.endpoint + '/cgi-bin/material/get_materialcount?access_token=' + this.token.accessToken;
330 this.request(url, {dataType: 'json'}, wrapper(callback));
331};
332
333/**
334 * 获取永久素材列表
335 * 详情请见:<http://mp.weixin.qq.com/wiki/12/2108cd7aafff7f388f41f37efa710204.html>
336 * Examples:
337 * ```
338 * api.getMaterials(type, offset, count, callback);
339 * ```
340 * Callback:
341 *
342 * - `err`, 调用失败时得到的异常
343 * - `result`, 调用正常时得到的文件Buffer对象
344 * - `res`, HTTP响应对象
345 *
346 * Result:
347 * ```
348 * {
349 * "total_count": TOTAL_COUNT,
350 * "item_count": ITEM_COUNT,
351 * "item": [{
352 * "media_id": MEDIA_ID,
353 * "name": NAME,
354 * "update_time": UPDATE_TIME
355 * },
356 * //可能会有多个素材
357 * ]
358 * }
359 * ```
360 * @param {String} type 素材的类型,图片(image)、视频(video)、语音 (voice)、图文(news)
361 * @param {Number} offset 从全部素材的该偏移位置开始返回,0表示从第一个素材 返回
362 * @param {Number} count 返回素材的数量,取值在1到20之间
363 * @param {Function} callback 回调函数
364 */
365exports.getMaterials = function (type, offset, count, callback) {
366 this.preRequest(this._getMaterials, arguments);
367};
368
369
370
371/*!
372 * 获取永久素材列表的未封装版本
373 */
374exports._getMaterials = function (type, offset, count, callback) {
375 var url = this.endpoint + '/cgi-bin/material/batchget_material?access_token=' + this.token.accessToken;
376 var data = {
377 type: type,
378 offset: offset,
379 count: count
380 };
381 this.request(url, postJSON(data), wrapper(callback));
382};