summaryrefslogtreecommitdiff
path: root/misc/freeswitch/scripts/dialplan/voicemail.lua
blob: ae7d0a16cbcc8e94e4bb61186d121f1843f96ccd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
-- Gemeinschaft 5 module: voicemail class
-- (c) AMOOMA GmbH 2012-2013
-- 

module(...,package.seeall)

Voicemail = {}

MESSAGE_LENGTH_MIN = 3;
MESSAGE_LENGTH_MAX = 120;
SILENCE_LENGTH_ABORT = 5;
SILENCE_LEVEL = 500;
BEEP = 'tone_stream://%(1000,0,500)';
RECORD_FILE_PREFIX = '/var/spool/freeswitch/voicemail_';

-- create voicemail object
function Voicemail.new(self, arg)
  arg = arg or {}
  object = arg.object or {}
  setmetatable(object, self);
  self.__index = self;
  self.class = 'voicemail';
  self.log = arg.log;
  self.database = arg.database;
  self.record = arg.record;
  return object
end

-- find voicemail account by sip account id
function Voicemail.find_by_sip_account_id(self, id)
  local sql_query = 'SELECT `a`.`id`, `a`.`uuid`, `a`.`auth_name`, `a`.`caller_name`, `b`.`name_path`, `b`.`greeting_path`, `a`.`voicemail_pin`, `b`.`password`, `c`.`host` AS `domain` \
    FROM `sip_accounts` `a` LEFT JOIN `voicemail_prefs` `b` ON `a`.`auth_name` = `b`.`username` \
    JOIN `sip_domains` `c` ON `a`.`sip_domain_id` = `c`.`id` \
    WHERE `a`.`id` = ' .. tonumber(id);

  local voicemail_account = nil;
  self.database:query(sql_query, function(entry)
    voicemail_account = Voicemail:new(self);
    voicemail_account.record = entry;
    voicemail_account.id = tonumber(entry.id);
    voicemail_account.uuid = entry.uuid;
  end)

  return voicemail_account;
end

-- Find Voicemail account by name
function Voicemail.find_by_name(self, account_name)
  id = tonumber(id) or 0;
  local sql_query = string.format('SELECT * FROM `voicemail_prefs` WHERE `username`= "%s" LIMIT 1', account_name)
  local record = nil

  self.database:query(sql_query, function(voicemail_entry)
    record = voicemail_entry
  end)

  if voicemail_account then
    voicemail_account.account_name = account_name;
    if record then
      voicemail_account.name_path = record.name_path;
      voicemail_account.greeting_path = record.greeting_path;
      voicemail_account.password = record.password;
    end
  end

  return voicemail_account
end

-- Find Voicemail account by name
function Voicemail.find_by_number(self, phone_number)
  local sip_account = nil;

  require "common.phone_number"
  local phone_number_class = common.phone_number.PhoneNumber:new{ log = self.log, database = self.database };
  local destination_number_object = phone_number_class:find_by_number(phone_number);
  if destination_number_object and destination_number_object.record.phone_numberable_type == "SipAccount" then
    return Voicemail:find_by_sip_account_id(destination_number_object.record.phone_numberable_id);
  end

  return false;
end


function Voicemail.leave(self, caller, phone_number)
  require 'common.str'

  self.log:info('VOICEMAIL_LEAVE - account=', self.record.id, '/', self.record.uuid, ', auth_name: ', self.record.auth_name, ', caller_name: ', self.record.caller_name);

  caller:set_callee_id(phone_number, self.record.caller_name);
  caller:answer();
  caller:send_display(common.str.to_s(self.record.caller_name), common.str.to_s(phone_number));
  caller:sleep(1000);

  if not common.str.blank(self.record.greeting_path) then
    caller.session:sayPhrase('voicemail_play_greeting', 'greeting:' .. tostring(self.record.greeting_path));
  elseif not common.str.blank(self.record.name_path) then
    caller.session:sayPhrase('voicemail_play_greeting', 'name:' .. tostring(self.record.name_path));
  elseif not common.str.blank(phone_number) then
    caller.session:sayPhrase('voicemail_play_greeting', (tostring(phone_number):gsub('[%D]', '')));
  end

  local record_file_name = RECORD_FILE_PREFIX .. caller.uuid .. '.wav';
  caller.session:streamFile(BEEP);
  self.log:info('VOICEMAIL_LEAVE - recording to file: ', tostring(record_file_name));
  local result = caller.session:recordFile(record_file_name, MESSAGE_LENGTH_MAX, SILENCE_LEVEL, SILENCE_LENGTH_ABORT);
  local duration = caller:to_i('record_seconds');

  if duration >= MESSAGE_LENGTH_MIN then   
    self.log:info('VOICEMAIL_LEAVE - saving recorded message to voicemail, duration: ', duration);
    require 'common.fapi'
    common.fapi.FApi:new{ log = self.log, uuid = caller.uuid }:execute('vm_inject', 
      self.record.auth_name .. 
      '@' .. self.record.domain .. " '" .. 
      record_file_name .. "' '" .. 
      caller.caller_id_number .. "' '" .. 
      caller.caller_id_name .. "' '" ..
      caller.uuid .. "'"
    );
    caller:set_variable('voicemail_message_len', duration);
    self:trigger_notification(caller);
  else
    caller:set_variable('voicemail_message_len');
  end 
  os.remove(record_file_name);
  return true;
end


function Voicemail.trigger_notification(self, caller)
  local command = 'http_request.lua ' .. caller.uuid .. ' http://127.0.0.1/trigger/voicemail?sip_account_id=' .. tostring(self.id);

  require 'common.fapi'
  return common.fapi.FApi:new():execute('luarun', command);
end


function Voicemail.menu(self, caller, authorized)
  self.log:info('VOICEMAIL_MENU - account: ', self.record.auth_name);

  if authorized then
    caller:set_variable('voicemail_authorized', true);
  end

  caller:set_callee_id(phone_number, self.record.caller_name);
  caller:answer();
  caller:send_display(common.str.to_s(self.record.caller_name), common.str.to_s(phone_number));

  caller:sleep(1000);
  caller:set_variable('skip_greeting', true);
  caller:set_variable('skip_instructions', true);
  
  caller:execute('voicemail', 'check default ' .. self.record.domain .. ' ' .. self.record.auth_name);
end