【App消息推送】.NET7简单实现个推服务端

 

一.添加基础设施

1.添加配置实体模型

    public class GetuiConfigOptions
    {
        public string AppID { get; set; }
        public string AppKey { get; set; }
        public string AppSecret { get; set; }
        public string MasterSecret { get; set; }
        public string Host { get; set; }
    }

2.添加Program.cs相关代码

     public static IServiceCollection AddPushNotifications(this IServiceCollection services)
        {
       var getuiConfig = AppSettings.GetModel<GetuiConfigOptions>($"PushNotifications:GeTui");//Masa.Utils.Configuration.Json
 
       if (getuiConfig == null) { throw new Exception("PushNotifications:GeTui is not null"); } services.AddSingleton<GetuiConfigOptions>(getuiConfig); services.AddHttpClient<IPushNotificationsBase, GetuiPushService>(options => { options.BaseAddress = new Uri(getuiConfig.Host); }); services.AddSingleton<IPushNotificationsBase, ApplePushService>();return services; }

3.添加appsettings.json配置

  "PushNotifications": {
    "Apple": {
      "CertContent": "-----BEGIN PRIVATE KEY-----\r\nMIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEYIKoZIzj0DAQehRANCAARXCUm3Rzh/fbBv\r\n/8J8RGzDStTBPgBibPh2ctNWLGRP3iu+MCb\r\nkssjSKCF\r\n-----END PRIVATE KEY-----",
      "KeyId": "LUFL2",
      "TeamId": "V4M2",
      "BundleId": "com.Apss.x",
      "UseSandbox": false
    },
    "GeTui": {
      "Host": "https://restapi.getui.com/v2/",
      "AppID": "WjYtI4cPbzi8L3",
      "AppKey": "Y0SKzdPv8rJ5",
      "AppSecret": "FibiA7VAESyA",
      "MasterSecret": "O9RGaQO9"
    }
  },

 

二.添加interface接口和工具类

1.Util工具类

  public static class Util
    {
        /// <summary>
        /// 获取时间撮
        /// </summary>
        /// <returns></returns>
        public static string GenerateTimeStamp()
        {
            TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
            return Convert.ToInt64(ts.TotalMilliseconds).ToString();
        }

        /// <summary>
        /// 加密算法
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static string Sha256(string data)
        {
            StringBuilder builder = new StringBuilder();

            byte[] bytes = Encoding.UTF8.GetBytes(data);
            byte[] hash = SHA256Managed.Create().ComputeHash(bytes);

            for (int i = 0; i < hash.Length; i++)
            {
                builder.Append(hash[i].ToString("X2"));
            }

            return builder.ToString();
        }
    }

2.interface类

    public interface IPushNotificationsBase
    {
        Task<IEnumerable<SendResponse>> SendAsync(params (string clientId, string title, string subTitle, string messageContont)[] request);
    }

三、使用方法

public class PushNotificationsIntergratiomEventHandlers
{
     private readonly IAppPushNotificationsBase appPushNotificationsClient; public PushNotificationsIntergratiomEventHandlers(IAppPushNotificationsBase appPushNotificationsClient) {
       this.appPushNotificationsClient = appPushNotificationsClient; } /// <summary> /// 发送消息 /// </summary> /// <param name="integrationEvent"></param> /// <returns></returns> [EventHandler] public async Task SendAsync(SendUserMessageCommand client) {
      await appPushNotificationsClient.SendAsync((client.ClientId, item.Title, item.SubTitle, item.MessageBody));
     } 
}

 

四.代码具体实现

1.APP个推帮助类

    /// <summary>
    /// APP个推帮助类
    /// </summary>
    public class GetuiPushService : IPushNotificationsBase
    {
        private const string AUTHORIZATION_KEY = "token";
        private static string appSendToken = "";
        private static DateTime tokenExpireTime = DateTime.UtcNow;

        private readonly GetuiConfigOptions configOptions;
        private readonly HttpClient httpClient;

        public GetuiPushService(GetuiConfigOptions configOptions, HttpClient httpClient)
        {
            this.configOptions = configOptions;
            this.httpClient = httpClient;
        }

        public async Task<IEnumerable<SendResponse>> SendAsync(params (string clientId, string title, string subTitle, string messageContont)[] request)
        {
            await this.RefreshTokenAsync();

            httpClient.DefaultRequestHeaders.Remove(AUTHORIZATION_KEY);
            httpClient.DefaultRequestHeaders.Add(AUTHORIZATION_KEY, appSendToken);

            var result = new List<SendResponse>();

            foreach (var item in request)
            {
                try
                {
                    var parameter = new
                    {
                        request_id = Guid.NewGuid().ToString(),
                        settings = new { ttl = 7200000 },
                        audience = new { cid = new[] { item.clientId } },
                        push_message = new
                        {
                            notification = new
                            {
                                title = item.title,
                                body = item.messageContont,
                                click_type = "url",
                                url = "https//:xxx"
                            }
                        }
                    };

                    var stringContont = new StringContent(JsonConvert.SerializeObject(parameter), Encoding.UTF8, "application/json");

                    await httpClient.PostAsync($"{configOptions.AppID}/push/single/cid", stringContont);
                }
                catch (Exception ex)
                {
                    result.Add(new(item.clientId, ex.Message));
                }
            }

            return result;
        }

        private async Task RefreshTokenAsync()
        {
            try
            {
                if (!string.IsNullOrWhiteSpace(appSendToken))
                {
                    if (tokenExpireTime > DateTime.UtcNow.AddHours(8))
                    {
                        return;
                    }
                }

                string timestamp = Util.GenerateTimeStamp();//时间戳
                string sign = Util.Sha256(configOptions.AppKey + timestamp + configOptions.MasterSecret);//sha256加密

                var parameter = new { sign, timestamp, appkey = configOptions.AppKey };
                var stringContont = new StringContent(JsonConvert.SerializeObject(parameter), Encoding.UTF8, "application/json");
                var httpResponseMessage = await httpClient.PostAsync($"{configOptions.AppID}/auth", stringContont);
                if (httpResponseMessage.StatusCode != HttpStatusCode.OK)
                {
                    return;
                }
                var httpResponse = await httpResponseMessage.Content.ReadFromJsonAsync<GeTuiResponseBase<GeTuiGetTokenResponse>>();
                tokenExpireTime = DateTime.UtcNow.AddHours(16);
                appSendToken = httpResponse.Data.Token;
            }
            catch (Exception ex)
            {
                throw;
            }
        }
    }

 

    public class GeTuiResponseBase<T>
    {
        public int Code { get; set; }
        public string Msg { get; set; }
        public virtual T Data { get; set; }
    }

    public class GeTuiGetTokenResponse
    {
        public long Expire_time { get; set; }
        public string Token { get; set; }
    }

    public class SendResponse
    {
        /// <summary>
        /// ClientId
        /// </summary>
        public string ClientId { get; set; }

        /// <summary>
        /// 错误内容
        /// </summary>
        public string ErrorContent { get; set; }

        public SendResponse() { }

        public SendResponse(string clientId, string errorContent)
        {
            ClientId = clientId;
            ErrorContent = errorContent;
        }
    }

 

posted @ 2023-03-02 17:43  棙九九  阅读(160)  评论(0)    收藏  举报