Initiate call from Lua

Hi.

I’m using FreeSwitch as a client registered to an external PBX. I can make and receive calls, and it’s Subscribed to Presence notifications, so I can get Events triggered when an extension on the external PBX changes state (“on the phone”, “ringing”, “ready”, etc).

I’ve created an Event Hook in Lua which responds to Presence Notifications, and this is currently just sending Log entries so I can see when the state of external extensions has changed. It’s working nicely.

Now I want to initial a call in FreeSwitch when an extension changes from “on the phone” to “ready”. It’s not clear to me how, in Lua, I can initiate a call.

Lua API Reference | FreeSWITCH Documentation suggests to me that I need to create a “Session”,

I need to pass some data from the Event Hook to the Dialplan, so once I have a Session in progress I assume I use session:setVariable to do that: Lua API Reference | FreeSWITCH Documentation

I’ve looked up FreeSwitch Sessions and found Session | FreeSWITCH Documentation but I’m still not quite sure about things like “at what point does the call actually get placed to the person who needs to answer it?”

So:

  1. Am I going in the right direction with this, thinking that I need to create a Session in Lua, which can then cause a call to be placed in the dialplan, or should I be going about this some completely other way?

  2. How does the timing of creating a Session, using setVariable, and actually placing the call (which uses some of the variable values) work together?

If anyone can point me at documented examples of how this should be done (I’ve looked, but been unable to find anything) that would be a great start.

Thanks,

Antony.

Depends what are you doing exactly and where are you doing these hooks? You can hook into events in lua.conf.xml and never bother the session.

/b

I have indeed created a hook in lua.conf.xml:

<hook event="NOTIFY_IN" script="Events.lua"/>

This calls my script Events.lua, which currently uses freeswitch.consoleLog to
show me that it’s got the right data and can parse it the way I need.

Now I need it to place a phone call to someone.

If you need detail of what I’m doing and why:

  • someone places a call which is for a number (“extension”) on the external
    PBX which happens to be busy at the time

  • the Lua script receives a Notify_in Event when the Presence Notification
    comes in from the external PBX saying that the extension is no longer busy

  • the script then needs to cause a call to be placed, not to the number which
    originally tried to place the call (so a simple “camp on” function won’t do
    what I want), but instead to a number which points at a queue, so the first
    agent in the queue able to take the call gets it and can deal with it.

What is the best way to get a Lua script to initiate a call? There is no
requirement for any audio; this simply needs to go to a standard SIP
telephone, with special Caller ID name and number, telling the person what
they need to do (hence the requirement for the Lua script to pass variables
into the dialplan before it makes the call).

I hope that explains in sufficient detail.

Antony.

Hi.

Did the additional detail I provided give enough context for someone to be
able to suggest whether I’m going about this the right way, and how I can get
Lua to initiate a call?

I simply find the documentation about freeswitch.Session, for example, rather
lacking in detail or examples, to show me how it should be used in practice.

Antony.

You’ll just use the API object and originate a call… do you know all the details such as the endpoint you need to call, its URL?

/b

Hi Brian

How can we pass the variable in argv[1] when we are sending the api request from postman to run the LUA bridge script.

Show me what you’re trying to do first so I can give you the right answer.

Basicall I trying to merege two call using bridge functionality. Calling First number after connected to first number calling to second number and once second number is connected trying to merge them using below lua script.

Now I need to pass value of argv[1] and argv[2] via postman using below api link

http://X.X.X.X:8080/txtapi/lua?portal/jal5.lua

as of now it is working for hardcoded value as mentioned in the script but same we have to send dynamic number via api for outbound calling purpose.

Do you have any idea how to achieve the same ?

uuid = 123456789;
dialstr1 = argv[1] Need to pass this from postman in variable—>“sofia/gateway/audiocode/1298XXXXXXXXX”;
dialstr2 = argv[2] Need to pass this from postman in variable—>“sofia/gateway/audiocode/1298XXXXXXXXX”;
max_retriesl1 = 1;
max_retriesl2 = 1;
connected = false;
timeout = 45;
local sessionOneAnswered = false
freeswitch.consoleLog(“notice”, “*********** STARTING Call \n");
freeswitch.consoleLog(“notice”, "
DIALING “…dialstr1…” \n");
originate_base1 = “{ignore_early_media=true,originate_timeout=90,hangup_after_bridge=true,uuid=”…uuid…“,leg=1}”;
originate_str1 = originate_base1…dialstr1;
session1 = null;
session2 = null;
session = null;
retries = 0;
ostr = “”;
repeat
retries = retries + 1;
if (retries % 2) then
ostr = originate_str1;
end
freeswitch.consoleLog(“notice”, "
Dialing Leg1: " … ostr … " - Try: “…retries…” \n");
session1 = freeswitch.Session(ostr);
local hcause = session1:hangupCause();
freeswitch.consoleLog(“notice”, "
Leg1: " … hcause … " - Try: “…retries…” \n");
until not ((hcause == ‘NO_ROUTE_DESTINATION’ or hcause == ‘RECOVERY_ON_TIMER_EXPIRE’ or hcause == ‘INCOMPATIBLE_DESTINATION’ or hcause == ‘CALL_REJECTED’ or hcause == ‘NORMAL_TEMPORARY_FAILURE’) and (retries < max_retriesl1))
if (session1:ready()) then
– log to the console
freeswitch.consoleLog(“notice”, "
Leg1 (”…ostr…“) CONNECTED! ***********\n”);
session1:setVariable(“ringback”, “%(2000,4000,440,480)”);
end

for j = 1, 35 do
freeswitch.consoleLog(“info”, “+++++++++++++++++in loop ++++++++++” … j)

freeswitch.msleep(1000)
if session1:answered() then
freeswitch.consoleLog(“info”, “+++++++++++++++++inside if ++++++++++” … j)
sessionOneAnswered = true

    break ;

elseif (session1:hangupCause() == "USER_BUSY") then

   break ;	
end

end

if (sessionOneAnswered) then
session1:setVariable(“ringback”, “%(2000,4000,440,480)”);

session1:setVariable(“RECORD_STEREO”, “true”);
session1:execute(“record_session”, “C:/Users/Administrator/Downloads/recordings/external/”…dialstr1…“.mp3”);

– Create session2

originate_base2 = “{ignore_early_media=true,originate_timeout=90,hangup_after_bridge=true,uuid=”…uuid…“,leg=2}”;
originate_str2 = originate_base2…dialstr2;
ostr2 = originate_str2
freeswitch.consoleLog(“notice”, “*********** Dialing: " … ostr2 … " Try: “…retries…” ***********\n”);

    session2 = freeswitch.Session(ostr2, session1);

    local hcause = session2:hangupCause();

   freeswitch.consoleLog("notice", "*********** Leg2: " .. hcause .. " Try: " .. retries .. " ***********\n");
 

if (session2:ready()) then

    freeswitch.consoleLog("notice", "*********** Leg2 ("..ostr2..") CONNECTED! ***********\n");

    freeswitch.bridge(session1, session2);

    -- session2 if session1 is over

    if (session2:ready()) then 
     freeswitch.consoleLog("notice", "***********session2 disconnected*********")
        session2:hangup(); 
    end

end
-- hangup when done

end
if (session1:ready()) then
freeswitch.consoleLog(“notice”, “**session1 disconnected”)
session1:hangup(); end
–end