WebHookHttpTrigger.cs 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. using Azure.Cosmos;
  2. using Azure.Storage.Blobs.Models;
  3. using HTEXLib.COMM.Helpers;
  4. using Microsoft.Azure.Cosmos.Table;
  5. using Microsoft.Azure.Functions.Worker;
  6. using Microsoft.Azure.Functions.Worker.Http;
  7. using System;
  8. using System.Collections.Generic;
  9. using System.IO;
  10. using System.Linq;
  11. using System.Net;
  12. using System.Net.Http;
  13. using System.Net.Http.Json;
  14. using System.Reflection;
  15. using System.Text;
  16. using System.Text.Json;
  17. using System.Threading.Tasks;
  18. using TEAMModelOS.Filter;
  19. using TEAMModelOS.SDK;
  20. using TEAMModelOS.SDK.DI;
  21. using TEAMModelOS.SDK.Extension;
  22. using TEAMModelOS.SDK.Models;
  23. using TEAMModelOS.SDK.Models.Cosmos.Teacher;
  24. using TEAMModelOS.SDK.Models.Table;
  25. using static TEAMModelOS.SDK.Models.Teacher;
  26. namespace TEAMModelOS.SDK.DI
  27. {
  28. public class WebHookHttpTrigger
  29. {
  30. private readonly AzureCosmosFactory _azureCosmos;
  31. private readonly DingDing _dingDing;
  32. private readonly AzureStorageFactory _azureStorage;
  33. private readonly AzureRedisFactory _azureRedis;
  34. private readonly HttpClient _httpClient;
  35. public WebHookHttpTrigger(HttpClient httpClient,AzureCosmosFactory azureCosmos, DingDing dingDing, AzureStorageFactory azureStorage , AzureRedisFactory azureRedis)
  36. {
  37. _azureCosmos = azureCosmos;
  38. _dingDing = dingDing;
  39. _azureStorage = azureStorage;
  40. _azureRedis = azureRedis;
  41. _httpClient = httpClient;
  42. }
  43. /// <summary>
  44. /// 学校数据授权变更,学校基础信息 10开头
  45. /// </summary>
  46. /// <param name="request"></param>
  47. /// <returns></returns>
  48. [Function("school-auth-change")]
  49. [ApiToken(Auth = "1001", Name = "学校数据授权变更", RWN = "N")]
  50. public async Task<HttpResponseData> NoticeSchoolAuthChange([HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "webhook/school-auth-change")] HttpRequestData request)
  51. {
  52. var response = request.CreateResponse(HttpStatusCode.OK);
  53. ( List<BusinessConfig> businessConfigs, List<string> webhookdomain, SchoolAuthChange data) = await GetRequestData<SchoolAuthChange>(request);
  54. if (webhookdomain.IsNotEmpty())
  55. {
  56. foreach (var domain in webhookdomain)
  57. {
  58. await send(new
  59. {
  60. data.addSchools,
  61. data.rmvSchools
  62. }, domain, "school-auth-change");
  63. }
  64. }
  65. return response;
  66. }
  67. public class SchoolAuthChange
  68. {
  69. public string bizcode { get; set; }
  70. /// <summary>
  71. /// 添加的学校数据授权
  72. /// </summary>
  73. public List<IdSchool> addSchools { get; set; } = new List<IdSchool>();
  74. /// <summary>
  75. /// 取消的学校数据授权
  76. /// </summary>
  77. public List<IdSchool> rmvSchools { get; set; } = new List<IdSchool>();
  78. }
  79. /// <summary>
  80. /// 名单变更通知,名单类12开头
  81. /// </summary>
  82. /// <param name="request"></param>
  83. /// <returns></returns>
  84. [Function("group-member-change")]
  85. [ApiToken(Auth = "1201", Name = "名单成员变更", RWN = "N")]
  86. public async Task<HttpResponseData> NoticeGroupChange([HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "webhook/group-member-change")] HttpRequestData request) {
  87. var response = request.CreateResponse(HttpStatusCode.OK);
  88. ( List < BusinessConfig > businessConfigs, List<string> webhookdomain, GroupChange data) = await GetRequestData<GroupChange>(request);
  89. if ( webhookdomain.IsNotEmpty()&& string.IsNullOrWhiteSpace(data.school)) {
  90. foreach (var domain in webhookdomain) {
  91. await send(new
  92. {
  93. data.status,
  94. data.type,
  95. data.listid,
  96. data.tmdjoin,
  97. data.tmdleave,
  98. data.stujoin,
  99. data.stuleave,
  100. data.tchjoin,
  101. data.tchleave,
  102. data.school
  103. }, domain,"group-member-change");
  104. }
  105. }
  106. return response;
  107. }
  108. /// <summary>
  109. /// 测试域名的webhook是否接入
  110. /// </summary>
  111. /// <param name="request"></param>
  112. /// <returns></returns>
  113. [Function("check-domain-webhook")]
  114. public async Task<HttpResponseData> CheckDomainWebhook([HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "webhook/check-domain-webhook")] HttpRequestData request) {
  115. string data = await new StreamReader(request.Body).ReadToEndAsync();
  116. var json = JsonDocument.Parse(data).RootElement;
  117. if (json.TryGetProperty("domain", out JsonElement domain) && json.TryGetProperty("https", out JsonElement _https))
  118. {
  119. string https = _https.ValueKind.Equals(JsonValueKind.Number) && int.Parse($"{_https}") == 1 ? "https" : "http";
  120. string url = $"{https}://{domain}";
  121. HttpStatusCode httpStatus = await send(new { }, url, "check-domain-webhook");
  122. var response = request.CreateResponse(httpStatus);
  123. return response;
  124. }
  125. else {
  126. var response = request.CreateResponse(HttpStatusCode.BadRequest);
  127. return response;
  128. }
  129. }
  130. /// <summary>
  131. /// 消息发送方法
  132. /// </summary>
  133. /// <param name="data"></param>
  134. /// <param name="domain"></param>
  135. /// <param name="notice"></param>
  136. public async Task<HttpStatusCode> send (dynamic data,string domain, string notice) {
  137. var timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
  138. _httpClient.Timeout=new TimeSpan(0,0,10);
  139. HttpResponseMessage httpResponse =await _httpClient.PostAsJsonAsync($"{domain}/webhook", new
  140. {
  141. time = timestamp,
  142. notice =notice,
  143. data = data
  144. });
  145. return httpResponse.StatusCode;
  146. }
  147. /// <summary>
  148. /// 解析HttpRequestData 传递的数据
  149. /// </summary>
  150. /// <typeparam name="T"></typeparam>
  151. /// <param name="request"></param>
  152. /// <returns></returns>
  153. public async Task<( List<BusinessConfig> businessConfigs,List<string> webhookdomain, T data)> GetRequestData<T>(HttpRequestData request)
  154. {
  155. //var response = request.CreateResponse(HttpStatusCode.OK);
  156. string data = await new StreamReader(request.Body).ReadToEndAsync();
  157. var json = JsonDocument.Parse(data).RootElement;
  158. string school = null;
  159. List<BusinessConfig> businessConfigs = null ;
  160. var table = _azureStorage.GetCloudTableClient().GetTableReference("IESOpenApi");
  161. if (json.TryGetProperty("school", out JsonElement _school))
  162. {
  163. school = _school.GetString();
  164. List<BusinessSchool> schools = table.FindListByDictSync<BusinessSchool>(new Dictionary<string, object> { { "PartitionKey", $"BusinessSchool" }, { "school", school } });
  165. var bizid = schools.Select(x => x.bizid).ToList();
  166. List<string> Codes = new List<string>();
  167. bizid.ForEach(x => {
  168. Codes.Add($" RowKey {QueryComparisons.Equal} '{x}' ");
  169. });
  170. string tbqurey = $"PartitionKey {QueryComparisons.Equal} 'BusinessConfig' and ( {string.Join(" or ", Codes)} ) ";
  171. var result = await table.ExecuteQuerySegmentedAsync(new TableQuery<BusinessConfig>().Where(tbqurey), null);
  172. if (result != null) {
  173. businessConfigs= result.Results;
  174. }
  175. }
  176. if (json.TryGetProperty("bizid", out JsonElement _bizid)) {
  177. string tbqurey = $"PartitionKey {QueryComparisons.Equal} 'BusinessConfig' and RowKey {QueryComparisons.Equal} '{_bizid}' ";
  178. var result = await table.ExecuteQuerySegmentedAsync(new TableQuery<BusinessConfig>().Where(tbqurey), null);
  179. if (result != null)
  180. {
  181. businessConfigs = result.Results;
  182. }
  183. }
  184. if (json.TryGetProperty("data", out JsonElement _data) && businessConfigs.IsNotEmpty())
  185. {
  186. var webhookdomain = businessConfigs.Where(z => !string.IsNullOrWhiteSpace(z.webhook)).ToList();
  187. List<string> webhookdomains = new List<string>();
  188. webhookdomain.ForEach(x => {
  189. webhookdomains.AddRange(x.webhook.Split(",").Select(y =>x.https==1? $"https://{y}":$"http://{y}"));
  190. });
  191. return ( businessConfigs, webhookdomains, _data.ToObject<T>());
  192. }
  193. else { return ( businessConfigs,null , default(T)); }
  194. }
  195. }
  196. public class WebhookSchoolData {
  197. public string school { get; set; }
  198. public string data { get; set; }
  199. }
  200. }