public TwiMLResult CallBackAfterConference(CallContextModel model)
        {
            var callSid = Request["CallSid"];
            var response = new TwilioResponse();
            try
            {
                if (model.IsCustomer)
                {
                    model.ReceiverSid = callSid;
                }
                else
                {
                    model.CallerSid = callSid;
                }

                response.Say(ConferenceConst.ThankForConsultantAndFollowupAction,
                            new { voice = VoiceInConference, language = LanguageInConference });
                response.Redirect(Url.Action("ConsultantAfterCall", model));

                return new TwiMLResult(response);
            }
            catch (Exception e)
            {
                Log.Error("Call back after conference. Error: ", e);

                // Error
                response.Say(ConferenceConst.ErrorMessage, new { voice = VoiceInConference, language = LanguageInConference });
                response.Hangup();
            }

            return new TwiMLResult(response);
        }
        public TwiMLResult FirstClientResponse(CallContextModel model, string digits)
        {
            var response = new TwilioResponse();
            try
            {
                if (model.IsCustomer) // Customer initiate call >> Consultant called first
                {
                    var optionKey = string.Empty;
                    var optionNotify = ConferenceConst.OptionNotifyForDefer;
                    var deferMinute = 5;

                    switch (digits)
                    {
                        case "1":
                            response.Redirect(Url.Action("FirstClientReady", model));

                            // Update on time and total consultation
                            Services.Call.UpdateOnTime(model.ReceiverId);
                            Services.Call.UpdateTotalConsultation(model.ReceiverId);

                            // Change css
                            CallHelper.ChangeCssDialToPhone(Services.Users.GetUserById(model.CallerId));
                            break;

                        case "2":

                            optionKey = ConferenceConst.OptionDefer5Minutes;
                            break;

                        case "3":

                            optionKey = ConferenceConst.OptionDefer10Minutes;
                            deferMinute = 10;
                            break;

                        case "4":

                            optionKey = ConferenceConst.OptionDefer15Minutes;
                            deferMinute = 15;
                            break;

                        case "5":

                            optionKey = ConferenceConst.OptionSchedule24Hours;
                            optionNotify = ConferenceConst.OptionNotifyForSchedule;
                            deferMinute = 24 * 60;
                            break;

                        case "6":

                            optionKey = ConferenceConst.OptionScheduleOver24Hours;
                            optionNotify = ConferenceConst.OptionNotifyForSchedule;
                            deferMinute = 48 * 60;
                            break;

                        case "9":

                            optionNotify = ConferenceConst.OptionDeclineConsultation;

                            // Update on time and total consultation
                            Services.Call.UpdateTotalConsultation(model.ReceiverId);
                            break;

                        default:

                            response.Redirect(Url.Action("FirstClientStart", model));
                            return new TwiMLResult(response);
                    }

                    var specialist = Services.Users.GetUserById(model.ReceiverId);

                    if (digits != "1")
                    {
                        if (digits != "9")
                        {
                            // Update booking to database
                            if (Services.Booking.UpdateBookingForDeferOrReSchedule(model.BookingId, deferMinute))
                            {
                                if (("7".Equals(digits) == false) || ("8".Equals(digits) == false))
                                {
                                    // Call function to show popup defer or reschedule for customer
                                    bool isDefer = false;
                                    if ("2".Equals(digits) || "3".Equals(digits) || "4".Equals(digits))
                                    {
                                        isDefer = true;
                                    }
                                    else
                                    {
                                        // Update status "Not available" for specilist when reschedule 5,6
                                        _cache.Remove(string.Format(ConferenceConst.CacheSpecialistStatus, specialist.Id));
                                        Services.Users.UpdateAvaibilityStatus(model.ReceiverId, AvailabilityStatus.NotAvailable);
                                    }

                                    CallHelper.ShowPopupTalkNowDeferOrReSchedule(model.CallerId, model.BookingId, isDefer, Services);
                                }
                            }
                            else // If update booking defer unsuccess
                            {
                                // Log
                                Log.Error("FirstClientResponse_Update booking fail");

                                throw new Exception("Update booking fail.");
                            }

                            response.Say(String.Format(ConferenceConst.PressKeyForSelectOption, digits, optionKey),
                                            new { voice = VoiceInConference, language = LanguageInConference });
                        }
                        else // Specialist declined the consultation
                        {
                            // Update defer for booking is -1
                            Services.Booking.UpdateDeferBooking(model.BookingId, -1);

                            // Notify for customer conference was declined by consultant
                            var customer = Services.Users.GetUserById(model.CallerId);
                            var sepecialist = Services.Users.GetUserById(model.ReceiverId);

                            CallHelper.ShowPopupNotifyInConference(customer,
                                    ConferencePopupConst.DeclinedTitle,
                                    string.Format(ConferencePopupConst.DeclinedContent, specialist.Name));

                            // Update status "Maybe available" for specilist when decline 9
                            _cache.Remove(string.Format(ConferenceConst.CacheSpecialistStatus, specialist.Id));

                            // Compare current status and only change status when it is available
                            if (AvailabilityStatus.Available.Equals(specialist.AvailabilityStatus))
                            {
                                Services.Users.UpdateAvaibilityStatus(model.ReceiverId, AvailabilityStatus.MaybeAvailable);
                            }
                        }

                        response.Say(optionNotify, new { voice = VoiceInConference, language = LanguageInConference });
                        response.Redirect(Url.Action("CallHangUpForDeferOrReSchedule", model));
                    }
                    else
                    {
                        // Add cache status for specialist when talk now to use reupdate after talknow
                        _cache.Add(string.Format(ConferenceConst.CacheSpecialistStatus, specialist.Id), specialist.AvailabilityStatus, new CacheItemPolicy { AbsoluteExpiration = DateTimeOffset.Now.AddDays(1) });

                        // Set status "NotAvailable" when begin talk now
                        Services.Users.UpdateAvaibilityStatus(model.ReceiverId, AvailabilityStatus.NotAvailable);
                    }
                }
                else // Consultant initiate call >>  Customer called first
                {
                    switch (digits)
                    {
                        case "1":

                            response.Redirect(Url.Action("FirstClientReady", model));
                            break;

                        default:
                            response.Redirect(Url.Action("FirstClientStart", model));
                            break;
                    }
                }

                return new TwiMLResult(response);
            }
            catch (Exception e)
            {
                // Log
                Log.Error("First client response. Error: ", e);

                // Error
                response.Say(ConferenceConst.ErrorMessage, new { voice = VoiceInConference, language = LanguageInConference });
                response.Hangup();
            }

            return new TwiMLResult(response);
        }
        public TwiMLResult FirstClientReady(CallContextModel model)
        {
            var response = new TwilioResponse();
            var message = string.Empty;

            try
            {
                // Make call to second client
                // If customer initiate call >> Customer will be call
                // If consultant initiate call >> Consultant will be call
                var customer = Services.Users.GetUserById(model.CallerId);
                var specialist = Services.Users.GetUserById(model.ReceiverId);

                try
                {
                    if (model.IsCustomer)
                    {
                        string fullPhoneNumber = customer.MobileCountryCode + customer.MobilePhone;

                        // Make call to customer
                        var call = Services.Call.Dial(Url.Action("SecondClientStart", model), fullPhoneNumber);

                        // Update callSid
                        Services.Call.UpdateCallSid(model.CallId, call.Sid, true);
                    }
                    else
                    {
                        customer = Services.Users.GetUserById(model.ReceiverId);
                        specialist = Services.Users.GetUserById(model.CallerId);

                        string fullPhoneNumber = specialist.MobileCountryCode + specialist.MobilePhone;

                        // Make call to consultant
                        var call = Services.Call.Dial(Url.Action("SecondClientStart", model), fullPhoneNumber);

                        // Update callSid
                        Services.Call.UpdateCallSid(model.CallId, call.Sid, true);
                    }
                }
                catch (Exception e)
                {
                    // Log
                    Log.Error("FirstClientReady_Call to second client failed. Error: ", e);
                }

                // Update call status
                model.ReceiverStatus = Request["CallStatus"];
                Services.Call.UpdateCallStatus(model.CallId, model.ReceiverStatus, false);

                if (model.IsCustomer) // Customer initiate call >> Consultant called first
                {
                    string template = ConferenceConst.AcceptCallNowForTalkNow;
                    message = string.Format(template, customer.Name);
                }
                else // Consultant initiate call >> Customer called first
                {
                    string template = ConferenceConst.AcceptCallNowForSchedule;
                    message = string.Format(template, specialist.Title, specialist.Name);
                }

                response.Say(message, new { voice = VoiceInConference, language = LanguageInConference });
                response.Redirect(Url.Action("FirstClientHold", model));
            }
            catch (Exception e)
            {
                Log.Error("First client ready. Error: ", e);

                // Error
                response.Say(ConferenceConst.ErrorMessage, new { voice = VoiceInConference, language = LanguageInConference });
                response.Hangup();
            }

            return new TwiMLResult(response);
        }
        public TwiMLResult FirstClientHold(CallContextModel model)
        {
            var response = new TwilioResponse();
            try
            {
                bool pickedUp = Services.Call.ReceiverPickedUp(model.CallId);
                bool ready = Services.Call.ReceiverReady(model.CallId);

                // Update call status
                model.ReceiverStatus = Request["CallStatus"];
                Services.Call.UpdateCallStatus(model.CallId, model.ReceiverStatus, false);

                if (pickedUp && ready)
                {
                    // Join conference room
                    response.Redirect(Url.Action("FirstClientConference", model));
                }
                else
                {
                    response.Pause(20);

                    if (model.IsCustomer) //do Customer initiate call >> Consultant called first
                    {
                        response.Say(ConferenceConst.WaitForCustomer, new { voice = VoiceInConference, language = LanguageInConference });
                    }
                    else // Consultant initiate call >>  Customer called first
                    {
                        response.Say(ConferenceConst.WaitForConsultant, new { voice = VoiceInConference, language = LanguageInConference });
                    }

                    response.Redirect(Url.Action("FirstClientHold", model));
                }

                return new TwiMLResult(response);
            }
            catch (Exception e)
            {
                Log.Error("First client hold. Error: ", e);

                // Error
                response.Say(ConferenceConst.ErrorMessage, new { voice = VoiceInConference, language = LanguageInConference });
                response.Hangup();
            }

            return new TwiMLResult(response);
        }
        public TwiMLResult FirstClientConference(CallContextModel model)
        {
            var response = new TwilioResponse();

            try
            {
                // Get fromUser and toUser
                var caller = Services.Users.GetUserById(model.CallerId);
                var receiver = Services.Users.GetUserById(model.ReceiverId);
                var callBackUrl = Utilities.FormatLink(Url.Action("CallBackAfterConference", "Conference", model));

                if (model.IsCustomer) // Customer initiate call >> Consultant called first
                {
                    // Get name conference room
                    var room = string.Format(ConferenceRoom, caller.UserName, receiver.UserName, model.BookingId);

                    // Check customer is readly in conference
                    if (Services.Call.CheckCallInStatus(model.CallId, CallStatus.InProgress, false))
                    {
                        response.Say(ConferenceConst.CustomerReadyTakeCall, new { voice = VoiceInConference, language = LanguageInConference });

                        // Update start time conference
                        Services.Call.UpdateConferenceTime(model.CallId, true);

                        // Begin call duration show popup to user
                        CallHelper.CallDuration(Request["CallSid"], model.IsCustomer, Services, true);

                        // Start conference timer
                        CallHelper.StartConferenceTimer(model.CallerId, model.CallId, model.BookingId, room);

                        // Dial conference
                        response.DialConference(room,
                            new
                            {
                                endConferenceOnExit = true,
                                waitUrl = "http://twimlets.com/holdmusic?Bucket=com.twilio.music.electronica"
                            },
                            new
                            {
                                record = false,
                                transcribe = false,
                                action = callBackUrl
                            });
                    }
                    else
                    {
                        response.Say(ConferenceConst.CustomerDenied, new { voice = VoiceInConference, language = LanguageInConference });
                    }
                }
                else // Consultant initiate call >>  Customer called first
                {
                    response.Say(ConferenceConst.ConsultantReadyTakeCall, new { voice = VoiceInConference, language = LanguageInConference });
                    // Get name conference room
                    var room = string.Format(ConferenceRoom, caller.UserName, receiver.UserName, model.BookingId);

                    // Update start time conference
                    Services.Call.UpdateConferenceTime(model.CallId, true);

                    // Begin call duration show popup to user
                    CallHelper.CallDuration(Request["CallSid"], model.IsCustomer, Services, true);

                    // Begin conference timer
                    CallHelper.StartConferenceTimer(model.ReceiverId, model.CallId, model.BookingId, room);

                    // Dial conference
                    var callHangUpUrl = Utilities.FormatLink(Url.Action("CallHangUp", "Conference", model));
                    response.DialConference(room,
                        new
                        {
                            endConferenceOnExit = true
                        },
                        new
                        {
                            record = true,
                            trim = "trim-silence",
                            transcribe = false,
                            action = callHangUpUrl
                        });
                }
            }
            catch (Exception e)
            {
                Log.Error("First client join conference. Error: ", e);

                // Error
                response.Say(ConferenceConst.ErrorMessage, new { voice = VoiceInConference, language = LanguageInConference });
                response.Hangup();
            }

            return new TwiMLResult(response);
        }
        public TwiMLResult ConsultantAfterCallResponse(CallContextModel model, string digits)
        {
            var response = new TwilioResponse();
            var message = ConferenceConst.AcctionCompleted;
            var specialist = new UserDto();
            var call = new CallDto();

            bool canWaiveFee = true;
            int transcriptSuccess = 2;

            try
            {
                if (digits.Equals("2") || digits.Equals("3") || digits.Equals("4") || digits.Equals("5"))
                {
                    call = Services.Call.GetByCallSid(Request["CallSid"]);

                    if (string.IsNullOrWhiteSpace(model.RecordUrl))
                    {
                        model.RecordSid = call.RecordSid;
                        model.RecordDuration = call.RecordDuration;
                        model.RecordUrl = call.RecordUrl;
                    }

                    // Get specialist
                    if (model.IsCustomer) // Caller is customer
                    {
                        specialist = Services.Users.GetUserById(model.ReceiverId);
                    }
                    else
                    {
                        specialist = Services.Users.GetUserById(model.CallerId);
                    }

                    int startingTime = Convert.ToInt32(Services.SystemConfig.GetByKey(ParamatricBusinessRules.STARTING_TIME.ToString()).Value);
                    if (call.Duration <= startingTime)
                    {
                        canWaiveFee = false;
                    }
                }

                switch (digits)
                {
                    case "1": // Dictate your follow up action
                        var statusCallBack = Utilities.FormatLink(Url.Action("VoiceMail", "Conference", model));
                        Services.Call.RedirectToVoiceMail(Request["CallSid"], statusCallBack);

                        break;

                    case "2": // Transcript consultation
                        // Send transcription request
                        transcriptSuccess = SendTranscriptionRequest(specialist.Id.ToString(), specialist.UserName,
                                                                        specialist.Email, call.RecordUrl,
                                                                        call.RecordDuration, call.Booking);

                        if (transcriptSuccess == 0)
                        {
                            message = ConferenceConst.BalanceNotEnoughForTranscript;
                        }
                        else if (transcriptSuccess == 1)
                        {
                            message = ConferenceConst.TranscriptError;
                        }

                        break;

                    case "3": // Play consultation record
                        response.Pause(5);
                        response.Play(model.RecordUrl);

                        break;

                    case "4": //  Play consultation record and transcription
                        // Play consultation record
                        response.Pause(5);
                        response.Play(model.RecordUrl);

                        // Send transcription request
                        transcriptSuccess = SendTranscriptionRequest(specialist.Id.ToString(), specialist.UserName,
                                                                        specialist.Email, call.RecordUrl,
                                                                        call.RecordDuration, call.Booking);

                        if (transcriptSuccess == 0)
                        {
                            message = ConferenceConst.BalanceNotEnoughForTranscript;
                        }
                        else if (transcriptSuccess == 1)
                        {
                            message = ConferenceConst.TranscriptError;
                        }

                        break;

                    case "5": // Waive consultation fee
                        if (canWaiveFee)
                        {
                            response.Redirect(Url.Action("WaiveFeeAction", model));
                        }
                        else
                        {
                            response.Redirect(Url.Action("ConsultantAfterCall", model));
                        }

                        break;

                    default:
                        response.Redirect(Url.Action("ConsultantAfterCall", model));
                        return new TwiMLResult(response);
                }
            }
            catch (Exception e)
            {
                // Log
                Log.Error("Consultant after call response. Error: ", e);

                // Error
                response.Say(ConferenceConst.ErrorMessage, new { voice = VoiceInConference, language = LanguageInConference });
                response.Hangup();
            }

            response.Say(message, new { voice = VoiceInConference, language = LanguageInConference });
            response.Redirect(Url.Action("ConsultantAfterCall", model));
            return new TwiMLResult(response);
        }
        public ActionResult SecondClientStart(CallContextModel model)
        {
            var response = new TwilioResponse();

            try
            {
                // Get info for call context
                model.CallerSid = Request["CallSid"];
                model.CallerStatus = Request["CallStatus"];

                Services.Call.UpdateCallStatus(model.CallId, model.CallerStatus, true);
                Services.Call.ReceiverHasPickedUp(model.CallId);

                // Get fromUser and toUser
                var fromUser = Services.Users.GetUserById(model.CallerId);
                var toUser = Services.Users.GetUserById(model.ReceiverId);

                var message = string.Empty;
                if (model.IsCustomer)  // Customer initiate call >> Second client and FromUser is customer
                {
                    string template = ConferenceConst.SecondClientStartForTalkNow;
                    message = string.Format(template, fromUser.Name, toUser.Name, model.NatureOfEnquiry);
                }
                else // Consultant initiate call >>  Second client and FromUser is consultant
                {
                    string template = ConferenceConst.SecondClientStartForSchedule;
                    message = string.Format(template, fromUser.Name, toUser.Name);
                }

                response.BeginGather(new { numDigits = 1, action = Url.Action("SecondClientResponse", model) });
                response.Pause(2);
                response.Say(message, new { voice = VoiceInConference, language = LanguageInConference });
                response.EndGather();
                response.Redirect(Url.Action("SecondClientStart", model));
                return new TwiMLResult(response);
            }
            catch (Exception e)
            {
                Log.Error("Second client start. Error: ", e);

                // Error
                response.Say(ConferenceConst.ErrorMessage, new { voice = VoiceInConference, language = LanguageInConference });
                response.Hangup();
            }

            return new TwiMLResult(response);
        }
        public TwiMLResult SecondClientReady(CallContextModel model)
        {
            var response = new TwilioResponse();

            try
            {
                model.CallerStatus = Request["CallStatus"];

                var message = string.Empty;

                // Get fromUser and toUser
                var fromUser = Services.Users.GetUserById(model.CallerId);
                var toUser = Services.Users.GetUserById(model.ReceiverId);

                if (model.IsCustomer) // Customer initiate call >> Second client and FromUser is customer
                {
                    // Check consultant is readly in conference
                    if (Services.Call.CheckCallInStatus(model.CallId, CallStatus.InProgress, true))
                    {
                        string template = ConferenceConst.SecondClientReadyForTalkNow;
                        message = string.Format(template, toUser.Name);

                        response.Say(message, new { voice = VoiceInConference, language = LanguageInConference });

                        // Get name conference room
                        var room = string.Format(ConferenceRoom, fromUser.UserName, toUser.UserName, model.BookingId);

                        // Update receiver call status
                        Services.Call.UpdateCallStatus(model.CallId, model.CallerStatus, true);

                        // Hangup Url
                        var callHangUpUrl = Utilities.FormatLink(Url.Action("CallHangUp", "Conference", model));
                        // Dial coference
                        response.DialConference(room,
                            new
                            {
                                endConferenceOnExit = true
                            },
                            new
                            {
                                record = true,
                                trim = "trim-silence",
                                transcribe = false,
                                action = callHangUpUrl
                            });
                    }
                    else
                    {
                        response.Say(ConferenceConst.ConsultantDenied, new { voice = VoiceInConference, language = LanguageInConference });
                    }
                }
                else
                {
                    string template = ConferenceConst.SecondClientReadyForSchedule;
                    message = string.Format(template, toUser.Name);
                    response.Say(message, new { voice = VoiceInConference, language = LanguageInConference });

                    // Get name conference room
                    var room = string.Format(ConferenceRoom, fromUser.UserName, toUser.UserName, model.BookingId); ;

                    // Dial coference
                    var callBackUrl = Utilities.FormatLink(Url.Action("CallBackAfterConference", "Conference", model));
                    response.DialConference(room,
                        new
                        {
                            endConferenceOnExit = true,
                            waitUrl = "http://twimlets.com/holdmusic?Bucket=com.twilio.music.electronica"
                        },
                        new
                        {
                            record = false,
                            transcribe = false,
                            action = callBackUrl
                        });

                    // Update receiver call status
                    Services.Call.UpdateCallStatus(model.CallId, model.CallerStatus, true);
                }
            }
            catch (Exception e)
            {
                Log.Error("Second client ready. Error: ", e);

                // Error
                response.Say(ConferenceConst.ErrorMessage, new { voice = VoiceInConference, language = LanguageInConference });
                response.Hangup();
            }

            return new TwiMLResult(response);
        }
        public TwiMLResult CallHangUpForDeferOrReSchedule(CallContextModel model)
        {
            var response = new TwilioResponse();
            try
            {
                Services.Call.UpdateCallStatus(Request["CallSid"], CallStatus.Completed);
                Services.Call.UpdateConferenceTime(model.CallId, false);

                response.Hangup();
            }
            catch (Exception e)
            {
                // Log
                Log.Error("Call hang up for defer or reschedule. Error: ", e);

                // Error
                response.Say(ConferenceConst.ErrorMessage, new { voice = VoiceInConference, language = LanguageInConference });
                response.Hangup();
            }

            return new TwiMLResult(response);
        }
        /// <summary>
        /// Send waive fee request
        /// </summary>
        /// <param name="model"></param>
        private void SendWaiveFeeRequest(CallContextModel model)
        {
            List<InvoiceDto> invoices = Services.Invoices.GetInvoiceByBookingId(model.BookingId);
            if (invoices != null && invoices.Any())
            {
                var customerInvoice = invoices.First(x => x.Booking.Customer.Id == x.User.Id
                                                        && x.Type == InvoiceType.Consultation);
                var specialistInvoice = invoices.First(x => x.Booking.Specialist.Id == x.User.Id);

                if (PaymentMethod.PrePayment.Equals(customerInvoice.User.PaymentMethod))
                {
                    customerInvoice.User.PrePaymentAmount = customerInvoice.User.PrePaymentAmount + specialistInvoice.Amount;
                    Services.Users.UpdateUserInfo(customerInvoice.User);
                }
                else
                {
                    var result = Services.Payment.Refund(customerInvoice.TransactionId, specialistInvoice.Amount);
                }

                var specialistId = model.ReceiverId; // Default receiver is specialist
                if (model.IsCustomer)
                {
                    specialistId = model.CallerId;
                }

                InvoiceDto waivedFeeInvoice = Services.Invoices.UpdateWaiveFeeForSpecialistByBookingId(model.BookingId, specialistId);

                System.Threading.Tasks.Task.Factory.StartNew(() =>
                {
                    // Subtract consultation fee
                    waivedFeeInvoice.Amount = -waivedFeeInvoice.Amount;

                    string mailContent = Services.Invoices.TranformToInvoiceTemplate(
                        waivedFeeInvoice.User, waivedFeeInvoice, null, ConstEmailTemplateKey.WaiveFeeTemplate, null);

                    byte[] pdfAsByte = HtmlToPdf.GetPdfData(mailContent, AppSettings.BaseUrl);

                    string fileName = string.Format("invoice_{0}.pdf", waivedFeeInvoice.InvoiceNumber);

                    Services.Invoices.SendInvoice(fileName, pdfAsByte,
                        mailContent, customerInvoice.User.Email, ConstEmailSubject.ConsultationInvoice);
                });
            }
        }
        public TwiMLResult WaiveFeeActionResponse(CallContextModel model, string digits)
        {
            var response = new TwilioResponse();

            try
            {
                switch (digits)
                {
                    case "1":
                        // Check waive fee already
                        var invoice = Services.Invoices.GetByBookingIdAndUserId(model.BookingId, model.CallerId);

                        if (invoice != null)
                        {
                            if (!invoice.IsWaiveFee)
                            {
                                // Send waive fee request
                                SendWaiveFeeRequest(model);

                                response.Say(ConferenceConst.AcctionCompleted, new { voice = VoiceInConference, language = LanguageInConference });
                            }
                            else
                            {
                                // Say waive fee alreadly
                                response.Say(ConferenceConst.WaiveFeeAlready, new { voice = VoiceInConference, language = LanguageInConference });
                            }
                        }

                        break;

                    default:
                        response.Redirect(Url.Action("ConsultantAfterCall", model));

                        break;
                }
            }
            catch (Exception e)
            {
                Log.Error("Waive fee action response. Error: ", e);

                // Error
                response.Say(ConferenceConst.ErrorMessage, new { voice = VoiceInConference, language = LanguageInConference });
                response.Hangup();
            }

            response.Redirect(Url.Action("ConsultantAfterCall", model));
            return new TwiMLResult(response);
        }
        public TwiMLResult CallHangUp(CallContextModel model)
        {
            var response = new TwilioResponse();
            try
            {
                // Get call
                var call = Services.Call.GetByCallSid(Request["CallSid"]);

                call.ConferenceSid = Request["ConferenceSid"];
                call.RecordSid = Request["RecordingSid"];
                call.RecordDuration = Convert.ToInt32(Request["RecordingDuration"]);
                call.RecordUrl = Request["RecordingUrl"];

                // Update conference sid
                Services.Call.Update(call);

                // Update end time conference
                Services.Call.UpdateConferenceTime(model.CallId, false);

                // End call duration timer
                CallHelper.CallDuration(Request["CallSid"], model.IsCustomer, Services, false);

                response.Hangup();
            }
            catch (Exception e)
            {
                // Log
                Log.Error("Call hang up. Error: ", e);

                // Error
                response.Say(ConferenceConst.ErrorMessage, new { voice = VoiceInConference, language = LanguageInConference });
                response.Hangup();
            }
            return new TwiMLResult(response);
        }
        public TwiMLResult WaiveFeeAction(CallContextModel model)
        {
            var response = new TwilioResponse();
            try
            {
                response.BeginGather(new { numDigits = 1, action = Url.Action("WaiveFeeActionResponse", model) });
                response.Say(ConferenceConst.WaiveFeeAction, new { voice = VoiceInConference, language = LanguageInConference });
                response.EndGather();
                response.Redirect(Url.Action("ConsultantAfterCall", model));
            }
            catch (Exception e)
            {
                // Log
                Log.Error("Waive fee action. Error: ", e);

                // Error
                response.Say(ConferenceConst.ErrorMessage, new { voice = VoiceInConference, language = LanguageInConference });
                response.Hangup();
            }

            return new TwiMLResult(response);
        }
        public TwiMLResult VoiceMailStatusCallBack(CallContextModel model)
        {
            var response = new TwilioResponse();
            try
            {
                // Get specialist
                var specialist = new UserDto();

                if (model.IsCustomer) // Caller is customer
                {
                    specialist = Services.Users.GetUserById(model.ReceiverId);
                }
                else
                {
                    specialist = Services.Users.GetUserById(model.CallerId);
                }

                string recordUrl = Request["RecordingUrl"];
                int recordDuration = Convert.ToInt32(Request["RecordingDuration"]);
                var booking = Services.Call.Get(model.CallId).Booking;

                // Send transcript request
                int transcriptSuccess = SendTranscriptionRequest(specialist.Id.ToString(), specialist.UserName,
                                                                specialist.Email, recordUrl, recordDuration, booking);

                switch (transcriptSuccess)
                {
                    case 0:
                        response.Say(ConferenceConst.BalanceNotEnoughForTranscript);
                        break;

                    case 2:
                        response.Say(ConferenceConst.DictateFollowUpActionCompleted);
                        break;

                    default:
                        response.Say(ConferenceConst.TranscriptError);
                        break;
                }
            }
            catch (Exception e)
            {
                // Log
                Log.Error("Voice email. Error: ", e);

                // Error
                response.Say(ConferenceConst.ErrorMessage, new { voice = VoiceInConference, language = LanguageInConference });
                response.Hangup();
            }

            response.Redirect(Url.Action("ConsultantAfterCall", model));
            return new TwiMLResult(response);
        }
        public TwiMLResult VoiceMail(CallContextModel model)
        {
            var response = new TwilioResponse();
            try
            {
                response.Say(ConferenceConst.DictateFollowUpAction,
                            new { voice = VoiceInConference, language = LanguageInConference });
                var callBackUrl = Utilities.FormatLink(Url.Action("VoiceMailStatusCallBack", "Conference", model));
                response.Record(new
                {
                    action = callBackUrl,
                    trim = "trim-silence",
                    finishOnKey = "#",
                    playBeep = true
                });
            }
            catch (Exception e)
            {
                // Log
                Log.Error("Voice email. Error: ", e);

                // Error
                response.Say(ConferenceConst.ErrorMessage, new { voice = VoiceInConference, language = LanguageInConference });
                response.Hangup();
            }
            return new TwiMLResult(response);
        }
        public TwiMLResult ClientDenied(CallContextModel model)
        {
            var response = new TwilioResponse();
            try
            {
                // Update call status
                model.ReceiverStatus = Request["CallStatus"];
                Services.Call.UpdateCallStatus(model.CallId, model.ReceiverStatus, false);

                if (model.IsCustomer) // Customer initiate call >> Consultant called first
                {
                    response.Say(ConferenceConst.CustomerDenied, new { voice = VoiceInConference, language = LanguageInConference });
                }
                else // Consultant initiate call >>  Customer called first
                {
                    response.Say(ConferenceConst.ConsultantDenied, new { voice = VoiceInConference, language = LanguageInConference });
                }
            }
            catch (Exception e)
            {
                Log.Error("First client denied. Error: ", e);

                // Error
                response.Say(ConferenceConst.ErrorMessage, new { voice = VoiceInConference, language = LanguageInConference });
            }

            // Hangup
            response.Hangup();
            return new TwiMLResult(response);
        }
        public TwiMLResult FirstClientStart(CallContextModel model)
        {
            var response = new TwilioResponse();

            try
            {
                var call = Services.Call.GetByCallSid(Request["CallSid"]);

                // Get info for call context
                model.CallId = call.Id;
                model.ReceiverSid = Request["CallSid"];
                model.ReceiverStatus = Request["CallStatus"];

                // Get first client and second client
                var fromUser = Services.Users.GetUserById(model.CallerId);
                var toUser = Services.Users.GetUserById(model.ReceiverId);

                // Update call status
                Services.Call.UpdateCallStatus(model.CallId, model.ReceiverStatus, false);

                var greeting = string.Empty;

                if (model.IsCustomer) // Customer initiate call >> Consultant called first
                {
                    string template = ConferenceConst.CallMenuForTalkNow;
                    greeting = string.Format(template, fromUser.Name, model.NatureOfEnquiry);
                }
                else // Consultant initiate call >> Customer called first
                {
                    string template = ConferenceConst.CallMenuForSchedule;
                    greeting = string.Format(template, toUser.Name, fromUser.Name, model.NatureOfEnquiry);
                }

                response.BeginGather(new { numDigits = 1, action = Url.Action("FirstClientResponse", model) });
                response.Pause(2);
                response.Say(greeting, new { voice = VoiceInConference, language = LanguageInConference });
                response.EndGather();
                response.Redirect(Url.Action("FirstClientStart", model));
            }
            catch (Exception e)
            {
                // Save Log
                Log.Error("First client start. Error:", e);

                // Error
                response.Say(ConferenceConst.ErrorMessage, new { voice = VoiceInConference, language = LanguageInConference });
                response.Hangup();
            }

            return new TwiMLResult(response);
        }
        public TwiMLResult ConsultantAfterCall(CallContextModel model)
        {
            var response = new TwilioResponse();
            try
            {
                response.BeginGather(new { numDigits = 1, action = Url.Action("ConsultantAfterCallResponse", model) });

                // Check call duration
                var call = Services.Call.GetByCallSid(Request["CallSid"]);
                int startingTime = Convert.ToInt32(Services.SystemConfig.GetByKey(ParamatricBusinessRules.STARTING_TIME.ToString()).Value);

                if (call.Duration <= startingTime)
                {
                    response.Say(ConferenceConst.ConsultantAfterCallNoInvoice, new { voice = VoiceInConference, language = LanguageInConference });
                }
                else
                {
                    response.Say(ConferenceConst.ConsultantAfterCall, new { voice = VoiceInConference, language = LanguageInConference });
                }

                response.EndGather();
                response.Redirect(Url.Action("ConsultantAfterCall", model));
            }
            catch (Exception e)
            {
                // Log
                Log.Error("Consultant after call. Error: ", e);

                // Error
                response.Say(ConferenceConst.ErrorMessage, new { voice = VoiceInConference, language = LanguageInConference });
                response.Hangup();
            }

            return new TwiMLResult(response);
        }
        public TwiMLResult SecondClientResponse(CallContextModel model, string digits)
        {
            var response = new TwilioResponse();

            try
            {
                model.CallerStatus = Request["CallStatus"];

                switch (digits)
                {
                    case "1":

                        // Update database second client is ready now and update status
                        Services.Call.ReceiverReadyNow(model.CallId);
                        Services.Call.UpdateCallStatus(model.CallId, model.CallerStatus, true);

                        response.Redirect(Url.Action("SecondClientReady", model));
                        break;

                    default:
                        response.Pause(10);

                        response.Redirect(Url.Action("SecondClientStart", model));
                        break;
                }
            }
            catch (Exception e)
            {
                Log.Error("First client response. Error: ", e);

                // Error
                response.Say(ConferenceConst.ErrorMessage, new { voice = VoiceInConference, language = LanguageInConference });
                response.Hangup();
            }

            return new TwiMLResult(response);
        }
Example #20
0
 /// <summary>
 /// Generate Twiml url
 /// </summary>
 /// <param name="model"></param>
 /// <returns></returns>
 public static string GenerateTwimlUrl(CallContextModel model)
 {
     var Url = new UrlHelper(HttpContext.Current.Request.RequestContext);
     var result = Url.Action("FirstClientStart", "Conference", model);
     return result;
 }