Skip to main content

Lua Group Pickup example

About​

We will try in this example to simulate group pickup as in Asterisk.

How it works​

The theory is that you put users in the groups table specifying the group_id they belongs. Then somebody can dial *4 and pickup the first call ringing in the group to which the caller belongs

The active_uuid table is a FIFO queue.

First: Create a sqlite3 DB as:

sqlite3 /opt/freeswitch/db/group_pickup.db
sqlite3> create table active_uuid(time_id bigint primary key, group_id varchar(32), uuid varchar(60));
sqlite3> create table groups(user varchar(32) primary key, group_id varchar(32));
sqlite3> .exit

Then add this extension to default.xml before extension global:

<extension name="intercept-group">
<condition field="destination_number" expression="^\*4$">
<action application="answer"/>
<action application="lua" data="pickup_group_uuid.lua ${callerid_number}"/>
<action application="intercept" data="${g_uuid}"/>
<action application="sleep" data="2000"/>
</condition>
</extension>

Inside '<extension name="global" continue="true">' add:

    <condition>
<anti-action application="lua" data="add_group_uuid.lua ${uuid} ${dialed_ext}"/>
<anti-action application="set" data="api_hangup_hook=lua del_group_uuid.lua ${uuid}"/>
<anti-action application="set" data="execute_on_answer=lua del_group_uuid.lua ${uuid}"/>
</condition>

Then create these scripts a nd put then in scripts folder.

Script: add_group_uuid.lua

--
-- add_group_uuid.lua
-- This script insert uuid into a FIFO queue to be retrieved on pickup
--

require "luasql.sqlite3";

env = assert (luasql.sqlite3());
con = assert (env:connect("/opt/freeswitch/db/group_pickup.db"));

local uuid = argv[1];
local called = argv[2];

-- retrieve called's group
cur = assert (con:execute(string.format("SELECT group_id from groups where user='%s'", called)));
row = cur:fetch({}, "a");

local group_id = row.group_id;

if (group_id ~= nil) then
freeswitch.consoleLog("info", "\n--- CALLED PARTY => " .. called .. " , GROUP = " .. group_id .. ", UUID = " .. uuid .. " ---\n")

-- insert data
res = assert (con:execute(string.format("INSERT INTO active_uuid VALUES(julianday('now'),'%s','%s')", group_id, uuid)));
end

-- close all
cur:close();
con:close();
env:close();

Script: del_group_uuid.lua

-- del_group_uuid.lua
-- Delete the uuid from the FIFO when the call is answered or abandoned
--

require "luasql.sqlite3";

env = assert (luasql.sqlite3());
con = assert (env:connect("/opt/freeswitch/db/group_pickup.db"));

local uuid = argv[1];

-- delete uuid from table
res = assert (con:execute(string.format("DELETE FROM active_uuid where uuid='%s'", uuid)));

freeswitch.consoleLog("info", "\n--- GROUP PIKCUP UUID: " .. uuid .. " DELETED ---\n")

-- close all
con:close();
env:close();

Script: pickup_group_uuid.lua

-- 
-- pickup_group_uuid.lua
--
-- This script get the first call ringing in the queue db for the group
--

require "luasql.sqlite3";

env = assert (luasql.sqlite3());
con = assert (env:connect("/opt/freeswitch/db/group_pickup.db"));

local caller = session:getVariable("effective_caller_id_number")

-- retrieve called's group
cur = assert (con:execute(string.format("SELECT group_id from groups where user='%s'", caller)));
row = cur:fetch({}, "a");

local group_id = row.group_id;
cur:close();

if (group_id ~= nil) then
freeswitch.consoleLog("info", "\n--- CALLER PARTY => " .. caller .. " , GROUP = " .. group_id .. " ---\n")
-- retrieve first waiting uuid from active_uuid for this group_id
cur = assert (con:execute(string.format("SELECT uuid from active_uuid where group_id = '%s' order by time_id desc limit 1", group_id)));
row = cur:fetch ({}, "a");
if (row ~= nil) then
local uuid = row.uuid;
session:setVariable("g_uuid", uuid);
res = assert (con:execute(string.format("DELETE FROM active_uuid where uuid = '%s'", uuid)));
end
end

-- close all
cur:close();
con:close();
env:close();