· 9 years ago · Dec 02, 2016, 07:50 PM
1-- sms.lua
2-- Part of FusionPBX
3-- Copyright (C) 2010 Mark J Crane <markjcrane@fusionpbx.com>
4-- All rights reserved.
5--
6-- Redistribution and use in source and binary forms, with or without
7-- modification, are permitted provided that the following conditions are met:
8--
9-- 1. Redistributions of source code must retain the above copyright notice,
10-- this list of conditions and the following disclaimer.
11--
12-- 2. Redistributions in binary form must reproduce the above copyright
13-- notice, this list of conditions and the following disclaimer in the
14-- documentation and/or other materials provided with the distribution.
15--
16-- THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
17-- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
18-- AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19-- AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
20-- OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25-- POSSIBILITY OF SUCH DAMAGE.
26
27--connect to the database
28 require "resources.functions.database_handle";
29 dbh = database_handle('system');
30
31--debug
32 debug["info"] = true;
33 debug["sql"] = true;
34
35--set the api
36 api = freeswitch.API();
37
38--define uuid function
39 local random = math.random;
40 local function uuid()
41 local template ='xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx';
42 return string.gsub(template, '[xy]', function (c)
43 local v = (c == 'x') and random(0, 0xf) or random(8, 0xb);
44 return string.format('%x', v);
45 end)
46 end
47
48--get the argv values
49 script_name = argv[0];
50 direction = argv[2];
51
52 if (debug["info"]) then
53 freeswitch.consoleLog("notice", "[sms] DIRECTION: " .. direction .. "\n");
54 freeswitch.consoleLog("info", "chat console\n");
55 end
56
57 if direction == "inbound" then
58 to = argv[3];
59 from = argv[4];
60 body = argv[5];
61 domain_name = string.match(to,'%@+(.+)');
62 extension = string.match(to,'%d+');
63
64 if (debug["info"]) then
65 freeswitch.consoleLog("notice", "[sms] DIRECTION: " .. direction .. "\n");
66 freeswitch.consoleLog("notice", "[sms] TO: " .. to .. "\n");
67 freeswitch.consoleLog("notice", "[sms] Extension: " .. extension .. "\n");
68 freeswitch.consoleLog("notice", "[sms] FROM: " .. from .. "\n");
69 freeswitch.consoleLog("notice", "[sms] BODY: " .. body .. "\n");
70 freeswitch.consoleLog("notice", "[sms] DOMAIN_NAME: " .. domain_name .. "\n");
71 end
72
73 local event = freeswitch.Event("CUSTOM", "SMS::SEND_MESSAGE");
74 event:addHeader("proto", "sip");
75 event:addHeader("dest_proto", "sip");
76 event:addHeader("from", "sip:" .. from);
77 event:addHeader("from_user", from);
78 event:addHeader("from_host", domain_name);
79 event:addHeader("from_full", "sip:" .. from);
80 event:addHeader("sip_profile","internal");
81 event:addHeader("to", to);
82 event:addHeader("to_user", extension);
83 event:addHeader("to_host", domain_name);
84 event:addHeader("subject", "SIMPLE MESSAGE");
85 event:addHeader("type", "text/plain");
86 event:addHeader("hint", "the hint");
87 event:addHeader("replying", "true");
88 event:addHeader("DP_MATCH", to);
89 event:addBody(body);
90
91 if (debug["info"]) then
92 freeswitch.consoleLog("info", event:serialize());
93 end
94 event:fire();
95 to = extension;
96 elseif direction == "outbound" then
97 if (argv[3] ~= nil) then
98 to_user = argv[3];
99 to = string.match(to_user,'%d+');
100 else
101 to = message:getHeader("to_user");
102 end
103 if (argv[3] ~= nil) then
104 domain_name = string.match(to_user,'%@+(.+)');
105 else
106 domain_name = message:getHeader("from_host");
107 end
108 if (argv[4] ~= nil) then
109 from = argv[4];
110 extension = string.match(from,'%d+');
111 if extension:len() > 7 then
112 outbound_caller_id_number = extension;
113 end
114 else
115 from = message:getHeader("from_user");
116 end
117 if (argv[5] ~= nil) then
118 body = argv[5];
119 else
120 body = message:getBody();
121 end
122
123 if (debug["info"]) then
124 if (message ~= nil) then
125 freeswitch.consoleLog("info", message:serialize());
126 end
127 freeswitch.consoleLog("notice", "[sms] DIRECTION: " .. direction .. "\n");
128 freeswitch.consoleLog("notice", "[sms] TO: " .. to .. "\n");
129 freeswitch.consoleLog("notice", "[sms] FROM: " .. from .. "\n");
130 freeswitch.consoleLog("notice", "[sms] BODY: " .. body .. "\n");
131 freeswitch.consoleLog("notice", "[sms] DOMAIN_NAME: " .. domain_name .. "\n");
132 end
133
134 if (domain_uuid == nil) then
135 --get the domain_uuid using the domain name required for multi-tenant
136 if (domain_name ~= nil) then
137 sql = "SELECT domain_uuid FROM v_domains ";
138 sql = sql .. "WHERE domain_name = '" .. domain_name .. "' and domain_enabled = 'true' ";
139 if (debug["sql"]) then
140 freeswitch.consoleLog("notice", "[sms] SQL: " .. sql .. "\n");
141 end
142 status = dbh:query(sql, function(rows)
143 domain_uuid = rows["domain_uuid"];
144 end);
145 end
146 end
147 freeswitch.consoleLog("notice", "[sms] DOMAIN_UUID: " .. domain_uuid .. "\n");
148 if (outbound_caller_id_number == nil) then
149 --get the outbound_caller_id_number using the domain_uuid and the extension number
150 if (domain_uuid ~= nil) then
151 sql = "SELECT outbound_caller_id_number, extension_uuid, carrier FROM v_extensions ";
152 sql = sql .. ", v_sms_destinations ";
153 sql = sql .. "WHERE outbound_caller_id_number = destination and ";
154 sql = sql .. "v_extensions.domain_uuid = '" .. domain_uuid .. "' and extension = '" .. from .."' and ";
155 sql = sql .. "v_sms_destinations.enabled = 'true' and ";
156 sql = sql .. "v_extensions.enabled = 'true'";
157
158 if (debug["sql"]) then
159 freeswitch.consoleLog("notice", "[sms] SQL: " .. sql .. "\n");
160 end
161 status = dbh:query(sql, function(rows)
162 outbound_caller_id_number = rows["outbound_caller_id_number"];
163 extension_uuid = rows["extension_uuid"];
164 carrier = rows["carrier"];
165 end);
166 end
167 elseif (outbound_caller_id_number ~= nil) then
168 --get the outbound_caller_id_number using the domain_uuid and the extension number
169 if (domain_uuid ~= nil) then
170 sql = "SELECT carrier FROM ";
171 sql = sql .. " v_sms_destinations ";
172 sql = sql .. "WHERE destination = '" .. from .. "' and ";
173 sql = sql .. "v_sms_destinations.domain_uuid = '" .. domain_uuid .. "' and ";
174 sql = sql .. "enabled = 'true'";
175 if (debug["sql"]) then
176 freeswitch.consoleLog("notice", "[sms] SQL: " .. sql .. "\n");
177 end
178 status = dbh:query(sql, function(rows)
179 carrier = rows["carrier"];
180 end);
181 end
182 end
183
184 sql = "SELECT default_setting_value FROM v_default_settings ";
185 sql = sql .. "where default_setting_category = 'sms' and default_setting_subcategory = '" .. carrier .. "_access_key'";
186 if (debug["sql"]) then
187 freeswitch.consoleLog("notice", "[sms] SQL: " .. sql .. "\n");
188 end
189 status = dbh:query(sql, function(rows)
190 access_key = rows["default_setting_value"];
191 end);
192
193 sql = "SELECT default_setting_value FROM v_default_settings ";
194 sql = sql .. "where default_setting_category = 'sms' and default_setting_subcategory = '" .. carrier .. "_secret_key'";
195 if (debug["sql"]) then
196 freeswitch.consoleLog("notice", "[sms] SQL: " .. sql .. "\n");
197 end
198 status = dbh:query(sql, function(rows)
199 secret_key = rows["default_setting_value"];
200 end);
201
202 sql = "SELECT default_setting_value FROM v_default_settings ";
203 sql = sql .. "where default_setting_category = 'sms' and default_setting_subcategory = '" .. carrier .. "_api_url'";
204 if (debug["sql"]) then
205 freeswitch.consoleLog("notice", "[sms] SQL: " .. sql .. "\n");
206 end
207 status = dbh:query(sql, function(rows)
208 api_url = rows["default_setting_value"];
209 end);
210
211 if (carrier == "flowroute") then
212 cmd = "curl -u ".. access_key ..":" .. secret_key .. " -H \"Content-Type: application/json\" -X POST -d '{\"to\":\"" .. to .. "\",\"from\":\"" .. outbound_caller_id_number .."\",\"body\":\"" .. body .. "\"}' " .. api_url;
213 elseif (carrier == "twilio") then
214 if to:len() < 11 then
215 to = "1" .. to;
216 end
217 if outbound_caller_id_number:len() < 11 then
218 outbound_caller_id_number = "1" .. outbound_caller_id_number;
219 end
220 -- Can be either +1NANNNNXXXX or NANNNNXXXX
221 cmd ="curl -X POST '" .. api_url .."' --data-urlencode 'To=+" .. to .."' --data-urlencode 'From=+" .. outbound_caller_id_number .. "' --data-urlencode 'Body=" .. body .. "' -u ".. access_key ..":" .. secret_key .. " --insecure";
222 elseif (carrier == "teli") then
223 cmd ="curl -X POST '" .. api_url .."' --data-urlencode 'destination=" .. to .."' --data-urlencode 'source=" .. outbound_caller_id_number .. "' --data-urlencode 'message=" .. body .. "' --data-urlencode 'token=" .. access_key .. "' --insecure";
224 elseif (carrier == "plivo") then
225 if to:len() <11 then
226 to = "1"..to;
227 end
228 cmd="curl -i --user " .. access_key .. ":" .. secret_key .. " -H \"Content-Type: application/json\" -d '{\"src\": \"" .. outbound_caller_id_number .. "\",\"dst\": \"" .. to .."\", \"text\": \"" .. body .. "\"}' " .. api_url;
229 elseif (carrier == "bandwidth") then
230 if to:len() <11 then
231 to = "1"..to;
232 end
233 if outbound_caller_id_number:len() < 11 then
234 outbound_caller_id_number = "1" .. outbound_caller_id_number;
235 end
236 cmd="curl -v -X POST " .. api_url .." -u " .. access_key .. ":" .. secret_key .. " -H \"Content-type: application/json\" -d '{\"from\": \"+" .. outbound_caller_id_number .. "\", \"to\": \"+" .. to .."\", \"text\": \"" .. body .."\"}'"
237
238 end
239 if (debug["info"]) then
240 freeswitch.consoleLog("notice", "[sms] CMD: " .. cmd .. "\n");
241 end
242 local handle = io.popen(cmd)
243 local result = handle:read("*a")
244 handle:close()
245 if (debug["info"]) then
246 freeswitch.consoleLog("notice", "[sms] CURL Returns: " .. result .. "\n");
247 end
248-- os.execute(cmd)
249
250 end
251
252--write message to DB
253
254 if (domain_uuid == nil) then
255 --get the domain_uuid using the domain name required for multi-tenant
256 if (domain_name ~= nil) then
257 sql = "SELECT domain_uuid FROM v_domains ";
258 sql = sql .. "WHERE domain_name = '" .. domain_name .. "' ";
259 if (debug["sql"]) then
260 freeswitch.consoleLog("notice", "[voicemail] SQL: " .. sql .. "\n");
261 end
262 status = dbh:query(sql, function(rows)
263 domain_uuid = rows["domain_uuid"];
264 end);
265 end
266 end
267 if (extension_uuid == nil) then
268 --get the extension_uuid using the domain_uuid and the extension number
269 if (domain_uuid ~= nil) then
270 sql = "SELECT extension_uuid FROM v_extensions ";
271 sql = sql .. "WHERE domain_uuid = '" .. domain_uuid .. "' and extension = '" .. extension .."' ";
272 if (debug["sql"]) then
273 freeswitch.consoleLog("notice", "[sms] SQL EXTENSION: " .. sql .. "\n");
274 end
275 status = dbh:query(sql, function(rows)
276 extension_uuid = rows["extension_uuid"];
277 end);
278 end
279 end
280 if (carrier == nil) then
281 carrier = '';
282 end
283
284
285 if (extension_uuid ~= nil) then
286 sql = "insert into v_sms_messages";
287 sql = sql .. "(sms_message_uuid,extension_uuid,domain_uuid,start_stamp,from_number,to_number,message,direction,response,carrier)";
288 sql = sql .. " values ('" .. uuid() .. "','" .. extension_uuid .. "','" .. domain_uuid .."',now(),'" .. from .. "','" .. to .. "','" .. body .. "','" .. direction .. "','','" .. carrier .."')";
289 if (debug["sql"]) then
290 freeswitch.consoleLog("notice", "[sms] "..sql.."\n");
291 end
292 dbh:query(sql);
293 end