or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced-services.mdindex.mdmaterial-management.mdmenu-management.mdmessage-handling.mdservice-management.mdshopping-guide.mdtemplate-messaging.mduser-management.md

material-management.mddocs/

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