Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Voicemail Fast Forward and Rewind #5662

Closed
wants to merge 1 commit into from

Conversation

noahmehl
Copy link
Contributor

@noahmehl noahmehl commented Apr 4, 2019

This is a first stab at integrating the uuid_fileman seek command in relation to call flows voicemail module to add the feature of fast forward and rewind of playback of voicemails.

I also want to note that in our testing, even if we can get kazoo to issue the correct FS command: uuid_fileman $uuid seek:+/- value, the voicemail doesn't actually seek. In my cursory testing, even issuing the command via fs_cli doesn't work either. I haven't had a chance to test via vanilla FS build/configs.

@extremerotary
Copy link
Contributor

@jamesaimonetti This would be pretty cool to add!

Copy link
Member

@jamesaimonetti jamesaimonetti left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First pass, some small things to clean up. Overall good stuff!

,{'prompt', <<"vm-message_menu">>}
].

play_prompt(Message, true=_AllowFfRw) ->
{'play', Message, ?VM_MESSAGE_TERMINATORS};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I customize keys in the callflow vm system_config to something other than 5 and 8, this will terminate playback instead of ff/rw.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also please tickie all atoms: true should be 'true'.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jamesaimonetti latest code has been updated for this, please take a look :)

forward_message(H, Box, Call),
{_, NMessage} = kvm_message:set_folder(?VM_FOLDER_SAVED, H, AccountId),
_ = kapps_call_command:prompt(<<"vm-saved">>, Call),
play_messages(T, [NMessage|PrevMessages], Count, Box, Call);
{ok, rewind} ->
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tickie (won't comment on all places that need it though).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jamesaimonetti latest code has been updated for this, please take a look :)

forward_message(H, Box, Call),
{_, NMessage} = kvm_message:set_folder(?VM_FOLDER_SAVED, H, AccountId),
_ = kapps_call_command:prompt(<<"vm-saved">>, Call),
play_messages(T, [NMessage|PrevMessages], Count, Box, Call);
{ok, rewind} ->
lager:notice("caller chose to rewind 10 sec of the message"),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this really 'notice'-level worthy? I would just use info for these unless you have a compelling reason for the higher level.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jamesaimonetti latest code has been updated for this, please take a look :)

allow_ff_rw(MailboxJObj) ->
case ?DEFAULT_ALLOW_FF_RW of
'true' -> 'true';
'false' -> kzd_voicemail_box:pin_required(MailboxJObj)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does 'pin_required' matter for whether ff/rewind is allowed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jamesaimonetti latest code has been updated for this, please take a look :)

@@ -30,6 +30,7 @@
,execute_extension/1, execute_extension_v/1
,break/1, break_v/1
,play/1, play_v/1, playstop/1, playstop_v/1
,playseek/1, playseek_v/1 %TODO
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No longer todo right? LOL

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jamesaimonetti latest code has been updated for this, please take a look :)

,{<<"Application-Name">>, <<"playseek">>}
,{<<"Insert-At">>, <<"now">>}
]).
-define(PLAY_SEEK_REQ_TYPES, []).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like Duration to have an fun is_integer/1 type validator.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jamesaimonetti latest code has been updated for this, please take a look :)

