首页 > 其他分享 >【App消息推送】.NET7简单实现个推服务端

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

时间:2023-03-02 17:57:38浏览次数:36  
标签:set string get App configOptions NET7 new public 服务端

 

一.添加基础设施

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;
        }
    }

 

标签:set,string,get,App,configOptions,NET7,new,public,服务端
From: https://www.cnblogs.com/duia/p/17172614.html

相关文章

  • Kodi官方遥控器APP:Kore 使用教程及下载地址
    为了让Kodi更适合在客厅、影音室等场合方便地使用,Kodi不仅支持很多硬件的遥控器,而且还提供了iOS和Android手机端的Kodi远程控制官方APP:Kore-OfficialRemotefor......
  • 【ZooKeeper基础-数据结构、服务端/客户端常用命令】
    一、ZooKeeper简介二、ZooKeeper数据结构&命令**1、数据结构**2、服务端常用命令①单机启动命令:./zkServer.shstart②状态查询命令:./zkServer.shstatus③停止服务......
  • 如何注册appuploader账号​
    我们上一篇讲到appuploader的下载安装,要想使用此软件呢,需要注册账号才能使用,今天我们来讲下如何注册appuploader账号来使用软件。​​1.Apple官网注册AppleID​​首先我们......
  • Fiddler 对真机(Android 系统)上 App 抓包图文详解 (超全)
    作为测试或开发经常需要抓取手机App的HTTP/HTTPS的数据包,通过查看App发出的HTTP请求和响应数据来协助开发去修复bug。对于测试而言,通过抓包+分析,去定位bug的前后端归属问题......
  • 解决当前标识(IIS APPPOOL\XXXX)没有对“C:\Windows\Microsoft.NET\Framework64\
    1、问题描述在WindowsServer2019数据中心版中搭建IIS项目,访问的时候出现如下所示的错误:当前标识(IISAPPPOOL\XXXX)没有对“C:\Windows\Microsoft.NET\Framework64\v4.0......
  • 如何使用appuploader制作描述文件​
    如何使用appuploader制作描述文件​承接上文我们讲述了怎么制作证书,本文我们来看下怎么制作描述文件吧。​1.描述文件​首先我们在主界面找到描述文件管理,点击进入描......
  • HttpServletRequestWrapper 类&过滤指定文字
    HttpServletWrapper和HttpServletResponseWrapper1).ServletAPI中提供了一个HttpServletRequestWrapper类来包装原始的request对象,   HttpServletReques......
  • 如何注册appuploader账号​
    如何注册appuploader账号​我们上一篇讲到appuploader的下载安装,要想使用此软件呢,需要注册账号才能使用,今​天我们来讲下如何注册appuploader账号来使用软件。​1.Apple......
  • 代购APP要怎么开发运营
    随着日常生活水平的提高,每个人的消费范围都有了显著的提高。在可接受的价格范围内,很多客户选择进口商品,因为进口商品更受欢迎。这就是为什么代购领域可以如此受到消费者的追......
  • /dev/mapper/centos-root 磁盘空间爆满的解决办法
    1、df-h查看磁盘空间使用情况2、从根目录开始,du-sh*查看每个目录下的磁盘占用情况3、cd空间占用较大的目录,继续执行du-sh*,依次往下查找,找到可删除的大文件,并删......