コード例 #1
0
        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));
        }
コード例 #2
0
 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);
 }
コード例 #3
0
 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);
 }
コード例 #4
0
        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();
        }
コード例 #5
0
        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();
        }
コード例 #6
0
        /// <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());
        }
コード例 #7
0
        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);
        }
コード例 #8
0
 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();
     }
 }
コード例 #9
0
        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();
        }
コード例 #10
0
 internal static CallEntry GetCallEntry(VoiceCall call)
 {
     return(new[] { call }.AsQueryable().Select(proj).Single());
 }
コード例 #11
0
        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();
        }