From 3adff3b155652af5872ba654c2781bd2bc4ddf11 Mon Sep 17 00:00:00 2001 From: Paul Schneider Date: Wed, 8 May 2019 16:33:29 +0100 Subject: [PATCH] getting rid of GCM --- .../Messaging/MessageWithPayloadResponse.cs | 4 - src/Yavsc.Server/Constants.cs | 8 +- src/Yavsc/Hubs/ChatHub.cs | 40 ++--- src/Yavsc/Services/GCMSender.cs | 102 ------------- src/Yavsc/Services/YavscMessageSender.cs | 139 ++++++++++++++++++ src/Yavsc/Startup/Startup.cs | 2 +- 6 files changed, 170 insertions(+), 125 deletions(-) delete mode 100644 src/Yavsc/Services/GCMSender.cs create mode 100644 src/Yavsc/Services/YavscMessageSender.cs diff --git a/src/Yavsc.Abstract/Google/Messaging/MessageWithPayloadResponse.cs b/src/Yavsc.Abstract/Google/Messaging/MessageWithPayloadResponse.cs index 96af0ac0..308b6a57 100644 --- a/src/Yavsc.Abstract/Google/Messaging/MessageWithPayloadResponse.cs +++ b/src/Yavsc.Abstract/Google/Messaging/MessageWithPayloadResponse.cs @@ -27,10 +27,6 @@ namespace Yavsc.Models.Google.Messaging /// Message with payload response. /// public class MessageWithPayloadResponse { - /// - /// The multicast identifier. - /// - public string multicast_id; /// /// The success count. /// diff --git a/src/Yavsc.Server/Constants.cs b/src/Yavsc.Server/Constants.cs index f1f761e8..fb499b84 100644 --- a/src/Yavsc.Server/Constants.cs +++ b/src/Yavsc.Server/Constants.cs @@ -57,7 +57,13 @@ namespace Yavsc { "openid", "profile", "email", "https://www.googleapis.com/auth/calendar" }; public static readonly string NoneCode = "none"; - + public const string HubGroupAuthenticated = "authenticated"; + public const string HubGroupAnonymous = "anonymous"; + public const string HubGroupCops= "cops"; public const int MaxChanelName = 255; } + public static class NotificationTypes { + public const string Connected = "connected"; + public const string DisConnected = "disconnected"; + } } diff --git a/src/Yavsc/Hubs/ChatHub.cs b/src/Yavsc/Hubs/ChatHub.cs index 50c4e500..d4d65c5f 100644 --- a/src/Yavsc/Hubs/ChatHub.cs +++ b/src/Yavsc/Hubs/ChatHub.cs @@ -37,9 +37,11 @@ namespace Yavsc { ApplicationDbContext _dbContext; ILogger _logger; + IUserIdProvider _userIdProvider; - public ChatHub() + public ChatHub(IUserIdProvider userIdProvider) { + _userIdProvider = userIdProvider; var scope = Startup.Services.GetRequiredService().CreateScope(); _dbContext = scope.ServiceProvider.GetService(); var loggerFactory = scope.ServiceProvider.GetService(); @@ -54,35 +56,39 @@ namespace Yavsc { isAuth = Context.User.Identity.IsAuthenticated; userName = Context.User.Identity.Name; + var group = isAuth ? - "authenticated" : "anonymous"; + Constants.HubGroupAuthenticated : Constants.HubGroupAnonymous; // Log ("Cx: " + group); await Groups.Add(Context.ConnectionId, group); if (isAuth) { - var user = _dbContext.Users.Include(u=>u.Connections).Single(u => u.UserName == userName); - if (user.Connections==null) - user.Connections = new List(); - var ucx = user.Connections.FirstOrDefault(c=>c.ConnectionId == Context.ConnectionId); - if (ucx==null) - user.Connections.Add(new ChatConnection + var userHadConnections = _dbContext.ChatConnection.Any(accx => accx.ConnectionId == Context.ConnectionId); + + if (userHadConnections) { + var ccx = _dbContext.ChatConnection.First(c=> c.ConnectionId == Context.ConnectionId); + ccx.Connected=true; + } + else + _dbContext.ChatConnection.Add(new ChatConnection { ConnectionId = Context.ConnectionId, UserAgent = Context.Request.Headers["User-Agent"], Connected = true }); - else { - ucx.Connected = true; - } _dbContext.SaveChanges(); - - Clients.CallerState.BlackListedBy = await _dbContext.BlackListed.Where(r=>r.UserId == user.Id).Select(r=>r.OwnerId).ToArrayAsync(); - + var userId = _userIdProvider.GetUserId(this.Context.Request); + Clients.CallerState.BlackListedBy = await _dbContext.BlackListed.Where(r=>r.UserId == userId).Select(r=>r.OwnerId).ToArrayAsync(); + // TODO ChatHubConnectioinFlags } + else + // FIXME is this line reached ? + await Groups.Add(Context.ConnectionId, Constants.HubGroupAnonymous); } - else await Groups.Add(Context.ConnectionId, "anonymous"); + else await Groups.Add(Context.ConnectionId, Constants.HubGroupAnonymous); - Clients.Group("authenticated").notify("connected", Context.ConnectionId, userName); + // TODO only notify followers + Clients.Group(Constants.HubGroupAuthenticated).notify(NotificationTypes.Connected, Context.ConnectionId, userName); await base.OnConnected(); } @@ -200,7 +206,7 @@ namespace Yavsc public void Abort() { - var cx = _dbContext .ChatConnection.SingleOrDefault(c=>c.ConnectionId == Context.ConnectionId); + var cx = _dbContext.ChatConnection.SingleOrDefault(c=>c.ConnectionId == Context.ConnectionId); if (cx!=null) { _dbContext.ChatConnection.Remove(cx); _dbContext.SaveChanges(); diff --git a/src/Yavsc/Services/GCMSender.cs b/src/Yavsc/Services/GCMSender.cs deleted file mode 100644 index 8333d5f9..00000000 --- a/src/Yavsc/Services/GCMSender.cs +++ /dev/null @@ -1,102 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.OptionsModel; -using Newtonsoft.Json; -using Yavsc.Interfaces.Workflow; -using Yavsc.Models.Google.Messaging; -using Yavsc.Models.Haircut; -using Yavsc.Models.Messaging; -using Yavsc.Server.Helpers; - -namespace Yavsc.Services -{ - public class GCMSender : IYavscMessageSender - { - private ILogger _logger; - SiteSettings siteSettings; - GoogleAuthSettings googleSettings; - - public GCMSender( - - ILoggerFactory loggerFactory, - IOptions sitesOptions, - IOptions smtpOptions, - IOptions googleOptions - ) - { _logger = loggerFactory.CreateLogger(); - siteSettings = sitesOptions?.Value; - googleSettings = googleOptions?.Value; - - } - public async Task NotifyEvent - ( IEnumerable regids, Event ev) - where Event : IEvent - { - if (ev == null) - throw new Exception("Spécifier un évènement"); - - if (ev.Sender == null) - throw new Exception("Spécifier un expéditeur"); - - if (regids == null ) - throw new NotImplementedException("Notify & No GCM reg ids"); - var raa = regids.ToArray(); - if (raa.Length<1) - throw new NotImplementedException("No GCM reg ids"); - var msg = new MessageWithPayload() - { - data = ev, - registration_ids = regids.ToArray() - }; - _logger.LogInformation("Sendding to Google : "+JsonConvert.SerializeObject(msg)); - try { - using (var m = new SimpleJsonPostMethod("https://gcm-http.googleapis.com/gcm/send",$"key={googleSettings.ApiKey}")) { - return await m.Invoke(msg); - } - } - catch (Exception ex) { - _logger.LogError(ex.Message); - throw new Exception ("Quelque chose s'est mal passé à l'envoi",ex); - - } - } - - - public async Task NotifyBookQueryAsync( IEnumerable registrationIds, RdvQueryEvent ev) - { - return await NotifyEvent(registrationIds, ev); - } - - public async Task NotifyEstimateAsync(IEnumerable registrationIds, EstimationEvent ev) - { - return await NotifyEvent(registrationIds, ev); - } - - public async Task NotifyHairCutQueryAsync( - IEnumerable registrationIds, HairCutQueryEvent ev) - { - return await NotifyEvent(registrationIds, ev); - } - - public async Task NotifyAsync(IEnumerable regids, IEvent yaev) - { - return await NotifyEvent(regids, yaev); - } - - /* SMS with Twilio: -public Task SendSmsAsync(TwilioSettings twilioSettigns, string number, string message) -{ -var Twilio = new TwilioRestClient(twilioSettigns.AccountSID, twilioSettigns.Token); -var result = Twilio.SendMessage( twilioSettigns.SMSAccountFrom, number, message); -// Status is one of Queued, Sending, Sent, Failed or null if the number is not valid -Trace.TraceInformation(result.Status); -// Twilio doesn't currently have an async API, so return success. - -return Task.FromResult(result.Status != "Failed"); - -} */ - } -} diff --git a/src/Yavsc/Services/YavscMessageSender.cs b/src/Yavsc/Services/YavscMessageSender.cs new file mode 100644 index 00000000..32d9d2a3 --- /dev/null +++ b/src/Yavsc/Services/YavscMessageSender.cs @@ -0,0 +1,139 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNet.SignalR; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.OptionsModel; +using Newtonsoft.Json; +using Yavsc.Interfaces.Workflow; +using Yavsc.Models; +using Yavsc.Models.Google.Messaging; +using Yavsc.Models.Haircut; +using Yavsc.Models.Messaging; + +namespace Yavsc.Services +{ + public class YavscMessageSender : IYavscMessageSender + { + private ILogger _logger; + IEmailSender _emailSender; + SiteSettings siteSettings; + private IHubContext hubContext; + ApplicationDbContext _dbContext; + + public YavscMessageSender( + ILoggerFactory loggerFactory, + IOptions sitesOptions, + IOptions smtpOptions, + IEmailSender emailSender, + ApplicationDbContext dbContext + ) + { + _logger = loggerFactory.CreateLogger(); + _emailSender = emailSender; + siteSettings = sitesOptions?.Value; + hubContext = GlobalHost.ConnectionManager.GetHubContext(); + } + public async Task NotifyEvent + (IEnumerable userIds, Event ev) + where Event : IEvent + { + + if (ev == null) + throw new Exception("Spécifier un évènement"); + + if (ev.Sender == null) + throw new Exception("Spécifier un expéditeur"); + + if (userIds == null ) + throw new NotImplementedException("Notify e No user id"); + + MessageWithPayloadResponse response = new MessageWithPayloadResponse(); + + var raa = userIds.ToArray(); + if (raa.Length<1) + throw new NotImplementedException("No GCM reg ids"); + + try { + _logger.LogInformation($"Sending to {string.Join(" ",raa)} using signalR : "+JsonConvert.SerializeObject(ev)); + List results = new List(); + foreach(var clientId in raa) { + MessageWithPayloadResponse.Result result = new MessageWithPayloadResponse.Result(); + result.registration_id = clientId; + + var hubClient = hubContext.Clients.User(clientId); + if (hubClient == null) + { + var user = _dbContext.Users.FirstOrDefault(u=> u.Id == clientId); + if (user==null) + { + result.error = "no such user."; + continue; + } + if (!user.EmailConfirmed){ + result.error = "user has not confirmed his email address."; + continue; + } + var body = ev.CreateBody(); + var sent = await _emailSender.SendEmailAsync(ev.Sender, user.Email, + ev.Topic, body + ); + result.message_id = sent.MessageId; + if (!sent.Sent) { + result.error = sent.ErrorMessage; + response.failure++; + } + else + response.success++; + } + else { + // we assume that each hub connected client will handle this signal + hubClient.notify(ev); + response.success++; + } + } + response.results = results.ToArray(); + return response; + } + catch (Exception ex) { + _logger.LogError("Quelque chose s'est mal passé à l'envoi: "+ex.Message); + throw; + } + } + + public async Task NotifyBookQueryAsync( IEnumerable registrationIds, RdvQueryEvent ev) + { + return await NotifyEvent(registrationIds, ev); + } + + public async Task NotifyEstimateAsync(IEnumerable registrationIds, EstimationEvent ev) + { + return await NotifyEvent(registrationIds, ev); + } + + public async Task NotifyHairCutQueryAsync( + IEnumerable registrationIds, HairCutQueryEvent ev) + { + return await NotifyEvent(registrationIds, ev); + } + + public async Task NotifyAsync(IEnumerable regids, IEvent yaev) + { + return await NotifyEvent(regids, yaev); + } + + /* SMS with Twilio: +public Task SendSmsAsync(TwilioSettings twilioSettigns, string number, string message) +{ +var Twilio = new TwilioRestClient(twilioSettigns.AccountSID, twilioSettigns.Token); +var result = Twilio.SendMessage( twilioSettigns.SMSAccountFrom, number, message); +// Status is one of Queued, Sending, Sent, Failed or null if the number is not valid +Trace.TraceInformation(result.Status); +// Twilio doesn't currently have an async API, so return success. + +return Task.FromResult(result.Status != "Failed"); + +} */ + } +} diff --git a/src/Yavsc/Startup/Startup.cs b/src/Yavsc/Startup/Startup.cs index 4d3c88f5..b2e80e6a 100755 --- a/src/Yavsc/Startup/Startup.cs +++ b/src/Yavsc/Startup/Startup.cs @@ -274,7 +274,7 @@ namespace Yavsc // Add application services. services.AddTransient(); - services.AddTransient(); + services.AddTransient(); services.AddTransient(); services.AddTransient( (sp) => new FileDataStore("googledatastore",false) ); services.AddTransient();