using System; using System.Linq; using System.Net; using System.Net.Http; using System.Threading.Tasks; using System.Web; using System.Web.Http; using Sony.ChartBot.Client.Commands; using Sony.ChartBot.Entities.MessengerApi; using Sony.ChartBot.Helpers; using Sony.ChartBot.Messages.Helpers; using Sony.ChartBot.Messages.MessageBuilders; using Sony.ChartBot.Repository; namespace Sony.ChartBot.Client.Controllers { public class CallbackController : ApiController { private readonly HandleMessageCommand _handleMessageCommand; private readonly HandleQuickReplyCommand _handleQuickReplyCommand; private readonly HandlePostbackCommand _handlePostbackCommand; private readonly MessageSender _messageSender; private readonly ErrorRepository _errorRepository; public CallbackController( HandleMessageCommand handleMessageCommand, HandleQuickReplyCommand handleQuickReplyCommand, HandlePostbackCommand handlePostbackCommand, MessageSender messageSender, ErrorRepository errorRepository ) { _handleMessageCommand = handleMessageCommand; _handleQuickReplyCommand = handleQuickReplyCommand; _handlePostbackCommand = handlePostbackCommand; _messageSender = messageSender; _errorRepository = errorRepository; } #region Endpoint validation [HttpGet] public IHttpActionResult Index() { var query = Request.GetQueryNameValuePairs().ToDictionary(nv => nv.Key, nv => nv.Value); string hubChallenge = null, hubVerifyToken = null; if (query.ContainsKey("hub.challenge")) { hubChallenge = query["hub.challenge"]; } if (query.ContainsKey("hub.verify_token")) { hubVerifyToken = query["hub.verify_token"]; } if (string.IsNullOrWhiteSpace(hubChallenge)) { return BadRequest(); } if (hubVerifyToken != "helloisitmeyourelookingfor") { return BadRequest(); } var resp = new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent(hubChallenge, System.Text.Encoding.UTF8, "text/plain") }; return ResponseMessage(resp); } #endregion [HttpPost] public async Task IndexAsync(Callback callback) { MessagingData data = null; try { data = GetFirstPostedData(callback); if (data == null) { throw new Exception("Missing callback data"); } // Handle incoming data IMessagingCommand command = null; if (data.message != null) { if (data.message.quick_reply != null) { command = _handleQuickReplyCommand; } else if (data.message.text != null) { command = _handleMessageCommand; } } else if (data.postback != null) { command = _handlePostbackCommand; } if (command == null) { throw new NotSupportedException("Could not perform command based on input"); } await command.HandleCallbackReceivedAsync(data); } catch (NotSupportedException ex) { await _messageSender.BuildAndSendMessagesAsync(data, ex); } catch (Exception ex) { // Log (continue if it fails) OnError.ResumeNext(() => _errorRepository.LogException(ex, HttpContext.Current)); // Send error response (continue if it fails) await OnError.ResumeNextAsync(() => _messageSender.BuildAndSendMessagesAsync(data, ex)); throw; } return Ok(); } private MessagingData GetFirstPostedData(Callback callback) { // We only expect one data entry to be returned return callback?.entry?.FirstOrDefault()?.messaging?.FirstOrDefault(); } } }