We have been using waitforresult to try and wait for AMD to come back with something but we are having issues with it hanging (never returning from that) and locking up a license). We have also tried using the amd_execute_on_person command as it doesn't seem to be working. We originally had the script setup to run amd_execute_on_person but that was never hit and we would end up just waiting the full timeout each time before checking the result: (amd.lua) dst_number = session:getVariable("sip_to_user")
initial_wait = session:getVariable("ppamd_initial_wait") max_wait = session:getVariable("ppamd_max_wait") if not max_wait then max_wait = 3000 end while (session:ready() and not session:answered()) do -- Waiting for answer. session:sleep(500) -- freeswitch.msleep(500) end function on_finished(reason) if reason == nil then reason = "unspecified" end session:setVariable("ppamd_reason", reason) session:execute("transfer", "process_amd XML default") end if session:ready() and session:answered() then freeswitch.consoleLog("INFO", string.format("AMD Enable on %s.\n", dst_number)) if initial_wait then session:sleep(initial_wait) end local use_amd = api:executeString("amd_available") if use_amd == "true" then -- Be sure to set these variables. They will stop the wait and immediatly transfer the call if it gets a hit session:setVariable("amd_execute_on_machine", "transfer amd_machine_detected XML default") session:setVariable("amd_execute_on_person", "transfer amd_person_detected XML default") session:setVariable("amd_execute_on_unsure", "transfer amd_unsure_detected XML default") session:execute("voice_start") -- Giving some time to AMD to work on the call. -- If a voicemail is detected, it will auto-transfer from the variables that are set. session:sleep(max_wait) local amd_finished_called = session:getVariable("amd_finished_called") if amd_finished_called == 'true' then freeswitch.consoleLog("INFO", string.format("AMD Finish script already called!\n")) else -- NOTE: Hopefully this never gets called as the module should auto transfer this freeswitch.consoleLog("INFO", string.format("AMD Timeout reached for vmd: %s\n", max_wait)) session:execute("voice_stop") local amd_detect = session:getVariable("amd_status") freeswitch.consoleLog("INFO", string.format("AMD amd_status: %s\n", amd_detect)) on_finished(amd_detect) end else freeswitch.consoleLog("WARNING", string.format("AMD not available for %s\n", dst_number)) on_finished("unavailable") end else freeswitch.consoleLog("WARNING", string.format("AMD Failed to run %s\n", dst_number)) on_finished("failure") return end
the amd_execute_on_XXX does not seem to do anything... The sleep would always max out and we would always hit the Timeout reached part of the script instead of getting transferred. After that didn't work because we would always wait the sleep time (3 seconds) we scrapped transfers and tried handling the whole thing through a single lua script using waitforresult: DEFAULT_MAX_WAIT = 3000 -- in (ms)
DEFAULT_INITIAL_WAIT = 100 -- in (ms) HUMAN_EXTENSION = "amd_queue" UNSURE_EXTENSION = "amd_queue" api = freeswitch.API()
dst_number = session:getVariable("sip_to_user") initial_wait = session:getVariable("ppamd_initial_wait") or DEFAULT_INITIAL_WAIT max_wait = session:getVariable("ppamd_max_wait") or DEFAULT_MAX_WAIT
while (session:ready() and not session:answered()) do session:sleep(500) end
freeswitch.consoleLog("INFO", string.format("AMD Attempting on %s. \n", dst_number)) if initial_wait then session:sleep(initial_wait) end
if session:ready() and session:answered() then local use_amd = api:executeString("amd_available") if use_amd == "true" then freeswitch.consoleLog("INFO", string.format("AMD Available Max Wait: %s, Initial Wait %s. \n", max_wait, initial_wait)) -- Allow AMD to run and analyze. freeswitch.consoleLog("INFO", "AMD Voice start. \n") session:execute("voice_start") freeswitch.consoleLog("INFO", "AMD Wait for result. \n") session:execute("waitforresult", string.format("%s", max_wait)) freeswitch.consoleLog("INFO", "AMD Voice stop. \n") session:execute("voice_stop") amd_detect = session:getVariable("amd_status") freeswitch.consoleLog("INFO", string.format("AMD Result: %s. \n", amd_detect)) if amd_detect == "machine" then freeswitch.consoleLog("INFO", "AMD Detected machine. \n") session:hangup() return elseif amd_detect == "person" then freeswitch.consoleLog("INFO", "AMD Detected human, transfering call. \n") session:execute("transfer", string.format("%s XML default", HUMAN_EXTENSION)) return else freeswitch.consoleLog("INFO", string.format("AMD Unknown: %s. \n", amd_detect)) session:execute("transfer", string.format("%s XML default", UNSURE_EXTENSION)) return end end else freeswitch.consoleLog("INFO", "AMD not enabled. \n") session:execute("transfer", string.format("%s XML default", UNSURE_EXTENSION)) return end
I prefer not having to do all that transferring around but to just run with waitforresult but it never comes back... The dialplan extensions just connect the call to an agent. Once we do the transfer it all works. The only problem is we have to replace the: session:execute("waitforresult", string.format("%s", max_wait)) with a sleep so no matter if the mod_com_amd detects its a person or not we ALWAYS have to wait the full sleep time. This is not really legal as we would be essentially abandoning every single call... Any thoughts on what we may be missing or how we could improve this?