ok;
seek(Direction, Duration, Call) ->
NoopId = noop_id(),
%Commands = [kz_json:from_list([{<<"Application-Name">>, <<"noop">>}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove commented code

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jamesaimonetti latest code has been updated for this, please take a look :)

-spec seek_command(atom(), kz_term:api_pos_integer()) -> kz_json:object().
seek_command(Direction, Duration) ->
kz_json:from_list([{<<"Application-Name">>, <<"playseek">>}
,{<<"Direction">>,Direction}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Space after the comma and before Direction. Same for Duration below

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jamesaimonetti latest code has been updated for this, please take a look :)

@@ -2446,7 +2511,8 @@ do_collect_digits(#wcc_collect_digits{max_digits=MaxDigits
do_collect_digits(Collect#wcc_collect_digits{after_timeout=kz_time:decr_timeout(After, Start)});
{'ok', Digit} ->
%% DTMF received, collect and start interdigit timeout
Digits =:= <<>>
FlushOnDigit
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We've been moving away from having the right-most arg not returning boolean() when using andalso/orelse.

I would move this to a function maybe_flush_queue(FlushOnDigit, Digits, Call) with a definition like

maybe_flush_queue('true', <<>>, Call) -> flush(Call);
maybe_flush_queue(_FlushOnDigit, _Digits, _Call) -> 'ok'.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jamesaimonetti latest code has been updated for this, please take a look :)

forward_message(H, Box, Call),
{_, NMessage} = kvm_message:set_folder(?VM_FOLDER_SAVED, H, AccountId),
_ = kapps_call_command:prompt(<<"vm-saved">>, Call),
play_messages(T, [NMessage|PrevMessages], Count, Box, Call);
{ok, rewind} ->
lager:notice("caller chose to rewind 10 sec of the message"),
_ = kapps_call_command:seek(rewind, 10000, Call),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the duration should be figured out for the mailbox when creating the mailbox record instead of hard-coded.

I would check the VM box, the owner_id's User doc, then the system_config doc for voicemail for this setting.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jamesaimonetti latest code has been updated for this, please take a look :)

@noahmehl
Copy link
Contributor Author

I've opened a bug in the Freeswitch Jira:

https://freeswitch.org/jira/browse/FS-11796

@@ -41,7 +41,16 @@
-define(KEY_DELETE_AFTER_NOTIFY, <<"delete_after_notify">>).
-define(KEY_SAVE_AFTER_NOTIFY, <<"save_after_notify">>).
-define(KEY_FORCE_REQUIRE_PIN, <<"force_require_pin">>).
-define(KEY_ALLOW_FF_RW, <<"allow_ff_rw">>).
-define(KEY_SEEK_DURATION, <<"seek_duration">>).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally speaking we try to put units of time in the names: seek_duration_ms in this case to ease reading.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jamesaimonetti latest code has been updated for this, please take a look :)

-define(MAX_INVALID_PIN_LOOPS, 3).
-define(DEFAULT_SEEK_DURATION, 10000).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In a similar vein, there are time related macros in kz_types.hrl to use to ease reading: 10 * ?MILLISECONDS_IN_SECOND would compile to 10000 but reads a little easier.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jamesaimonetti latest code has been updated for this, please take a look :)

@@ -1629,6 +1688,20 @@ should_require_pin(MailboxJObj) ->
'false' -> kzd_voicemail_box:pin_required(MailboxJObj)
end.

-spec allow_ff_rw(kz_json:object()) -> boolean().
allow_ff_rw(MailboxJObj) ->
case ?DEFAULT_ALLOW_FF_RW of
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the logic is not quite right here. The kapps_config flag should be used to allow the voicemail box's setting to be used (and not as an allowed-by-default setting like it is this way). I would rewrite this to:

case ?DEFAULT_ALLOW_FF_RW of
    'true' -> kzd_voicemail_box:allow_ff_rw(MailboxJObj);
    'false' -> 'false'
end

So if kapps_config returns false the ff/rw feature is not available on this system, full stop (retaining backwards compat). If the system operator turns that config flag to true then the voicemail box's setting is used (defaulting to false to preserve existing functionality).

Does that make sense?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jamesaimonetti There was some confusion here. We actually only want to have to enable the feature at the kapps_config level. We removed any VMBox level config.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jamesaimonetti We have updated as requested.

@extremerotary
Copy link
Contributor

Hey @lazedo ,
Do you think you'll have some time to check out the freeswitch bug that was discovered during this programming?
https://freeswitch.org/jira/browse/FS-11796

I think this fast-forward and rewind feature is pretty sweet, and we need your help to finish it off!

@noahmehl
Copy link
Contributor Author

noahmehl commented May 9, 2019

@lazedo @extremerotary @jamesaimonetti Great news! We found someone to provide a patch for this. I have submitted it to the Jira issue and created a PR for the Freeswitch repo:

https://freeswitch.org/stash/projects/FS/repos/freeswitch/pull-requests/1725 (master)

Also, I have a v1.8 version here:
https://freeswitch.org/stash/users/noahmehl_reper.io/repos/freeswitch/browse?at=refs%2Fheads%2Fv1.8

@noahmehl
Copy link
Contributor Author

FF:RW.graffle.pdf

This is what we propose for logic on whether the feature is enabled.

@jamesaimonetti
Copy link
Member

@noahmehl i wouldn't even worry about account config. As I said in IRC:

is_ff_rw_enabled(VMBox) ->
    case kapps_config:get(?CONFIG_CAT, <<"is_voicemail_ff_rw_enabled">>, 'false')
        andalso kzd_vmboxes:is_ff_rw_enabled(VMBox, 'false').

First check ensures the system operator has opted-in and second check ensures the vmbox owner wants to use the feature (and presumably has tested that there are no conflicts in DTMF mapping).

As stated in IRC as well, a separate PR should be created to categorize DTMF keys and check for conflicting keys within a category when creating VM boxes via API.

@noahmehl
Copy link
Contributor Author

@jamesaimonetti I have updated the logic document:

FF:RW - 1.0.2.pdf

We will work on this update.

@noahmehl
Copy link
Contributor Author

@@ -133,8 +153,10 @@
,prev = <<"4">> :: kz_term:ne_binary()
,next = <<"6">> :: kz_term:ne_binary()
,delete = <<"7">> :: kz_term:ne_binary()
,rewind = <<"5">> :: kz_term:ne_binary()
,fastforward = <<"8">> :: kz_term:ne_binary()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about to use this menu

              ,keep = <<"1">> :: kz_term:ne_binary()
              ,replay = <<"2">> :: kz_term:ne_binary()
              ,forward = <<"3">> :: kz_term:ne_binary()
              ,prev = <<"4">> :: kz_term:ne_binary()
              ,callback = <<"5">> :: kz_term:ne_binary()
              ,next = <<"6">> :: kz_term:ne_binary()
              ,rewind = <<"7">> :: kz_term:ne_binary()
              ,delete = <<"8">> :: kz_term:ne_binary()
              ,fastforward = <<"9">> :: kz_term:ne_binary()

Callback feature on PR #5267

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the biggest problem with that is that it would change the default behavior for every deployed system and user (because you changed delete).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the point is that we should not change any existing keys, and since key mapping is available per mailbox, any operator could apply the mapping you suggest at any time.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From my view this change is acceptable for kazoo 5.x.x branch.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jamesaimonetti or @lazedo can you please comment?

Copy link
Member

@jamesaimonetti jamesaimonetti left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rebase to address conflicts plus a couple more notes


-spec seek(atom(), kz_term:api_pos_integer(), kapps_call:call()) -> kapps_api_std_return().
seek(_Direction, 0, _Call) ->
'ok';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This 'ok' is not a kapps_api_std_return(). Perhaps b_seek should pattern-match the 0 and return immediately rather than call wait_for_noop with 'ok' in the second parameter?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alternatively you could return 'undefined' instead. Then the return type would be kz_term:api_ne_binary()

Copy link
Contributor

@T0ha T0ha May 17, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Siims 'ok' is kapps_api_std_return()

-type kapps_api_std_return() :: kapps_api_error() |
                                {'ok', kz_json:object() |
                                 kz_term:ne_binary()
                                } |
                                'ok'.

Copy link
Contributor Author

@noahmehl noahmehl May 17, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jamesaimonetti I think we're a little confused on why it's not a kapps_api_std_return(). I imagine that it's because this is an OK from freeswitch?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jamesaimonetti turns out b_seek/3 wasn't needed, and we removed it. Does this help?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This appears to still return 'ok' and b_seek still uses that return value (unless I'm missing something?).

forward_message(H, Box, Call),
{_, NMessage} = kvm_message:set_folder(?VM_FOLDER_SAVED, H, AccountId),
_ = kapps_call_command:prompt(<<"vm-saved">>, Call),
play_messages(T, [NMessage|PrevMessages], Count, Box, Call);
{ok, 'rewind'} ->
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tickie ok atoms

@noahmehl noahmehl force-pushed the voicemail_ff_rw branch 2 times, most recently from 7a8b67b to a5e50f7 Compare May 17, 2019 14:45
@lazedo
Copy link
Member

lazedo commented May 17, 2019

@noahmehl please squash your commits and push. thanks.
note that you also have several errors maybe due to a failed rebase.

src/ecallmgr_util.erl:119: head mismatch
src/ecallmgr_util.erl:13: function send_cmd/5 undefined
src/ecallmgr_util.erl:95: function send_cmd/5 undefined
src/ecallmgr_util.erl:97: spec for undefined function send_cmd/5
src/ecallmgr_util.erl:194: function cmd_is_empty/1 is unused
../../make/kz.mk:81: recipe for target 'ebin/ecallmgr.app' failed
make[2]: *** [ebin/ecallmgr.app] Error 1

@noahmehl
Copy link
Contributor Author

@jamesaimonetti I have created a Jira issue for the populate_keys work:

https://2600hz.atlassian.net/browse/KAZOO-6102

@noahmehl noahmehl force-pushed the voicemail_ff_rw branch 3 times, most recently from f812cd3 to 9c82b44 Compare May 28, 2019 17:26
@noahmehl noahmehl force-pushed the voicemail_ff_rw branch 2 times, most recently from d10183d to 441a161 Compare June 2, 2019 19:26
@noahmehl
Copy link
Contributor Author

noahmehl commented Jun 2, 2019

@jamesaimonetti @lazedo we believe that everything has been addressed. Also, I just rebased from master. Can we get this merged?

forward_message(H, Box, Call),
{_, NMessage} = kvm_message:set_folder(?VM_FOLDER_SAVED, H, AccountId),
_ = kapps_call_command:prompt(<<"vm-saved">>, Call),
play_messages(T, [NMessage|PrevMessages], Count, Box, Call);
{'ok', 'rewind'} ->
lager:info("caller chose to rewind 10 sec of the message"),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here and some strings bottom rewind/forward duration is configurable.
Please update log message.
Think value may removed from log message.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed the values.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe need use

lager:info("caller chose to rewind message"),

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, my bad. all corect

-spec is_ff_rw_enabled(kz_json:object()) -> boolean().
is_ff_rw_enabled(MailboxJObj) ->
case ?IS_FF_RW_ENABLED of
'true' -> kzd_voicemail_box:is_ff_rw_enabled(MailboxJObj);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks as kzd_voicemail_box module is deprecated. And need use kzd_vmboxes in this PR.
@jamesaimonetti, @lazedo could you look.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They need to be merged into one module; that can be taken care of at a future time.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But new functionality should go in kzd_vmboxes, that is the module that tracks the schema.

@@ -2373,6 +2410,7 @@ b_privacy(Mode, Call) ->
,call :: kapps_call:call()
,digits_collected = <<>> :: binary()
,after_timeout = ?MILLISECONDS_IN_DAY :: pos_integer()
,flush_on_digit = true
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tickie atom

@@ -165,6 +181,8 @@
,transcribe_voicemail = 'false' :: boolean()
,notifications :: kz_term:api_object()
,after_notify_action = 'nothing' :: 'nothing' | 'delete' | 'save'
,is_ff_rw_enabled = false :: boolean()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tickie

@@ -1057,6 +1102,8 @@ message_menu(Prompt, #mailbox{keys=#keys{replay=Replay
,kapps_call_command:default_collect_timeout()
,Interdigit
,NoopId
,[<<"#">>]
,false
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tickie

@@ -17,6 +17,8 @@
,pin/1, pin/2
,mailbox_number/1, mailbox_number/2
,pin_required/1, pin_required/2
,is_ff_rw_enabled/1, is_ff_rw_enabled/2
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should not duplicate this between kzd_vmboxes and kzd_voicemail_boxes. Please focus on kzd_vmboxes as this is the module that tracks the schema.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jamesaimonetti I believe we have resolved this and the other tickie items. Can you take a look?

@jamesaimonetti
Copy link
Member

Merged! Yay it happened lol

itlevel3 pushed a commit to sipengines/kazoo that referenced this pull request Oct 16, 2019
itlevel3 pushed a commit to sipengines/kazoo that referenced this pull request Oct 16, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
6 participants