arnaudcoquelet / fusionpbx

Automatically exported from code.google.com/p/fusionpbx
0 stars 0 forks source link

Call forwarding does not work from extension #785

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
*I initially opened this report with the wrong title #784 please close that 
issue.

What steps will reproduce the problem?
1.Dial *72 or *74
2.Follow prompts and put in correct information
3.press # to end the call.

What is the expected output? What do you see instead?
Call forward should work after this, however it does not work. Adding a call 
forward on a extension works only if you do it within the fusionpbx interface. 
Additionally this is the error I see from fs_cli:

2014-12-04 16:45:53.100121 [ERR] switch_pgsql.c:645 Error executing query:
ERROR:  invalid input syntax for uuid: ""
LINE 1: ...951df1-54be-4ae9-8a1b-9ae0a3265667' and follow_me_uuid = ''
                                                                    ^

2014-12-04 16:45:53.100121 [ERR] freeswitch_lua.cpp:446 DBH NOT Connected.

I can see that normally I would get DBH NOT connected if it was unable to 
connect to the database, however since I can call forward from the webpage, 
perform other actions which require database access I'm unsure this is the case.

What version of the product are you using? On what operating system?
3.7.1 
Debian 7
 Linux fusion 3.2.0-4-amd64 #1 SMP Debian 3.2.60-1+deb7u3 x86_64 GNU/Linux 

Please provide any additional information below.
AFAIK everything else works no other issues to report.

Original issue reported on code.google.com by scristop...@gmail.com on 4 Dec 2014 at 11:03

GoogleCodeExporter commented 9 years ago
does not work on 2 different servers both on 3.7.1 

Original comment by scristop...@gmail.com on 5 Dec 2014 at 12:39

GoogleCodeExporter commented 9 years ago
commented out or removed the follow_me_uuid stuff from call_forward.lua and now 
it properly works

root@fusion:/usr/local/freeswitch# cp ./scripts/call_forward.lua{,.bak}

--
--      FusionPBX
--      Version: MPL 1.1
--
--      The contents of this file are subject to the Mozilla Public License 
Version
--      1.1 (the "License"); you may not use this file except in compliance with
--      the License. You may obtain a copy of the License at
--      http://www.mozilla.org/MPL/
--
--      Software distributed under the License is distributed on an "AS IS" 
basis,
--      WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
--      for the specific language governing rights and limitations under the
--      License.
--
--      The Original Code is FusionPBX
--
--      The Initial Developer of the Original Code is
--      Mark J Crane <markjcrane@fusionpbx.com>
--      Copyright (C) 2010-2014
--      the Initial Developer. All Rights Reserved.
--
--      Contributor(s):
--      Mark J Crane <markjcrane@fusionpbx.com>

--set default variables
        min_digits = "1";
        max_digits = "11";
        max_tries = "3";
        digit_timeout = "3000";

--debug
        debug["sql"] = false;

--define the trim function
        function trim (s)
                return (string.gsub(s, "^%s*(.-)%s*$", "%1"))
        end

--define the explode function
        function explode ( seperator, str )
                local pos, arr = 0, {}
                for st, sp in function() return string.find( str, seperator, pos, true ) end do -- for each divider found
                        table.insert( arr, string.sub( str, pos, st-1 ) ) -- attach chars left of current divider
                        pos = sp + 1 -- jump past current divider
                end
                table.insert( arr, string.sub( str, pos ) ) -- attach chars right of last divider
                return arr
        end

--create the api object
        api = freeswitch.API();

--include config.lua
        scripts_dir = string.sub(debug.getinfo(1).source,2,string.len(debug.getinfo(1).source)-(string.len(argv[0])+1));
        dofile(scripts_dir.."/resources/functions/config.lua");
        dofile(config());

