Skip to content

Commit

Permalink
Merge pull request 2600hz#472 from siplabs/KAZOO-2862
Browse files Browse the repository at this point in the history
KAZOO-2862: camper: bugfix, per-calflow config
  • Loading branch information
k-anderson committed Aug 26, 2014
2 parents ec0232f + b831d91 commit 56e2086
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 48 deletions.
63 changes: 42 additions & 21 deletions applications/callflow/src/module/cf_camping_feature.erl
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,17 @@
%%% Sends request to start the call to recepient when he's available
%%%
%%% data: {
%%% "timeout": "_minutes_timeout"
%%% ,"tries": "_count"
%%% ,"try_interval": "_minutes_interval"
%%% ,"stop_after": "_minutes_timeout"
%%% }
%%%
%%% uses cf_capture_group to extract extension number
%%%
%%% `timeout`, `tries`, `try_interval` & `stop_after` will correct system
%%% defaults if present
%%%
%%% usage example
%%%
%%% 1) create a "pattern callflow" with "patterns": ["^\\*7([0-9]*)$"]
Expand All @@ -30,6 +37,7 @@
,type :: ne_binary()
,number :: ne_binary()
,channels :: wh_json:objects()
,config :: wh_json:object()
}).
-type state() :: #state{}.

Expand All @@ -49,38 +57,43 @@ just(X) ->
nothing() ->
'Nothing'.

init(Call) ->
init([Data, Call]) ->
whapps_call_command:answer(Call),
lager:info("Camping feature started"),
Number = whapps_call:kvs_fetch('cf_capture_group', Call),
CF = cf_util:lookup_callflow(Number, whapps_call:account_id(Call)),
case CF of
{'ok', Callflow, IsNoMatch} -> just(#state{callflow = Callflow
,is_no_match = IsNoMatch
,number = Number
,config = Data
});
_ -> nothing()
end.

