MediaApi.cs 51 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091
  1. #region Apache License Version 2.0
  2. /*----------------------------------------------------------------
  3. Copyright 2019 Jeffrey Su & Suzhou Senparc Network Technology Co.,Ltd.
  4. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
  5. except in compliance with the License. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software distributed under the
  8. License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
  9. either express or implied. See the License for the specific language governing permissions
  10. and limitations under the License.
  11. Detail: https://github.com/JeffreySu/WeiXinMPSDK/blob/master/license.md
  12. ----------------------------------------------------------------*/
  13. #endregion Apache License Version 2.0
  14. /*----------------------------------------------------------------
  15. Copyright (C) 2019 Senparc
  16. 文件名:MediaAPI.cs
  17. 文件功能描述:素材管理接口(原多媒体文件接口)
  18. 创建标识:Senparc - 20150211
  19. 修改标识:Senparc - 20150303
  20. 修改描述:整理接口
  21. 修改标识:Senparc - 20150312
  22. 修改描述:开放代理请求超时时间
  23. 修改标识:Senparc - 20150321
  24. 修改描述:变更为素材管理接口
  25. 修改标识:Senparc - 20150401
  26. 修改描述:上传临时图文消息接口
  27. 修改标识:Senparc - 20150407
  28. 修改描述:上传永久视频接口修改
  29. 修改标识:Senparc - 20160703
  30. 修改描述:修改接口http为https
  31. 修改标识:Senparc - 20160719
  32. 修改描述:增加其接口的异步方法
  33. 修改标识:Senparc - 20170305
  34. 修改描述:v14.3.131 为MediaApi.Get()方法提供ApiHandlerWapper.TryCommonApi()方法支持,可以传入AppId
  35. 修改标识:Senparc - 20170707
  36. 修改描述:v14.5.1 完善异步方法async/await
  37. 修改标识:Senparc - 20180424
  38. 修改描述:v14.12.2 修正 MediaApi.GetForeverMedia() 方法永久视频的文件下载过程。
  39. 修改标识:Senparc - 20190129
  40. 修改描述:统一 CommonJsonSend.Send<T>() 方法请求接口
  41. ----------------------------------------------------------------*/
  42. /*
  43. 接口详见:http://mp.weixin.qq.com/wiki/index.php?title=%E4%B8%8A%E4%BC%A0%E4%B8%8B%E8%BD%BD%E5%A4%9A%E5%AA%92%E4%BD%93%E6%96%87%E4%BB%B6
  44. */
  45. using System.Collections.Generic;
  46. using System.IO;
  47. using System.Threading.Tasks;
  48. using Senparc.CO2NET.Extensions;
  49. using Senparc.NeuChar;
  50. using Senparc.Weixin.CommonAPIs;
  51. using Senparc.Weixin.Entities;
  52. using Senparc.Weixin.Helpers;
  53. using Senparc.Weixin.HttpUtility;
  54. using Senparc.Weixin.MP.AdvancedAPIs.GroupMessage;
  55. using Senparc.Weixin.MP.AdvancedAPIs.Media;
  56. using Senparc.Weixin.MP.CommonAPIs;
  57. namespace Senparc.Weixin.MP.AdvancedAPIs
  58. {
  59. /// <summary>
  60. /// 素材管理接口(原多媒体文件接口)
  61. /// </summary>
  62. public static class MediaApi
  63. {
  64. #region 同步方法
  65. #region 临时素材
  66. /// <summary>
  67. /// 新增临时素材(原上传媒体文件)
  68. /// </summary>
  69. /// <param name="accessTokenOrAppId">AccessToken或AppId(推荐使用AppId,需要先注册)</param>
  70. /// <param name="type">媒体文件类型</param>
  71. /// <param name="file">上传文件的绝对路径</param>
  72. /// <param name="timeOut">代理请求超时时间(毫秒)</param>
  73. /// <returns></returns>
  74. [ApiBind(NeuChar.PlatformType.WeChat_OfficialAccount, "MediaApi.UploadTemporaryMedia", true)]
  75. public static UploadTemporaryMediaResult UploadTemporaryMedia(string accessTokenOrAppId, UploadMediaFileType type, string file, int timeOut = Config.TIME_OUT)
  76. {
  77. return ApiHandlerWapper.TryCommonApi(accessToken =>
  78. {
  79. var url = string.Format(Config.ApiMpHost + "/cgi-bin/media/upload?access_token={0}&type={1}", accessToken.AsUrlData(), type.ToString().AsUrlData());
  80. var fileDictionary = new Dictionary<string, string>();
  81. fileDictionary["media"] = file;
  82. return CO2NET.HttpUtility.Post.PostFileGetJson<UploadTemporaryMediaResult>(url, null, fileDictionary, null, timeOut: timeOut);
  83. }, accessTokenOrAppId);
  84. }
  85. /// <summary>
  86. /// 上传临时图文消息素材(原上传图文消息素材)
  87. /// </summary>
  88. /// <param name="accessTokenOrAppId">Token</param>
  89. /// <param name="news">图文消息组</param>
  90. /// <param name="timeOut">代理请求超时时间(毫秒)</param>
  91. /// <returns></returns>
  92. [ApiBind(NeuChar.PlatformType.WeChat_OfficialAccount, "MediaApi.UploadTemporaryNews", true)]
  93. public static UploadTemporaryMediaResult UploadTemporaryNews(string accessTokenOrAppId, int timeOut = Config.TIME_OUT, params NewsModel[] news)
  94. {
  95. return ApiHandlerWapper.TryCommonApi(accessToken =>
  96. {
  97. string urlFormat = Config.ApiMpHost + "/cgi-bin/media/uploadnews?access_token={0}";
  98. var data = new
  99. {
  100. articles = news
  101. };
  102. return CommonJsonSend.Send<UploadTemporaryMediaResult>(accessToken, urlFormat, data, timeOut: timeOut);
  103. }, accessTokenOrAppId);
  104. }
  105. /// <summary>
  106. /// 获取临时素材(原下载媒体文件)
  107. /// </summary>
  108. /// <param name="accessTokenOrAppId">AccessToken或AppId(推荐使用AppId,需要先注册)</param>
  109. /// <param name="mediaId"></param>
  110. /// <param name="stream"></param>
  111. [ApiBind(NeuChar.PlatformType.WeChat_OfficialAccount, "MediaApi.Get", true)]
  112. public static void Get(string accessTokenOrAppId, string mediaId, Stream stream)
  113. {
  114. try
  115. {
  116. ApiHandlerWapper.TryCommonApi(accessToken =>
  117. {
  118. var url = string.Format(Config.ApiMpFileHost + "/cgi-bin/media/get?access_token={0}&media_id={1}", accessToken.AsUrlData(), mediaId.AsUrlData());
  119. CO2NET.HttpUtility.Get.Download(url, stream);
  120. return new WxJsonResult() { errcode = ReturnCode.请求成功, errmsg = "ok" };//无实际意义
  121. }, accessTokenOrAppId);
  122. }
  123. catch (System.Exception)
  124. {
  125. throw;
  126. }
  127. }
  128. /// <summary>
  129. /// 获取临时素材(原下载媒体文件),保存到指定文件夹
  130. /// </summary>
  131. /// <param name="accessTokenOrAppId">AccessToken或AppId(推荐使用AppId,需要先注册)</param>
  132. /// <param name="mediaId"></param>
  133. /// <param name="dir">储存目录</param>
  134. /// <returns>储存文件的完整路径</returns>
  135. [ApiBind(NeuChar.PlatformType.WeChat_OfficialAccount, "MediaApi.Get", true)]
  136. public static string Get(string accessTokenOrAppId, string mediaId, string dir)
  137. {
  138. var result = ApiHandlerWapper.TryCommonApi(accessToken =>
  139. {
  140. var url = string.Format(Config.ApiMpFileHost + "/cgi-bin/media/get?access_token={0}&media_id={1}", accessToken.AsUrlData(), mediaId.AsUrlData());
  141. var str = CO2NET.HttpUtility.Get.Download(url, dir);
  142. return new WxJsonResult() { errcode = ReturnCode.请求成功, errmsg = str };
  143. }, accessTokenOrAppId);
  144. return result.errmsg;
  145. }
  146. /// <summary>
  147. /// 附录:高清语音素材获取接口
  148. /// </summary>
  149. /// <param name="accessTokenOrAppId">AccessToken或AppId(推荐使用AppId,需要先注册)</param>
  150. /// <param name="mediaId"></param>
  151. /// <param name="stream"></param>
  152. /// <param name="timeOut"></param>
  153. /// <returns></returns>
  154. [ApiBind(NeuChar.PlatformType.WeChat_OfficialAccount, "MediaApi.GetJssdk", true)]
  155. public static WxJsonResult GetJssdk(string accessTokenOrAppId, string mediaId, Stream stream, int timeOut = Config.TIME_OUT)
  156. {
  157. return ApiHandlerWapper.TryCommonApi(accessToken =>
  158. {
  159. var urlFormat = string.Format(Config.ApiMpHost + "/cgi-bin/media/get/jssdk?access_token={0}&media_id={1}", accessToken.AsUrlData(), mediaId.AsUrlData());
  160. if (stream != null)
  161. {
  162. stream.Seek(0, SeekOrigin.Begin);
  163. CO2NET.HttpUtility.Get.Download(urlFormat, stream);
  164. }
  165. return new WxJsonResult() { errcode = ReturnCode.不合法的媒体文件id, errmsg = "invalid media_id" };//错误情况下的返回
  166. }, accessTokenOrAppId);
  167. }
  168. #endregion
  169. #region 永久素材
  170. /*
  171. 1、新增的永久素材也可以在公众平台官网素材管理模块中看到
  172. 2、永久素材的数量是有上限的,请谨慎新增。图文消息素材和图片素材的上限为5000,其他类型为1000
  173. 3、调用该接口需https协议
  174. */
  175. /// <summary>
  176. /// 新增永久图文素材
  177. /// </summary>
  178. /// <param name="accessTokenOrAppId">Token</param>
  179. /// <param name="news">图文消息组</param>
  180. /// <param name="timeOut">代理请求超时时间(毫秒)</param>
  181. /// <returns></returns>
  182. [ApiBind(NeuChar.PlatformType.WeChat_OfficialAccount, "MediaApi.UploadNews", true)]
  183. public static UploadForeverMediaResult UploadNews(string accessTokenOrAppId, int timeOut = Config.TIME_OUT, params NewsModel[] news)
  184. {
  185. return ApiHandlerWapper.TryCommonApi(accessToken =>
  186. {
  187. string urlFormat = Config.ApiMpHost + "/cgi-bin/material/add_news?access_token={0}";
  188. var data = new
  189. {
  190. articles = news
  191. };
  192. return CommonJsonSend.Send<UploadForeverMediaResult>(accessToken, urlFormat, data, timeOut: timeOut);
  193. }, accessTokenOrAppId);
  194. }
  195. /// <summary>
  196. /// 新增其他类型永久素材(图片(image)、语音(voice)和缩略图(thumb))
  197. /// </summary>
  198. /// <param name="accessTokenOrAppId">AccessToken或AppId(推荐使用AppId,需要先注册)</param>
  199. /// <param name="file">上传文件的绝对路径</param>
  200. /// <param name="timeOut">代理请求超时时间(毫秒)</param>
  201. /// <returns></returns>
  202. [ApiBind(NeuChar.PlatformType.WeChat_OfficialAccount, "MediaApi.UploadForeverMedia", true)]
  203. public static UploadForeverMediaResult UploadForeverMedia(string accessTokenOrAppId, string file, int timeOut = Config.TIME_OUT)
  204. {
  205. return ApiHandlerWapper.TryCommonApi(accessToken =>
  206. {
  207. var url = string.Format(Config.ApiMpHost + "/cgi-bin/material/add_material?access_token={0}", accessToken.AsUrlData());
  208. //因为有文件上传,所以忽略dataDictionary,全部改用文件上传格式
  209. //var dataDictionary = new Dictionary<string, string>();
  210. //dataDictionary["type"] = UploadMediaFileType.image.ToString();
  211. var fileDictionary = new Dictionary<string, string>();
  212. //fileDictionary["type"] = UploadMediaFileType.image.ToString();//不提供此参数也可以上传成功
  213. fileDictionary["media"] = file;
  214. return CO2NET.HttpUtility.Post.PostFileGetJson<UploadForeverMediaResult>(url, null, fileDictionary, null, timeOut: timeOut);
  215. }, accessTokenOrAppId);
  216. }
  217. /// <summary>
  218. /// 新增永久视频素材
  219. /// </summary>
  220. /// <param name="accessTokenOrAppId">AccessToken或AppId(推荐使用AppId,需要先注册)</param>
  221. /// <param name="file">上传文件的绝对路径</param>
  222. /// <param name="title"></param>
  223. /// <param name="introduction"></param>
  224. /// <param name="timeOut">代理请求超时时间(毫秒)</param>
  225. /// <returns></returns>
  226. [ApiBind(NeuChar.PlatformType.WeChat_OfficialAccount, "MediaApi.UploadForeverVideo", true)]
  227. public static UploadForeverMediaResult UploadForeverVideo(string accessTokenOrAppId, string file, string title, string introduction, int timeOut = 40000)
  228. {
  229. return ApiHandlerWapper.TryCommonApi(accessToken =>
  230. {
  231. var url = string.Format(Config.ApiMpHost + "/cgi-bin/material/add_material?access_token={0}", accessToken.AsUrlData());
  232. var fileDictionary = new Dictionary<string, string>();
  233. fileDictionary["media"] = file;
  234. fileDictionary["description"] = string.Format("{{\"title\":\"{0}\", \"introduction\":\"{1}\"}}", title, introduction);
  235. return CO2NET.HttpUtility.Post.PostFileGetJson<UploadForeverMediaResult>(url, null, fileDictionary, null, timeOut: timeOut);
  236. }, accessTokenOrAppId);
  237. }
  238. /// <summary>
  239. /// 获取永久图文素材
  240. /// </summary>
  241. /// <param name="accessTokenOrAppId">AccessToken或AppId(推荐使用AppId,需要先注册)</param>
  242. /// <param name="mediaId"></param>
  243. /// <param name="timeOut">代理请求超时时间(毫秒)</param>
  244. /// <returns></returns>
  245. [ApiBind(NeuChar.PlatformType.WeChat_OfficialAccount, "MediaApi.GetForeverNews", true)]
  246. public static GetNewsResultJson GetForeverNews(string accessTokenOrAppId, string mediaId, int timeOut = Config.TIME_OUT)
  247. {
  248. return ApiHandlerWapper.TryCommonApi(accessToken =>
  249. {
  250. string url = Config.ApiMpHost + "/cgi-bin/material/get_material?access_token={0}";
  251. var data = new
  252. {
  253. media_id = mediaId
  254. };
  255. return CommonJsonSend.Send<GetNewsResultJson>(accessToken, url, data, CommonJsonSendType.POST, timeOut: timeOut);
  256. }, accessTokenOrAppId);
  257. }
  258. /// <summary>
  259. /// 获取永久素材(除了图文、视频)
  260. /// </summary>
  261. /// <param name="accessTokenOrAppId">AccessToken或AppId(推荐使用AppId,需要先注册)</param>
  262. /// <param name="mediaId">要获取的素材的media_id</param>
  263. /// <param name="stream">写入文件流</param>
  264. /// <param name="timeOut"></param>
  265. [ApiBind(NeuChar.PlatformType.WeChat_OfficialAccount, "MediaApi.GetForeverMedia", true)]
  266. public static WxJsonResult GetForeverMedia(string accessTokenOrAppId, string mediaId, Stream stream, int timeOut = Config.TIME_OUT)
  267. {
  268. return ApiHandlerWapper.TryCommonApi(accessToken =>
  269. {
  270. string urlFormat = string.Format(Config.ApiMpHost + "/cgi-bin/material/get_material?access_token={0}", (object)accessToken.AsUrlData());
  271. var data = new
  272. {
  273. media_id = mediaId
  274. };
  275. if (stream != null)
  276. {
  277. stream.Seek(0, SeekOrigin.Begin);
  278. CO2NET.HttpUtility.Post.Download(urlFormat, data.ToJson(), stream);
  279. }
  280. return new WxJsonResult() { errcode = ReturnCode.请求成功, errmsg = "ok" };//无实际意义
  281. }, accessTokenOrAppId);
  282. }
  283. /// <summary>
  284. /// 获取永久视频素材
  285. /// </summary>
  286. /// <param name="accessTokenOrAppId"></param>
  287. /// <param name="mediaId">要获取的素材的media_id</param>
  288. /// <param name="timeOut"></param>
  289. /// <returns></returns>
  290. [ApiBind(NeuChar.PlatformType.WeChat_OfficialAccount, "MediaApi.GetForeverVideo", true)]
  291. public static GetForeverMediaVideoResultJson GetForeverVideo(string accessTokenOrAppId, string mediaId, int timeOut = Config.TIME_OUT)
  292. {
  293. return ApiHandlerWapper.TryCommonApi(accessToken =>
  294. {
  295. string url = Config.ApiMpHost + "/cgi-bin/material/get_material?access_token={0}";
  296. var data = new
  297. {
  298. media_id = mediaId
  299. };
  300. return CommonJsonSend.Send<GetForeverMediaVideoResultJson>(accessToken, url, data, CommonJsonSendType.POST, timeOut: timeOut);
  301. }, accessTokenOrAppId);
  302. }
  303. /// <summary>
  304. /// 删除永久素材
  305. /// </summary>
  306. /// <param name="accessTokenOrAppId">AccessToken或AppId(推荐使用AppId,需要先注册)</param>
  307. /// <param name="mediaId"></param>
  308. /// <param name="timeOut">代理请求超时时间(毫秒)</param>
  309. /// <returns></returns>
  310. [ApiBind(NeuChar.PlatformType.WeChat_OfficialAccount, "MediaApi.DeleteForeverMedia", true)]
  311. public static WxJsonResult DeleteForeverMedia(string accessTokenOrAppId, string mediaId, int timeOut = Config.TIME_OUT)
  312. {
  313. return ApiHandlerWapper.TryCommonApi(accessToken =>
  314. {
  315. string url = Config.ApiMpHost + "/cgi-bin/material/del_material?access_token={0}";
  316. var data = new
  317. {
  318. media_id = mediaId
  319. };
  320. return CommonJsonSend.Send<WxJsonResult>(accessToken, url, data, CommonJsonSendType.POST, timeOut);
  321. }, accessTokenOrAppId);
  322. }
  323. /// <summary>
  324. /// 修改永久图文素材
  325. /// </summary>
  326. /// <param name="accessTokenOrAppId">AccessToken或AppId(推荐使用AppId,需要先注册)</param>
  327. /// <param name="mediaId">要修改的图文消息的id</param>
  328. /// <param name="index">要更新的文章在图文消息中的位置(多图文消息时,此字段才有意义),第一篇为0</param>
  329. /// <param name="timeOut">代理请求超时时间(毫秒)</param>
  330. /// <param name="news">图文素材</param>
  331. /// <returns></returns>
  332. [ApiBind(NeuChar.PlatformType.WeChat_OfficialAccount, "MediaApi.UpdateForeverNews", true)]
  333. public static WxJsonResult UpdateForeverNews(string accessTokenOrAppId, string mediaId, int? index, NewsModel news, int timeOut = Config.TIME_OUT)
  334. {
  335. return ApiHandlerWapper.TryCommonApi(accessToken =>
  336. {
  337. string url = Config.ApiMpHost + "/cgi-bin/material/update_news?access_token={0}";
  338. var data = new
  339. {
  340. media_id = mediaId,
  341. index = index,
  342. articles = news
  343. };
  344. return CommonJsonSend.Send<WxJsonResult>(accessToken, url, data, CommonJsonSendType.POST, timeOut);
  345. }, accessTokenOrAppId);
  346. }
  347. /// <summary>
  348. /// 获取素材总数
  349. /// 永久素材的总数,也会计算公众平台官网素材管理中的素材
  350. /// 图片和图文消息素材(包括单图文和多图文)的总数上限为5000,其他素材的总数上限为1000
  351. /// </summary>
  352. /// <param name="accessTokenOrAppId">AccessToken或AppId(推荐使用AppId,需要先注册)</param>
  353. /// <returns></returns>
  354. [ApiBind(NeuChar.PlatformType.WeChat_OfficialAccount, "MediaApi.GetMediaCount", true)]
  355. public static GetMediaCountResultJson GetMediaCount(string accessTokenOrAppId)
  356. {
  357. return ApiHandlerWapper.TryCommonApi(accessToken =>
  358. {
  359. string url = string.Format(Config.ApiMpHost + "/cgi-bin/material/get_materialcount?access_token={0}", accessToken.AsUrlData());
  360. return CommonJsonSend.Send<GetMediaCountResultJson>(null, url, null, CommonJsonSendType.GET);
  361. }, accessTokenOrAppId);
  362. }
  363. /// <summary>
  364. /// 获取图文素材列表
  365. /// </summary>
  366. /// <param name="accessTokenOrAppId">AccessToken或AppId(推荐使用AppId,需要先注册)</param>
  367. /// <param name="offset">从全部素材的该偏移位置开始返回,0表示从第一个素材 返回</param>
  368. /// <param name="count">返回素材的数量,取值在1到20之间</param>
  369. /// <param name="timeOut">代理请求超时时间(毫秒)</param>
  370. /// <returns></returns>
  371. [ApiBind(NeuChar.PlatformType.WeChat_OfficialAccount, "MediaApi.GetNewsMediaList", true)]
  372. public static MediaList_NewsResult GetNewsMediaList(string accessTokenOrAppId, int offset, int count, int timeOut = Config.TIME_OUT)
  373. {
  374. return ApiHandlerWapper.TryCommonApi(accessToken =>
  375. {
  376. string url = string.Format(Config.ApiMpHost + "/cgi-bin/material/batchget_material?access_token={0}", accessToken.AsUrlData());
  377. var date = new
  378. {
  379. type = "news",
  380. offset = offset,
  381. count = count
  382. };
  383. return CommonJsonSend.Send<MediaList_NewsResult>(null, url, date, CommonJsonSendType.POST, timeOut);
  384. }, accessTokenOrAppId);
  385. }
  386. /// <summary>
  387. /// 获取图片、视频、语音素材列表
  388. /// </summary>
  389. /// <param name="accessTokenOrAppId">AccessToken或AppId(推荐使用AppId,需要先注册)</param>
  390. /// <param name="type">素材的类型,图片(image)、视频(video)、语音 (voice)</param>
  391. /// <param name="offset"></param>
  392. /// <param name="count"></param>
  393. /// <param name="timeOut">代理请求超时时间(毫秒)</param>
  394. /// <returns></returns>
  395. [ApiBind(NeuChar.PlatformType.WeChat_OfficialAccount, "MediaApi.GetOthersMediaList", true)]
  396. public static MediaList_OthersResult GetOthersMediaList(string accessTokenOrAppId, UploadMediaFileType type, int offset,
  397. int count, int timeOut = Config.TIME_OUT)
  398. {
  399. return ApiHandlerWapper.TryCommonApi(accessToken =>
  400. {
  401. string url = string.Format(Config.ApiMpHost + "/cgi-bin/material/batchget_material?access_token={0}", accessToken.AsUrlData());
  402. var date = new
  403. {
  404. type = type.ToString(),
  405. offset = offset,
  406. count = count
  407. };
  408. return CommonJsonSend.Send<MediaList_OthersResult>(null, url, date, CommonJsonSendType.POST, timeOut);
  409. }, accessTokenOrAppId);
  410. }
  411. /// <summary>
  412. /// 上传图文消息内的图片获取URL
  413. /// </summary>
  414. /// <param name="accessTokenOrAppId">AccessToken或AppId(推荐使用AppId,需要先注册)</param>
  415. /// <param name="file">上传文件的绝对路径</param>
  416. /// <param name="timeOut">代理请求超时时间(毫秒)</param>
  417. /// <returns></returns>
  418. [ApiBind(NeuChar.PlatformType.WeChat_OfficialAccount, "MediaApi.UploadImg", true)]
  419. public static UploadImgResult UploadImg(string accessTokenOrAppId, string file, int timeOut = Config.TIME_OUT)
  420. {
  421. //接口文档参考:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1444738729
  422. return ApiHandlerWapper.TryCommonApi(accessToken =>
  423. {
  424. var url = string.Format(Config.ApiMpHost + "/cgi-bin/media/uploadimg?access_token={0}", accessToken.AsUrlData());
  425. var fileDictionary = new Dictionary<string, string>();
  426. fileDictionary["media"] = file;
  427. return CO2NET.HttpUtility.Post.PostFileGetJson<UploadImgResult>(url, null, fileDictionary, null, timeOut: timeOut);
  428. }, accessTokenOrAppId);
  429. }
  430. #endregion
  431. #region AI开放接口
  432. /// <summary>
  433. /// 提交语音
  434. /// </summary>
  435. /// <param name="accessTokenOrAppId"></param>
  436. /// <param name="format"></param>
  437. /// <param name="voiceId"></param>
  438. /// <param name="lang"></param>
  439. /// <param name="timeOut"></param>
  440. /// <returns></returns>
  441. [ApiBind(NeuChar.PlatformType.WeChat_OfficialAccount, "MediaApi.AddVoice", true)]
  442. public static WxJsonResult AddVoice(string accessTokenOrAppId, string format, string voiceId, string lang, int timeOut = Config.TIME_OUT)
  443. {
  444. return ApiHandlerWapper.TryCommonApi(accessToken =>
  445. {
  446. string urlFormat = Config.ApiMpHost + "/cgi-bin/media/voice/addvoicetorecofortext?access_token={0}";
  447. var data = new
  448. {
  449. format = format,
  450. voice_id = voiceId,
  451. lang = lang
  452. };
  453. return CommonJsonSend.Send<WxJsonResult>(accessToken, urlFormat, data, timeOut: timeOut);
  454. }, accessTokenOrAppId);
  455. }
  456. /// <summary>
  457. /// 获取语音识别结果
  458. /// </summary>
  459. /// <param name="accessTokenOrAppId"></param>
  460. /// <param name="voiceId"></param>
  461. /// <param name="lang"></param>
  462. /// <param name="timeOut"></param>
  463. /// <returns></returns>
  464. [ApiBind(NeuChar.PlatformType.WeChat_OfficialAccount, "MediaApi.QueryRecoResult", true)]
  465. public static QueryRecoResultResultJson QueryRecoResult(string accessTokenOrAppId, string voiceId, string lang, int timeOut = Config.TIME_OUT)
  466. {
  467. return ApiHandlerWapper.TryCommonApi(accessToken =>
  468. {
  469. string urlFormat = Config.ApiMpHost + "/cgi-bin/media/voice/queryrecoresultfortext?access_token={0}";
  470. var data = new
  471. {
  472. voice_id = voiceId,
  473. lang = lang
  474. };
  475. return CommonJsonSend.Send<QueryRecoResultResultJson>(accessToken, urlFormat, data, timeOut: timeOut);
  476. }, accessTokenOrAppId);
  477. }
  478. /// <summary>
  479. /// 微信翻译
  480. /// </summary>
  481. /// <param name="accessTokenOrAppId"></param>
  482. /// <param name="Ifrom"></param>
  483. /// <param name="Ito"></param>
  484. /// <param name="timeOut"></param>
  485. /// <returns></returns>
  486. [ApiBind(NeuChar.PlatformType.WeChat_OfficialAccount, "MediaApi.TranslateContent", true)]
  487. public static TranslateContentResultJson TranslateContent(string accessTokenOrAppId, string Ifrom, string Ito, int timeOut = Config.TIME_OUT)
  488. {
  489. return ApiHandlerWapper.TryCommonApi(accessToken =>
  490. {
  491. string urlFormat = Config.ApiMpHost + "/cgi-bin/media/voice/translatecontent?access_token={0}";
  492. var data = new
  493. {
  494. Ifrom,
  495. Ito
  496. };
  497. return CommonJsonSend.Send<TranslateContentResultJson>(accessToken, urlFormat, data, timeOut: timeOut);
  498. }, accessTokenOrAppId);
  499. }
  500. #endregion
  501. #endregion
  502. #if !NET35 && !NET40
  503. #region 异步方法
  504. #region 临时素材
  505. /// <summary>
  506. /// 【异步方法】新增临时素材(原上传媒体文件)
  507. /// </summary>
  508. /// <param name="accessTokenOrAppId">AccessToken或AppId(推荐使用AppId,需要先注册)</param>
  509. /// <param name="type"></param>
  510. /// <param name="file">上传文件的绝对路径</param>
  511. /// <param name="timeOut">代理请求超时时间(毫秒)</param>
  512. /// <returns></returns>
  513. [ApiBind(NeuChar.PlatformType.WeChat_OfficialAccount, "MediaApi.UploadTemporaryMediaAsync", true)]
  514. public static async Task<UploadTemporaryMediaResult> UploadTemporaryMediaAsync(string accessTokenOrAppId, UploadMediaFileType type, string file, int timeOut = Config.TIME_OUT)
  515. {
  516. return await ApiHandlerWapper.TryCommonApiAsync(async accessToken =>
  517. {
  518. var url = string.Format(Config.ApiMpHost + "/cgi-bin/media/upload?access_token={0}&type={1}", accessToken.AsUrlData(), type.ToString().AsUrlData());
  519. var fileDictionary = new Dictionary<string, string>();
  520. fileDictionary["media"] = file;
  521. return await CO2NET.HttpUtility.Post.PostFileGetJsonAsync<UploadTemporaryMediaResult>(url, null, fileDictionary, null, null, null, false, timeOut: timeOut);
  522. }, accessTokenOrAppId);
  523. }
  524. /// <summary>
  525. /// 【异步方法】上传临时图文消息素材(原上传图文消息素材)
  526. /// </summary>
  527. /// <param name="accessTokenOrAppId">Token</param>
  528. /// <param name="news">图文消息组</param>
  529. /// <param name="timeOut">代理请求超时时间(毫秒)</param>
  530. /// <returns></returns>
  531. [ApiBind(NeuChar.PlatformType.WeChat_OfficialAccount, "MediaApi.UploadTemporaryNewsAsync", true)]
  532. public static async Task<UploadTemporaryMediaResult> UploadTemporaryNewsAsync(string accessTokenOrAppId, int timeOut = Config.TIME_OUT, params NewsModel[] news)
  533. {
  534. return await ApiHandlerWapper.TryCommonApiAsync(async accessToken =>
  535. {
  536. string urlFormat = Config.ApiMpHost + "/cgi-bin/media/uploadnews?access_token={0}";
  537. var data = new
  538. {
  539. articles = news
  540. };
  541. return await Senparc.Weixin.CommonAPIs.CommonJsonSend.SendAsync<UploadTemporaryMediaResult>(accessToken, urlFormat, data, timeOut: timeOut);
  542. }, accessTokenOrAppId);
  543. }
  544. /// <summary>
  545. /// 【异步方法】获取临时素材(原下载媒体文件)
  546. /// </summary>
  547. /// <param name="accessTokenOrAppId">AccessToken或AppId(推荐使用AppId,需要先注册)</param>
  548. /// <param name="mediaId"></param>
  549. /// <param name="stream"></param>
  550. [ApiBind(NeuChar.PlatformType.WeChat_OfficialAccount, "MediaApi.GetAsync", true)]
  551. public static async Task GetAsync(string accessTokenOrAppId, string mediaId, Stream stream)
  552. {
  553. await ApiHandlerWapper.TryCommonApiAsync(async accessToken =>
  554. {
  555. var url = string.Format(Config.ApiMpHost + "/cgi-bin/media/get?access_token={0}&media_id={1}", accessToken.AsUrlData(), mediaId.AsUrlData());
  556. await CO2NET.HttpUtility.Get.DownloadAsync(url, stream);
  557. return new WxJsonResult() { errcode = ReturnCode.请求成功, errmsg = "ok" };//无实际意义
  558. }, accessTokenOrAppId);
  559. }
  560. /// <summary>
  561. /// 【异步方法】获取临时素材(原下载媒体文件),保存到指定文件夹
  562. /// </summary>
  563. /// <param name="accessTokenOrAppId">AccessToken或AppId(推荐使用AppId,需要先注册)</param>
  564. /// <param name="mediaId"></param>
  565. /// <param name="dir"></param>
  566. /// <returns></returns>
  567. [ApiBind(NeuChar.PlatformType.WeChat_OfficialAccount, "MediaApi.GetAsync", true)]
  568. public static async Task<string> GetAsync(string accessTokenOrAppId, string mediaId, string dir)
  569. {
  570. var result = await ApiHandlerWapper.TryCommonApiAsync(async accessToken =>
  571. {
  572. var url = string.Format(Config.ApiMpHost + "/cgi-bin/media/get?access_token={0}&media_id={1}", accessToken.AsUrlData(), mediaId.AsUrlData());
  573. var str = await CO2NET.HttpUtility.Get.DownloadAsync(url, dir);
  574. return new WxJsonResult() { errcode = ReturnCode.请求成功, errmsg = str };
  575. }, accessTokenOrAppId);
  576. return result.errmsg;
  577. }
  578. /// <summary>
  579. /// 【异步方法】附录:高清语音素材获取接口
  580. /// </summary>
  581. /// <param name="accessTokenOrAppId">AccessToken或AppId(推荐使用AppId,需要先注册)</param>
  582. /// <param name="mediaId"></param>
  583. /// <param name="stream"></param>
  584. /// <param name="timeOut"></param>
  585. /// <returns></returns>
  586. [ApiBind(NeuChar.PlatformType.WeChat_OfficialAccount, "MediaApi.GetJssdkAsync", true)]
  587. public static async Task<WxJsonResult> GetJssdkAsync(string accessTokenOrAppId, string mediaId, Stream stream, int timeOut = Config.TIME_OUT)
  588. {
  589. return await ApiHandlerWapper.TryCommonApiAsync(async accessToken =>
  590. {
  591. var urlFormat = string.Format(Config.ApiMpHost + "/cgi-bin/media/get/jssdk?access_token={0}&media_id={1}", accessToken.AsUrlData(), mediaId.AsUrlData());
  592. if (stream != null)
  593. {
  594. stream.Seek(0, SeekOrigin.Begin);
  595. await CO2NET.HttpUtility.Get.DownloadAsync(urlFormat, stream);
  596. }
  597. return new WxJsonResult() { errcode = ReturnCode.不合法的媒体文件id, errmsg = "invalid media_id" };//错误情况下的返回
  598. }, accessTokenOrAppId);
  599. }
  600. #endregion
  601. #region 永久素材
  602. /*
  603. 1、新增的永久素材也可以在公众平台官网素材管理模块中看到
  604. 2、永久素材的数量是有上限的,请谨慎新增。图文消息素材和图片素材的上限为5000,其他类型为1000
  605. 3、调用该接口需https协议
  606. */
  607. /// <summary>
  608. /// 【异步方法】新增永久图文素材
  609. /// </summary>
  610. /// <param name="accessTokenOrAppId">Token</param>
  611. /// <param name="news">图文消息组</param>
  612. /// <param name="timeOut">代理请求超时时间(毫秒)</param>
  613. /// <returns></returns>
  614. [ApiBind(NeuChar.PlatformType.WeChat_OfficialAccount, "MediaApi.UploadNewsAsync", true)]
  615. public static async Task<UploadForeverMediaResult> UploadNewsAsync(string accessTokenOrAppId, int timeOut = Config.TIME_OUT, params NewsModel[] news)
  616. {
  617. return await ApiHandlerWapper.TryCommonApiAsync(async accessToken =>
  618. {
  619. string urlFormat = Config.ApiMpHost + "/cgi-bin/material/add_news?access_token={0}";
  620. var data = new
  621. {
  622. articles = news
  623. };
  624. return await Senparc.Weixin.CommonAPIs.CommonJsonSend.SendAsync<UploadForeverMediaResult>(accessToken, urlFormat, data, timeOut: timeOut);
  625. }, accessTokenOrAppId);
  626. }
  627. /// <summary>
  628. /// 【异步方法】新增其他类型永久素材(图片(image)、语音(voice)和缩略图(thumb))
  629. /// </summary>
  630. /// <param name="accessTokenOrAppId">AccessToken或AppId(推荐使用AppId,需要先注册)</param>
  631. /// <param name="file">文件路径</param>
  632. /// <param name="timeOut">代理请求超时时间(毫秒)</param>
  633. /// <returns></returns>
  634. [ApiBind(NeuChar.PlatformType.WeChat_OfficialAccount, "MediaApi.UploadForeverMediaAsync", true)]
  635. public static async Task<UploadForeverMediaResult> UploadForeverMediaAsync(string accessTokenOrAppId, string file, int timeOut = Config.TIME_OUT)
  636. {
  637. return await ApiHandlerWapper.TryCommonApiAsync(async accessToken =>
  638. {
  639. var url = string.Format(Config.ApiMpHost + "/cgi-bin/material/add_material?access_token={0}", accessToken.AsUrlData());
  640. //因为有文件上传,所以忽略dataDictionary,全部改用文件上传格式
  641. //var dataDictionary = new Dictionary<string, string>();
  642. //dataDictionary["type"] = UploadMediaFileType.image.ToString();
  643. var fileDictionary = new Dictionary<string, string>();
  644. //fileDictionary["type"] = UploadMediaFileType.image.ToString();//不提供此参数也可以上传成功
  645. fileDictionary["media"] = file;
  646. return await CO2NET.HttpUtility.Post.PostFileGetJsonAsync<UploadForeverMediaResult>(url, null, fileDictionary, null, timeOut: timeOut);
  647. }, accessTokenOrAppId);
  648. }
  649. /// <summary>
  650. /// 【异步方法】新增永久视频素材
  651. /// </summary>
  652. /// <param name="accessTokenOrAppId">AccessToken或AppId(推荐使用AppId,需要先注册)</param>
  653. /// <param name="file">文件路径</param>
  654. /// <param name="title"></param>
  655. /// <param name="introduction"></param>
  656. /// <param name="timeOut">代理请求超时时间(毫秒)</param>
  657. /// <returns></returns>
  658. [ApiBind(NeuChar.PlatformType.WeChat_OfficialAccount, "MediaApi.UploadForeverVideoAsync", true)]
  659. public static async Task<UploadForeverMediaResult> UploadForeverVideoAsync(string accessTokenOrAppId, string file, string title, string introduction, int timeOut = 40000)
  660. {
  661. return await ApiHandlerWapper.TryCommonApiAsync(async accessToken =>
  662. {
  663. var url = string.Format(Config.ApiMpHost + "/cgi-bin/material/add_material?access_token={0}", accessToken.AsUrlData());
  664. var fileDictionary = new Dictionary<string, string>();
  665. fileDictionary["media"] = file;
  666. fileDictionary["description"] = string.Format("{{\"title\":\"{0}\", \"introduction\":\"{1}\"}}", title, introduction);
  667. return await CO2NET.HttpUtility.Post.PostFileGetJsonAsync<UploadForeverMediaResult>(url, null, fileDictionary, null, timeOut: timeOut);
  668. }, accessTokenOrAppId);
  669. }
  670. /// <summary>
  671. /// 【异步方法】获取永久图文素材
  672. /// </summary>
  673. /// <param name="accessTokenOrAppId">AccessToken或AppId(推荐使用AppId,需要先注册)</param>
  674. /// <param name="mediaId"></param>
  675. /// <param name="timeOut">代理请求超时时间(毫秒)</param>
  676. /// <returns></returns>
  677. [ApiBind(NeuChar.PlatformType.WeChat_OfficialAccount, "MediaApi.GetForeverNewsAsync", true)]
  678. public static async Task<GetNewsResultJson> GetForeverNewsAsync(string accessTokenOrAppId, string mediaId, int timeOut = Config.TIME_OUT)
  679. {
  680. return await ApiHandlerWapper.TryCommonApiAsync(async accessToken =>
  681. {
  682. string url = Config.ApiMpHost + "/cgi-bin/material/get_material?access_token={0}";
  683. var data = new
  684. {
  685. media_id = mediaId
  686. };
  687. return await Senparc.Weixin.CommonAPIs.CommonJsonSend.SendAsync<GetNewsResultJson>(accessToken, url, data, CommonJsonSendType.POST, timeOut: timeOut);
  688. }, accessTokenOrAppId);
  689. }
  690. /// <summary>
  691. /// 【异步方法】获取永久素材(除了图文、视频)
  692. /// </summary>
  693. /// <param name="accessTokenOrAppId">AccessToken或AppId(推荐使用AppId,需要先注册)</param>
  694. /// <param name="mediaId">要获取的素材的media_id</param>
  695. /// <param name="stream">写入文件流</param>
  696. /// <param name="timeOut"></param>
  697. [ApiBind(NeuChar.PlatformType.WeChat_OfficialAccount, "MediaApi.GetForeverMediaAsync", true)]
  698. public static async Task<WxJsonResult> GetForeverMediaAsync(string accessTokenOrAppId, string mediaId, Stream stream, int timeOut = Config.TIME_OUT)
  699. {
  700. return await ApiHandlerWapper.TryCommonApiAsync(async accessToken =>
  701. {
  702. string urlFormat = string.Format(Config.ApiMpHost + "/cgi-bin/material/get_material?access_token={0}", (object)accessToken.AsUrlData());
  703. var data = new
  704. {
  705. media_id = mediaId
  706. };
  707. if (stream != null)
  708. {
  709. stream.Seek(0, SeekOrigin.Begin);
  710. await CO2NET.HttpUtility.Post.DownloadAsync(urlFormat, data.ToJson(), stream);
  711. }
  712. return new WxJsonResult() { errcode = ReturnCode.请求成功, errmsg = "ok" };//无实际意义
  713. }, accessTokenOrAppId);
  714. }
  715. /// <summary>
  716. /// 获取永久视频素材
  717. /// </summary>
  718. /// <param name="accessTokenOrAppId"></param>
  719. /// <param name="mediaId">要获取的素材的media_id</param>
  720. /// <param name="timeOut"></param>
  721. /// <returns></returns>
  722. [ApiBind(NeuChar.PlatformType.WeChat_OfficialAccount, "MediaApi.GetForeverVideoAsync", true)]
  723. public static async Task<GetForeverMediaVideoResultJson> GetForeverVideoAsync(string accessTokenOrAppId, string mediaId, int timeOut = Config.TIME_OUT)
  724. {
  725. return await ApiHandlerWapper.TryCommonApiAsync(async accessToken =>
  726. {
  727. string url = Config.ApiMpHost + "/cgi-bin/material/get_material?access_token={0}";
  728. var data = new
  729. {
  730. media_id = mediaId
  731. };
  732. var result = await Senparc.Weixin.CommonAPIs.CommonJsonSend.SendAsync<GetForeverMediaVideoResultJson>(accessToken, url, data, CommonJsonSendType.POST, timeOut: timeOut);
  733. return result;
  734. }, accessTokenOrAppId);
  735. }
  736. /// <summary>
  737. /// 【异步方法】删除永久素材
  738. /// </summary>
  739. /// <param name="accessTokenOrAppId">AccessToken或AppId(推荐使用AppId,需要先注册)</param>
  740. /// <param name="mediaId"></param>
  741. /// <param name="timeOut">代理请求超时时间(毫秒)</param>
  742. /// <returns></returns>
  743. [ApiBind(NeuChar.PlatformType.WeChat_OfficialAccount, "MediaApi.DeleteForeverMediaAsync", true)]
  744. public static async Task<WxJsonResult> DeleteForeverMediaAsync(string accessTokenOrAppId, string mediaId, int timeOut = Config.TIME_OUT)
  745. {
  746. return await ApiHandlerWapper.TryCommonApiAsync(async accessToken =>
  747. {
  748. string url = Config.ApiMpHost + "/cgi-bin/material/del_material?access_token={0}";
  749. var data = new
  750. {
  751. media_id = mediaId
  752. };
  753. return await Senparc.Weixin.CommonAPIs.CommonJsonSend.SendAsync<WxJsonResult>(accessToken, url, data, CommonJsonSendType.POST, timeOut);
  754. }, accessTokenOrAppId);
  755. }
  756. /// <summary>
  757. /// 【异步方法】修改永久图文素材
  758. /// </summary>
  759. /// <param name="accessTokenOrAppId">AccessToken或AppId(推荐使用AppId,需要先注册)</param>
  760. /// <param name="mediaId">要修改的图文消息的id</param>
  761. /// <param name="index">要更新的文章在图文消息中的位置(多图文消息时,此字段才有意义),第一篇为0</param>
  762. /// <param name="timeOut">代理请求超时时间(毫秒)</param>
  763. /// <param name="news">图文素材</param>
  764. /// <returns></returns>
  765. [ApiBind(NeuChar.PlatformType.WeChat_OfficialAccount, "MediaApi.UpdateForeverNewsAsync", true)]
  766. public static async Task<WxJsonResult> UpdateForeverNewsAsync(string accessTokenOrAppId, string mediaId, int? index, NewsModel news, int timeOut = Config.TIME_OUT)
  767. {
  768. return await ApiHandlerWapper.TryCommonApiAsync(async accessToken =>
  769. {
  770. string url = Config.ApiMpHost + "/cgi-bin/material/update_news?access_token={0}";
  771. var data = new
  772. {
  773. media_id = mediaId,
  774. index = index,
  775. articles = news
  776. };
  777. return await Senparc.Weixin.CommonAPIs.CommonJsonSend.SendAsync<WxJsonResult>(accessToken, url, data, CommonJsonSendType.POST, timeOut);
  778. }, accessTokenOrAppId);
  779. }
  780. /// <summary>
  781. /// 【异步方法】获取素材总数
  782. /// 永久素材的总数,也会计算公众平台官网素材管理中的素材
  783. /// 图片和图文消息素材(包括单图文和多图文)的总数上限为5000,其他素材的总数上限为1000
  784. /// </summary>
  785. /// <param name="accessTokenOrAppId">AccessToken或AppId(推荐使用AppId,需要先注册)</param>
  786. /// <returns></returns>
  787. [ApiBind(NeuChar.PlatformType.WeChat_OfficialAccount, "MediaApi.GetMediaCountAsync", true)]
  788. public static async Task<GetMediaCountResultJson> GetMediaCountAsync(string accessTokenOrAppId)
  789. {
  790. return await ApiHandlerWapper.TryCommonApiAsync(async accessToken =>
  791. {
  792. string url = string.Format(Config.ApiMpHost + "/cgi-bin/material/get_materialcount?access_token={0}", accessToken.AsUrlData());
  793. return await CommonJsonSend.SendAsync<GetMediaCountResultJson>(null, url, null, CommonJsonSendType.GET);
  794. }, accessTokenOrAppId);
  795. }
  796. /// <summary>
  797. /// 【异步方法】获取图文素材列表
  798. /// </summary>
  799. /// <param name="accessTokenOrAppId">AccessToken或AppId(推荐使用AppId,需要先注册)</param>
  800. /// <param name="offset">从全部素材的该偏移位置开始返回,0表示从第一个素材 返回</param>
  801. /// <param name="count">返回素材的数量,取值在1到20之间</param>
  802. /// <param name="timeOut">代理请求超时时间(毫秒)</param>
  803. /// <returns></returns>
  804. [ApiBind(NeuChar.PlatformType.WeChat_OfficialAccount, "MediaApi.GetNewsMediaListAsync", true)]
  805. public static async Task<MediaList_NewsResult> GetNewsMediaListAsync(string accessTokenOrAppId, int offset, int count, int timeOut = Config.TIME_OUT)
  806. {
  807. return await ApiHandlerWapper.TryCommonApiAsync(async accessToken =>
  808. {
  809. string url = string.Format(Config.ApiMpHost + "/cgi-bin/material/batchget_material?access_token={0}", accessToken.AsUrlData());
  810. var date = new
  811. {
  812. type = "news",
  813. offset = offset,
  814. count = count
  815. };
  816. return await CommonJsonSend.SendAsync<MediaList_NewsResult>(null, url, date, CommonJsonSendType.POST, timeOut);
  817. }, accessTokenOrAppId);
  818. }
  819. /// <summary>
  820. /// 【异步方法】获取图片、视频、语音素材列表
  821. /// </summary>
  822. /// <param name="accessTokenOrAppId">AccessToken或AppId(推荐使用AppId,需要先注册)</param>
  823. /// <param name="type">素材的类型,图片(image)、视频(video)、语音 (voice)</param>
  824. /// <param name="offset"></param>
  825. /// <param name="count"></param>
  826. /// <param name="timeOut"></param>
  827. /// <returns></returns>
  828. [ApiBind(NeuChar.PlatformType.WeChat_OfficialAccount, "MediaApi.GetOthersMediaListAsync", true)]
  829. public static async Task<MediaList_OthersResult> GetOthersMediaListAsync(string accessTokenOrAppId, UploadMediaFileType type, int offset,
  830. int count, int timeOut = Config.TIME_OUT)
  831. {
  832. return await ApiHandlerWapper.TryCommonApiAsync(async accessToken =>
  833. {
  834. string url = string.Format(Config.ApiMpHost + "/cgi-bin/material/batchget_material?access_token={0}", accessToken.AsUrlData());
  835. var date = new
  836. {
  837. type = type.ToString(),
  838. offset = offset,
  839. count = count
  840. };
  841. return await CommonJsonSend.SendAsync<MediaList_OthersResult>(null, url, date, CommonJsonSendType.POST, timeOut);
  842. }, accessTokenOrAppId);
  843. }
  844. /// <summary>
  845. /// 【异步方法】上传图文消息内的图片获取URL
  846. /// </summary>
  847. /// <param name="accessTokenOrAppId">AccessToken或AppId(推荐使用AppId,需要先注册)</param>
  848. /// <param name="file"></param>
  849. /// <param name="timeOut"></param>
  850. /// <returns></returns>
  851. [ApiBind(NeuChar.PlatformType.WeChat_OfficialAccount, "MediaApi.UploadImgAsync", true)]
  852. public static async Task<UploadImgResult> UploadImgAsync(string accessTokenOrAppId, string file, int timeOut = Config.TIME_OUT)
  853. {
  854. //接口文档参考:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1444738729
  855. return await ApiHandlerWapper.TryCommonApiAsync(async accessToken =>
  856. {
  857. var url = string.Format(Config.ApiMpHost + "/cgi-bin/media/uploadimg?access_token={0}", accessToken.AsUrlData());
  858. var fileDictionary = new Dictionary<string, string>();
  859. fileDictionary["media"] = file;
  860. return await CO2NET.HttpUtility.Post.PostFileGetJsonAsync<UploadImgResult>(url, null, fileDictionary, null, timeOut: timeOut);
  861. }, accessTokenOrAppId);
  862. }
  863. #endregion
  864. #region AI开放接口
  865. /// <summary>
  866. /// 【异步方法】提交语音
  867. /// </summary>
  868. /// <param name="accessTokenOrAppId"></param>
  869. /// <param name="format"></param>
  870. /// <param name="voiceId"></param>
  871. /// <param name="lang"></param>
  872. /// <param name="timeOut"></param>
  873. /// <returns></returns>
  874. [ApiBind(NeuChar.PlatformType.WeChat_OfficialAccount, "MediaApi.AddVoiceAsync", true)]
  875. public static async Task<WxJsonResult> AddVoiceAsync(string accessTokenOrAppId, string format, string voiceId, string lang, int timeOut = Config.TIME_OUT)
  876. {
  877. return await ApiHandlerWapper.TryCommonApiAsync(async accessToken =>
  878. {
  879. string urlFormat = Config.ApiMpHost + "/cgi-bin/media/voice/addvoicetorecofortext?access_token={0}";
  880. var data = new
  881. {
  882. format = format,
  883. voice_id = voiceId,
  884. lang = lang
  885. };
  886. return await CommonJsonSend.SendAsync<WxJsonResult>(accessToken, urlFormat, data, timeOut: timeOut);
  887. }, accessTokenOrAppId);
  888. }
  889. /// <summary>
  890. /// 【异步方法】获取语音识别结果
  891. /// </summary>
  892. /// <param name="accessTokenOrAppId"></param>
  893. /// <param name="format"></param>
  894. /// <param name="voiceId"></param>
  895. /// <param name="lang"></param>
  896. /// <param name="timeOut"></param>
  897. /// <returns></returns>
  898. [ApiBind(NeuChar.PlatformType.WeChat_OfficialAccount, "MediaApi.QueryRecoResultAsync", true)]
  899. public static async Task<QueryRecoResultResultJson> QueryRecoResultAsync(string accessTokenOrAppId, string voiceId, string lang, int timeOut = Config.TIME_OUT)
  900. {
  901. return await ApiHandlerWapper.TryCommonApiAsync(async accessToken =>
  902. {
  903. string urlFormat = Config.ApiMpHost + "/cgi-bin/media/voice/queryrecoresultfortext?access_token={0}";
  904. var data = new
  905. {
  906. voice_id = voiceId,
  907. lang = lang
  908. };
  909. return await CommonJsonSend.SendAsync<QueryRecoResultResultJson>(accessToken, urlFormat, data, timeOut: timeOut);
  910. }, accessTokenOrAppId);
  911. }
  912. /// <summary>
  913. /// 【异步方法】微信翻译
  914. /// </summary>
  915. /// <param name="accessTokenOrAppId"></param>
  916. /// <param name="Ifrom"></param>
  917. /// <param name="Ito"></param>
  918. /// <param name="timeOut"></param>
  919. /// <returns></returns>
  920. [ApiBind(NeuChar.PlatformType.WeChat_OfficialAccount, "MediaApi.TranslateContentAsync", true)]
  921. public static async Task<TranslateContentResultJson> TranslateContentAsync(string accessTokenOrAppId, string Ifrom, string Ito, int timeOut = Config.TIME_OUT)
  922. {
  923. return await ApiHandlerWapper.TryCommonApiAsync(async accessToken =>
  924. {
  925. string urlFormat = Config.ApiMpHost + "/cgi-bin/media/voice/translatecontent?access_token={0}";
  926. var data = new
  927. {
  928. Ifrom,
  929. Ito
  930. };
  931. return await CommonJsonSend.SendAsync<TranslateContentResultJson>(accessToken, urlFormat, data, timeOut: timeOut);
  932. }, accessTokenOrAppId);
  933. }
  934. #endregion
  935. #endregion
  936. #endif
  937. }
  938. }