public async Task <TwilioResponse> Answer(TwilioRequest request) { await SetMemberInfoFromPhone(request.From); await UpdateSigninStatus(); using (var db = dbFactory()) { var call = new VoiceCall { CallId = request.CallSid, Number = request.From, CallTime = TimeUtils.GetLocalDateTime(this.config), Name = this.session.MemberName }; db.Calls.Add(call); await db.SaveChangesAsync(); this.config.GetPushHub <CallsHub>().updatedCall(CallsController.GetCallEntry(call)); } var response = new TwilioResponse(); BeginMenu(response); if (this.session.MemberId == null) { response.SayVoice(Speeches.WelcomeUnknownCaller); } await EndMenu(response); return(LogResponse(response)); }
public void LongDistance() { var call = new VoiceCall(new TimeSpan(0, 0, 1, 0), TestCalls.LongDiscanceCall); var plan = VoicePlan.Costing(4).BilledPerMinute(); new VoiceTaxation() .CalculatePrice(call, plan) .Value.Should().Be(6); }
public void BilledPerSecond(int hours, int minutes, int seconds, int expectedPrice) { var call = new VoiceCall(new TimeSpan(0, hours, minutes, seconds), TestCalls.LocalCall); var plan = VoicePlan.Costing(2).BilledPerSecond(); new VoiceTaxation() .CalculatePrice(call, plan) .Value.Should().Be(expectedPrice); }
private async Task PersistVoiceCallInfo(string roomId) { if (RoomsConnectionsDictionary[roomId].Count > 1) { // Second user joined voice chat room - call is accepted if (RoomsVoiceCallsDictionary.ContainsKey(roomId)) { var currentVoiceCall = RoomsVoiceCallsDictionary[roomId]; currentVoiceCall.Accepted = DateTime.Now; currentVoiceCall.CalleeId = _chatModel.UsersInRoom(roomId, currentVoiceCall.CallerId).FirstOrDefault(); ((DbContext)_db).Entry(currentVoiceCall).State = EntityState.Modified; Log.SignalR(LogTag.SavingAcceptedCallToDb, new { roomId }, Context); } else { // Something wrong have happened and we don't have a VoiceCall object in dict yet Log.SignalRError(LogTag.AcceptedVoiceCallRoomIdNotFoundDictionary, new { roomId }, Context); } } else { if (RoomsVoiceCallsDictionary.ContainsKey(roomId)) { Log.SignalRError(LogTag.VoiceCallRoomAlreadyExistsOnInitiatingCall, new { roomId }, Context); return; } // One user is here - call initiated var userId = GetUserIdFromClaims(); var vc = new VoiceCall { Created = DateTime.Now, CallerId = userId, CalleeId = _chatModel.UsersInRoom(roomId, userId).FirstOrDefault() ?? _chatModel.GetAbsentPrivateChatUserIds(roomId).First(), Platform = Enumerables.VoicePlatforms.OnSiteWebRtc, Source = Enumerables.SourceFeatures.PrivateTextChat }; RoomsVoiceCallsDictionary.Add(roomId, vc); _db.VoiceCalls.Add(vc); Log.SignalR(LogTag.SavingInitiatedCallToDb, new { roomId }, Context); } await _db.SaveChangesAsync(); }
private async Task PersistVoiceCallInfo(string roomId) { if (RoomsConnectionsDictionary[roomId].Count > 1) { // Second user joined voice chat room - call is accepted if (RoomsVoiceCallsDictionary.ContainsKey(roomId)) { var currentVoiceCall = RoomsVoiceCallsDictionary[roomId]; currentVoiceCall.Accepted = DateTime.Now; currentVoiceCall.CalleeId = TextChatController.PartnerInPrivateRoom(roomId, currentVoiceCall.CallerId); ((DbContext)_db).Entry(currentVoiceCall).State = EntityState.Modified; Log.SignalR(LogTag.SavingAcceptedCallToDb, new { roomId }, Context); } else { // Something wrong have happened and we don't have a VoiceCall object in dict yet Log.SignalRError(LogTag.AcceptedVoiceCallRoomIdNotFoundDictionary, new { roomId }, Context); } } else { if (RoomsVoiceCallsDictionary.ContainsKey(roomId)) { Log.SignalRError(LogTag.VoiceCallRoomAlreadyExistsOnInitiatingCall, new { roomId }, Context); return; } // One user is here - call initiated var userId = Context.User.Identity.GetClaims().Id; var vc = new VoiceCall { Created = DateTime.Now, CallerId = userId, CalleeId = TextChatController.PartnerInPrivateRoom(roomId, userId), Platform = 1, // Formerly obtained from VoicePlatforms table (table abandonned when VoiceOut got removed) Source = Enumerables.SourceFeatures.PrivateTextChat }; RoomsVoiceCallsDictionary.Add(roomId, vc); _db.VoiceCalls.Add(vc); Log.SignalR(LogTag.SavingInitiatedCallToDb, new { roomId }, Context); } await _db.SaveChangesAsync(); }
/// <summary> /// Allows you to make a voice call from your LongCode to a valid phone number and will speak the provided sentance /// </summary> /// <param name="accountId"></param> /// <param name="longCode">Long code (From phone number) in the following format Ex.1xxxxxxxxxx</param> /// <returns></returns> public string VoiceCall(int accountId, string longCode, VoiceCall model) { var request = new RestRequest(VOICE_CALL_URI, Method.POST) { RequestFormat = DataFormat.Json, JsonSerializer = new NewtonsoftSerializer() }; request.AddUrlSegment("accountId", accountId.ToString()); request.AddUrlSegment("longCode", longCode); request.AddBody(model); var res = Execute <object>(request) ?? ""; // TODO: Map a flattened contact to an unflattened one. return(res.ToString()); }
private static Notify GetNotifyType(NotifyType notifyType) { Notify rtnNotify; switch (notifyType) { case NotifyType.PushNotification: rtnNotify = new PushNotification(); break; case NotifyType.VoiceCall: rtnNotify = new VoiceCall(); break; default: rtnNotify = new SMS(); break; } return(rtnNotify); }
public Price CalculatePrice(PriceCalculationViewModel priceCalculation) { var voiceCall = new VoiceCall(new TimeSpan(0, 0, priceCalculation.Units), _standardHardcodedCall); var textCall = new TextCall(priceCalculation.Units, _standardHardcodedCall); var dataCall = new DataCall(priceCalculation.Units.KByte(), _standardHardcodedCall); switch (priceCalculation.PlanType) { case PlanType.VoicePlan1: return _voiceTaxation.CalculatePrice(voiceCall, StandardPlans.VoicePlan1); case PlanType.VoicePlan2: return _voiceTaxation.CalculatePrice(voiceCall, StandardPlans.VoicePlan2); case PlanType.DataPlan1: return _dataTaxation.CalculatePrice(dataCall, StandardPlans.DataPlan1); case PlanType.DataPlan2: return _dataTaxation.CalculatePrice(dataCall, StandardPlans.DataPlan2); case PlanType.TextPlan1: return _textTaxation.CalculatePrice(textCall, StandardPlans.TextPlan1); case PlanType.TextPlan2: return _textTaxation.CalculatePrice(textCall, StandardPlans.TextPlan2); default: throw new ArgumentOutOfRangeException(); } }
public async Task CallFinished(string roomId, string reasonString) { if (string.IsNullOrEmpty(roomId)) { return; } Log.SignalR(LogTag.ReceivedCallFinished, new { roomId, reason = reasonString }, Context); var reason = CallFinishedReason.Parse(reasonString); VoiceCall vc; RoomsVoiceCallsDictionary.TryGetValue(roomId, out vc); var userId = GetUserIdFromClaims(); if (vc == null) { if (reason.Reason == "unsupported" && reason.Src != CallFinishedReason.Reporter.Peer) { // Special case! Reporting about call finish and failed to initiate it // so we don't have anything for it in RoomsVoiceCallsDictionary but have to save something to DB vc = new VoiceCall { Created = DateTime.Now, CallerId = userId, CalleeId = _chatModel.UsersInRoom(roomId, userId).FirstOrDefault() ?? _chatModel.GetAbsentPrivateChatUserIds(roomId).First(), Platform = Enumerables.VoicePlatforms.OnSiteWebRtc, Source = Enumerables.SourceFeatures.PrivateTextChat }; RoomsVoiceCallsDictionary.Add(roomId, vc); _db.VoiceCalls.Add(vc); } else { return; } } else { ((DbContext)_db).Entry(vc).State = EntityState.Modified; } RoomsVoiceCallsDictionary.Remove(roomId); vc.Ended = DateTime.Now; var isCallerEvent = (userId == vc.CallerId && reason.Src != CallFinishedReason.Reporter.Peer) || (userId != vc.CallerId && reason.Src == CallFinishedReason.Reporter.Peer); byte outcome; switch (reason.Reason) { case "cancelled": outcome = Enumerables.VoiceCallOutcomes.Cancel; break; case "declined": outcome = Enumerables.VoiceCallOutcomes.Decline; break; case "unsupported": if (reason.Detail == "browser") { outcome = isCallerEvent ? Enumerables.VoiceCallOutcomes.FailOnCallerUnsupportedBrowser : Enumerables.VoiceCallOutcomes.FailOnCalleeUnsupportedBrowser; } else { outcome = isCallerEvent ? Enumerables.VoiceCallOutcomes.FailOnCallerMicNotFound : Enumerables.VoiceCallOutcomes.FailOnCalleeMicNotFound; } break; case "hangout": outcome = isCallerEvent ? Enumerables.VoiceCallOutcomes.AcceptThenCallerHangout : Enumerables.VoiceCallOutcomes.AcceptThenCalleeHangout; break; case "leftRoom": outcome = isCallerEvent ? Enumerables.VoiceCallOutcomes.AcceptThenCallerLeft : Enumerables.VoiceCallOutcomes.AcceptThenCalleeLeft; break; case "disconnected": outcome = isCallerEvent ? Enumerables.VoiceCallOutcomes.AcceptThenLostCaller : Enumerables.VoiceCallOutcomes.AcceptThenLostCallee; break; default: outcome = Enumerables.VoiceCallOutcomes.Error; break; } vc.Outcome = outcome; Log.SignalR(LogTag.SavingCallOutcome, new { roomId }, Context); await _db.SaveChangesAsync(); }
internal static CallEntry GetCallEntry(VoiceCall call) { return(new[] { call }.AsQueryable().Select(proj).Single()); }
public async Task CallFinished(string roomId, string reasonString) { if (string.IsNullOrEmpty(roomId)) { return; } Log.SignalR(LogTag.ReceivedCallFinished, new { roomId, reason = reasonString }, Context); VoiceCall vc; var reason = CallFinishedReason.Parse(reasonString); RoomsVoiceCallsDictionary.TryGetValue(roomId, out vc); var userId = Context.User.Identity.GetClaims().Id; if (vc == null) { if (reason.Reason == "unsupported" && reason.Src != CallFinishedReason.Reporter.Peer) { // Special case #2. unsupported_join stands for voice call attempt from the same user that was already joined to the same room // We're not finishing established call in this case if (reason.Detail == "join") { return; } // Special case! Reporting about call finish and failed to initiate it // so we don't have anything for it in RoomsVoiceCallsDictionary but have to save something to DB vc = new VoiceCall { Created = DateTime.Now, CallerId = userId, CalleeId = TextChatController.PartnerInPrivateRoom(roomId, userId), Platform = 1, // Formerly obtained from VoicePlatforms table (table abandonned when VoiceOut got removed) Source = Enumerables.SourceFeatures.PrivateTextChat }; RoomsVoiceCallsDictionary.Add(roomId, vc); _db.VoiceCalls.Add(vc); } else { return; } } else { ((DbContext)_db).Entry(vc).State = EntityState.Modified; } RoomsVoiceCallsDictionary.Remove(roomId); vc.Ended = DateTime.Now; var isCallerEvent = (userId == vc.CallerId && reason.Src != CallFinishedReason.Reporter.Peer) || (userId != vc.CallerId && reason.Src == CallFinishedReason.Reporter.Peer); byte outcome; switch (reason.Reason) { case "cancelled": outcome = Enumerables.VoiceCallOutcomes.Cancel; break; case "declined": outcome = Enumerables.VoiceCallOutcomes.Decline; break; case "unsupported": if (reason.Detail == "browser") { outcome = isCallerEvent ? Enumerables.VoiceCallOutcomes.FailOnCallerUnsupportedBrowser : Enumerables.VoiceCallOutcomes.FailOnCalleeUnsupportedBrowser; } else { outcome = isCallerEvent ? Enumerables.VoiceCallOutcomes.FailOnCallerMicNotFound : Enumerables.VoiceCallOutcomes.FailOnCalleeMicNotFound; } break; case "hangout": outcome = isCallerEvent ? Enumerables.VoiceCallOutcomes.CallerHangout : Enumerables.VoiceCallOutcomes.CalleeHangout; break; case "leftRoom": outcome = isCallerEvent ? Enumerables.VoiceCallOutcomes.CallerLeft : Enumerables.VoiceCallOutcomes.CalleeLeft; break; case "disconnected": outcome = isCallerEvent ? Enumerables.VoiceCallOutcomes.LostCaller : Enumerables.VoiceCallOutcomes.LostCallee; break; default: outcome = Enumerables.VoiceCallOutcomes.Error; break; } vc.Outcome = outcome; Log.SignalR(LogTag.SavingCallOutcome, new { roomId }, Context); await _db.SaveChangesAsync(); }