using System; using System.Linq; using System.Threading.Tasks; using Sony.ChartBot.Entities; using Sony.ChartBot.Entities.MessengerApi; using Sony.ChartBot.Entities.Storage; using Sony.ChartBot.Helpers; using Sony.ChartBot.Messages.Helpers; using Sony.ChartBot.Messages.MessageBuilders; using Sony.ChartBot.MessengerApi; using Sony.ChartBot.Repository; namespace Sony.ChartBot.Client.Commands { public class HandlePostbackCommand : IMessagingCommand { private readonly MessengerApiClient _messengerApiClient; private readonly CountryRepository _countryRepository; private readonly SubscriptionRepository _subscriptionRepository; private readonly MessageSender _messageSender; private readonly ChartTrackModelBuilder _chartTrackModelBuilder; public HandlePostbackCommand( MessengerApiClient messengerApiClient, CountryRepository countryRepository, SubscriptionRepository subscriptionRepository, MessageSender messageSender, ChartTrackModelBuilder chartTrackModelBuilder) { _messengerApiClient = messengerApiClient; _countryRepository = countryRepository; _subscriptionRepository = subscriptionRepository; _messageSender = messageSender; _chartTrackModelBuilder = chartTrackModelBuilder; } public async Task HandleCallbackReceivedAsync(MessagingData input) { switch (input.postback.payload) { // User clicked "Get started"-button case "started": await HandleGetStartedCallbackReceivedAsync(input); return; // User clicked "Next artist"-button case "next": await HandleNextArtistCallbackReceivedAsync(input); return; } // User clicked "Compare"-button if (input.postback.payload.StartsWith("compare")) { await HandleCompareCallbackReceivedAsync(input); return; } // User clicked "Subscribe"-button else if (input.postback.payload.StartsWith("subscribe")) { await HandleSubscribeCallbackReceivedAsync(input); return; } // User clicked "Unsubscribe"-button else if (input.postback.payload.StartsWith("unsubscribe")) { await HandleUnsubscribeCallbackReceivedAsync(input); return; } throw new NotImplementedException(); } private async Task HandleGetStartedCallbackReceivedAsync(MessagingData input) { // Get user data and try to find a supported country from it var user = await _messengerApiClient.GetUserDataAsync(input.sender.id); if (user == null || user.locale == null) { throw new Exception($"Failded fetching user data for user {input.sender.id}"); } SupportedCountry country = null; if (user.locale.Length == 5) // e.g. sv_SE { var countryCode = user.locale.Substring(3, 2); country = _countryRepository.GetSupportedCountry(countryCode); } if (country != null) { await _countryRepository.SetDefaultCountryAsync(input.sender.id, country, user.timezone); } // Send welcome message await _messageSender.BuildAndSendMessagesAsync>(input, Tuple.Create(user, country)); } private async Task HandleNextArtistCallbackReceivedAsync(MessagingData input) { // Ask for next artist (and country) await _messageSender.BuildAndSendMessagesAsync(input); } private async Task HandleCompareCallbackReceivedAsync(MessagingData input) { // Keep track refence to track which track to compare with var trackReference = ReadTrackReference(input); var model = await _chartTrackModelBuilder.BuildModel(trackReference, input.sender.id); // Ask for artist (and country) to compare with await _messageSender.BuildAndSendMessagesAsync( input, model, InquiryType.AskForComparison, trackReference); } private async Task HandleSubscribeCallbackReceivedAsync(MessagingData input) { // Keep track refence to track which track to subscribe to var trackReference = ReadTrackReference(input); var model = await _chartTrackModelBuilder.BuildModel(trackReference, input.sender.id); // Store subscription and send confirmation message await _subscriptionRepository.AddSubscriptionAsync(input.sender.id, trackReference); await _messageSender.BuildAndSendMessagesAsync( input, model, InquiryType.AskForComparison, trackReference); await Task.Delay(100); // Ask for next artist (and country) await _messageSender.BuildAndSendMessagesAsync(input); } private async Task HandleUnsubscribeCallbackReceivedAsync(MessagingData input) { // Keep track refence to track which track to unsubscribe to var trackReference = ReadTrackReference(input); var model = await _chartTrackModelBuilder.BuildModel(trackReference, input.sender.id); // Delete subscription and send confirmation message await _subscriptionRepository.RemoveSubscriptionAsync(input.sender.id, trackReference); await _messageSender.BuildAndSendMessagesAsync( input, model, InquiryType.AskForComparison, trackReference); await Task.Delay(100); // Ask for next artist (and country) await _messageSender.BuildAndSendMessagesAsync(input); } private string ReadTrackReference(MessagingData data) { var payload = data.postback.payload; var parts = payload.Split('-'); if (parts.Length != 2) { throw new Exception($"Invalid compare payload: {payload}"); } var trackReference = parts.Last(); return trackReference; } } }