func (app *AnsweringMachine) incomingCallHandler(w http.ResponseWriter, req *http.Request) { glog.V(2).Infof("Incoming call") tropoHandler := tropo.NewHandler(w, req) if req.Method != "POST" { glog.V(0).Infof("POST expected, not a %s", req.Method) tropoHandler.ReplyBadRequest("Expecting a POST, please check tropo documentation") return } var session *tropo.Session var err error if session, err = tropoHandler.DecodeSession(); err != nil { glog.V(1).Infof("Cannot process incoming payload") tropoHandler.ReplyInternalError("DECODE FAILED", "Cannot process incoming payload") return } // check a human issued the call if !(session.IsHumanInitiated() && session.IsCall()) { glog.V(1).Infof("Unsupported request, a voice call is expected") tropoHandler.ReplyBadRequest("An incoming voice session is expected, not a M2M dialog") return } glog.V(0).Infof(`SessionID "%s", CallID "%s", From "+%s"`, session.ID, session.CallID, session.From.ID) // redirect to check messages if the answering machine registered checker is calling if session.From.ID == app.env.CheckerPhoneNumber { app.checkMessagesHandlerInternal(tropoHandler, session, w, req) return } app.welcomeHandlerInternal(tropoHandler, session, w, req) }
func (app *AnsweringMachine) recordingSuccessHandler(w http.ResponseWriter, req *http.Request) { glog.V(2).Infof("Recording response") tropoHandler := tropo.NewHandler(w, req) var answer *tropo.RecordingResult var err error if answer, err = tropoHandler.DecodeRecordingAnswer(); err != nil { glog.V(1).Infof("Cannot process recording result") tropoHandler.ReplyInternalError("DECODING ERROR", "Cannot process recording result") return } glog.V(0).Infof(`SessionID "%s", CallID "%s"`, answer.SessionID, answer.CallID) glog.V(2).Infof("Recording result details: %s\n", answer) // Store the recording success var vm *VoiceMessage vm, err = app.db.GetVoiceMessageForCallID(answer.CallID) if err != nil { glog.V(2).Infof("Cannot find message with callID: %s", answer.CallID) // TODO Analyse how often this case would happen, by default we'll fail but alternatively we could not create a brand new message tropoHandler.Say(app.messages.RecordingFailedMessage, app.messages.DefaultVoice) return } // Did the caller hang down without leaving a message if answer.State == tropo.STATE_DISCONNECTED || answer.State == tropo.STATE_FAILED { glog.V(2).Infof("Call was disconnected (user hang down before beep) or failed, state:%s, callID:", answer.State, answer.CallID) vm.Progress = NOMESSAGE if err := app.db.Store(vm); err != nil { glog.V(2).Infof("Cannot update message with callID: %s", answer.CallID) // TODO Analyse how often this case would happen, we should at a minimum update the message state to FAILED } return } // Did the caller left a message if answer.State == tropo.STATE_ANSWERED { vm.Progress = RECORDED vm.Recording = answer.Actions.URL vm.Duration = answer.Actions.Duration vm.Status = NEW if err := app.db.Store(vm); err != nil { glog.V(2).Infof("Cannot update message with callID: %s", answer.CallID) // TODO Analyse how often this case would happen, we should at a minimum update the message state to FAILED // say an error happened, your message was not recorded tropoHandler.Say(app.messages.RecordingFailedMessage, app.messages.DefaultVoice) return } // say good bye tropoHandler.Say(app.messages.RecordingOKMessage, app.messages.DefaultVoice) return } glog.Warningf("Unhandled case in RecordResult, state: %s, callID: %s", answer.State, answer.CallID) }
func (app *AnsweringMachine) recordingErrorHandler(w http.ResponseWriter, req *http.Request) { glog.V(2).Infof("RecordingErrordHandler") tropoHandler := tropo.NewHandler(w, req) tropoHandler.Say(app.messages.RecordingFailedMessage, app.messages.DefaultVoice) }