inotify/Inotify/Sends/Products/BarkSendTemplate.cs
xpnas bb7e25729f 增加版本数据库兼容
增加多通道消息发送
BARK部分代码
2021-04-02 01:14:09 +08:00

249 lines
8.0 KiB
C#

using Inotify.Common;
using Inotify.Data;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Security.Policy;
using System.Text;
using System.Threading.Tasks;
namespace Inotify.Sends.Products
{
public class BarkMessage
{
public BarkMessage(string body) : this(string.Empty, body) { }
public BarkMessage(string title, string body)
{
this.Title = title;
this.Body = body;
}
#region
/// <summary>
/// 标题,加粗
/// </summary>
public string Title { get; set; } = string.Empty;
/// <summary>
/// 正文
/// </summary>
public string Body { get; set; } = string.Empty;
/// <summary>
/// 自动保存
/// </summary>
public string IsArchive { get; set; } = "1";
/// <summary>
/// 链接
/// </summary>
public string Url { get; set; } = string.Empty;
/// <summary>
/// 自动复制
/// </summary>
public string AutoMaticallyCopy { get; set; } = "0";
/// <summary>
/// 复制文本
/// </summary>
public string Copy { get; set; } = string.Empty;
#endregion
#region
/// <summary>
/// 设置链接
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
public BarkMessage SetUrl(string url)
{
this.Url = url;
return this;
}
/// <summary>
/// 设置保存,默认保存
/// </summary>
/// <returns></returns>
public BarkMessage SetArchive()
{
IsArchive = "1";
return this;
}
/// <summary>
/// 设置不保存,默认保存
/// </summary>
/// <returns></returns>
public BarkMessage SetNotArchive()
{
IsArchive = "0";
return this;
}
/// <summary>
/// 设置自动复制,默认不自动复制
/// </summary>
/// <returns></returns>
public BarkMessage SetAutoCopy()
{
this.AutoMaticallyCopy = "1";
return this;
}
/// <summary>
/// 设置不自动复制,默认不自动复制
/// </summary>
/// <returns></returns>
public BarkMessage SetNotAutoCopy()
{
this.AutoMaticallyCopy = "1";
return this;
}
/// <summary>
/// 设置自动拷贝的文本,默认拷贝全文
/// </summary>
/// <param name="text"></param>
/// <returns></returns>
public BarkMessage SetCopyText(string text)
{
Copy = text;
return this;
}
#endregion
}
public class BarkAuth
{
[InputTypeAttribte(0, "IsArchive", "自动保存", "1")]
public string IsArchive { get; set; }
[InputTypeAttribte(0, "AutoMaticallyCopy", "自动复制", "0")]
public string AutoMaticallyCopy { get; set; }
[InputTypeAttribte(0, "DeviceToken", "DeviceToken", "DeviceToken",false)]
public string DeviceToken { get; set; }
}
[SendMethodKey("3B6DE04D-A9EF-4C91-A151-60B7425C5AB2", "Bark(未完成)", Order = -1)]
public class BarkSendTemplate : SendTemplate<BarkAuth>
{
private static readonly string Topic = "me.fin.bark";
private static readonly string KeyID = "LH4T9V5U4R";
private static readonly string TeamID = "5U8LBRXG3A";
private static CngKey SecretKey;
public override BarkAuth Auth { get; set; }
public override bool SendMessage(SendMessage message)
{
var barkMessage = new BarkMessage(message.Title, message.Data)
{
IsArchive = Auth.IsArchive,
AutoMaticallyCopy = Auth.AutoMaticallyCopy
};
SendMesssage(barkMessage, Auth.DeviceToken);
return false;
}
private bool SendMesssage(BarkMessage barkMessage, string device_Tokne)
{
if (SecretKey == null)
{
var authPath = Path.Combine(DBManager.Instance.Inotify_Data, "AuthKey_LH4T9V5U4R_5U8LBRXG3A.p8");
var privateKeyContent = File.ReadAllText(authPath).Split('\n')[1];
SecretKey = CngKey.Import(Convert.FromBase64String(privateKeyContent), CngKeyBlobFormat.Pkcs8PrivateBlob);
}
if (barkMessage == null)
return false;
if (device_Tokne == null)
return false;
var expiration = DateTime.Now.ToUniversalTime() - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
var expirationSeconds = (long)expiration.TotalSeconds;
var alert = new Dictionary<string, object>();
if (!string.IsNullOrEmpty(barkMessage.Body))
alert.Add("body", barkMessage.Body);
if (!string.IsNullOrEmpty(barkMessage.Title))
alert.Add("title", barkMessage.Title);
var aps = new Dictionary<string, object>
{
{ "category", "Bark" },
{ "sound", "1107" },
{ "badge", "0" },
{ "mutable-content", "1" },
{ "alert", alert }
};
var payload = new Dictionary<string, object>
{
{ "aps", aps },
{ "isarchive", barkMessage.IsArchive },
{ "automaticallycopy", barkMessage.AutoMaticallyCopy },
{ "iss", TeamID},
{ "iat", expirationSeconds}
};
if (!string.IsNullOrEmpty(barkMessage.Url))
payload.Add("url", barkMessage.Url);
if (!string.IsNullOrEmpty(barkMessage.Copy))
payload.Add("copy", barkMessage.Copy);
var headers = new
{
alg = "ES256",
kid = KeyID
};
var hearderString = JObject.FromObject(headers).ToString();
var payloadString = JObject.FromObject(payload).ToString();
var accessToken = SignES256(SecretKey, hearderString, payloadString);
var data = Encoding.UTF8.GetBytes(payloadString);
var httpClient = new HttpClient();
var requestMessage = new HttpRequestMessage
{
RequestUri = new Uri(string.Format("https://{0}:{1}/3/device/{2}", "api.development.push.apple.com", 443, device_Tokne))
};
requestMessage.Headers.Add("authorization", string.Format("bearer {0}", accessToken));
requestMessage.Headers.Add("apns-id", Guid.NewGuid().ToString());
requestMessage.Headers.Add("apns-expiration", "0");
requestMessage.Headers.Add("apns-priority", "10");
requestMessage.Headers.Add("apns-topic", Topic);
requestMessage.Method = HttpMethod.Post;
requestMessage.Content = new ByteArrayContent(data);
var task = httpClient.SendAsync(requestMessage);
task.Wait();
var responseMessage = task.Result;
if (responseMessage.StatusCode == System.Net.HttpStatusCode.OK)
{
return true;
}
return true;
}
private string SignES256(CngKey secretKey, string header, string payload)
{
using ECDsaCng dsa = new ECDsaCng(secretKey)
{
HashAlgorithm = CngAlgorithm.Sha256
};
var unsignedJwtData = Convert.ToBase64String(Encoding.UTF8.GetBytes(header)) + "." + Convert.ToBase64String(Encoding.UTF8.GetBytes(payload));
var signature = dsa.SignData(Encoding.UTF8.GetBytes(unsignedJwtData));
return unsignedJwtData + "." + Convert.ToBase64String(signature);
}
}
}