voicemail 0.2.0 → 1.0.0.beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +44 -0
  3. data/README.md +57 -2
  4. data/lib/voicemail.rb +15 -8
  5. data/lib/voicemail/{application_controller.rb → call_controllers/application_controller.rb} +14 -1
  6. data/lib/voicemail/call_controllers/authentication_controller.rb +60 -0
  7. data/lib/voicemail/call_controllers/mailbox_controller.rb +46 -0
  8. data/lib/voicemail/{mailbox_main_menu_controller.rb → call_controllers/mailbox_main_menu_controller.rb} +9 -4
  9. data/lib/voicemail/call_controllers/mailbox_messages_controller.rb +48 -0
  10. data/lib/voicemail/{mailbox_play_message_controller.rb → call_controllers/mailbox_play_message_controller.rb} +26 -10
  11. data/lib/voicemail/call_controllers/mailbox_play_message_intro_controller.rb +72 -0
  12. data/lib/voicemail/{mailbox_set_greeting_controller.rb → call_controllers/mailbox_set_greeting_controller.rb} +2 -2
  13. data/lib/voicemail/{mailbox_set_pin_controller.rb → call_controllers/mailbox_set_pin_controller.rb} +0 -0
  14. data/lib/voicemail/call_controllers/voicemail_controller.rb +57 -0
  15. data/lib/voicemail/localization_loader.rb +28 -0
  16. data/lib/voicemail/matcher.rb +14 -0
  17. data/lib/voicemail/plugin.rb +40 -15
  18. data/lib/voicemail/storage_pstore.rb +49 -2
  19. data/lib/voicemail/version.rb +1 -1
  20. data/spec/voicemail/call_controllers/application_controller_spec.rb +31 -0
  21. data/spec/voicemail/call_controllers/authentication_controller_spec.rb +59 -0
  22. data/spec/voicemail/call_controllers/mailbox_controller_spec.rb +107 -0
  23. data/spec/voicemail/{mailbox_main_menu_controller_spec.rb → call_controllers/mailbox_main_menu_controller_spec.rb} +9 -2
  24. data/spec/voicemail/call_controllers/mailbox_messages_controller_spec.rb +110 -0
  25. data/spec/voicemail/call_controllers/mailbox_play_message_controller_spec.rb +97 -0
  26. data/spec/voicemail/call_controllers/mailbox_play_message_intro_controller_spec.rb +81 -0
  27. data/spec/voicemail/{mailbox_set_greeting_controller_spec.rb → call_controllers/mailbox_set_greeting_controller_spec.rb} +24 -6
  28. data/spec/voicemail/{mailbox_set_pin_controller_spec.rb → call_controllers/mailbox_set_pin_controller_spec.rb} +0 -0
  29. data/spec/voicemail/call_controllers/voicemail_controller_spec.rb +97 -0
  30. data/spec/voicemail/localization_loader_spec.rb +21 -0
  31. data/spec/voicemail/storage_pstore_spec.rb +64 -2
  32. data/templates/en.yml +67 -0
  33. data/voicemail.gemspec +2 -2
  34. metadata +42 -26
  35. data/lib/voicemail/mailbox_controller.rb +0 -56
  36. data/lib/voicemail/mailbox_messages_controller.rb +0 -55
  37. data/lib/voicemail/voicemail_controller.rb +0 -33
  38. data/spec/voicemail/mailbox_controller_spec.rb +0 -79
  39. data/spec/voicemail/mailbox_messages_controller_spec.rb +0 -71
  40. data/spec/voicemail/mailbox_play_message_controller_spec.rb +0 -70
  41. data/spec/voicemail/voicemail_controller_spec.rb +0 -76
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8ece901d2e7597ad7c46d21892c1c18860366229
4
- data.tar.gz: 5179e5142890487aafe759b21d459212f90e8170
3
+ metadata.gz: fb2e43cb58958f29572591333898ac974619e7b9
4
+ data.tar.gz: db211cf3e65e54e4863d08d098a64229183630c6
5
5
  SHA512:
