mirror of
https://gitee.com/binary/weixin-java-tools.git
synced 2025-08-20 00:44:25 +08:00
🆕 #3320【企业微信】增加异步上传临时素材相关接口
This commit is contained in:
parent
2279105fef
commit
2d8d1df00e
@ -2,6 +2,8 @@ package me.chanjar.weixin.cp.api;
|
||||
|
||||
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
|
||||
import me.chanjar.weixin.common.error.WxErrorException;
|
||||
import me.chanjar.weixin.cp.bean.media.MediaUploadByUrlReq;
|
||||
import me.chanjar.weixin.cp.bean.media.MediaUploadByUrlResult;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@ -133,4 +135,21 @@ public interface WxCpMediaService {
|
||||
* @throws WxErrorException the wx error exception
|
||||
*/
|
||||
String uploadImg(File file) throws WxErrorException;
|
||||
|
||||
/**
|
||||
* 生成异步上传任务
|
||||
* 跟上传临时素材拿到的media_id使用场景是不通用的,目前适配的接口如下:https://developer.work.weixin.qq.com/document/path/96488#%E4%BD%BF%E7%94%A8%E5%9C%BA%E6%99%AF%E8%AF%B4%E6%98%8E
|
||||
* @param req 请求参数
|
||||
* @return 返回异步任务id
|
||||
* @throws WxErrorException the wx error exception
|
||||
*/
|
||||
String uploadByUrl(MediaUploadByUrlReq req) throws WxErrorException;
|
||||
|
||||
/**
|
||||
* 查询异步任务结果
|
||||
* @param jobId 任务id。最长为128字节,60分钟内有效
|
||||
* @return 返回异步任务结果
|
||||
* @throws WxErrorException the wx error exception
|
||||
*/
|
||||
MediaUploadByUrlResult uploadByUrl(String jobId) throws WxErrorException;
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package me.chanjar.weixin.cp.api.impl;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
|
||||
import me.chanjar.weixin.common.error.WxErrorException;
|
||||
@ -9,8 +10,12 @@ import me.chanjar.weixin.common.util.http.BaseMediaDownloadRequestExecutor;
|
||||
import me.chanjar.weixin.common.util.http.InputStreamData;
|
||||
import me.chanjar.weixin.common.util.http.MediaInputStreamUploadRequestExecutor;
|
||||
import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor;
|
||||
import me.chanjar.weixin.common.util.json.GsonHelper;
|
||||
import me.chanjar.weixin.common.util.json.GsonParser;
|
||||
import me.chanjar.weixin.cp.api.WxCpMediaService;
|
||||
import me.chanjar.weixin.cp.api.WxCpService;
|
||||
import me.chanjar.weixin.cp.bean.media.MediaUploadByUrlReq;
|
||||
import me.chanjar.weixin.cp.bean.media.MediaUploadByUrlResult;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@ -20,7 +25,12 @@ import java.net.URL;
|
||||
import java.nio.file.Files;
|
||||
import java.util.UUID;
|
||||
|
||||
import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.Media.*;
|
||||
import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.Media.GET_UPLOAD_BY_URL_RESULT;
|
||||
import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.Media.IMG_UPLOAD;
|
||||
import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.Media.JSSDK_MEDIA_GET;
|
||||
import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.Media.MEDIA_GET;
|
||||
import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.Media.MEDIA_UPLOAD;
|
||||
import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.Media.UPLOAD_BY_URL;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
@ -119,4 +129,20 @@ public class WxCpMediaServiceImpl implements WxCpMediaService {
|
||||
return this.mainService.execute(MediaUploadRequestExecutor.create(this.mainService.getRequestHttp()), url, file)
|
||||
.getUrl();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String uploadByUrl(MediaUploadByUrlReq req) throws WxErrorException {
|
||||
final String url = this.mainService.getWxCpConfigStorage().getApiUrl(UPLOAD_BY_URL);
|
||||
String responseContent = this.mainService.post(url, req.toJson());
|
||||
return GsonHelper.getString(GsonParser.parse(responseContent), "jobid");
|
||||
}
|
||||
|
||||
@Override
|
||||
public MediaUploadByUrlResult uploadByUrl(String jobId) throws WxErrorException {
|
||||
final String url = this.mainService.getWxCpConfigStorage().getApiUrl(GET_UPLOAD_BY_URL_RESULT);
|
||||
JsonObject jsonObject = new JsonObject();
|
||||
jsonObject.addProperty("jobid", jobId);
|
||||
String post = this.mainService.post(url, jsonObject.toString());
|
||||
return MediaUploadByUrlResult.fromJson(post);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,58 @@
|
||||
package me.chanjar.weixin.cp.bean.media;
|
||||
|
||||
import lombok.Data;
|
||||
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
|
||||
|
||||
/**
|
||||
* 生成异步上传任务
|
||||
* @author <a href="https://github.com/imyzt">imyzt</a>
|
||||
* @date 2025/04/27
|
||||
*/
|
||||
@Data
|
||||
public class MediaUploadByUrlReq {
|
||||
|
||||
/**
|
||||
* 场景值。1-客户联系入群欢迎语素材(目前仅支持1)。 注意:每个场景值有对应的使用范围,详见上面的「使用场景说明」
|
||||
*/
|
||||
private Integer scene;
|
||||
|
||||
/**
|
||||
* 媒体文件类型。目前仅支持video-视频,file-普通文件 不超过32字节。
|
||||
*/
|
||||
private String type;
|
||||
|
||||
/**
|
||||
* 文件名,标识文件展示的名称。比如,使用该media_id发消息时,展示的文件名由该字段控制。 不超过128字节。
|
||||
*/
|
||||
private String filename;
|
||||
|
||||
/**
|
||||
* 文件cdn url。url要求支持Range分块下载 不超过1024字节。 如果为腾讯云cos链接,则需要设置为「公有读」权限。
|
||||
*/
|
||||
private String url;
|
||||
|
||||
/**
|
||||
* 文件md5。对比从url下载下来的文件md5是否一致。 不超过32字节。
|
||||
*/
|
||||
private String md5;
|
||||
|
||||
/**
|
||||
* From json wx cp base resp.
|
||||
*
|
||||
* @param json the json
|
||||
* @return the wx cp base resp
|
||||
*/
|
||||
public static MediaUploadByUrlReq fromJson(String json) {
|
||||
return WxCpGsonBuilder.create().fromJson(json, MediaUploadByUrlReq.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* To json string.
|
||||
*
|
||||
* @return the string
|
||||
*/
|
||||
public String toJson() {
|
||||
return WxCpGsonBuilder.create().toJson(this);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
package me.chanjar.weixin.cp.bean.media;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import me.chanjar.weixin.cp.bean.WxCpBaseResp;
|
||||
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 异步上传企微素材
|
||||
* @author <a href="https://github.com/imyzt">imyzt</a>
|
||||
* @date 2025/4/27
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class MediaUploadByUrlResult extends WxCpBaseResp implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 330834334738622341L;
|
||||
|
||||
/**
|
||||
* 任务状态。1-处理中,2-完成,3-异常失败
|
||||
*/
|
||||
@SerializedName("status")
|
||||
private Integer status;
|
||||
|
||||
@SerializedName("detail")
|
||||
private Detail detail;
|
||||
|
||||
@Data
|
||||
public static class Detail {
|
||||
|
||||
/**
|
||||
* 任务失败返回码。当status为3时返回非0,其他返回0
|
||||
* 830001 url非法 确认url是否支持Range分块下载
|
||||
* 830003 url下载数据失败 确认url本身是否能正常访问
|
||||
* 45001 文件大小超过限制 确认文件在5字节~200M范围内
|
||||
* 301019 文件MD5不匹配 确认url对应的文件内容md5,跟所填的md5参数是否一致
|
||||
* 注意: status=2时,此处微信并未返回任何值
|
||||
*/
|
||||
@SerializedName("errcode")
|
||||
private Integer errCode;
|
||||
|
||||
/**
|
||||
* 注意: status=2时,此处微信并未返回任何值
|
||||
*/
|
||||
@SerializedName("errmsg")
|
||||
private String errMsg;
|
||||
|
||||
/**
|
||||
* 媒体文件上传后获取的唯一标识,3天内有效。当status为2时返回。
|
||||
*/
|
||||
@SerializedName("media_id")
|
||||
private String mediaId;
|
||||
|
||||
/**
|
||||
* 媒体文件创建的时间戳。当status为2时返回。
|
||||
*/
|
||||
@SerializedName("created_at")
|
||||
private String createdAt;
|
||||
}
|
||||
|
||||
/**
|
||||
* From json wx cp media upload by url result.
|
||||
*
|
||||
* @param json the json
|
||||
* @return the wx cp media upload by url result
|
||||
*/
|
||||
public static MediaUploadByUrlResult fromJson(String json) {
|
||||
return WxCpGsonBuilder.create().fromJson(json, MediaUploadByUrlResult.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* To json string.
|
||||
*
|
||||
* @return the string
|
||||
*/
|
||||
public String toJson() {
|
||||
return WxCpGsonBuilder.create().toJson(this);
|
||||
}
|
||||
}
|
@ -198,6 +198,13 @@ public class WxCpXmlMessage implements Serializable {
|
||||
@XStreamAlias("SelectedItems")
|
||||
private List<SelectedItem> selectedItems;
|
||||
|
||||
/**
|
||||
* <a href="https://developer.work.weixin.qq.com/document/path/96488#%E5%9B%9E%E8%B0%83%E5%BC%82%E6%AD%A5%E4%BB%BB%E5%8A%A1%E7%BB%93%E6%9E%9C">异步任务id</a>
|
||||
*/
|
||||
@XStreamAlias("JobId")
|
||||
@XStreamConverter(value = XStreamCDataConverter.class)
|
||||
private String jobId;
|
||||
|
||||
/**
|
||||
* 微信客服
|
||||
* 调用拉取消息接口时,需要传此token,用于校验请求的合法性
|
||||
|
@ -238,6 +238,12 @@ public interface WxCpApiPathConsts {
|
||||
* The constant JSSDK_MEDIA_GET.
|
||||
*/
|
||||
String JSSDK_MEDIA_GET = "/cgi-bin/media/get/jssdk";
|
||||
|
||||
/** The constant GET_UPLOAD_BY_URL_RESULT. */
|
||||
String GET_UPLOAD_BY_URL_RESULT = "/cgi-bin/media/get_upload_by_url_result";
|
||||
|
||||
/** The constant UPLOAD_BY_URL. */
|
||||
String UPLOAD_BY_URL = "/cgi-bin/media/upload_by_url";
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -219,6 +219,11 @@ public class WxCpConsts {
|
||||
*/
|
||||
public static final String CUSTOMER_ACQUISITION = "customer_acquisition";
|
||||
|
||||
/**
|
||||
* <a href="https://developer.work.weixin.qq.com/document/path/96488#%E5%9B%9E%E8%B0%83%E5%BC%82%E6%AD%A5%E4%BB%BB%E5%8A%A1%E7%BB%93%E6%9E%9C">异步上传临时素材结果回调通知</a>
|
||||
*/
|
||||
public static final String UPLOAD_MEDIA_JOB_FINISH = "upload_media_job_finish";
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -7,6 +7,8 @@ import me.chanjar.weixin.common.error.WxErrorException;
|
||||
import me.chanjar.weixin.cp.api.ApiTestModule;
|
||||
import me.chanjar.weixin.cp.api.TestConstants;
|
||||
import me.chanjar.weixin.cp.api.WxCpService;
|
||||
import me.chanjar.weixin.cp.bean.media.MediaUploadByUrlReq;
|
||||
import me.chanjar.weixin.cp.bean.media.MediaUploadByUrlResult;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Guice;
|
||||
import org.testng.annotations.Test;
|
||||
@ -127,4 +129,38 @@ public class WxCpMediaServiceImplTest {
|
||||
assertThat(file).isNotNull();
|
||||
System.out.println(file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test upload media by url.
|
||||
*
|
||||
* @throws WxErrorException the wx error exception
|
||||
*/
|
||||
@Test
|
||||
public void testUploadMediaByUrl() throws WxErrorException {
|
||||
MediaUploadByUrlReq req = new MediaUploadByUrlReq();
|
||||
req.setScene(1);
|
||||
req.setType("video");
|
||||
req.setFilename("mov_bbb");
|
||||
req.setUrl("https://www.w3school.com.cn/example/html5/mov_bbb.mp4");
|
||||
req.setMd5("198918f40ecc7cab0fc4231adaf67c96");
|
||||
String jobId = this.wxService.getMediaService().uploadByUrl(req);
|
||||
System.out.println(jobId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test upload media by url.
|
||||
*
|
||||
* @throws WxErrorException the wx error exception
|
||||
*/
|
||||
@Test
|
||||
public void testUploadMediaByUrlResult() throws WxErrorException, InterruptedException {
|
||||
String jobId = "job1745801375_5GIKWuFF3M7hcIkeSNMqs_W26xy5VeSWjLaLFTEdSfQ";
|
||||
MediaUploadByUrlResult result = this.wxService.getMediaService().uploadByUrl(jobId);
|
||||
System.out.println(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUploadMediaJobFinishEvent() throws WxErrorException {
|
||||
File file = this.wxService.getMediaService().getJssdkFile("....");
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import me.chanjar.weixin.cp.util.xml.XStreamTransformer;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static me.chanjar.weixin.cp.constant.WxCpConsts.EventType.TASKCARD_CLICK;
|
||||
import static me.chanjar.weixin.cp.constant.WxCpConsts.EventType.UPLOAD_MEDIA_JOB_FINISH;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
@ -421,4 +422,24 @@ public class WxCpXmlMessageTest {
|
||||
assertThat(wxCpXmlMessage.getApprovalInfo().getApprovalNodes().get(0).getItems().get(0).getItemName()).isNotEmpty();
|
||||
assertThat(wxCpXmlMessage.getApprovalInfo().getNotifyNodes().get(0).getItemName()).isNotEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test open approval change.
|
||||
*/
|
||||
public void testUploadMediaJobFinishEvent() {
|
||||
String xml = "<xml>\n" +
|
||||
"\t<ToUserName><![CDATA[wx28dbb14e3720FAKE]]></ToUserName>\n" +
|
||||
"\t<FromUserName><![CDATA[sys]]></FromUserName>\n" +
|
||||
"\t<CreateTime>1425284517</CreateTime>\n" +
|
||||
"\t<MsgType><![CDATA[event]]></MsgType>\n" +
|
||||
"\t<Event><![CDATA[upload_media_job_finish]]></Event>\n" +
|
||||
"\t<JobId><![CDATA[jobid_S0MrnndvRG5fadSlLwiBqiDDbM143UqTmKP3152FZk4]]></JobId>\n" +
|
||||
"</xml>";
|
||||
|
||||
WxCpXmlMessage wxCpXmlMessage = WxCpXmlMessage.fromXml(xml);
|
||||
assertThat(wxCpXmlMessage).isNotNull();
|
||||
assertThat(wxCpXmlMessage.getJobId()).isNotEmpty();
|
||||
assertThat(wxCpXmlMessage.getJobId()).isEqualTo("jobid_S0MrnndvRG5fadSlLwiBqiDDbM143UqTmKP3152FZk4");
|
||||
assertThat(wxCpXmlMessage.getEvent()).isEqualTo(UPLOAD_MEDIA_JOB_FINISH);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user