__uas_identify__ = "application" __uas_version__ = "1.0b1" from prosody.uas import Hangup, Error, ICanRun """ An inbound application that answers the call and says "Welcome to the voicemail server for ". is obtained from the application_parameters and must be registered on the inbound services page of the CWP. The application uses to determine whether the caller owns the voicemail box. It does this by comparing with the property of the inbound call. If the caller owns the voicemail box, the top level options given are: 1. Play all existing messages 2. Delete all existing messages If the caller does not own the voicemail box, he can leave a new message. The name of the WAV file to save to will be "samples/voicemail3//msg.wav". The is a variable, initialised to 1, which increments each time a message is successfully saved. This application is part of the online Voice Mail tutorial. """ class VoiceMailBox: def __init__(self, box_name, channel, file_manager, logger): self._channel = channel self._file_manager = file_manager self._logger = logger self._file_format = "samples/voicemail3/" + box_name + "/msg{0}.wav" self._recorded_file_counter = 1 self._set_message_counter() def _set_message_counter(self): # check the message box and set the counter while(self._file_manager.exists(self._file_format.format(self._recorded_file_counter))): self._logger.info("{0} exists".format(self._recorded_file_counter)) self._recorded_file_counter += 1 def say_tts(self, message, bargein=False, beep=False): cause = self._channel.FilePlayer.say(message, barge_in=bargein) if cause == self._channel.FilePlayer.Cause.BARGEIN: return if cause == self._channel.FilePlayer.Cause.NORMAL: if beep is True: cause = self._channel.DTMFPlayer.play("#"); if cause != self._channel.DTMFPlayer.Cause.NORMAL: raise Error("Play tone failed: caused is {0}".format(cause)) else: raise Error("Say '{0}' failed: cause is {1}".format(message, cause)) def play_file(self, filename): cause = self._channel.FilePlayer.play(filename) if cause != self._channel.FilePlayer.Cause.NORMAL: raise Error("Play '{0}' failed: cause is {1}".format(filename, cause)) def record_new_message(self, replace=False): if replace is True and self._recorded_file_counter > 1: self._recorded_file_counter -= 1 filename = self._file_format.format(self._recorded_file_counter) self._recorded_file_counter += 1 self.say_tts("Please record a message after the tone. Press any digit to stop the recording.", beep=True) cause = self._channel.FileRecorder.record(filename, milliseconds_max_silence=3000, seconds_timeout=60, barge_in=True) if cause != self._channel.FileRecorder.Cause.SILENCE and cause != self._channel.FileRecorder.Cause.BARGEIN: raise Error("Record message failed: cause is {0}".format(cause)) # check whether the file has been saved correctly, does it exist? if not self._file_manager.exists(filename): self.say_tts("Your message could not be saved.") else: self.say_tts("The following message has been recorded") self.play_file(filename) def play_all_messages(self): counter = 1 filename = self._file_format.format(counter) while self._file_manager.exists(filename): self.say_tts("Message {0}".format(counter)) self.play_file(filename) counter += 1 filename = self._file_format.format(counter) if counter == 1: self.say_tts("You have no messages to play.") else: self.say_tts("End of messages.") def delete_all_messages(self): counter = 1 filename = self._file_format.format(counter) while self._file_manager.exists(filename): self._file_manager.delete_file(filename) counter += 1 filename = self._file_format.format(counter) if counter == 1: self.say_tts("You have no messages to delete.") else: self.say_tts("All messages deleted.") self._recorded_file_counter = 1 def main(channel, application_instance_id, file_man, my_log, application_parameters): my_log.info ("Voicemail 3 started.") return_code = 0 try: # The voicemail box name must have been configured at service registration if len(application_parameters) == 0: raise Error("Argument list is empty") mailbox = VoiceMailBox(application_parameters, channel, file_man, my_log) channel.ring(2) channel.answer() caller = get_caller(channel) my_log.info ("Call from {0} to {1}'s Voicemail answered".format(caller, application_parameters)) mailbox.say_tts("Welcome to the voicemail server for {0}".format(" ".join(list(application_parameters)))) if caller == application_parameters: top_level_menu(channel, mailbox) else: replace = False # wait on i_can_run to prevent an accidental infinite loop i_can_run = ICanRun(channel) while i_can_run: mailbox.record_new_message(replace) key_selected = get_menu_select(channel, mailbox, "Please press 1 to keep this message or 2 to record an alternative message", 20, "12") if key_selected == '1': mailbox.say_tts("Message saved.") break replace = True mailbox.say_tts("Goodbye.") channel.hang_up(); except Hangup as exc: my_log.info("Completed with Hangup: {0}".format(exc)) return_code = -100 except Error as exc: my_log.error("Completed with Error exception! {0}".format(exc)) return_code = -101 except Exception as exc: my_log.exception("Completed with exception! {0}".format(exc)) return_code = -102 finally: if channel.state() != channel.State.IDLE: channel.hang_up() my_log.info("Voicemail 3 example completed") return return_code def get_caller(channel): caller = channel.Details.call_from # Extract the username from the SIP address if caller.startswith("sip:"): caller = caller[4:] return caller.split('@', 1)[0] def top_level_menu(channel, mailbox): key_selected = get_menu_select(channel, mailbox, "Press 1 to listen to all messages. \ Press 2 to delete all messages. \ Press 3 to quit.", 20, "123") if key_selected == '1': mailbox.play_all_messages() elif key_selected == '2': mailbox.delete_all_messages() def get_menu_select(channel, mailbox, prompt, seconds_repeat_prompt, valid_keys): channel.DTMFDetector.clear_digits() # wait on i_can_run to prevent an accidental infinite loop i_can_run = ICanRun(channel) while i_can_run: mailbox.say_tts(prompt, bargein=True, beep=True) digits = channel.DTMFDetector.get_digits(end=valid_keys, seconds_predigits_timeout=seconds_repeat_prompt) cause = channel.DTMFDetector.cause() if cause == channel.DTMFDetector.Cause.END: return digits[-1] else: mailbox.say_tts("Invalid selection.")