/src/SSCMS.Core/Services/WxManager.cs

https://github.com/siteserver/cms · C# · 137 lines · 122 code · 15 blank · 0 comment · 16 complexity · f637a98efa15a0efc785a8762975a00b MD5 · raw file

  1. using System;
  2. using System.Threading.Tasks;
  3. using Senparc.Weixin;
  4. using Senparc.Weixin.Exceptions;
  5. using Senparc.Weixin.MP;
  6. using Senparc.Weixin.MP.Containers;
  7. using SSCMS.Core.Utils;
  8. using SSCMS.Enums;
  9. using SSCMS.Repositories;
  10. using SSCMS.Services;
  11. using SSCMS.Utils;
  12. namespace SSCMS.Core.Services
  13. {
  14. public partial class WxManager : IWxManager
  15. {
  16. private readonly ISettingsManager _settingsManager;
  17. private readonly IPathManager _pathManager;
  18. private readonly ITaskManager _taskManager;
  19. private readonly IWxAccountRepository _wxAccountRepository;
  20. private readonly IWxMenuRepository _wxMenuRepository;
  21. private readonly IWxChatRepository _wxChatRepository;
  22. private readonly IWxReplyRuleRepository _wxReplyRuleRepository;
  23. private readonly IWxReplyKeywordRepository _wxReplyKeywordRepository;
  24. private readonly IWxReplyMessageRepository _wxReplyMessageRepository;
  25. private readonly IMaterialMessageRepository _materialMessageRepository;
  26. private readonly IMaterialArticleRepository _materialArticleRepository;
  27. private readonly IMaterialImageRepository _materialImageRepository;
  28. private readonly IMaterialAudioRepository _materialAudioRepository;
  29. private readonly IMaterialVideoRepository _materialVideoRepository;
  30. public WxManager(ISettingsManager settingsManager, IPathManager pathManager, ITaskManager taskManager, IWxAccountRepository wxAccountRepository,
  31. IWxMenuRepository wxMenuRepository, IWxChatRepository wxChatRepository, IWxReplyRuleRepository wxReplyRuleRepository,
  32. IWxReplyKeywordRepository wxReplyKeywordRepository, IWxReplyMessageRepository wxReplyMessageRepository,
  33. IMaterialMessageRepository materialMessageRepository, IMaterialArticleRepository materialArticleRepository, IMaterialImageRepository materialImageRepository,
  34. IMaterialAudioRepository materialAudioRepository, IMaterialVideoRepository materialVideoRepository)
  35. {
  36. _settingsManager = settingsManager;
  37. _pathManager = pathManager;
  38. _taskManager = taskManager;
  39. _wxAccountRepository = wxAccountRepository;
  40. _wxMenuRepository = wxMenuRepository;
  41. _wxChatRepository = wxChatRepository;
  42. _wxReplyRuleRepository = wxReplyRuleRepository;
  43. _wxReplyKeywordRepository = wxReplyKeywordRepository;
  44. _wxReplyMessageRepository = wxReplyMessageRepository;
  45. _materialMessageRepository = materialMessageRepository;
  46. _materialArticleRepository = materialArticleRepository;
  47. _materialImageRepository = materialImageRepository;
  48. _materialAudioRepository = materialAudioRepository;
  49. _materialVideoRepository = materialVideoRepository;
  50. }
  51. public async Task<(bool, string, string)> GetAccessTokenAsync(int siteId)
  52. {
  53. var account = await _wxAccountRepository.GetBySiteIdAsync(siteId);
  54. if (string.IsNullOrEmpty(account.MpAppId) || string.IsNullOrEmpty(account.MpAppSecret))
  55. {
  56. return (false, null, "微信公众号AppId及AppSecret未设置,请到平台账号配置中设置");
  57. }
  58. return await GetAccessTokenAsync(account.MpAppId, account.MpAppSecret);
  59. }
  60. public async Task<(bool, string, string)> GetAccessTokenAsync(string mpAppId, string mpAppSecret)
  61. {
  62. var success = false;
  63. var errorMessage = string.Empty;
  64. string token = null;
  65. try
  66. {
  67. token = await AccessTokenContainer.TryGetAccessTokenAsync(mpAppId, mpAppSecret);
  68. success = true;
  69. }
  70. catch (ErrorJsonResultException ex)
  71. {
  72. if (ex.JsonResult.errcode == ReturnCode.调用接口的IP地址不在白名单中)
  73. {
  74. var startIndex = ex.JsonResult.errmsg.IndexOf("invalid ip ", StringComparison.Ordinal) + 11;
  75. var endIndex = ex.JsonResult.errmsg.IndexOf(" ipv6", StringComparison.Ordinal);
  76. var ip = ex.JsonResult.errmsg.Substring(startIndex, endIndex - startIndex);
  77. errorMessage = $"调用接口的IP地址不在白名单中,请进入微信公众平台,将本服务器的IP地址 {ip} 添加至白名单";
  78. }
  79. else
  80. {
  81. errorMessage = $"API 调用发生错误:{ex.JsonResult.errmsg}";
  82. }
  83. }
  84. catch (Exception ex)
  85. {
  86. errorMessage = $"执行过程发生错误:{ex.Message}";
  87. }
  88. return (success, token, errorMessage);
  89. }
  90. private GroupMessageType GetGroupMessageType(MaterialType materialType)
  91. {
  92. if (materialType == MaterialType.Message) return GroupMessageType.mpnews;
  93. if (materialType == MaterialType.Text) return GroupMessageType.text;
  94. if (materialType == MaterialType.Image) return GroupMessageType.image;
  95. if (materialType == MaterialType.Audio) return GroupMessageType.voice;
  96. if (materialType == MaterialType.Video) return GroupMessageType.video;
  97. return GroupMessageType.mpnews;
  98. }
  99. private string SaveImages(string content)
  100. {
  101. var originalImageSrcs = RegexUtils.GetOriginalImageSrcs(content);
  102. foreach (var originalImageSrc in originalImageSrcs)
  103. {
  104. if (!PageUtils.IsProtocolUrl(originalImageSrc)) continue;
  105. var extName = "png";
  106. if (StringUtils.Contains(originalImageSrc, "wx_fmt="))
  107. {
  108. extName = originalImageSrc.Substring(originalImageSrc.LastIndexOf("=", StringComparison.Ordinal) + 1);
  109. }
  110. var materialFileName = PathUtils.GetMaterialFileNameByExtName(extName);
  111. var virtualDirectoryPath = PathUtils.GetMaterialVirtualDirectoryPath(UploadType.Image);
  112. var directoryPath = PathUtils.Combine(_settingsManager.WebRootPath, virtualDirectoryPath);
  113. var filePath = PathUtils.Combine(directoryPath, materialFileName);
  114. WebClientUtils.Download(originalImageSrc, filePath);
  115. var imageUrl = PageUtils.Combine(virtualDirectoryPath, materialFileName);
  116. content = content.Replace(" data-src=", "src=");
  117. content = content.Replace(originalImageSrc, imageUrl);
  118. }
  119. return content;
  120. }
  121. }
  122. }