|
@@ -10,6 +10,13 @@ using System.Net.Http;
|
|
|
using Flurl.Http.Configuration;
|
|
|
using System.Net;
|
|
|
using QuzrtzJob.Factory;
|
|
|
+using Org.BouncyCastle.Crypto.Parameters;
|
|
|
+using System.IO;
|
|
|
+using CurlThin;
|
|
|
+using CurlThin.Enums;
|
|
|
+using CurlThin.Helpers;
|
|
|
+using CurlThin.Native;
|
|
|
+using CurlThin.SafeHandles;
|
|
|
|
|
|
namespace OASystem.API.OAMethodLib.APNs
|
|
|
{
|
|
@@ -53,6 +60,18 @@ namespace OASystem.API.OAMethodLib.APNs
|
|
|
return this.GetnerateAPNsJWTToken(APNsService.token);
|
|
|
}
|
|
|
|
|
|
+ //private static CngKey GetPrivateKey()
|
|
|
+ //{
|
|
|
+ // using (var reader = System.IO.File.OpenText("File/AuthKey_RMV7Y4KM9V.p8"))
|
|
|
+ // {
|
|
|
+ // var ecPrivateKeyParameters = (ECPrivateKeyParameters)new PemReader(reader).ReadObject();
|
|
|
+ // var x = ecPrivateKeyParameters.Parameters.G.AffineXCoord.GetEncoded();
|
|
|
+ // var y = ecPrivateKeyParameters.Parameters.G.AffineYCoord.GetEncoded();
|
|
|
+ // var d = ecPrivateKeyParameters.D.ToByteArrayUnsigned();
|
|
|
+ // return EccKey.New(x, y, d);
|
|
|
+ // }
|
|
|
+ //}
|
|
|
+
|
|
|
/// <summary>
|
|
|
/// 生成 APNs JWT token
|
|
|
/// </summary>
|
|
@@ -115,11 +134,101 @@ namespace OASystem.API.OAMethodLib.APNs
|
|
|
return APNsService.token;
|
|
|
}
|
|
|
|
|
|
+ public async Task<Result> PushNotification1(string apnsTopic, string deviceToken, NotificationType type, string title, string subtitle, string body)
|
|
|
+ {
|
|
|
+
|
|
|
+ var res = new Result() { Code = 0, Msg = "", Data = "" };
|
|
|
+
|
|
|
+ res.Msg += $"[PushNotification1] --> Start\t\t\t\t\t";
|
|
|
+ //This string is for extracting libcurl and ssl libs to the bin directory.
|
|
|
+ CurlResources.Init();
|
|
|
+ var global = CurlNative.Init();
|
|
|
+ var easy = CurlNative.Easy.Init();
|
|
|
+ string content=string.Empty;
|
|
|
+ try
|
|
|
+ {
|
|
|
+ var token = GetnerateAPNsJWTToken(); ;
|
|
|
+
|
|
|
+ res.Msg += $"[PushNotification1] --> Token:[{token}]\t\t\t\t\t";
|
|
|
+ var dataCopier = new DataCallbackCopier();
|
|
|
+
|
|
|
+ CurlNative.Easy.SetOpt(easy, CURLoption.URL, $"https://api.push.apple.com:443/3/device/{deviceToken}");
|
|
|
+ CurlNative.Easy.SetOpt(easy, CURLoption.WRITEFUNCTION, dataCopier.DataHandler);
|
|
|
+ //This string is needed when you call a https endpoint.
|
|
|
+ CurlNative.Easy.SetOpt(easy, CURLoption.CAINFO, CurlResources.CaBundlePath);
|
|
|
+
|
|
|
+
|
|
|
+ var httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, APNsService.baseUrl + deviceToken)
|
|
|
+ {
|
|
|
+ Headers =
|
|
|
+ {
|
|
|
+ { HeaderNames.Authorization, "bearer " + token },
|
|
|
+ { "apns-topic", apnsTopic },
|
|
|
+ { "apns-expiration", "0" }
|
|
|
+ },
|
|
|
+ Version = new Version(2, 0)
|
|
|
+ };
|
|
|
+
|
|
|
+ res.Msg += $"[PushNotification1] --> httpRequestMessage:baseUrl[{APNsService.baseUrl + deviceToken}]\t\t\t\t\t";
|
|
|
+ var notContent = new
|
|
|
+ {
|
|
|
+ aps = new
|
|
|
+ {
|
|
|
+ alert = new
|
|
|
+ {
|
|
|
+ title = title,
|
|
|
+ subtitle = subtitle,
|
|
|
+ body = body
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ var headers = CurlNative.Slist.Append(SafeSlistHandle.Null, $"Authorization: Bearer {token}");
|
|
|
+ CurlNative.Slist.Append(headers, $"apns-topic: {apnsTopic}");
|
|
|
+ CurlNative.Slist.Append(headers, $"apns-expiration: 0");
|
|
|
+
|
|
|
+ CurlNative.Easy.SetOpt(easy, CURLoption.HTTPHEADER, headers.DangerousGetHandle());
|
|
|
+
|
|
|
+ var contentJson = new StringContent(System.Text.Json.JsonSerializer.Serialize(notContent), System.Text.Encoding.UTF8, Application.Json);
|
|
|
+ CurlNative.Easy.SetOpt(easy, CURLoption.POSTFIELDS, System.Text.Json.JsonSerializer.Serialize(notContent));
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ //Your set of ciphers, full list is here https://curl.se/docs/ssl-ciphers.html
|
|
|
+ CurlNative.Easy.SetOpt(easy, CURLoption.SSL_CIPHER_LIST, "ECDHE-RSA-AES256-GCM-SHA384");
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ res.Msg += $"[PushNotification1] --> 发送请求\t\t\t\t\t";
|
|
|
+ CurlNative.Easy.Perform(easy);
|
|
|
+
|
|
|
+ content = Encoding.UTF8.GetString(dataCopier.Stream.ToArray());
|
|
|
+ }
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+ res.Msg += $"[PushNotification1] ExMsg:{ex.Message}";
|
|
|
+ if (ex.InnerException != null)
|
|
|
+ {
|
|
|
+ res.Msg += $"[PushNotification1] InnerException:{ex.InnerException.Message}";
|
|
|
+ }
|
|
|
+ }
|
|
|
+ finally
|
|
|
+ {
|
|
|
+ easy.Dispose();
|
|
|
+
|
|
|
+ if (global == CURLcode.OK)
|
|
|
+ CurlNative.Cleanup();
|
|
|
+ }
|
|
|
+ res.Data = content;
|
|
|
+ return res;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
/// <summary>
|
|
|
/// 发送推送通知
|
|
|
/// </summary>
|
|
|
/// <param name="apnsTopic">APP Id</param>
|
|
|
- /// <param name="deviceToken">设备标识</param>
|
|
|
+ /// <param name="deviceToken">设备标识</param>[文件:AuthKey_RMV7Y4KM9V.p8]
|
|
|
/// <param name="type">通知类型</param>
|
|
|
/// <param name="title">标题</param>
|
|
|
/// <param name="subtitle">子标题</param>
|