/// <summary> /// 推送到微信公共号 /// </summary> /// <returns></returns> public async Task <ActionResult> PushToWeixinAsync() { int maxTitleLength = 60; // 获取新闻原内容 var news = _context.News .Where(n => n.IsPublishToMP == false && n.CreatedTime.Date >= DateTime.Now.Date.AddDays(-5)) .OrderByDescending(n => n.CreatedTime) .Take(10) .ToList(); var random = new Random(); int number = random.Next(3, 6); var blogs = _context.Blogs .Where(b => b.IsPublishMP == false && b.Status != Data.Entity.Status.Obsolete && !string.IsNullOrEmpty(b.Content)) .OrderByDescending(b => b.UpdatedTime) .Take(number) .ToList(); try { var newsList = new List <NewsModel>(); var token = AccessTokenContainer.TryGetAccessToken(AppId, AppSecret); DumpConsole("开始处理新闻"); // 新闻内容 if (news != null && news.Count > 0) { string content = ""; // 上传文章内图片 using (var wc = new WebClient()) { var firstNews = news.FirstOrDefault(); foreach (var item in news) { var tempFileName = StringTools.GetTempFileName("jpg"); wc.DownloadFile(item.ThumbnailUrl + "&w=600", tempFileName); var uploadImgResult = await MediaApi.UploadImgAsync(token, tempFileName); System.IO.File.Delete(tempFileName); // 替换图片链接 content += $@"<div class='row'> <div class='news-title mt-1'> <strong style='font-size:18px;color:#015cda'>{item.Title}</strong> </div> <div> <img src='{uploadImgResult.url}' width='100%' /> </div> <div class='news-description'>{item.Description}</div> <br /><br /> </div>"; item.IsPublishToMP = true; } // 上传封面图片 wc.DownloadFile(firstNews?.ThumbnailUrl + "&w=600", "temp.jpg"); var thumbImg = await MediaApi.UploadForeverMediaAsync(token, "temp.jpg"); // TODO:上传后可删除 var mainNews = new NewsModel { author = "MSDev_NilTor", thumb_media_id = thumbImg.media_id, content = content, title = "资讯一览:" + firstNews?.Title, show_cover_pic = "0", content_source_url = "https://guandian.tech", digest = "", }; mainNews.title = mainNews.title.Length > maxTitleLength?mainNews.title.Substring(0, maxTitleLength) : mainNews.title; newsList.Add(mainNews); } } DumpConsole("新闻处理完成"); DumpConsole("开始处理博客"); // 博客内容 if (blogs != null && blogs.Count > 0) { using (var hc = new HttpClient()) { hc.Timeout = TimeSpan.FromSeconds(5); var htmlDoc = new HtmlDocument(); try { foreach (var item in blogs) { // 处理文章内图片 htmlDoc.LoadHtml(item.Content); var root = htmlDoc.DocumentNode; var imageNodes = root.SelectNodes(".//img"); // 移除视频元素 var videoNodes = root.SelectNodes(".//video"); if (videoNodes != null && videoNodes.Count > 0) { foreach (var video in videoNodes) { root.SelectSingleNode(video.XPath).Remove(); } } string mediaId = ""; if (imageNodes != null) { for (int i = 0; i < imageNodes.Count; i++) { var url = imageNodes[i].GetAttributeValue("src", null); // 只保留jpg图片 if (!url.EndsWith(".jpg")) { root.SelectSingleNode(imageNodes[i].XPath).Remove(); } else { DumpConsole(item.Title + " 图片处理"); var image = imageNodes[i].Attributes["src"].Value; var tempFileName = StringTools.GetTempFileName("jpg"); await DownloadFile(hc, image, tempFileName); // 判断大小. TODO:处理图片大小 var file = new FileInfo(tempFileName); if (file.Length > 1 * 1024 * 1024) { continue; } var uploadImgResult = await MediaApi.UploadImgAsync(token, tempFileName); DumpConsole("上传图片" + image + " " + file.Length / 1024); System.IO.File.Delete(tempFileName); // 替换文本 imageNodes[i].SetAttributeValue("src", uploadImgResult.url); // TODO:后面可删除该封面 } } } // 缩略图 var mediaResult = await MediaApi.GetOthersMediaListAsync(token, Senparc.Weixin.MP.UploadMediaFileType.image, 0, 2); var defaultMediaId = mediaResult.item?.FirstOrDefault()?.media_id; // 下载缩略图,下载失败则使用默认图 var tempFileName1 = StringTools.GetTempFileName("jpg"); await DownloadFile(hc, item.Thumbnail, tempFileName1); if (System.IO.File.Exists(tempFileName1)) { var thumbImg = await MediaApi.UploadForeverMediaAsync(token, tempFileName1); mediaId = thumbImg.media_id; } else { mediaId = defaultMediaId; } // 处理内容,微信消息最大长度为2W字符,小于1M Console.WriteLine("长度:" + root.InnerHtml.Length); if (root.InnerHtml.Length >= 20000) { root.InnerHtml = root.InnerHtml.Substring(0, 19500); } // 构造图文消息体 var currentNews = new NewsModel { author = item.AuthorName, thumb_media_id = mediaId, // html如果有#,会报错 content = root.InnerHtml.Replace("#", ""), // 长度处理 title = item.Title.Length > maxTitleLength?item.Title.Substring(0, maxTitleLength) : item.Title, show_cover_pic = "0", content_source_url = "https://guandian.tech/blogs/detail/" + item.Id, digest = "", }; DumpConsole("博客标题:" + currentNews.title + "; 长度:" + currentNews.title.Length); item.IsPublishMP = true; newsList.Add(currentNews); } } catch (Exception e) { DumpConsole(e.Message); } } } if (newsList.Count < 1) { DumpConsole("无可推送内容"); return(Ok()); } // 上传图文 var uploadNewsResult = await MediaApi.UploadNewsAsync(token, news : newsList.ToArray()); if (uploadNewsResult.media_id != null) { var userList = await UserApi.GetAsync(token, null); var firstUserOpenId = userList.data.openid.FirstOrDefault(); // 预览 var sendPreviewResult = await GroupMessageApi.SendGroupMessagePreviewAsync(token, Senparc.Weixin.MP.GroupMessageType.mpnews, uploadNewsResult.media_id, null, "EstNil"); // 群发消息 var sendNewsResult = await GroupMessageApi.SendGroupMessageByTagIdAsync(token, null, uploadNewsResult.media_id, Senparc.Weixin.MP.GroupMessageType.mpnews, true); // 未成功则删除上传的素材 if (sendNewsResult.errcode != 0) { var deleteResult = await MediaApi.DeleteForeverMediaAsync(token, uploadNewsResult.media_id); } else { // 成功后更新数据库标识 _context.UpdateRange(news); _context.UpdateRange(blogs); _context.SaveChanges(); } } } catch (Exception e) { DumpConsole(e.Message + e.InnerException); } return(Ok()); }
/// <summary> /// 获取素材列表(图片、视频、音频) /// </summary> /// <param name="appId"></param> /// <param name="mediaFileType"></param> /// <param name="offset"></param> /// <param name="count"></param> /// <returns></returns> public async Task <MediaList_OthersResult> GetOthersMediaListAsync(string appId, UploadMediaFileType mediaFileType, int offset, int count) { var wxRet = await MediaApi.GetOthersMediaListAsync(appId, mediaFileType, offset, count); return(wxRet); }
public async Task PullMaterialAsync(string accessTokenOrAppId, MaterialType materialType, int groupId) { var count = await MediaApi.GetMediaCountAsync(accessTokenOrAppId); if (materialType == MaterialType.Message) { if (count.news_count > 0) { var newsList = await MediaApi.GetNewsMediaListAsync(accessTokenOrAppId, 0, count.news_count); newsList.item.Reverse(); foreach (var message in newsList.item) { if (await _materialMessageRepository.IsExistsAsync(message.media_id)) { continue; } //var news = await MediaApi.GetForeverNewsAsync(accessTokenOrAppId, message.media_id); var messageItems = new List <MaterialMessageItem>(); foreach (var item in message.content.news_item) { var imageUrl = string.Empty; if (!string.IsNullOrEmpty(item.thumb_media_id) && !string.IsNullOrEmpty(item.thumb_url)) { await using var ms = new MemoryStream(); await MediaApi.GetForeverMediaAsync(accessTokenOrAppId, item.thumb_media_id, ms); ms.Seek(0, SeekOrigin.Begin); var extName = "png"; if (StringUtils.Contains(item.thumb_url, "wx_fmt=")) { extName = item.thumb_url.Substring(item.thumb_url.LastIndexOf("=", StringComparison.Ordinal) + 1); } var materialFileName = PathUtils.GetMaterialFileNameByExtName(extName); var virtualDirectoryPath = PathUtils.GetMaterialVirtualDirectoryPath(UploadType.Image); var directoryPath = PathUtils.Combine(_settingsManager.WebRootPath, virtualDirectoryPath); var filePath = PathUtils.Combine(directoryPath, materialFileName); await FileUtils.WriteStreamAsync(filePath, ms); imageUrl = PageUtils.Combine(virtualDirectoryPath, materialFileName); } else if (!string.IsNullOrEmpty(item.thumb_url)) { var extName = "png"; if (StringUtils.Contains(item.thumb_url, "wx_fmt=")) { extName = item.thumb_url.Substring(item.thumb_url.LastIndexOf("=", StringComparison.Ordinal) + 1); } var materialFileName = PathUtils.GetMaterialFileNameByExtName(extName); var virtualDirectoryPath = PathUtils.GetMaterialVirtualDirectoryPath(UploadType.Image); var directoryPath = PathUtils.Combine(_settingsManager.WebRootPath, virtualDirectoryPath); var filePath = PathUtils.Combine(directoryPath, materialFileName); WebClientUtils.Download(item.thumb_url, filePath); imageUrl = PageUtils.Combine(virtualDirectoryPath, materialFileName); } var commentType = CommentType.Block; if (item.need_open_comment == 1) { commentType = item.only_fans_can_comment == 1 ? CommentType.OnlyFans : CommentType.Everyone; } messageItems.Add(new MaterialMessageItem { MessageId = 0, MaterialType = MaterialType.Article, MaterialId = 0, Taxis = 0, ThumbMediaId = item.thumb_media_id, Author = item.author, Title = item.title, ContentSourceUrl = item.content_source_url, Content = SaveImages(item.content), Digest = item.digest, ShowCoverPic = item.show_cover_pic == "1", ThumbUrl = imageUrl, Url = item.url, CommentType = commentType }); } await _materialMessageRepository.InsertAsync(groupId, message.media_id, messageItems); } } } else if (materialType == MaterialType.Image) { if (count.image_count > 0) { var list = await MediaApi.GetOthersMediaListAsync(accessTokenOrAppId, UploadMediaFileType.image, 0, count.image_count); foreach (var image in list.item) { if (await _materialImageRepository.IsExistsAsync(image.media_id)) { continue; } await using var ms = new MemoryStream(); await MediaApi.GetForeverMediaAsync(accessTokenOrAppId, image.media_id, ms); ms.Seek(0, SeekOrigin.Begin); var extName = image.url.Substring(image.url.LastIndexOf("=", StringComparison.Ordinal) + 1); var materialFileName = PathUtils.GetMaterialFileNameByExtName(extName); var virtualDirectoryPath = PathUtils.GetMaterialVirtualDirectoryPath(UploadType.Image); var directoryPath = PathUtils.Combine(_settingsManager.WebRootPath, virtualDirectoryPath); var filePath = PathUtils.Combine(directoryPath, materialFileName); await FileUtils.WriteStreamAsync(filePath, ms); var material = new MaterialImage { GroupId = groupId, Title = image.name, Url = PageUtils.Combine(virtualDirectoryPath, materialFileName), MediaId = image.media_id }; await _materialImageRepository.InsertAsync(material); } } } else if (materialType == MaterialType.Audio) { if (count.voice_count > 0) { var list = await MediaApi.GetOthersMediaListAsync(accessTokenOrAppId, UploadMediaFileType.voice, 0, count.voice_count); foreach (var voice in list.item) { if (await _materialAudioRepository.IsExistsAsync(voice.media_id)) { continue; } await using var ms = new MemoryStream(); await MediaApi.GetForeverMediaAsync(accessTokenOrAppId, voice.media_id, ms); ms.Seek(0, SeekOrigin.Begin); var extName = voice.url.Substring(voice.url.LastIndexOf("=", StringComparison.Ordinal) + 1); var materialFileName = PathUtils.GetMaterialFileNameByExtName(extName); var virtualDirectoryPath = PathUtils.GetMaterialVirtualDirectoryPath(UploadType.Audio); var directoryPath = PathUtils.Combine(_settingsManager.WebRootPath, virtualDirectoryPath); var filePath = PathUtils.Combine(directoryPath, materialFileName); await FileUtils.WriteStreamAsync(filePath, ms); var audio = new MaterialAudio { GroupId = groupId, Title = voice.name, FileType = extName.ToUpper().Replace(".", string.Empty), Url = PageUtils.Combine(virtualDirectoryPath, materialFileName), MediaId = voice.media_id }; await _materialAudioRepository.InsertAsync(audio); } } } else if (materialType == MaterialType.Video) { if (count.video_count > 0) { var list = await MediaApi.GetOthersMediaListAsync(accessTokenOrAppId, UploadMediaFileType.video, 0, count.video_count); foreach (var video in list.item) { if (await _materialVideoRepository.IsExistsAsync(video.media_id)) { continue; } await using var ms = new MemoryStream(); await MediaApi.GetForeverMediaAsync(accessTokenOrAppId, video.media_id, ms); ms.Seek(0, SeekOrigin.Begin); var extName = "mp4"; if (!string.IsNullOrEmpty(video.url)) { extName = video.url.Substring(video.url.LastIndexOf("=", StringComparison.Ordinal) + 1); } var materialFileName = PathUtils.GetMaterialFileNameByExtName(extName); var virtualDirectoryPath = PathUtils.GetMaterialVirtualDirectoryPath(UploadType.Video); var directoryPath = PathUtils.Combine(_settingsManager.WebRootPath, virtualDirectoryPath); var filePath = PathUtils.Combine(directoryPath, materialFileName); await FileUtils.WriteStreamAsync(filePath, ms); var material = new MaterialVideo { GroupId = groupId, Title = video.name, FileType = extName.ToUpper().Replace(".", string.Empty), Url = PageUtils.Combine(virtualDirectoryPath, materialFileName), MediaId = video.media_id }; await _materialVideoRepository.InsertAsync(material); } } } }