--check if the session is ready
        if (session:ready()) then
                --answer the call
                        session:answer();

                --get the variables
                        enabled = session:getVariable("enabled");
                        pin_number = session:getVariable("pin_number");
                        sounds_dir = session:getVariable("sounds_dir");
                        domain_uuid = session:getVariable("domain_uuid");
                        domain_name = session:getVariable("domain_name");
                        extension_uuid = session:getVariable("extension_uuid");
                        context = session:getVariable("context");
                        if (not context ) then context = 'default'; end
                        request_id = session:getVariable("request_id");

                --set the sounds path for the language, dialect and voice
                        default_language = session:getVariable("default_language");
                        default_dialect = session:getVariable("default_dialect");
                        default_voice = session:getVariable("default_voice");
                        if (not default_language) then default_language = 'en'; end
                        if (not default_dialect) then default_dialect = 'us'; end
                        if (not default_voice) then default_voice = 'callie'; end

                --a moment to sleep
                        session:sleep(1000);

                --connect to the database
                        dofile(scripts_dir.."/resources/functions/database_handle.lua");
                        dbh = database_handle('system');

                --request id is true
                        if (request_id == "true") then
                                --unset extension uuid
                                        extension_uuid = nil;

                                --get the id
                                        if (session:ready()) then
                                                min_digits = 2;
                                                max_digits = 20;
                                                id = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", "phrase:voicemail_enter_id:#", "", "\\d+");
                                        end

                                --get the pin number
                                        if (session:ready()) then
                                                min_digits = 3;
                                                max_digits = 20;
                                                caller_pin_number = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", "phrase:voicemail_enter_pass:#", "", "\\d+");
                                        end

                                --check to see if the pin number is correct
                                        if (session:ready()) then
                                                sql = "SELECT * FROM v_voicemails ";
                                                sql = sql .. "WHERE domain_uuid = '" .. domain_uuid .."' ";
                                                sql = sql .. "AND voicemail_id = '" .. id .."' ";
                                                if (debug["sql"]) then
                                                        freeswitch.consoleLog("notice", "[call_forward] "..sql .."\n");
                                                end
                                                dbh:query(sql, function(row)
                                                        voicemail_password = row.voicemail_password;
                                                        --freeswitch.consoleLog("notice", "[call_forward] "..voicemail_password .."\n");
                                                end);
                                                if (voicemail_password ~= caller_pin_number) then
                                                        --access denied
                                                        session:streamFile("phrase:voicemail_fail_auth:#");
                                                        session:hangup("NORMAL_CLEARING");
                                                end
                                        end
                        end

                --determine whether to update the dial string
                        if (session:ready()) then
                                sql = "select * from v_extensions ";
                                sql = sql .. "where domain_uuid = '"..domain_uuid.."' ";
                                if (extension_uuid ~= nil) then
                                        sql = sql .. "and extension_uuid = '"..extension_uuid.."' ";
                                else
                                        sql = sql .. "and (extension = '"..id.."' or number_alias = '"..id.."') ";
                                end
                                if (debug["sql"]) then
                                        freeswitch.consoleLog("notice", "[call_forward] "..sql.."\n");
                                end
                                status = dbh:query(sql, function(row)
                                        extension_uuid = row.extension_uuid;
                                        extension = row.extension;
                                        number_alias = row.number_alias;
                                        accountcode = row.accountcode;
                                        forward_all_enabled = row.forward_all_enabled;
--                                      follow_me_uuid = row.follow_me_uuid;
                                        --freeswitch.consoleLog("NOTICE", "[call forward] extension "..row.extension.."\n");
                                        --freeswitch.consoleLog("NOTICE", "[call forward] accountcode "..row.accountcode.."\n");
                                end);
                        end

                --toggle enabled
                        if (session:ready() and enabled == "toggle") then
                                if (forward_all_enabled == "true") then
                                        enabled = "false";
                                else
                                        enabled = "true";
                                end
                        end

                --get the forward destination
                        if (session:ready() and enabled == "true" or enabled == "toggle") then
                                forward_all_destination = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/ivr/ivr-enter_destination_telephone_number.wav", "", "\\d+");
                        end

                --set the dial string
                        if (session:ready() and enabled == "true") then
                                dial_string = "{presence_id="..forward_all_destination.."@"..domain_name;
                                dial_string = dial_string .. ",instant_ringback=true";
                                dial_string = dial_string .. ",domain_uuid="..domain_uuid;
                                dial_string = dial_string .. ",sip_invite_domain="..domain_name;
                                dial_string = dial_string .. ",domain_name="..domain_name;
                                dial_string = dial_string .. ",domain="..domain_name;
                                if (accountcode ~= nil) then
                                        dial_string = dial_string .. ",accountcode="..accountcode;
                                end
                                dial_string = dial_string .. "}";

                                cmd = "user_exists id ".. forward_all_destination .." "..domain_name;
                                user_exists = trim(api:executeString(cmd));
                                if (user_exists) then
                                        dial_string = dial_string .. "user/"..forward_all_destination.."@"..domain_name;
                                else
                                        dial_string = dial_string .. "loopback/"..forward_all_destination;
                                end
                        end

                --set call forward
                        if (session:ready() and enabled == "true") then
                                --set forward_all_enabled
                                        forward_all_enabled = "true";
                                --notify the caller
                                        session:streamFile(sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/ivr/ivr-call_forwarding_has_been_set.wav");
                        end

                --unset call forward
                        if (session:ready() and enabled == "false") then
                                --set forward_all_enabled
                                        forward_all_enabled = "false";
                                --notify the caller
                                        session:streamFile(sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/ivr/ivr-call_forwarding_has_been_cancelled.wav");
                        end

                --disable the follow me
                        if (session:ready() and enabled == "true") then
                                sql = "update v_follow_me set ";
                                sql = sql .. "follow_me_enabled = 'false' ";
                                sql = sql .. "where domain_uuid = '"..domain_uuid.."' ";
--                              sql = sql .. "and follow_me_uuid = 
'"..follow_me_uuid.."' ";
                                if (debug["sql"]) then
                                        freeswitch.consoleLog("notice", "[call_forward] "..sql.."\n");
                                end
                                dbh:query(sql);
                        end

                --update the extension
                        if (session:ready()) then
                                sql = "update v_extensions set ";
                                if (enabled == "true") then
                                        sql = sql .. "forward_all_destination = '"..forward_all_destination.."', ";
                                        sql = sql .. "dial_string = '"..dial_string.."', ";
                                        sql = sql .. "do_not_disturb = 'false', ";
                                else
                                        sql = sql .. "dial_string = null, ";
                                end
                                sql = sql .. "forward_all_enabled = '"..forward_all_enabled.."' ";
                                sql = sql .. "where domain_uuid = '"..domain_uuid.."' ";
                                sql = sql .. "and extension_uuid = '"..extension_uuid.."' ";
                                if (debug["sql"]) then
                                        freeswitch.consoleLog("notice", "[call_forward] "..sql.."\n");
                                end
                                dbh:query(sql);
                        end

                --clear the cache and hangup
                        if (session:ready()) then
                                --clear the cache
                                        if (extension ~= nil) then
                                                api:execute("memcache", "delete directory:"..extension.."@"..domain_name);
                                        end

                                --wait for the file to be written before proceeding
                                        session:sleep(100);

                                --end the call
                                        session:hangup();
                        end
        end

Original comment by scristop...@gmail.com on 5 Dec 2014 at 1:07

GoogleCodeExporter commented 9 years ago
root@fusion:/usr/local/freeswitch# diff ./scripts/call_forward.lua 
./scripts/call_forward.lua.bak
146c146
< --                                    follow_me_uuid = row.follow_me_uuid;
---
>                                       follow_me_uuid = row.follow_me_uuid;
205c205
<                       if (session:ready() and enabled == "true") then
---
>                       if (session:ready() and enabled == "true" and 
follow_me_uuid ~= nil) then
209c209
< --                            sql = sql .. "and follow_me_uuid = 
'"..follow_me_uuid.."' ";
---
>                               sql = sql .. "and follow_me_uuid = 
'"..follow_me_uuid.."' ";
248c248
<       end
---
>       end
\ No newline at end of file

Original comment by scristop...@gmail.com on 5 Dec 2014 at 1:12

GoogleCodeExporter commented 9 years ago
I don't have an up to date postgres install to test this on but is it possible 
that the original cause of the error is that the uuid is set to an empty string 
and should be set to NULL for the postgres uuid data type?

Original comment by Digitald...@gmail.com on 5 Dec 2014 at 1:35

GoogleCodeExporter commented 9 years ago
I'm not sure this is the proper way to fix this. If anyone has any insight on 
this I would appreciate it.

Original comment by scristop...@gmail.com on 5 Dec 2014 at 4:02

GoogleCodeExporter commented 9 years ago
The suggested fix should break follow me for anyone using it on a domain. The 
actual fix was completed a couple weeks ago. Lua scripts need to be updated.

Original comment by markjcrane@gmail.com on 5 Dec 2014 at 6:03

GoogleCodeExporter commented 9 years ago
not to be a pain but may want to make it so that it always promts for a 
destination, for me it doesnt after setting it once I had to clear it out of 
the gui to get the phone to prompt me to set a different call forward number. 
example - I would call *72 input call forward number - hang up test and it 
works. Dial *73 to disable, CF was disabled. Call *72 to set a destination - I 
get a message that call forwarding has been set. Check in the GUI and it was 
set to the last used destination. I edited the lua script to make it always 
prompt:

   144                  --get the forward destination
   145                          if (session:ready() and enabled == "true" or enabled == "toggle") then
   146  --This should always promt                            if (string.len(forward_all_destination) == 0) then
   147                                          forward_all_destination = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/ivr/ivr-enter_destination_telephone_number.wav", "", "\\d+");
   148  -- have to remove an end since we are removing an if.                             end
   149                          end

Original comment by scristop...@gmail.com on 5 Dec 2014 at 6:05

GoogleCodeExporter commented 9 years ago
or perhaps prompting to use the previous number if it exists is a good idea as 
well... 

i made a recording with a few merged freeswitch audio files that say to confirm 
push 1 to modify push 2, because i dont know how to add multiple files in lua. 
I changed the section to if the number is not 0 to play that file, gather the 
digits, if 1 then use previous entry if 2 ask for a new destination. This 
worked on my system (sorry its not very clean at the moment).

   144                  --get the forward destination
   145                          if (session:ready() and enabled == "true" or enabled == "toggle") then
   146  --                              if (string.len(forward_all_destination) == 0) then
   147  --                                      forward_all_destination = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/ivr/ivr-enter_destination_telephone_number.wav", "", "\\d+");
   148  --                              else
   149                                  if (string.len(forward_all_destination) ~= 0) then
   150                                          forward_clear_confirm  = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/ivr/ivr-to_confirm_modify.wav", "", "\\d+");
   151                                  if (forward_clear_confirm == "1") then
   152                                  forward_all_destination = forward_all_destination
   153                                  else
   154                                  if (forward_clear_confirm == "2") then
   155                                          forward_all_destination = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/ivr/ivr-enter_destination_telephone_number.wav", "", "\\d+");
   156                                          end
   157                                  end
   158                          end
   159                  end

Original comment by scristop...@gmail.com on 5 Dec 2014 at 9:09

GoogleCodeExporter commented 9 years ago
I'm really sorry for posting so much on this. I cleaned up the above code and 
realized I had commented out the option to ask for a destination if there was 
no entry currenly listed. As the same with above I am using a wav file I 
created with the freeswitch audio files that says to confirm push 1 to modify 
push 2. pushing 1 will use the previous call forward entry if it was ever used, 
pushing 2 will take the user to the default "enter destination number" which 
will allow you to enter a new destination to forward to. 

   144                  --get the forward destination
   145                          if (session:ready() and enabled == "true" or enabled == "toggle") then
   146                                  if (string.len(forward_all_destination) == 0) then
   147                                          forward_all_destination = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/ivr/ivr-enter_destination_telephone_number.wav", "", "\\d+");
   148                                  else
   149                                  if (string.len(forward_all_destination) ~= 0) then
   150                                          forward_clear_confirm  = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/ivr/ivr-to_confirm_modify.wav", "", "\\d+");
   151                                  if (forward_clear_confirm == "1") then
   152                                  forward_all_destination = forward_all_destination
   153                                  else
   154                                  if (forward_clear_confirm == "2") then
   155                                          forward_all_destination = session:playAndGetDigits(min_digits, max_digits, max_tries, digit_timeout, "#", sounds_dir.."/"..default_language.."/"..default_dialect.."/"..default_voice.."/ivr/ivr-enter_destination_telephone_number.wav", "", "\\d+");
   156                                          end
   157                                  end
   158                          end
   159                  end
   160          end

Original comment by scristop...@gmail.com on 5 Dec 2014 at 9:33