Aucune description

FeiShuiHelper.cs 18KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442
  1. using Newtonsoft.Json;
  2. using Newtonsoft.Json.Linq;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.IO;
  6. using System.Linq;
  7. using System.Net;
  8. using System.Net.Http;
  9. using System.Net.Http.Headers;
  10. using System.Text;
  11. namespace CallCenter.Utility
  12. {
  13. public class FeiShuiHelper
  14. {
  15. static string app_id = Configs.GetValue("FeiShui_AppId");
  16. static string app_secret = Configs.GetValue("FeiShui_AppSecret");
  17. //获取tenant_access_token
  18. private static string GetTenantAccessToken()
  19. {
  20. string result = string.Empty;
  21. var param = new
  22. {
  23. app_id = app_id,
  24. app_secret = app_secret,
  25. };
  26. var strresult = HttpMethods.HttpPost("https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal", param.ToJson(),"application/json; charset=utf-8");
  27. if (!string.IsNullOrEmpty(strresult))
  28. {
  29. var resultobj = strresult.ToJObject();
  30. if (resultobj["code"].ToString() != "0")
  31. {
  32. LogFactory.GetLogger("tenant_access_token").Error(strresult);
  33. result = resultobj["msg"].ToString();
  34. }
  35. else
  36. {
  37. result = resultobj["tenant_access_token"].ToString();
  38. }
  39. }
  40. return result;
  41. }
  42. //获取user_access_token
  43. private static string GetUserAccessToken(string code)
  44. {
  45. string result = string.Empty;
  46. var param = new
  47. {
  48. grant_type = "authorization_code",
  49. client_id = app_id,
  50. client_secret=app_secret,
  51. code= code
  52. };
  53. var strresult = HttpMethods.HttpPost("https://open.feishu.cn/open-apis/authen/v2/oauth/token", param.ToJson(), "application/json; charset=utf-8");
  54. if (!string.IsNullOrEmpty(strresult))
  55. {
  56. var resultobj = strresult.ToJObject();
  57. if (resultobj["code"].ToString() != "0")
  58. {
  59. LogFactory.GetLogger("error").Error(strresult);
  60. result = resultobj["error"].ToString();
  61. }
  62. else
  63. {
  64. result = resultobj["access_token"].ToString();
  65. }
  66. }
  67. return result;
  68. }
  69. //通过手机号获取用户id
  70. private static string GetUserid(string mobile)
  71. {
  72. string result = string.Empty;
  73. //Dictionary<string, object> param = new Dictionary<string, object>();
  74. //param.Add("mobiles", new string[] { mobile });
  75. //param.Add("include_resigned", true);
  76. var postData = new { mobiles = new string[] { mobile }, include_resigned = true };
  77. var strresult = SendPostRequest
  78. ("https://open.feishu.cn/open-apis/contact/v3/users/batch_get_id?user_id_type=user_id", postData);
  79. if (!string.IsNullOrEmpty(strresult))
  80. {
  81. generalResult<userslist> resultobj = JsonConvert.
  82. DeserializeObject<generalResult<userslist>>(strresult);
  83. if (resultobj.code != "0")
  84. {
  85. LogFactory.GetLogger("GetUserid").Error(resultobj.msg);
  86. result = "";
  87. }
  88. else
  89. {
  90. if (resultobj.data!=null&& resultobj.data.user_list.Count>0)
  91. result = resultobj.data.user_list[0].user_id;
  92. }
  93. }
  94. return result;
  95. }
  96. //发送消息
  97. public static string SendMsg(string title,
  98. string workrodercode, string name, string phone,
  99. string address, string products, string description,
  100. string mobile, string msg, long WoID = 0,int type=0)
  101. {
  102. string userid = GetUserid(mobile);
  103. if (string.IsNullOrEmpty(userid))
  104. return "";
  105. Guid guid = Guid.NewGuid();
  106. string uuid = guid.ToString();
  107. string result = string.Empty;
  108. //Dictionary<string, object> param = new Dictionary<string, object>();
  109. //param.Add("receive_id", userid);
  110. //param.Add("msg_type", "text");
  111. //param.Add( "content", "{\"text\":\"" + msg + "\"}");
  112. //param.Add("uuid", uuid);
  113. var postData = new { receive_id = userid, msg_type = "post",
  114. content = "{\"zh_cn\":{\"title\":\""+ title +
  115. "\",\"content\":[[{\"tag\":\"text\",\"text\":\"工单编号:"+ workrodercode + "\"}]," +
  116. "[{\"tag\":\"text\",\"text\":\"投诉人姓名:" + name + "\"}]," +
  117. "[{\"tag\":\"text\",\"text\":\"投诉人手机号:" + phone + "\"}]," +
  118. "[{\"tag\":\"text\",\"text\":\"投诉人地址:" + address + "\"}]," +
  119. "[{\"tag\":\"text\",\"text\":\"产品地址:" + products + "\"}]," +
  120. "[{\"tag\":\"text\",\"text\":\"问题描述:" + description + "\"}]," +
  121. "[{\"tag\":\"text\",\"text\":\"\"}]," +
  122. "[{\"tag\":\"text\",\"text\":\"点击查看详情 :\"},{\"tag\":\"a\",\"href\":\"https://applink.feishu.cn/client/web_app/open?appId=" + app_id + "&wid=" + WoID+"\",\"text\":\"[查看详情链接]\"}]," +
  123. "[{\"tag\":\"text\",\"text\":\"\"}]," +
  124. "[{\"tag\":\"a\",\"href\":\"https://applink.feishu.cn/client/web_app/open?appId="+ app_id + "\",\"text\":\"[进入售后平台]\"}]" +
  125. "]}}",
  126. uuid = uuid,
  127. };
  128. var strresult = SendPostRequest
  129. ("https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=user_id", postData);
  130. if (!string.IsNullOrEmpty(strresult))
  131. {
  132. var resultobj = strresult.ToJObject();
  133. if (resultobj["code"].ToString() != "0")
  134. {
  135. LogFactory.GetLogger("SendMsg").Error(strresult);
  136. result = resultobj["msg"].ToString();
  137. }
  138. else
  139. {
  140. //"message_id"
  141. //加急短信
  142. JObject jo = (JObject)JsonConvert.DeserializeObject(resultobj["data"].ToJson());
  143. if (jo != null)
  144. {
  145. if (type==1)
  146. {
  147. string message_id = jo["message_id"].ToString();
  148. if (!string.IsNullOrEmpty(message_id))
  149. {
  150. var user_id_list = new { user_id_list = new string[] { userid } };
  151. var message = SendPatchRequest
  152. ("https://open.feishu.cn/open-apis/im/v1/messages/" + message_id + "/urgent_sms?user_id_type=user_id", user_id_list);
  153. return message;
  154. }
  155. }
  156. }
  157. result = resultobj.ToJson() ;
  158. }
  159. }
  160. return result;
  161. }
  162. //获取单个用户
  163. public static string GetUser(string code)
  164. {
  165. string token = GetUserAccessToken(code);
  166. Guid guid = Guid.NewGuid();
  167. string uuid = guid.ToString();
  168. string result = string.Empty;
  169. var strresult = SendGetRequest("https://open.feishu.cn/open-apis/authen/v1/user_info",token);
  170. if (!string.IsNullOrEmpty(strresult))
  171. {
  172. generalResult<user> resultobj = JsonConvert.DeserializeObject<generalResult<user>>(strresult);
  173. if (resultobj.code != "0")
  174. {
  175. LogFactory.GetLogger("GetUser").Error(resultobj.msg);
  176. result = resultobj.msg;
  177. }
  178. else
  179. {
  180. if (resultobj.data != null )
  181. result = resultobj.data.mobile;
  182. }
  183. }
  184. return result;
  185. }
  186. public static string SendGetRequest(string url, string authToken)
  187. {
  188. // 创建请求对象
  189. HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
  190. request.Method = "GET";
  191. request.ContentType = "application/json; charset=utf-8"; // 设置 Content-Type
  192. request.Headers.Add("Authorization", $"Bearer {authToken}");
  193. // 如果需要忽略 SSL 证书验证(仅测试环境使用)
  194. // ServicePointManager.ServerCertificateValidationCallback +=
  195. // (sender, certificate, chain, sslPolicyErrors) => true;
  196. try
  197. {
  198. // 获取响应
  199. using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
  200. using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
  201. {
  202. return reader.ReadToEnd();
  203. }
  204. }
  205. catch (WebException ex)
  206. {
  207. // 处理错误响应
  208. if (ex.Response is HttpWebResponse errorResponse)
  209. {
  210. using (Stream errorStream = errorResponse.GetResponseStream())
  211. using (StreamReader reader = new StreamReader(errorStream, Encoding.UTF8))
  212. {
  213. string errorContent = reader.ReadToEnd();
  214. throw new Exception($"HTTP Error {(int)errorResponse.StatusCode}: {errorContent}");
  215. }
  216. }
  217. throw;
  218. }
  219. }
  220. public static string HttpGet(string url, string token)
  221. {
  222. ServicePointManager.Expect100Continue = true;
  223. ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
  224. ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, errors) => true;
  225. HttpClient client = new HttpClient();
  226. client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json; charset=utf-8"));
  227. client.DefaultRequestHeaders.Authorization = new
  228. AuthenticationHeaderValue
  229. ("Bearer", token);
  230. var result = client.GetAsync(url).Result.Content.ReadAsStringAsync().Result;
  231. return result;
  232. }
  233. public static string SendPatchRequest(string url, object data)
  234. {
  235. string authToken = GetTenantAccessToken();
  236. HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
  237. request.Method = "PATCH"; // 指定 PATCH 方法
  238. request.ContentType = "application/json; charset=utf-8";
  239. request.Headers.Add("Authorization", $"Bearer {authToken}");
  240. // 如需忽略 SSL 证书验证(仅测试环境)
  241. // ServicePointManager.ServerCertificateValidationCallback =
  242. // (sender, cert, chain, sslPolicyErrors) => true;
  243. try
  244. {
  245. // 序列化请求数据
  246. string json = JsonConvert.SerializeObject(data);
  247. byte[] payload = Encoding.UTF8.GetBytes(json);
  248. // 写入请求体
  249. request.ContentLength = payload.Length;
  250. using (Stream stream = request.GetRequestStream())
  251. {
  252. stream.Write(payload, 0, payload.Length);
  253. }
  254. // 获取响应
  255. using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
  256. using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
  257. {
  258. return reader.ReadToEnd();
  259. }
  260. }
  261. catch (WebException ex)
  262. {
  263. // 处理错误响应
  264. if (ex.Response is HttpWebResponse errorResponse)
  265. {
  266. using (Stream errorStream = errorResponse.GetResponseStream())
  267. using (StreamReader reader = new StreamReader(errorStream, Encoding.UTF8))
  268. {
  269. string errorContent = reader.ReadToEnd();
  270. throw new Exception($"HTTP Error {(int)errorResponse.StatusCode}: {errorContent}");
  271. }
  272. }
  273. throw new Exception("Network error: " + ex.Message);
  274. }
  275. }
  276. public static string SendPostRequest(string url, object data)
  277. {
  278. string authToken = GetTenantAccessToken();
  279. // 创建请求对象
  280. HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
  281. request.Method = "POST";
  282. request.ContentType = "application/json; charset=utf-8";
  283. // 添加 Authorization 头
  284. request.Headers.Add("Authorization", $"Bearer {authToken}");
  285. // 如果需要忽略 SSL 证书验证(仅测试环境使用)
  286. // ServicePointManager.ServerCertificateValidationCallback +=
  287. // (sender, certificate, chain, sslPolicyErrors) => true;
  288. try
  289. {
  290. // 序列化数据为 JSON
  291. string json = JsonConvert.SerializeObject(data);
  292. byte[] postData = Encoding.UTF8.GetBytes(json);
  293. // 写入请求体
  294. request.ContentLength = postData.Length;
  295. using (Stream stream = request.GetRequestStream())
  296. {
  297. stream.Write(postData, 0, postData.Length);
  298. }
  299. // 获取响应
  300. using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
  301. using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
  302. {
  303. return reader.ReadToEnd();
  304. }
  305. }
  306. catch (WebException ex)
  307. {
  308. // 处理错误响应
  309. if (ex.Response is HttpWebResponse errorResponse)
  310. {
  311. using (Stream errorStream = errorResponse.GetResponseStream())
  312. using (StreamReader reader = new StreamReader(errorStream, Encoding.UTF8))
  313. {
  314. string errorContent = reader.ReadToEnd();
  315. throw new Exception($"HTTP Error {(int)errorResponse.StatusCode}: {errorContent}");
  316. }
  317. }
  318. throw;
  319. }
  320. }
  321. public static string HttpPost(string url, Dictionary<string, object> dic)
  322. {
  323. string result = ""; string token = GetTenantAccessToken();
  324. try
  325. {
  326. // 创建 HttpWebRequest 对象
  327. HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
  328. // 设置请求方法为 POST
  329. request.Method = "POST";
  330. // 设置 Content-Type
  331. request.ContentType = "application/json; charset=utf-8";
  332. // 设置 Authorization 头部
  333. request.Headers.Add("Authorization", token);
  334. var d = JsonConvert.SerializeObject(dic);
  335. // 将请求体数据转换为字节数组
  336. byte[] requestBodyBytes = Encoding.UTF8.GetBytes(d);
  337. // 设置请求体的长度
  338. request.ContentLength = requestBodyBytes.Length;
  339. // 获取请求流
  340. using (Stream requestStream = request.GetRequestStream())
  341. {
  342. // 将请求体数据写入请求流
  343. requestStream.Write(requestBodyBytes, 0, requestBodyBytes.Length);
  344. }
  345. // 发送请求并获取响应
  346. using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
  347. {
  348. // 检查响应状态码
  349. if (response.StatusCode == HttpStatusCode.OK)
  350. {
  351. // 获取响应流
  352. using (Stream responseStream = response.GetResponseStream())
  353. {
  354. if (responseStream != null)
  355. {
  356. // 创建 StreamReader 用于读取响应流
  357. using (StreamReader reader = new StreamReader(responseStream, Encoding.UTF8))
  358. {
  359. // 读取响应内容
  360. string responseBody = reader.ReadToEnd();
  361. Console.WriteLine("请求成功,响应内容:");
  362. return responseBody;
  363. }
  364. }
  365. }
  366. }
  367. else
  368. {
  369. return $"请求失败,状态码:{response.StatusCode}";
  370. }
  371. }
  372. }
  373. catch (WebException ex)
  374. {
  375. if (ex.Status == WebExceptionStatus.ProtocolError)
  376. {
  377. HttpWebResponse errorResponse = (HttpWebResponse)ex.Response;
  378. return $"请求失败,状态码:{errorResponse.StatusCode}";
  379. }
  380. else
  381. {
  382. return $"发生网络异常:{ex.Message}";
  383. }
  384. }
  385. catch (Exception ex)
  386. {
  387. return $"发生异常:{ex.Message}";
  388. }
  389. return result;
  390. }
  391. private class generalResult<T> where T : class
  392. {
  393. public string code { get; set; }
  394. public string msg { get; set; }
  395. public T data { get; set; }
  396. }
  397. private class userlist
  398. {
  399. public string user_id { get; set; }
  400. }
  401. private class userslist
  402. {
  403. public List<userlist> user_list { get; set; }
  404. }
  405. private class user
  406. {
  407. public string mobile { get; set; }
  408. }
  409. }
  410. }