6
- metadata.gz: f741bdf352fb6c34412461e81a1ce85810d01d2ad680248e41d54c3d2dc033dd817edcc0d025a50147b7115c85a9220d77ea46e5171b3e5bf1a6180e84f18d3a
7
- data.tar.gz: bbc20bd448644acb1b896835f09f28254f5730d3d1a8579207c981bd83b4cff4ca49120987c079ec7f729e0b415350776ef1f36a6815d0ceda6be4686ebec692
6
+ metadata.gz: f2167ad8cf793941cb4abfde3a9daaab8d0bbdf84a5da10993980d6cd2e11e2d49d6edb87e7979bb4ccef275834cdce12cac193e3d8264f61156a12bfdf4f42b
7
+ data.tar.gz: 4020fc20353a8ce76e16e911272113876bd21e3570bd4b036c80ce85bacff270ba9610083cdedc51f7eed800e6070b4c5f7dc172290b83b13e078659f333349d
@@ -0,0 +1,44 @@
1
+ #v1.0.0..
2
+ * FEATURE - Optional per-mailbox override of default recording hash
3
+ * FEATURE - Optional rerecording of voicemail messages
4
+ * FEATURE - I18n numeric methods
5
+ * FEATURE - I18n support for keys
6
+ * FEATURE - Seperate pin_checking into seperate matcher class, so that it can be overriden if desired
7
+ * FEATURE - Allow `pin_tries` to be set to 0 for infinite loop
8
+ * FEATURE - Pass the complete recording complete object to `#save_recording`, giving the storage more information; `PStore` only uses the uri, but now you have access to more information (such as duration) if desired for your own storage adapter
9
+ * FEATURE - Seperate weclome/authentication from `MailboxController`, for those that wish to use their own.
10
+ * FEATURE - Add saved count to `MailboxController`
11
+ * FEATURE - Allow overriding `MailboxMainMenuController` with your own custom menu class
12
+ * FEATURE - Ability to listen to new OR saved messages, and archive/unarchive at will.
13
+ * FEATURE - Improved passing of a storage mechanism between controllers
14
+ * FEATURE - Customizable method for using TTS/ahn_say for things like "You have #{x} new messages"
15
+ * CS - Rename config option for when to answer
16
+ * CS - DRY up duplicated `#mailbox_not_found` method
17
+ * CS - Move all the call controllers to their own call_controller directory, to avoid clutter
18
+ * CS - Remove unused `#section_menu` in `MailboxMessagesController`
19
+ * CS - Remove specs for `#main_menu` in `AuthenticationController` since that controller never calls it
20
+ * BUGFIX - Calls passed to `VoicemailController` were never formally hungup
21
+ * BUGFIX - Don't strip extensions or `file://'` - punchblock will do that if needed
22
+ * BUGFIX - Apply datetime formatting to ahnsaid dates
23
+ * DOC - Add Justin Aiken to authors
24
+
25
+ # v0.2.0 - 2012-08-30
26
+ ## Require adhearsion 2.4 or higher
27
+ * FEATURE - Put more `#record` options into the config instead of hardcoded
28
+ * FEATURE - Freeswitch support
29
+ * FEATURE - Add MIT license to gemspec
30
+ * FEATURE - Add optional location setting for `#answer`
31
+ * CS - Refactoring
32
+
33
+
34
+ # v0.1.0 - 2013-08-28
35
+ * BUGFIX - typo in `#load_message`
36
+ * BUGFIX - `#load_message` not actually called
37
+ * BUGFIX - Pass mailbox id to `MailboxPlayMessageController`
38
+ * BUGFIX - Remove calls to nonexistant `#message_loop`
39
+ * FEATURE - Allow passing in storage adapter
40
+ * FEATURE - Only record one end of voicemail - save 50% of storage costs!
41
+ * FEATURE - TravisCI status added to README
42
+
43
+ # v0.0.1
44
+ * First release!
data/README.md CHANGED
@@ -20,6 +20,12 @@ To allow access by users to the mailboxes, `invoke MailboxController`. You will
20
20
  invoke Voicemail::MailboxController, mailbox: mailbox_id
