|
|
@@ -0,0 +1,378 @@ |
|
|
require("lsqlite3") |
|
|
|
|
|
-- Igmar: Wanneer closen we dat DB object eigenlijk ? |
|
|
db = sqlite3.open('/etc/asterisk/users.sqlite') |
|
|
|
|
|
--CONSOLE = "Console/dsp" -- Console interface for demo |
|
|
--CONSOLE = "DAHDI/1" |
|
|
--CONSOLE = "Phone/phone0" |
|
|
|
|
|
TRUNK = "DAHDI/G1" |
|
|
TRUNKMSD = 1 |
|
|
|
|
|
APIKEY = "oursecretapikey" |
|
|
|
|
|
-- The default comment is here |
|
|
|
|
|
function e_drop_call(context, entension) |
|
|
app.hangup(29) |
|
|
end |
|
|
|
|
|
function e_hotdesk_login(context, extension) |
|
|
-- Find out the peername |
|
|
name = channel.CALLERID("name"):get() |
|
|
peername = channel.CHANNEL("peername"):get() |
|
|
extension = string.sub(extension, 2) |
|
|
|
|
|
status = get_extension_status(extension) |
|
|
if status == false then |
|
|
app.Playback("acces-denied") |
|
|
app.Verbose(1, "Extension " .. extension .. " disabled") |
|
|
app.Hangup(29) |
|
|
end |
|
|
|
|
|
-- Already logged in ? |
|
|
location = extension_to_location(extension) |
|
|
if location ~= nil then |
|
|
app.Verbose(1, "Extension " .. extension .. " already logged in") |
|
|
app.Playback("agent-alreadyon") |
|
|
app.Hangup(29) |
|
|
return |
|
|
end |
|
|
|
|
|
app.Playback("please-enter-the&access-code") |
|
|
app.Verbose(1, "Logging in at the PBX context : " .. context .. " extension " .. extension .. " peername " .. peername) |
|
|
|
|
|
userstatus = "FALSE" |
|
|
userpin = get_extension_pin(extension) |
|
|
|
|
|
-- Ask the PIN |
|
|
app.Read("pin", "", 4) |
|
|
pin = channel["pin"]:get() |
|
|
|
|
|
if pin == userpin then |
|
|
app.Verbose(1, "PIN OK") |
|
|
-- Update the location field |
|
|
res, error = db:exec(string.format("UPDATE ast_users SET location = '%s' WHERE extension = %s", peername, extension)) |
|
|
if res > 0 then |
|
|
app.Verbose(1, string.format("UPDATE on ast_users failed : %d", res)) |
|
|
app.Hangup(29) |
|
|
return |
|
|
end |
|
|
app.Playback("agent-loginok") |
|
|
else |
|
|
app.Playback("acces-denied") |
|
|
app.Hangup(29) |
|
|
return |
|
|
end |
|
|
|
|
|
-- Put the user in the queue |
|
|
queue = get_extension_queue(extension) |
|
|
if queue ~= nil then |
|
|
app.Verbose(1, string.format("Adding member to queue : %s", queue)) |
|
|
app.AddQueueMember(queue) |
|
|
end |
|
|
end |
|
|
|
|
|
function e_hotdesk_logout(context, extension) |
|
|
name = channel.CALLERID("name"):get() |
|
|
peername = channel.CHANNEL("peername"):get() |
|
|
|
|
|
extension = location_to_extension(peername) |
|
|
if extension == nil then |
|
|
app.Verbose(1, "Location " .. peername .. " is not logged in") |
|
|
app.Hangup(29) |
|
|
return |
|
|
end |
|
|
|
|
|
app.Verbose(1, "Logging out at the PBX context : " .. context .. " extension " .. extension .. " peername " .. peername) |
|
|
|
|
|
res, error = db:exec(string.format("UPDATE ast_users SET location = null WHERE extension = %s", extension)) |
|
|
if res > 0 then |
|
|
app.Verbose(1, string.format("UPDATE on ast_users failed")) |
|
|
app.Hangup(29) |
|
|
return |
|
|
end |
|
|
|
|
|
app.Playback("agent-loggedoff") |
|
|
queue = get_extension_queue(extension) |
|
|
app.Verbose(1, string.format("Removing member from queue : %s", queue)) |
|
|
app.RemoveQueueMember(queue) |
|
|
app.Answer() |
|
|
end |
|
|
|
|
|
function e_outgoing_sip(context, extension) |
|
|
name = channel.CALLERID("name"):get() |
|
|
peername = channel.CHANNEL("peername"):get() |
|
|
|
|
|
app.Verbose("Called outgoing " .. extension .. " in context " .. context) |
|
|
|
|
|
-- Already logged in ? |
|
|
my_extension = location_to_extension(peername) |
|
|
if my_extension == nil then |
|
|
app.Verbose(1, "Location " .. peername .. " not logged in") |
|
|
app.Playback("acces-denied") |
|
|
app.Hangup(29) |
|
|
end |
|
|
|
|
|
app.Dial(TRUNK .. "/" .. extension) |
|
|
end |
|
|
|
|
|
|
|
|
function e_outgoing_emergency(context, extension) |
|
|
name = channel.CALLERID("name"):get() |
|
|
peername = channel.CHANNEL("peername"):get() |
|
|
|
|
|
app.Verbose("Emergency dial " .. extension .. " in context " .. context) |
|
|
|
|
|
app.Dial(TRUNK .. "/112") |
|
|
end |
|
|
|
|
|
function e_internal_sip(context, extension) |
|
|
app.Verbose("Called internal extension " .. extension .. " in context " .. context) |
|
|
-- Is this device logged on ? |
|
|
name = channel.CALLERID("name"):get() |
|
|
peername = channel.CHANNEL("peername"):get() |
|
|
callee = channel.CALLERID("num"):get() |
|
|
my_extension = nil |
|
|
|
|
|
app.Verbose(1, string.format("Device name : %s, callee %s", name, callee)) |
|
|
callee_extension = location_to_extension(callee) |
|
|
callee_name = location_to_name(callee) |
|
|
|
|
|
-- peername is nil on a direct call transfer. Handle this |
|
|
if peername ~= nil then |
|
|
-- What is my own extension number ? Find it. |
|
|
my_extension = location_to_extension(peername) |
|
|
if my_extension == nil then |
|
|
app.Verbose(1, "Location " .. peername .. " not logged in") |
|
|
app.Playback("acces-denied") |
|
|
app.Hangup(26) |
|
|
end |
|
|
|
|
|
if my_extension == extension then |
|
|
app.Verbose(1, "We called outselves. Bad") |
|
|
app.Playback("all-your-base") |
|
|
app.Hangup(26) |
|
|
end |
|
|
end |
|
|
|
|
|
dialed_location = extension_to_location(extension) |
|
|
if dialed_location == nil then |
|
|
app.Verbose(1, "Extension " .. extension .. " not active") |
|
|
app.Playback("extension&T-is-not-available") |
|
|
app.Hangup(20) |
|
|
return |
|
|
end |
|
|
|
|
|
if callee_extension ~= nil then |
|
|
app.Verbose(1, string.format("Callee extension : %s", callee_extension)); |
|
|
channel.CALLERID("all"):set(string.format("%s <%s>", callee_name, callee_extension)) |
|
|
end |
|
|
|
|
|
app.Dial("SIP/" .. dialed_location) |
|
|
end |
|
|
|
|
|
function e_dial_custnr(context, extension) |
|
|
peername = channel.CHANNEL("peername"):get() |
|
|
app.Verbose(1, string.format("Peername : %s", peername)) |
|
|
|
|
|
my_extension = location_to_extension(peername) |
|
|
if my_extension == nil then |
|
|
app.Verbose(1, "Location " .. peername .. " not logged in") |
|
|
app.Playback("acces-denied") |
|
|
app.Hangup(29) |
|
|
end |
|
|
|
|
|
local https = require('ssl.https') |
|
|
|
|
|
-- Ditch the initial * |
|
|
extension = string.sub(extension, 2) |
|
|
app.Verbose(1, "Entering dial_custnr_phone") |
|
|
-- Build the URL |
|
|
url = string.format("https://X.X.X.X/rest/?apikey=%s&cmd=custinfo&arg1=%s", APIKEY, extension) |
|
|
app.Verbose(1, string.format("Requesting %s", url)) |
|
|
r, c, h, s = https.request(url) |
|
|
for s1, s2 in string.gmatch(r, "([%w%s]+):([%w%s]+)") do |
|
|
name = s1 |
|
|
number = s2 |
|
|
end |
|
|
app.Verbose(1, string.format("Data for customer %s : %s %s", extension, name, number)) |
|
|
app.Dial(TRUNK .. "/" .. number) |
|
|
|
|
|
end |
|
|
|
|
|
function e_dial_employee(context, extension) |
|
|
peername = channel.CHANNEL("peername"):get() |
|
|
app.Verbose(1, string.format("Peername : %s", peername)) |
|
|
|
|
|
my_extension = location_to_extension(peername) |
|
|
if my_extension == nil then |
|
|
app.Verbose(1, "Location " .. peername .. " not logged in") |
|
|
app.Playback("acces-denied") |
|
|
app.Hangup(29) |
|
|
end |
|
|
|
|
|
local https = require('ssl.https') |
|
|
extension = string.sub(extension, 3) |
|
|
app.Verbose(1, string.format("Dialing employee %s", extension)) |
|
|
url = string.format("https://X.X.X.X/rest/?apikey=%s&cmd=emplinfo&arg1=%s", APIKEY, extension) |
|
|
app.Verbose(1, string.format("Requesting %s", url)) |
|
|
r, c, h, s = https.request(url) |
|
|
for s1, s2 in string.gmatch(r, "([%w%s]+):([%w%s]+)") do |
|
|
name = s1 |
|
|
number = s2 |
|
|
end |
|
|
app.Verbose(1, string.format("Data for employee %s : %s %s", extension, name, number)) |
|
|
app.Dial(TRUNK .. "/" .. number) |
|
|
end |
|
|
|
|
|
function e_incoming(context, extension) |
|
|
-- Check if we are open |
|
|
if in_office_hours() == false then |
|
|
app.Playback("/var/lib/asterisk/sounds/custom/beantwoorder") |
|
|
app.Hangup(16) |
|
|
end |
|
|
|
|
|
local https = require('ssl.https') |
|
|
callee = channel.CALLERID("num"):get() |
|
|
app.Verbose(1, string.format("Received call for %s from %s", extension, callee)) |
|
|
url = string.format("https://X.X.X.X/rest/?apikey=%s&cmd=numinfo&arg1=%s", APIKEY, callee) |
|
|
app.Verbose(1, string.format("Requesting %s", url)) |
|
|
r, c, h, s = https.request(url) |
|
|
name = nil |
|
|
number = callee |
|
|
for s1, s2 in string.gmatch(r, "([%w%s]+):([%w%s]+)") do |
|
|
name = s1 |
|
|
end |
|
|
if name == nil then |
|
|
name = "" |
|
|
end |
|
|
if number == nil then |
|
|
number = callee |
|
|
end |
|
|
channel.CALLERID("all"):set(string.format("%s <%s>", name, '0' .. number)) |
|
|
app.Queue("q1", "tTrn", "", "", 12) |
|
|
app.Queue("q2", "tTr", "", "", 28) |
|
|
app.Hangup(17) |
|
|
end |
|
|
|
|
|
|
|
|
-- Helper functions |
|
|
|
|
|
function extension_to_location(extension) |
|
|
for row in db:nrows(string.format("SELECT * FROM ast_users WHERE extension = '%s' LIMIT 1", extension)) do |
|
|
if row['location'] == nil then |
|
|
return nil |
|
|
end |
|
|
return string.format("%s", row['location']) |
|
|
end |
|
|
|
|
|
return nil |
|
|
end |
|
|
|
|
|
function location_to_extension(location) |
|
|
for row in db:nrows(string.format("SELECT * FROM ast_users WHERE location = '%s' LIMIT 1", location)) do |
|
|
if row['extension'] == nil then |
|
|
return nil |
|
|
end |
|
|
return string.format("%s", row['extension']) |
|
|
end |
|
|
|
|
|
return nil |
|
|
end |
|
|
|
|
|
function location_to_name(location) |
|
|
for row in db:nrows(string.format("SELECT * FROM ast_users WHERE location = '%s' LIMIT 1", location)) do |
|
|
if row['first_name'] == nil then |
|
|
return nil |
|
|
end |
|
|
return string.format("%s", row['first_name']) |
|
|
end |
|
|
|
|
|
return nil |
|
|
end |
|
|
|
|
|
function get_extension_status(extension) |
|
|
for row in db:nrows(string.format("SELECT * FROM ast_users WHERE extension = '%s' LIMIT 1", extension)) do |
|
|
if row['status'] == 1 then |
|
|
return true |
|
|
else |
|
|
return false |
|
|
end |
|
|
end |
|
|
end |
|
|
|
|
|
function get_extension_pin(extension) |
|
|
for row in db:nrows(string.format("SELECT * FROM ast_users WHERE extension = '%s' LIMIT 1", extension)) do |
|
|
return string.format("%s", row['pin']) |
|
|
end |
|
|
end |
|
|
|
|
|
function get_extension_queue(extension) |
|
|
for row in db:nrows(string.format("SELECT * FROM ast_users WHERE extension = '%s' LIMIT 1", extension)) do |
|
|
return string.format("%s", row['queue']) |
|
|
end |
|
|
end |
|
|
|
|
|
function in_office_hours() |
|
|
t = os.date("*t") |
|
|
|
|
|
-- Werkdagen + zaterdag en zondag |
|
|
if t['wday'] == 1 or t['wday'] == 7 or t['hour'] >= 17 or t['hour'] < 8 or (t['hour'] == 8 and t['min'] < 30) then |
|
|
return false |
|
|
end |
|
|
|
|
|
-- Koninginnedag |
|
|
if t['month'] == 4 and t['day'] == 30 then |
|
|
return false |
|
|
end |
|
|
|
|
|
-- Bevrijdingsdag |
|
|
if t['month'] == 5 and t['day'] == 5 then |
|
|
return false |
|
|
end |
|
|
|
|
|
-- Kerstdagen |
|
|
if t['month'] == 12 and t['day'] == 25 then |
|
|
return false |
|
|
end |
|
|
if t['month'] == 12 and t['day'] == 26 then |
|
|
return false |
|
|
end |
|
|
|
|
|
-- Oudejaarsdag |
|
|
if t['month'] == 12 and t['day'] == 31 then |
|
|
return false |
|
|
end |
|
|
|
|
|
return true |
|
|
end |
|
|
|
|
|
extensions = { |
|
|
-- Incoming calls |
|
|
["unauthenticated"] = { |
|
|
["_."] = e_drop_call |
|
|
}; |
|
|
|
|
|
["sipphones"] = { |
|
|
["_#NXX"] = e_hotdesk_login, |
|
|
["_#000"] = e_hotdesk_logout, |
|
|
["_0X."] = e_outgoing_sip, |
|
|
["_NXX"] = e_internal_sip, |
|
|
["112"] = e_outgoing_emergency, |
|
|
["911"] = e_outgoing_emergency, |
|
|
["_*."] = e_dial_custnr, |
|
|
["_**."] = e_dial_employee |
|
|
}; |
|
|
|
|
|
["bri-incoming"] = { |
|
|
["_X."] = e_incoming |
|
|
|
|
|
}; |
|
|
|
|
|
["default"] = { |
|
|
include = { "unauthenticated" } |
|
|
}; |
|
|
} |
|
|
|