Пример #1
0
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)
}
Пример #2
0
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)
}
Пример #3
0
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)
}