0
# Material Management
1
2
Upload, download, and manage permanent and temporary media materials for WeChat Official Account content.
3
4
## Material Service Interface
5
6
```java { .api }
7
interface WxMpMaterialService {
8
// Temporary material operations
9
WxMediaUploadResult mediaUpload(String mediaType, String fileType, InputStream inputStream) throws WxErrorException;
10
WxMediaUploadResult mediaUpload(String mediaType, String fileType, File file) throws WxErrorException;
11
File mediaDownload(String mediaId) throws WxErrorException;
12
InputStream mediaDownload(String mediaId, boolean buffered) throws WxErrorException;
13
14
// Permanent material operations
15
WxMpMaterialUploadResult materialFileUpload(String mediaType, String fileName, InputStream inputStream) throws WxErrorException;
16
WxMpMaterialUploadResult materialFileUpload(String mediaType, File file) throws WxErrorException;
17
WxMpMaterialNewsUploadResult materialNewsUpload(WxMpMaterialNews news) throws WxErrorException;
18
WxMpMaterialVideoInfoResult materialVideoInfo(String mediaId) throws WxErrorException;
19
WxMpMaterialNews materialNewsInfo(String mediaId) throws WxErrorException;
20
InputStream materialImageOrVoiceDownload(String mediaId) throws WxErrorException;
21
WxMpMaterialFileBatchGetResult materialFileBatchGet(String type, int offset, int count) throws WxErrorException;
22
WxMpMaterialNewsBatchGetResult materialNewsBatchGet(int offset, int count) throws WxErrorException;
23
boolean materialDelete(String mediaId) throws WxErrorException;
24
WxMpMaterialCountResult materialCount() throws WxErrorException;
25
WxMpMaterialNewsUploadResult materialNewsUpdate(WxMpMaterialArticleUpdate wxMpMaterialArticleUpdate) throws WxErrorException;
26
27
// Image upload for articles
28
WxMpMaterialUploadResult materialImgUpload(File file) throws WxErrorException;
29
WxMpMaterialUploadResult materialImgUpload(InputStream inputStream, String fileName) throws WxErrorException;
30
}
31
```
32
33
## Data Models
34
35
### Upload Results
36
37
```java { .api }
38
class WxMediaUploadResult implements Serializable {
39
private String type;
40
private String mediaId;
41
private long createdAt;
42
43
public String getType();
44
public void setType(String type);
45
public String getMediaId();
46
public void setMediaId(String mediaId);
47
public long getCreatedAt();
48
public void setCreatedAt(long createdAt);
49
}
50
51
class WxMpMaterialUploadResult implements Serializable {
52
private String mediaId;
53
private String url;
54
55
public String getMediaId();
56
public void setMediaId(String mediaId);
57
public String getUrl();
58
public void setUrl(String url);
59
}
60
61
class WxMpMaterialNewsUploadResult extends WxMpMaterialUploadResult {
62
// Inherits mediaId and url fields
63
}
64
```
65
66
### News Materials
67
68
```java { .api }
69
class WxMpMaterialNews implements Serializable {
70
private List<WxMpMaterialNews.WxMpMaterialNewsArticle> articles;
71
72
public List<WxMpMaterialNewsArticle> getArticles();
73
public void setArticles(List<WxMpMaterialNewsArticle> articles);
74
public void addArticle(WxMpMaterialNewsArticle article);
75
76
public static class WxMpMaterialNewsArticle implements Serializable {
77
private String title;
78
private String author;
79
private String digest;
80
private String content;
81
private String contentSourceUrl;
82
private String thumbMediaId;
83
private Integer showCoverPic;
84
private Integer needOpenComment;
85
private Integer onlyFansCanComment;
86
87
public String getTitle();
88
public void setTitle(String title);
89
public String getAuthor();
90
public void setAuthor(String author);
91
public String getDigest();
92
public void setDigest(String digest);
93
public String getContent();
94
public void setContent(String content);
95
public String getContentSourceUrl();
96
public void setContentSourceUrl(String contentSourceUrl);
97
public String getThumbMediaId();
98
public void setThumbMediaId(String thumbMediaId);
99
public Integer getShowCoverPic();
100
public void setShowCoverPic(Integer showCoverPic);
101
public Integer getNeedOpenComment();
102
public void setNeedOpenComment(Integer needOpenComment);
103
public Integer getOnlyFansCanComment();
104
public void setOnlyFansCanComment(Integer onlyFansCanComment);
105
}
106
}
107
```
108
109
### Video Information
110
111
```java { .api }
112
class WxMpMaterialVideoInfoResult implements Serializable {
113
private String title;
114
private String description;
115
private String downUrl;
116
117
public String getTitle();
118
public void setTitle(String title);
119
public String getDescription();
120
public void setDescription(String description);
121
public String getDownUrl();
122
public void setDownUrl(String downUrl);
123
}
124
```
125
126
### Batch Get Results
127
128
```java { .api }
129
class WxMpMaterialFileBatchGetResult implements Serializable {
130
private int totalCount;
131
private int itemCount;
132
private List<WxMpMaterialFileBatchGetResult.WxMpMaterialFileBatchGetNewsItem> items;
133
134
public int getTotalCount();
135
public void setTotalCount(int totalCount);
136
public int getItemCount();
137
public void setItemCount(int itemCount);
138
public List<WxMpMaterialFileBatchGetNewsItem> getItems();
139
public void setItems(List<WxMpMaterialFileBatchGetNewsItem> items);
140
141
public static class WxMpMaterialFileBatchGetNewsItem implements Serializable {
142
private String mediaId;
143
private String name;
144
private long updateTime;
145
private String url;
146
147
public String getMediaId();
148
public void setMediaId(String mediaId);
149
public String getName();
150
public void setName(String name);
151
public long getUpdateTime();
152
public void setUpdateTime(long updateTime);
153
public String getUrl();
154
public void setUrl(String url);
155
}
156
}
157
158
class WxMpMaterialNewsBatchGetResult implements Serializable {
159
private int totalCount;
160
private int itemCount;
161
private List<WxMpMaterialNewsBatchGetResult.WxMpMaterialNewsBatchGetNewsItem> items;
162
163
public int getTotalCount();
164
public void setTotalCount(int totalCount);
165
public int getItemCount();
166
public void setItemCount(int itemCount);
167
public List<WxMpMaterialNewsBatchGetNewsItem> getItems();
168
public void setItems(List<WxMpMaterialNewsBatchGetNewsItem> items);
169
170
public static class WxMpMaterialNewsBatchGetNewsItem implements Serializable {
171
private String mediaId;
172
private WxMpMaterialNews content;
173
private long updateTime;
174
175
public String getMediaId();
176
public void setMediaId(String mediaId);
177
public WxMpMaterialNews getContent();
178
public void setContent(WxMpMaterialNews content);
179
public long getUpdateTime();
180
public void setUpdateTime(long updateTime);
181
}
182
}
183
```
184
185
### Material Count
186
187
```java { .api }
188
class WxMpMaterialCountResult implements Serializable {
189
private int voiceCount;
190
private int videoCount;
191
private int imageCount;
192
private int newsCount;
193
194
public int getVoiceCount();
195
public void setVoiceCount(int voiceCount);
196
public int getVideoCount();
197
public void setVideoCount(int videoCount);
198
public int getImageCount();
199
public void setImageCount(int imageCount);
200
public int getNewsCount();
201
public void setNewsCount(int newsCount);
202
}
203
```
204
205
### Article Update
206
207
```java { .api }
208
class WxMpMaterialArticleUpdate implements Serializable {
209
private String mediaId;
210
private int index;
211
private WxMpMaterialNews.WxMpMaterialNewsArticle articles;
212
213
public String getMediaId();
214
public void setMediaId(String mediaId);
215
public int getIndex();
216
public void setIndex(int index);
217
public WxMpMaterialNews.WxMpMaterialNewsArticle getArticles();
218
public void setArticles(WxMpMaterialNews.WxMpMaterialNewsArticle articles);
219
}
220
```
221
222
## Media Types
223
224
```java { .api }
225
// Common media type constants
226
public static final String MEDIA_TYPE_IMAGE = "image";
227
public static final String MEDIA_TYPE_VOICE = "voice";
228
public static final String MEDIA_TYPE_VIDEO = "video";
229
public static final String MEDIA_TYPE_THUMB = "thumb";
230
public static final String MEDIA_TYPE_NEWS = "news";
231
```
232
233
## Draft and Publishing Services
234
235
```java { .api }
236
interface WxMpDraftService {
237
// Draft operations
238
WxMpDraftUploadResult addDraft(WxMpDraftArticles articles) throws WxErrorException;
239
WxMpDraftArticles getDraft(String mediaId) throws WxErrorException;
240
void delDraft(String mediaId) throws WxErrorException;
241
WxMpDraftUpdateResult updateDraft(String mediaId, int index, WxMpDraftArticles articles) throws WxErrorException;
242
WxMpDraftListResult getDraftList(int offset, int count, int noContent) throws WxErrorException;
243
int getDraftTotalCount() throws WxErrorException;
244
}
245
246
interface WxMpFreePublishService {
247
// Free publishing operations
248
WxMpFreePublishResult submitPublish(String mediaId) throws WxErrorException;
249
WxMpFreePublishStatus getPublishStatus(String publishId) throws WxErrorException;
250
void deletePublish(String articleId, int index) throws WxErrorException;
251
WxMpFreePublishArticles getPublishArticle(String articleId) throws WxErrorException;
252
WxMpFreePublishList getPublishList(int offset, int count, int noContent) throws WxErrorException;
253
}
254
```
255
256
## Usage Examples
257
258
### Upload Temporary Media
259
260
```java
261
// Upload image file
262
File imageFile = new File("path/to/image.jpg");
263
WxMediaUploadResult result = wxService.getMaterialService()
264
.mediaUpload(WxConsts.MediaFileType.IMAGE, "image", imageFile);
265
266
String mediaId = result.getMediaId();
267
System.out.println("Uploaded media ID: " + mediaId);
268
269
// Upload with InputStream
270
InputStream inputStream = new FileInputStream("path/to/voice.mp3");
271
WxMediaUploadResult voiceResult = wxService.getMaterialService()
272
.mediaUpload(WxConsts.MediaFileType.VOICE, "voice", inputStream);
273
```
274
275
### Download Temporary Media
276
277
```java
278
// Download as File
279
String mediaId = "media_id_from_upload";
280
File downloadedFile = wxService.getMaterialService().mediaDownload(mediaId);
281
282
// Download as InputStream
283
InputStream downloadStream = wxService.getMaterialService()
284
.mediaDownload(mediaId, true);
285
286
// Save to local file
287
try (FileOutputStream fos = new FileOutputStream("downloaded_media.jpg")) {
288
byte[] buffer = new byte[1024];
289
int bytesRead;
290
while ((bytesRead = downloadStream.read(buffer)) != -1) {
291
fos.write(buffer, 0, bytesRead);
292
}
293
}
294
```
295
296
### Upload Permanent Materials
297
298
```java
299
// Upload permanent image
300
File permanentImage = new File("path/to/permanent_image.jpg");
301
WxMpMaterialUploadResult permanentResult = wxService.getMaterialService()
302
.materialFileUpload(WxConsts.MediaFileType.IMAGE, permanentImage);
303
304
String permanentMediaId = permanentResult.getMediaId();
305
String imageUrl = permanentResult.getUrl();
306
307
// Upload permanent video with metadata
308
File videoFile = new File("path/to/video.mp4");
309
WxMpMaterialUploadResult videoResult = wxService.getMaterialService()
310
.materialFileUpload(WxConsts.MediaFileType.VIDEO, videoFile);
311
```
312
313
### Create and Upload News Articles
314
315
```java
316
// Create news article
317
WxMpMaterialNews news = new WxMpMaterialNews();
318
List<WxMpMaterialNews.WxMpMaterialNewsArticle> articles = new ArrayList<>();
319
320
// Create first article
321
WxMpMaterialNews.WxMpMaterialNewsArticle article1 =
322
new WxMpMaterialNews.WxMpMaterialNewsArticle();
323
article1.setTitle("Article Title");
324
article1.setAuthor("Author Name");
325
article1.setDigest("Article summary");
326
article1.setContent("<p>Article content in HTML</p>");
327
article1.setContentSourceUrl("https://example.com/source");
328
article1.setThumbMediaId("thumb_media_id");
329
article1.setShowCoverPic(1);
330
article1.setNeedOpenComment(1);
331
article1.setOnlyFansCanComment(0);
332
articles.add(article1);
333
334
// Add more articles if needed
335
WxMpMaterialNews.WxMpMaterialNewsArticle article2 =
336
new WxMpMaterialNews.WxMpMaterialNewsArticle();
337
article2.setTitle("Second Article");
338
article2.setAuthor("Author Name");
339
article2.setDigest("Second article summary");
340
article2.setContent("<p>Second article content</p>");
341
article2.setThumbMediaId("thumb_media_id_2");
342
articles.add(article2);
343
344
news.setArticles(articles);
345
346
// Upload news
347
WxMpMaterialNewsUploadResult newsResult = wxService.getMaterialService()
348
.materialNewsUpload(news);
349
String newsMediaId = newsResult.getMediaId();
350
```
351
352
### Update News Articles
353
354
```java
355
// Update specific article in news
356
WxMpMaterialArticleUpdate update = new WxMpMaterialArticleUpdate();
357
update.setMediaId("news_media_id");
358
update.setIndex(0); // Update first article (0-based index)
359
360
WxMpMaterialNews.WxMpMaterialNewsArticle updatedArticle =
361
new WxMpMaterialNews.WxMpMaterialNewsArticle();
362
updatedArticle.setTitle("Updated Title");
363
updatedArticle.setContent("<p>Updated content</p>");
364
updatedArticle.setThumbMediaId("updated_thumb_media_id");
365
366
update.setArticles(updatedArticle);
367
368
WxMpMaterialNewsUploadResult updateResult = wxService.getMaterialService()
369
.materialNewsUpdate(update);
370
```
371
372
### Get Material Information
373
374
```java
375
// Get video information
376
WxMpMaterialVideoInfoResult videoInfo = wxService.getMaterialService()
377
.materialVideoInfo("video_media_id");
378
System.out.println("Video title: " + videoInfo.getTitle());
379
System.out.println("Video description: " + videoInfo.getDescription());
380
381
// Get news information
382
WxMpMaterialNews newsInfo = wxService.getMaterialService()
383
.materialNewsInfo("news_media_id");
384
List<WxMpMaterialNews.WxMpMaterialNewsArticle> articles = newsInfo.getArticles();
385
for (WxMpMaterialNews.WxMpMaterialNewsArticle article : articles) {
386
System.out.println("Article: " + article.getTitle());
387
}
388
```
389
390
### Download Permanent Materials
391
392
```java
393
// Download permanent image or voice
394
InputStream permanentStream = wxService.getMaterialService()
395
.materialImageOrVoiceDownload("permanent_media_id");
396
397
// Save to file
398
try (FileOutputStream fos = new FileOutputStream("permanent_material.jpg")) {
399
byte[] buffer = new byte[1024];
400
int bytesRead;
401
while ((bytesRead = permanentStream.read(buffer)) != -1) {
402
fos.write(buffer, 0, bytesRead);
403
}
404
}
405
```
406
407
### Batch Get Materials
408
409
```java
410
// Get permanent images in batches
411
WxMpMaterialFileBatchGetResult imageList = wxService.getMaterialService()
412
.materialFileBatchGet(WxConsts.MediaFileType.IMAGE, 0, 20);
413
414
System.out.println("Total images: " + imageList.getTotalCount());
415
for (WxMpMaterialFileBatchGetResult.WxMpMaterialFileBatchGetNewsItem item : imageList.getItems()) {
416
System.out.println("Image: " + item.getName() + " - " + item.getMediaId());
417
}
418
419
// Get news articles in batches
420
WxMpMaterialNewsBatchGetResult newsList = wxService.getMaterialService()
421
.materialNewsBatchGet(0, 20);
422
423
System.out.println("Total news: " + newsList.getTotalCount());
424
for (WxMpMaterialNewsBatchGetResult.WxMpMaterialNewsBatchGetNewsItem item : newsList.getItems()) {
425
System.out.println("News: " + item.getMediaId());
426
WxMpMaterialNews content = item.getContent();
427
for (WxMpMaterialNews.WxMpMaterialNewsArticle article : content.getArticles()) {
428
System.out.println(" Article: " + article.getTitle());
429
}
430
}
431
```
432
433
### Get Material Count
434
435
```java
436
// Get count of all material types
437
WxMpMaterialCountResult count = wxService.getMaterialService().materialCount();
438
System.out.println("Images: " + count.getImageCount());
439
System.out.println("Videos: " + count.getVideoCount());
440
System.out.println("Voices: " + count.getVoiceCount());
441
System.out.println("News: " + count.getNewsCount());
442
```
443
444
### Delete Materials
445
446
```java
447
// Delete permanent material
448
boolean deleted = wxService.getMaterialService().materialDelete("media_id_to_delete");
449
if (deleted) {
450
System.out.println("Material deleted successfully");
451
} else {
452
System.out.println("Failed to delete material");
453
}
454
```
455
456
### Upload Images for Articles
457
458
```java
459
// Upload image for use in article content
460
File articleImage = new File("path/to/article_image.jpg");
461
WxMpMaterialUploadResult articleImgResult = wxService.getMaterialService()
462
.materialImgUpload(articleImage);
463
464
String articleImageUrl = articleImgResult.getUrl();
465
466
// Use the URL in article content
467
String articleContent = "<p>Article text</p>" +
468
"<img src=\"" + articleImageUrl + "\" alt=\"Article Image\">" +
469
"<p>More article text</p>";
470
```
471
472
### Batch Operations
473
474
```java
475
// Get all permanent materials with pagination
476
List<WxMpMaterialFileBatchGetResult.WxMpMaterialFileBatchGetNewsItem> allImages = new ArrayList<>();
477
int offset = 0;
478
int count = 20;
479
WxMpMaterialFileBatchGetResult result;
480
481
do {
482
result = wxService.getMaterialService()
483
.materialFileBatchGet(WxConsts.MediaFileType.IMAGE, offset, count);
484
allImages.addAll(result.getItems());
485
offset += count;
486
} while (result.getItemCount() == count);
487
488
System.out.println("Retrieved " + allImages.size() + " images");
489
490
// Get all news articles
491
List<WxMpMaterialNewsBatchGetResult.WxMpMaterialNewsBatchGetNewsItem> allNews = new ArrayList<>();
492
offset = 0;
493
WxMpMaterialNewsBatchGetResult newsResult;
494
495
do {
496
newsResult = wxService.getMaterialService().materialNewsBatchGet(offset, count);
497
allNews.addAll(newsResult.getItems());
498
offset += count;
499
} while (newsResult.getItemCount() == count);
500
501
System.out.println("Retrieved " + allNews.size() + " news articles");
502
```
503
504
## File Size Limits
505
506
WeChat has specific file size limits for different media types:
507
508
- **Images**: 10MB max, supports JPG, PNG formats
509
- **Voice**: 2MB max, duration ≤ 60 seconds, supports AMR, MP3 formats
510
- **Video**: 10MB max, duration ≤ 60 seconds, supports MP4 format
511
- **Thumb**: 64KB max, supports JPG format
512
513
## Temporary vs Permanent Materials
514
515
### Temporary Materials
516
- Valid for 3 days
517
- Used for immediate message sending
518
- Limited storage quota
519
- Automatically cleaned up
520
521
### Permanent Materials
522
- No expiration time
523
- Used for long-term storage
524
- Higher storage quota
525
- Must be manually deleted
526
527
## Error Handling
528
529
```java
530
try {
531
WxMpMaterialUploadResult result = wxService.getMaterialService()
532
.materialFileUpload(WxConsts.MediaFileType.IMAGE, imageFile);
533
} catch (WxErrorException e) {
534
int errorCode = e.getError().getErrorCode();
535
536
switch (errorCode) {
537
case 40004:
538
System.err.println("Invalid media type");
539
break;
540
case 40005:
541
System.err.println("Invalid file type");
542
break;
543
case 40006:
544
System.err.println("Invalid file size");
545
break;
546
case 40007:
547
System.err.println("Invalid media file id");
548
break;
549
case 40008:
550
System.err.println("Invalid message type");
551
break;
552
case 45001:
553
System.err.println("Media size out of limit");
554
break;
555
case 45002:
556
System.err.println("Message content out of limit");
557
break;
558
case 45003:
559
System.err.println("Title length out of limit");
560
break;
561
case 45004:
562
System.err.println("Description length out of limit");
563
break;
564
case 45005:
565
System.err.println("URL length out of limit");
566
break;
567
case 45006:
568
System.err.println("Picture URL length out of limit");
569
break;
570
default:
571
System.err.println("Upload failed: " + e.getError().getErrorMsg());
572
}
573
}
574
```
575
576
## Best Practices
577
578
1. **File Management**: Always close InputStreams and delete temporary files
579
2. **Error Handling**: Implement retry logic for network failures
580
3. **Quota Management**: Monitor material counts to avoid quota limits
581
4. **Naming Convention**: Use descriptive names for materials
582
5. **Content Validation**: Validate content before upload to avoid rejection
583
6. **Thumbnail Management**: Always upload thumbnails for videos
584
7. **URL Validation**: Ensure external URLs in articles are accessible