21
21
  ```
22
22
 
23
+ If you want the users to go through pin-based authentication first, pass to the `AuthenticationController` instead:
24
+ ```ruby
25
+ # inside a CallController method
26
+ invoke Voicemail::AuthenticationController, mailbox: mailbox_id
27
+ ```
28
+
23
29
  ## Storage
24
30
 
25
31
  Mailbox metadata is stored in a PStore hash on disk for easy drop-in functionality.
@@ -39,9 +45,58 @@ Alternatively, you can pass in a storage layer dynamically when invoking the con
39
45
  # etc.
40
46
  ```
41
47
 
42
- ## Author
48
+ ## Method Overrides
49
+
50
+ If you prefer to use your own main menu instead of the [one provided](https://github.com/adhearsion/voicemail/blob/develop/lib/voicemail/call_controllers/mailbox_main_menu_controller.rb#L10-L13), you can set the class to use like so:
51
+ ```ruby
52
+ config.voicemail.main_menu_class = MyMenuController
53
+ ```
54
+
55
+ Another override provided is the [pin matcher](https://github.com/adhearsion/voicemail/blob/develop/lib/voicemail/call_controllers/authentication_controller.rb#L43-L45) used to verify authentication - if you want to use your own match-checker (to check against an API or some use), you can also override it:
56
+ ```ruby
57
+ config.voicemail.matcher_class = MyMatcher
58
+ ```
59
+
60
+ ## Numeric Methods
61
+
62
+ When you have something like `You have -x- new messages` or `message received on -x-` you can either use the default setting, which will fill the x with TTS, or to use [ahnsay](https://www.github.com/polysics/ahnsay) to use audio files for each digit.
63
+ ```ruby
64
+ config.voicemail.numeric_method = :play_numeric #default
65
+ "You have two new messages"
66
+
67
+ config.voicemail.numeric_method = :ahn_say
68
+ "You have" + "file://...two.ul" + "new messages"
69
+ ```
70
+
71
+ ## Internationalization
72
+
73
+ This plugin also provides support for internationalization:
74
+
75
+ ```ruby
76
+ # Enable I18n support in the plugin
77
+ config.voicemail.use_i18n = true
78
+
79
+ # Tell your application where your local files are, and set a default
80
+ I18n.load_path += Dir[File.join(config.platform.root, 'config', 'locales', '*.{rb,yml}').to_s]
81
+ I18n.default_locale = :en
82
+ ```
83
+
84
+ Either run `rake voicemail:i18n_init` to copy a starting `en.yml` file from the plugin into your application (default location is `#{ahn_root}/config/locales/en.yml`), or [look at the template](https://github.com/adhearsion/voicemail/blob/develop/templates/en.yml) to get an idea of what translation keys to add to your app's existing localization files.
85
+
86
+ You can also use I18n to handle the numeric methods:
87
+
88
+ ```ruby
89
+ config.voicemail.numeric_method = :i18n_string
90
+ "You have two new messages"
91
+ "You have one new message"
92
+ ```
93
+
94
+ Using I18n for the numeric method will nicely handle pluralizing message counts and formating the datetime messages were received on.
95
+
96
+ ## Authors
43
97
 
44
- Original author: [Luca Pradovera](https://github.com/polysics)
98
+ * Original author: [Luca Pradovera](https://github.com/polysics)
99
+ * Also contributed: [Justin Aiken](https://github.com/JustinAiken)
45
100
 
46
101
  ## Links
47
102
 
@@ -1,14 +1,21 @@
1
+ require 'adhearsion'
2
+
1
3
  module Voicemail; end
2
4
  require "voicemail/version"
3
5
  require "voicemail/storage_pstore"
4
6
  require "voicemail/storage"
5
- require "voicemail/application_controller"
6
- require "voicemail/voicemail_controller"
7
- require "voicemail/mailbox_controller"
8
- require "voicemail/mailbox_main_menu_controller"
9
- require "voicemail/mailbox_messages_controller"
10
- require "voicemail/mailbox_play_message_controller"
11
- require "voicemail/mailbox_set_greeting_controller"
12
- require "voicemail/mailbox_set_pin_controller"
7
+ require "voicemail/matcher"
8
+ require "voicemail/localization_loader"
9
+ require "voicemail/call_controllers/application_controller"
10
+ require "voicemail/call_controllers/voicemail_controller"
11
+ require "voicemail/call_controllers/mailbox_controller"
12
+ require "voicemail/call_controllers/authentication_controller"
13
+ require "voicemail/call_controllers/mailbox_main_menu_controller"
14
+ require "voicemail/call_controllers/mailbox_messages_controller"
15
+ require "voicemail/call_controllers/mailbox_play_message_intro_controller"
16
+ require "voicemail/call_controllers/mailbox_play_message_controller"
17
+ require "voicemail/call_controllers/mailbox_set_greeting_controller"
18
+ require "voicemail/call_controllers/mailbox_set_pin_controller"
19
+
13
20
 
14
21
  require "voicemail/plugin"
@@ -1,7 +1,7 @@
1
1
  module Voicemail
2
2
  class ApplicationController < ::Adhearsion::CallController
3
3
  def main_menu
4
- pass MailboxMainMenuController, mailbox: mailbox[:id]
4
+ pass config.main_menu_class, mailbox: mailbox[:id], storage: storage
5
5
  end
6
6
 
7
7
  private
@@ -23,5 +23,18 @@ module Voicemail
23
23
  raise ArgumentError, "Voicemail needs a mailbox specified in metadata" unless mailbox_id
24
24
  storage.get_mailbox mailbox_id
25
25
  end
26
+
27
+ def record_options
28
+ if config.use_mailbox_opts_for_recording
29
+ config.recording.to_hash.merge mailbox[:record_options]
30
+ else
31
+ config.recording.to_hash
32
+ end
33
+ end
34
+
35
+ def mailbox_not_found
36
+ play config.mailbox_not_found
37
+ hangup
38
+ end
26
39
  end
27
40
  end
@@ -0,0 +1,60 @@
1
+ module Voicemail
2
+ class AuthenticationController < ApplicationController
3
+
4
+ attr_accessor :tries, :auth_ok, :input
5
+
6
+ def initialize(call, metadata={})
7
+ @tries = 0
8
+ @auth_ok = false
9
+
10
+ super call, metadata
11
+ end
12
+
13
+ def run
14
+ if mailbox
15
+ play_greeting
16
+ authenticate
17
+ fail_auth unless auth_ok
18
+ pass MailboxController, mailbox: mailbox[:id]
19
+ else
20
+ mailbox_not_found
21
+ end
22
+ end
23
+
24
+ def authenticate
25
+ while still_going?
26
+ @tries += 1
27
+ get_input
28
+ if matches?
29
+ @auth_ok = true
30
+ else
31
+ play config.mailbox.pin_wrong
32
+ end
33
+ end
34
+ end
35
+
36
+ private
37
+
38
+ def still_going?
39
+ return false if auth_ok
40
+ config.mailbox.pin_tries == 0 || tries < config.mailbox.pin_tries
41
+ end
42
+
43
+ def matches?
44
+ config.matcher_class.new(input, mailbox[:pin]).matches?
45
+ end
46
+
47
+ def get_input
48
+ @input = ask config.mailbox.please_enter_pin, terminator: "#", timeout: config.prompt_timeout
49
+ end
50
+
51
+ def play_greeting
52
+ play config.mailbox.greeting_message
53
+ end
54
+
55
+ def fail_auth
56
+ play config.mailbox.could_not_auth
57
+ hangup
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,46 @@
1
+ module Voicemail
2
+ class MailboxController < ApplicationController
3
+
4
+ attr_accessor :new_or_saved
5
+
6
+ def run
7
+ if mailbox
8
+ play_number_of_messages :new
9
+ play_number_of_messages :saved
10
+ main_menu
11
+ else
12
+ mailbox_not_found
13
+ end
14
+ end
15
+
16
+ def play_number_of_messages(new_or_saved)
17
+ @new_or_saved = new_or_saved
18
+ get_count
19
+
20
+ if @number > 0
21
+ play_message_count
22
+ else
23
+ play config.messages["no_#{new_or_saved}_messages".to_sym]
24
+ end
25
+ end
26
+
27
+ def play_message_count
28
+ case config.numeric_method
29
+ when :i18n_string
30
+ play I18n.t("voicemail.mailbox.x_#{new_or_saved}_messages", count: @number)
31
+ when :play_numeric
32
+ play config.mailbox.number_before
33
+ play_numeric @number
34
+ play config.mailbox["number_after_#{new_or_saved}".to_sym]
35
+ when :ahn_say
36
+ play config.mailbox.number_before
37
+ play *sounds_for_number(@number)
38
+ play config.mailbox["number_after_#{new_or_saved}".to_sym]
39
+ end
40
+ end
41
+
42
+ def get_count
43
+ @number = storage.send "count_#{new_or_saved}_messages", mailbox[:id]
44
+ end
45
+ end
46
+ end
@@ -7,9 +7,10 @@ module Voicemail
7
7
  def main_menu
8
8
  menu config.mailbox.menu_greeting,
9
9
  timeout: config.menu_timeout, tries: config.menu_tries do
10
- match(1) { listen_to_messages }
11
- match(2) { set_greeting }
12
- match(3) { set_pin }
10
+ match(1) { listen_to_new_messages }
11
+ match(2) { listen_to_saved_messages }
12
+ match(3) { set_greeting }
13
+ match(4) { set_pin }
13
14
 
14
15
  timeout do
15
16
  play config.mailbox.menu_timeout_message
@@ -34,8 +35,12 @@ module Voicemail
34
35
  invoke MailboxSetPinController, mailbox: mailbox[:id]
35
36
  end
36
37
 
37
- def listen_to_messages
38
+ def listen_to_new_messages
38
39
  invoke MailboxMessagesController, mailbox: mailbox[:id]
39
40
  end
41
+
42
+ def listen_to_saved_messages
43
+ invoke MailboxMessagesController, mailbox: mailbox[:id], new_or_saved: :saved
44
+ end
40
45
  end
41
46
  end
@@ -0,0 +1,48 @@
1
+ module Voicemail
2
+ class MailboxMessagesController < ApplicationController
3
+
4
+ attr_accessor :new_or_saved
5
+
6
+ def initialize(call, metadata={})
7
+ @new_or_saved = metadata[:new_or_saved] || :new
8
+
9
+ super call, metadata
10
+ end
11
+
12
+ def run
13
+ message_loop
14
+ end
15
+
16
+ def message_loop
17
+ if messages_remaining > 0
18
+ next_message
19
+ else
20
+ bail_out
21
+ end
22
+ end
23
+
24
+ def next_message
25
+ handle_message current_message
26
+ message_loop
27
+ end
28
+
29
+ def handle_message(message)
30
+ invoke MailboxPlayMessageController, message: message, mailbox: mailbox[:id], new_or_saved: new_or_saved, storage: storage
31
+ end
32
+
33
+ private
34
+
35
+ def messages_remaining
36
+ storage.send "count_#{new_or_saved}_messages", mailbox[:id]
37
+ end
38
+
39
+ def current_message
40
+ storage.send "next_#{new_or_saved}_message", mailbox[:id]
41
+ end
42
+
43
+ def bail_out
44
+ play config.messages["no_#{new_or_saved}_messages"]
45
+ main_menu
46
+ end
47
+ end
48
+ end
@@ -1,6 +1,14 @@
1
1
  module Voicemail
2
2
  class MailboxPlayMessageController < ApplicationController
3
3
 
4
+ attr_accessor :new_or_saved
5
+
6
+ def initialize(call, metadata={})
7
+ @new_or_saved = metadata[:new_or_saved] || :new
8
+
9
+ super call, metadata
10
+ end
11
+
4
12
  def run
5
13
  load_message
6
14
  intro_message
@@ -8,9 +16,9 @@ module Voicemail
8
16
  end
9
17
 
10
18
  def play_message
11
- menu message_uri, config.messages.menu, timeout: config.menu_timeout, tries: config.menu_tries do
19
+ menu message_uri, play_message_menu, timeout: config.menu_timeout, tries: config.menu_tries do
12
20
  match 1 do
13
- archive_message
21
+ archive_or_unarchive_message
14
22
  end
15
23
 
16
24
  match 5 do
@@ -36,19 +44,27 @@ module Voicemail
36
44
  end
37
45
 
38
46
  def intro_message
39
- play config.messages.message_received_on
40
- play_time current_message[:received], format: config.datetime_format
41
- play config.messages.from
42
- from_digits = current_message[:from].scan(/\d/).join
43
- say_characters from_digits unless from_digits.empty?
47
+ invoke MailboxPlayMessageIntroController, message: current_message, mailbox: mailbox[:id], storage: storage
48
+ end
49
+
50
+ def play_message_menu
51
+ if new_or_saved == :new
52
+ config.messages.menu_new
53
+ else
54
+ config.messages.menu_saved
55
+ end
44
56
  end
45
57
 
46
58
  def rewind_message
47
59
  play_message
48
60
  end
49
61
 
50
- def archive_message
51
- storage.archive_message mailbox[:id], current_message[:id]
62
+ def archive_or_unarchive_message
63
+ if new_or_saved == :new
64
+ storage.archive_message mailbox[:id], current_message[:id]
65
+ else
66
+ storage.unarchive_message mailbox[:id], current_message[:id]
67
+ end
52
68
  end
53
69
 
54
70
  def delete_message
@@ -65,7 +81,7 @@ module Voicemail
65
81
  end
66
82
 
67
83
  def message_uri
68
- current_message[:uri].gsub(/\.wav/, '')
84
+ current_message[:uri]
69
85
  end
70
86
  end
71
87
  end
@@ -0,0 +1,72 @@
1
+ module Voicemail
2
+ class MailboxPlayMessageIntroController < ApplicationController
3
+
4
+ def run
5
+ load_message
6
+ intro_message
7
+ end
8
+
9
+ def intro_message
10
+ play_time_message
11
+ play_from_message
12
+ end
13
+
14
+ def play_time_message
15
+ case config.numeric_method
16
+ when :i18n_string
17
+ play I18n.t("voicemail.messages.message_received_on_x", received_on: I18n.localize(current_message[:received]))
18
+ when :play_numeric
19
+ play config.messages.message_received_on
20
+ play_time current_message[:received], format: config.datetime_format
21
+ when :ahn_say
22
+ play config.messages.message_received_on
23
+ play *sounds_for_time(current_message[:received], format: config.datetime_format)
24
+ end
25
+ end
26
+
27
+ def play_from_message
28
+ case config.numeric_method
29
+ when :i18n_string
30
+ play I18n.t("voicemail.messages.message_received_from_x", from: from_string)
31
+ when :play_numeric
32
+ play config.messages.from
33
+ say_characters from_digits unless from_digits.empty?
34
+ when :ahn_say
35
+ play config.messages.from
36
+ play *sounds_for_digits(from_digits)
37
+ end
38
+ end
39
+
40
+ private
41
+
42
+ def from_digits
43
+ current_message[:from].scan(/\d/).join
44
+ end
45
+
46
+ def from_string
47
+ "".tap do |string|
48
+ from_digits.each_char do |char|
49
+ digit_word = I18n.t "numbers.#{char}"
50
+ if digit_word =~ /missing/
51
+ string << char
52
+ else
53
+ string << digit_word
54
+ end
55
+ end
56
+ end
57
+ end
58
+
59
+ def current_message
60
+ @message
61
+ end
62
+
63
+ def load_message
64
+ @message = metadata[:message] || nil
65
+ raise ArgumentError, "MailboxPlayMessageIntroController needs a valid message passed to it" unless @message
66
+ end
67
+
68
+ def message_uri
69
+ current_message[:uri]
70
+ end
71
+ end
72
+ end