-spec get_target(state()) -> maybe(state()).
get_target(#state{callflow = Callflow} = S) ->
lager:debug("Getting target"),
TargetId = wh_json:get_ne_value([<<"flow">>, <<"data">>, <<"id">>], Callflow),
TargetType = wh_json:get_ne_value([<<"flow">>, <<"module">>], Callflow),
case {TargetType, TargetId} of
% coz i can
{<<"offnet">>, _} -> just(S#state{type = TargetType});
{'undefined', _} -> nothing();
{_, 'undefined'} -> nothing();
{_, _} -> just(S#state{id = TargetId, type = TargetType})
end.

-spec check_target_type(state()) -> maybe(state()).
check_target_type(#state{type = TargetType} = S) ->
lager:debug("Checking target type"),
case lists:member(TargetType, [<<"offnet">>, <<"user">>, <<"device">>]) of
'true' -> just(S);
'false' -> nothing()
end.

-spec get_channels(state(), whapps_call:call()) -> maybe(state()).
get_channels(#state{type = TargetType, id = TargetId} = S, Call) ->
lager:debug("Exlpoing channels"),
Usernames = case TargetType of
<<"device">> -> cf_util:sip_users_from_device_ids([TargetId], Call);
<<"user">> ->
Expand All @@ -93,6 +106,7 @@ get_channels(#state{type = TargetType, id = TargetId} = S, Call) ->

-spec check_self(state(), whapps_call:call()) -> maybe(state()).
check_self(State, Call) ->
lager:debug("Check on self"),
case {whapps_call:authorizing_id(Call), whapps_call:authorizing_type(Call)} of
{'undefined', _} -> nothing();
{_, 'undefined'} -> nothing();
Expand All @@ -101,6 +115,7 @@ check_self(State, Call) ->

-spec send_request(state(), whapps_call:call()) -> maybe('ok').
send_request(#state{channels = Channels} = S, Call) ->
lager:debug("Sending request"),
case Channels of
[] -> no_channels(S, Call);
_ -> has_channels(S, Call)
Expand All @@ -119,14 +134,14 @@ do(Monad, Actions) ->
%% @end
%%--------------------------------------------------------------------
-spec handle(wh_json:object(), whapps_call:call()) -> 'ok'.
handle(_Data, Call) ->
Ok = do(just(Call),[fun init/1
,fun get_target/1
,fun check_target_type/1
,fun (State) -> check_self(State, Call) end
,fun (State) -> get_channels(State, Call) end
,fun (State) -> send_request(State, Call) end
]),
handle(Data, Call) ->
Ok = do(just([Data, Call]),[fun init/1
,fun get_target/1
,fun check_target_type/1
,fun (State) -> check_self(State, Call) end
,fun (State) -> get_channels(State, Call) end
,fun (State) -> send_request(State, Call) end
]),
case Ok of
{'Just', 'ok'} -> whapps_call_command:b_prompt(<<"camper-queue">>, Call);
'Nothing' -> whapps_call_command:b_prompt(<<"camper-deny">>, Call)
Expand Down Expand Up @@ -163,12 +178,16 @@ no_channels(#state{id = TargetId
no_channels(#state{type = <<"offnet">>
,is_no_match = 'true'
,number = Number
,config = CFG
}
,Call) ->
Msg = wh_json:from_list([{<<"Number">>, Number}
,{<<"Call">>, whapps_call:to_json(Call)}
]),
JObj = wh_json:from_list([{<<"Delegate-Message">>, Msg}
MsgProps = props:filter_undefined([{<<"Number">>, Number}
,{<<"Call">>, whapps_call:to_json(Call)}
,{<<"Tries">>, wh_json:get_value(<<"tries">>, CFG)}
,{<<"Stop-After">>, wh_json:get_value(<<"stop_after">>, CFG)}
,{<<"Try-Interval">>, wh_json:get_value(<<"try_interval">>, CFG)}
]),
JObj = wh_json:from_list([{<<"Delegate-Message">>, wh_json:from_list(MsgProps)}
| wh_api:default_headers(?APP_NAME, ?APP_VERSION)
]),
wapi_delegate:publish_delegate(<<"camper">>, JObj, <<"offnet">>).
Expand All @@ -177,15 +196,17 @@ no_channels(#state{type = <<"offnet">>
has_channels(#state{id = TargetId
,type = TargetType
,number = Number
,config = CFG
}, Call) ->
Targets = get_sip_usernames_for_target(TargetId, TargetType, Call),
Msg = wh_json:from_list([{<<"Account-DB">>, whapps_call:account_db(Call)}
,{<<"Authorizing-ID">>, whapps_call:authorizing_id(Call)}
,{<<"Authorizing-Type">>, whapps_call:authorizing_type(Call)}
,{<<"Number">>, Number}
,{<<"Targets">>, Targets}
]),
JObj = wh_json:from_list([{<<"Delegate-Message">>, Msg}
MsgProps = props:filter_undefined([{<<"Account-DB">>, whapps_call:account_db(Call)}
,{<<"Authorizing-ID">>, whapps_call:authorizing_id(Call)}
,{<<"Authorizing-Type">>, whapps_call:authorizing_type(Call)}
,{<<"Number">>, Number}
,{<<"Targets">>, Targets}
,{<<"Timeout">>, wh_json:get_value(<<"timeout">>, CFG)}
]),
JObj = wh_json:from_list([{<<"Delegate-Message">>, wh_json:from_list(MsgProps)}
| wh_api:default_headers(?APP_NAME, ?APP_VERSION)
]),
wapi_delegate:publish_delegate(<<"camper">>, JObj, <<"onnet">>).
2 changes: 1 addition & 1 deletion applications/camper/src/camper.hrl
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
-define(CAMPER_CONFIG_CAT, <<"camper">>).

-define(TIMEOUT, <<"timeout">>).
-define(DEFAULT_TIMEOUT, 15*?SECONDS_IN_MINUTE).
-define(DEFAULT_TIMEOUT, 15).

-define(CAMPER_HRL, 'true').
-endif.
26 changes: 18 additions & 8 deletions applications/camper/src/camper_offnet_handler.erl
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
,handle_resource_response/2
]).

-export([add_request/2]).
-export([add_request/1]).

-include("camper.hrl").

Expand Down Expand Up @@ -68,11 +68,20 @@ start_link(Args) ->
,{'consume_options', ?CONSUME_OPTIONS}
], Args).

init([Exten, Call]) ->
init(JObj) ->
Exten = wh_json:get_value(<<"Number">>, JObj),
Call = whapps_call:from_json(wh_json:get_value(<<"Call">>, JObj)),
lager:info("Statred offnet handler(~p) for request ~s->~s", [self(), whapps_call:from_user(Call), Exten]),
MaxTries = whapps_config:get(?CAMPER_CONFIG_CAT, <<"tries">>, 10),
TryInterval = whapps_config:get(?CAMPER_CONFIG_CAT, <<"try_interval">>, timer:minutes(3)),
StopAfter = whapps_config:get(?CAMPER_CONFIG_CAT, <<"stop_after">>, timer:minutes(31)),

MaxTriesSystem = whapps_config:get(?CAMPER_CONFIG_CAT, <<"tries">>, 10),
MaxTries = wh_json:get_value(<<"Tries">>, JObj, MaxTriesSystem),

TryIntervalSystem = whapps_config:get(?CAMPER_CONFIG_CAT, <<"try_interval">>,3),
TryInterval = timer:minutes(wh_json:get_value(<<"Try-Interval">>, JObj, TryIntervalSystem)),

StopAfterSystem = whapps_config:get(?CAMPER_CONFIG_CAT, <<"stop_after">>, 31),
StopAfter = timer:minutes(wh_json:get_value(<<"Stop-After">>, JObj, StopAfterSystem)),

StopTimer = timer:apply_after(StopAfter, 'gen_listener', 'cast', [self(), 'stop_campering']),
{'ok', #state{exten = Exten
,stored_call = Call
Expand Down Expand Up @@ -168,10 +177,11 @@ handle_cast(_Msg, State) ->
lager:debug("unhandled cast: ~p", [_Msg]),
{'noreply', State}.

-spec add_request(ne_binary(), whapps_call:call()) -> 'ok'.
add_request(Exten, Call) ->
-spec add_request(wh_json:object()) -> 'ok'.
add_request(JObj) ->
Exten = wh_json:get_value(<<"Number">>, JObj),
lager:info("adding offnet request to ~s", [Exten]),
camper_offnet_sup:new(Exten, Call).
camper_offnet_sup:new(JObj).

%%--------------------------------------------------------------------
%% @private
Expand Down
6 changes: 3 additions & 3 deletions applications/camper/src/camper_offnet_sup.erl
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

%% API
-export([start_link/0
,new/2
,new/1
]).

%% Supervisor callbacks
Expand All @@ -38,8 +38,8 @@
start_link() ->
supervisor:start_link({local, ?MODULE}, ?MODULE, []).

-spec new(ne_binary(), whapps_call:call()) -> sup_startchild_ret().
new(Exten, Call) -> supervisor:start_child(?MODULE, [[Exten, Call]]).
-spec new(wh_json:object()) -> sup_startchild_ret().
new(JObj) -> supervisor:start_child(?MODULE, [JObj]).

%%%===================================================================
%%% Supervisor callbacks
Expand Down
21 changes: 15 additions & 6 deletions applications/camper/src/camper_onnet_handler.erl
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
,terminate/2
,code_change/3
]).
-export([add_request/4
-export([add_request/1
,available_device/2]).

-include("camper.hrl").
Expand Down Expand Up @@ -59,9 +59,9 @@ set_requests(S, Val) ->
set_requestor_queues(S, Val) ->
S#'state'{'requestor_queues' = Val}.

-spec add_request(ne_binary(), {ne_binary(), ne_binary()}, ne_binary(), ne_binaries()) -> 'ok'.
add_request(AccountDb, Authorizing, Exten, Targets) ->
gen_server:cast(?MODULE, {'add_request', AccountDb, Authorizing, Exten, Targets}).
-spec add_request(wh_json:object()) -> 'ok'.
add_request(JObj) ->
gen_server:cast(?MODULE, {'add_request', JObj}).

-spec available_device(ne_binary(), ne_binary()) -> 'ok'.
available_device(AccountId, SIPName) ->
Expand Down Expand Up @@ -125,10 +125,19 @@ handle_call(_Request, _From, State) ->
%% {stop, Reason, State}
%% @end
%%--------------------------------------------------------------------
handle_cast({'add_request',AccountDb, Dev, Exten, Targets}, GlobalState) ->
handle_cast({'add_request', JObj}, GlobalState) ->
AccountDb = wh_json:get_value(<<"Account-DB">>, JObj),
AccountId = wh_util:format_account_id(AccountDb, 'raw'),
Dev = {wh_json:get_value(<<"Authorizing-ID">>, JObj)
,wh_json:get_value(<<"Authorizing-Type">>, JObj)
},
Exten = wh_json:get_value(<<"Number">>, JObj),
Targets = wh_json:get_value(<<"Targets">>, JObj),
Timeout = timer:minutes(wh_json:get_value(<<"Timeout">>
,JObj
,whapps_config:get(?APP_NAME, ?TIMEOUT, ?DEFAULT_TIMEOUT)
)),
wh_hooks:register(AccountId, <<"CHANNEL_DESTROY">>),
Timeout = whapps_config:get(?APP_NAME, ?TIMEOUT, ?DEFAULT_TIMEOUT),
NewGlobal = with_state(AccountId
,GlobalState
,fun(Local) ->
Expand Down
11 changes: 2 additions & 9 deletions applications/camper/src/camper_request_listener.erl
Original file line number Diff line number Diff line change
Expand Up @@ -70,17 +70,10 @@ handle_camper_req(JObj, _Props, #'basic.deliver'{'routing_key' = Key}) ->
case binary:split(Key, <<".">>, ['global']) of
[_, ?APP_NAME, <<"offnet">>] ->
Msg = wh_json:get_value(<<"Delegate-Message">>, JObj),
Number = wh_json:get_value(<<"Number">>, Msg),
Call = whapps_call:from_json(wh_json:get_value(<<"Call">>, Msg)),
camper_offnet_handler:add_request(Number, Call);
camper_offnet_handler:add_request(Msg);
[_, ?APP_NAME, <<"onnet">>] ->
Msg = wh_json:get_value(<<"Delegate-Message">>, JObj),
AccountDb = wh_json:get_value(<<"Account-DB">>, Msg),
Id = wh_json:get_value(<<"Authorizing-ID">>, Msg),
Type = wh_json:get_value(<<"Authorizing-Type">>, Msg),
Number = wh_json:get_value(<<"Number">>, Msg),
Targets = wh_json:get_value(<<"Targets">>, Msg),
camper_onnet_handler:add_request(AccountDb, {Id, Type}, Number, Targets)
camper_onnet_handler:add_request(Msg)
end.

%%%===================================================================
Expand Down

0 comments on commit 56e2086

Please sign in to comment.