Răsfoiți Sursa

Updates to the SMS app (#123)

Chris Black 6 ani în urmă
părinte
comite
ded05a10c7

+ 31 - 25
sms/README.md

@@ -39,7 +39,7 @@
 		$apps[$x]['permissions'][$y]['name'] = "sms_enabled";
 		$apps[$x]['permissions'][$y]['groups'][] = "superadmin";
 		$y++;
-		
+
 	//default settings
 		$y = 0;
 		$apps[$x]['default_settings'][$y]['default_setting_uuid'] = '67511e2d-35e1-4f70-80ac-4265ec39d2fe';
@@ -90,15 +90,15 @@
 		$apps[$x]['default_settings'][$y]['default_setting_enabled'] = 'true';
 		$apps[$x]['default_settings'][$y]['default_setting_description'] = '';
 		$y++;
-		$apps[$x]['default_settings'][$y]['default_setting_uuid'] = '9b36edac-eeac-4a3e-b8d4-664962e3f78c';
-		$apps[$x]['default_settings'][$y]['default_setting_category'] = 'sms';
-		$apps[$x]['default_settings'][$y]['default_setting_subcategory'] = 'carriers';
-		$apps[$x]['default_settings'][$y]['default_setting_name'] = 'array';
-		$apps[$x]['default_settings'][$y]['default_setting_value'] = 'telnyx';
-		$apps[$x]['default_settings'][$y]['default_setting_enabled'] = 'true';
-		$apps[$x]['default_settings'][$y]['default_setting_description'] = '';
-		$y++;
-		
+        $apps[$x]['default_settings'][$y]['default_setting_uuid'] = '9b36edac-eeac-4a3e-b8d4-664962e3f78c';
+        $apps[$x]['default_settings'][$y]['default_setting_category'] = 'sms';
+        $apps[$x]['default_settings'][$y]['default_setting_subcategory'] = 'carriers';
+        $apps[$x]['default_settings'][$y]['default_setting_name'] = 'array';
+        $apps[$x]['default_settings'][$y]['default_setting_value'] = 'telnyx';
+        $apps[$x]['default_settings'][$y]['default_setting_enabled'] = 'true';
+        $apps[$x]['default_settings'][$y]['default_setting_description'] = '';
+        $y++;
+
 		$apps[$x]['default_settings'][$y]['default_setting_uuid'] = 'e997203c-ca48-45b4-828d-e347ff66fa7c';
 		$apps[$x]['default_settings'][$y]['default_setting_category'] = 'sms';
 		$apps[$x]['default_settings'][$y]['default_setting_subcategory'] = 'twilio_api_url';
@@ -145,16 +145,16 @@
 		$apps[$x]['default_settings'][$y]['default_setting_name'] = 'text';
 		$apps[$x]['default_settings'][$y]['default_setting_value'] = 'https://api.thinq.com/account/{ACCOUNT}/product/origination/sms/send';
 		$apps[$x]['default_settings'][$y]['default_setting_enabled'] = 'false';
-		$apps[$x]['default_settings'][$y]['default_setting_description'] = '';	
-		$y++;	
+		$apps[$x]['default_settings'][$y]['default_setting_description'] = '';
+		$y++;
 		$apps[$x]['default_settings'][$y]['default_setting_uuid'] = '2f246db7-eb07-4c2c-a752-e81466276c89';
 		$apps[$x]['default_settings'][$y]['default_setting_category'] = 'sms';
 		$apps[$x]['default_settings'][$y]['default_setting_subcategory'] = 'telnyx_api_url';
 		$apps[$x]['default_settings'][$y]['default_setting_name'] = 'text';
 		$apps[$x]['default_settings'][$y]['default_setting_value'] = 'https://sms.telnyx.com/messages';
 		$apps[$x]['default_settings'][$y]['default_setting_enabled'] = 'false';
-		$apps[$x]['default_settings'][$y]['default_setting_description'] = '';   
-		$y++;   
+		$apps[$x]['default_settings'][$y]['default_setting_description'] = '';
+		$y++;
 
 		$apps[$x]['default_settings'][$y]['default_setting_uuid'] = '14101c26-c3f9-46aa-a67a-3642752e56f4';
 		$apps[$x]['default_settings'][$y]['default_setting_category'] = 'sms';
@@ -172,7 +172,7 @@
 		$apps[$x]['default_settings'][$y]['default_setting_enabled'] = 'false';
 		$apps[$x]['default_settings'][$y]['default_setting_description'] = '';
 		$y++;
-	
+
 		$apps[$x]['default_settings'][$y]['default_setting_uuid'] = '551b3948-8328-42be-a873-9a32f8b49463';
 		$apps[$x]['default_settings'][$y]['default_setting_category'] = 'sms';
 		$apps[$x]['default_settings'][$y]['default_setting_subcategory'] = 'teli_access_key';
@@ -189,7 +189,7 @@
 		$apps[$x]['default_settings'][$y]['default_setting_enabled'] = 'false';
 		$apps[$x]['default_settings'][$y]['default_setting_description'] = '';
 		$y++;
-	
+
 		$apps[$x]['default_settings'][$y]['default_setting_uuid'] = 'c56042fc-4cd4-425b-a39a-9297aaed7743';
 		$apps[$x]['default_settings'][$y]['default_setting_category'] = 'sms';
 		$apps[$x]['default_settings'][$y]['default_setting_subcategory'] = 'twilio_access_key';
@@ -206,7 +206,7 @@
 		$apps[$x]['default_settings'][$y]['default_setting_enabled'] = 'false';
 		$apps[$x]['default_settings'][$y]['default_setting_description'] = '';
 		$y++;
-	
+
 		$apps[$x]['default_settings'][$y]['default_setting_uuid'] = '4a86c939-9d80-4da7-bbda-49d6bf1c3882';
 		$apps[$x]['default_settings'][$y]['default_setting_category'] = 'sms';
 		$apps[$x]['default_settings'][$y]['default_setting_subcategory'] = 'bandwidth_access_key';
@@ -229,7 +229,7 @@
 		$apps[$x]['default_settings'][$y]['default_setting_name'] = 'text';
 		$apps[$x]['default_settings'][$y]['default_setting_value'] = '';
 		$apps[$x]['default_settings'][$y]['default_setting_enabled'] = 'false';
-		$apps[$x]['default_settings'][$y]['default_setting_description'] = '';		
+		$apps[$x]['default_settings'][$y]['default_setting_description'] = '';
 		$y++;
 		$apps[$x]['default_settings'][$y]['default_setting_uuid'] = 'cc4725d7-66e4-4ee8-ae95-475b8903ba91';
 		$apps[$x]['default_settings'][$y]['default_setting_category'] = 'sms';
@@ -237,7 +237,7 @@
 		$apps[$x]['default_settings'][$y]['default_setting_name'] = 'text';
 		$apps[$x]['default_settings'][$y]['default_setting_value'] = '';
 		$apps[$x]['default_settings'][$y]['default_setting_enabled'] = 'false';
-		$apps[$x]['default_settings'][$y]['default_setting_description'] = '';		
+		$apps[$x]['default_settings'][$y]['default_setting_description'] = '';
 		$y++;
 		$apps[$x]['default_settings'][$y]['default_setting_uuid'] = '604c1f7c-e830-441d-9596-31c8d091f8c2';
 		$apps[$x]['default_settings'][$y]['default_setting_category'] = 'sms';
@@ -245,7 +245,7 @@
 		$apps[$x]['default_settings'][$y]['default_setting_name'] = 'text';
 		$apps[$x]['default_settings'][$y]['default_setting_value'] = '';
 		$apps[$x]['default_settings'][$y]['default_setting_enabled'] = 'false';
-		$apps[$x]['default_settings'][$y]['default_setting_description'] = '';       
+		$apps[$x]['default_settings'][$y]['default_setting_description'] = '';
 		$y++;
 		$apps[$x]['default_settings'][$y]['default_setting_uuid'] = 'abcd3f80-71c2-4b58-ae9d-3a37cb503faf';
 		$apps[$x]['default_settings'][$y]['default_setting_category'] = 'sms';
@@ -253,7 +253,7 @@
 		$apps[$x]['default_settings'][$y]['default_setting_name'] = 'text';
 		$apps[$x]['default_settings'][$y]['default_setting_value'] = '';
 		$apps[$x]['default_settings'][$y]['default_setting_enabled'] = 'false';
-		$apps[$x]['default_settings'][$y]['default_setting_description'] = '';       
+		$apps[$x]['default_settings'][$y]['default_setting_description'] = '';
 		$y++;
 		$apps[$x]['default_settings'][$y]['default_setting_uuid'] = 'cede4bca-e855-4191-a14c-6f69b3aefb2e';
 		$apps[$x]['default_settings'][$y]['default_setting_category'] = 'sms';
@@ -261,12 +261,13 @@
 		$apps[$x]['default_settings'][$y]['default_setting_name'] = 'text';
 		$apps[$x]['default_settings'][$y]['default_setting_value'] = '';
 		$apps[$x]['default_settings'][$y]['default_setting_enabled'] = 'false';
-		$apps[$x]['default_settings'][$y]['default_setting_description'] = '';       
+		$apps[$x]['default_settings'][$y]['default_setting_description'] = '';
 		$y++;
 
-		//schema details
+	//schema details
 		$y=0;
-		$apps[$x]['db'][$y]['table'] = "v_sms_messages";
+		$apps[$x]['db'][$y]['table']['name'] = "v_sms_messages";
+		$apps[$x]['db'][$y]['table']['parent'] = "";
 		$z=0;
 		$apps[$x]['db'][$y]['fields'][$z]['name'] = "sms_message_uuid";
 		$apps[$x]['db'][$y]['fields'][$z]['type']['pgsql'] = "uuid";
@@ -321,7 +322,8 @@
 		$z++;
 
 		$y=1;
-		$apps[$x]['db'][$y]['table'] = "v_sms_destinations";
+		$apps[$x]['db'][$y]['table']['name'] = "v_sms_destinations";
+		$apps[$x]['db'][$y]['table']['parent'] = "";
 		$z=0;
 		$apps[$x]['db'][$y]['fields'][$z]['name'] = "sms_destination_uuid";
 		$apps[$x]['db'][$y]['fields'][$z]['type']['pgsql'] = "uuid";
@@ -354,5 +356,9 @@
 		$apps[$x]['db'][$y]['fields'][$z]['type'] = "text";
 		$apps[$x]['db'][$y]['fields'][$z]['description']['en-us'] = "";
 		$z++;
+		$apps[$x]['db'][$y]['fields'][$z]['name'] = "chatplan_detail_data";
+		$apps[$x]['db'][$y]['fields'][$z]['type'] = "text";
+		$apps[$x]['db'][$y]['fields'][$z]['description']['en-us'] = "";
+		$z++;
 
 ?>

+ 26 - 0
sms/app_defaults.php

@@ -130,6 +130,32 @@ $text['label-message']['de-at'] = "";
 $text['label-message']['ar-eg'] = "";
 $text['label-message']['he'] = "";
 
+$text['label-chatplan_detail_data']['en-us'] = "Extension or Ring Group";
+$text['label-chatplan_detail_data']['es-cl'] = "";
+$text['label-chatplan_detail_data']['pt-pt'] = "";
+$text['label-chatplan_detail_data']['fr-fr'] = "";
+$text['label-chatplan_detail_data']['pt-br'] = "";
+$text['label-chatplan_detail_data']['pl'] = " ";
+$text['label-chatplan_detail_data']['uk'] = "";
+$text['label-chatplan_detail_data']['sv-se'] = "";
+$text['label-chatplan_detail_data']['ro'] = "";
+$text['label-chatplan_detail_data']['de-at'] = "";
+$text['label-chatplan_detail_data']['ar-eg'] = "";
+$text['label-chatplan_detail_data']['he'] = "";
+
+$text['description-chatplan_detail_data']['en-us'] = "Routing extension or ring group for inbound SMS messages";
+$text['description-chatplan_detail_data']['es-cl'] = "";
+$text['description-chatplan_detail_data']['pt-pt'] = "";
+$text['description-chatplan_detail_data']['fr-fr'] = "";
+$text['description-chatplan_detail_data']['pt-br'] = "";
+$text['description-chatplan_detail_data']['pl'] = " ";
+$text['description-chatplan_detail_data']['uk'] = "";
+$text['description-chatplan_detail_data']['sv-se'] = "";
+$text['description-chatplan_detail_data']['ro'] = "";
+$text['description-chatplan_detail_data']['de-at'] = "";
+$text['description-chatplan_detail_data']['ar-eg'] = "";
+$text['description-chatplan_detail_data']['he'] = "";
+
 $text['button-mdr']['en-us'] = "MDRs";
 $text['button-mdr']['es-cl'] = "";
 $text['button-mdr']['pt-pt'] = "";

+ 1 - 1
sms/app_menu.php

@@ -20,4 +20,4 @@ if (check_acl()) {
 	error_log('ACCESS DENIED [SMS]: ' .  print_r($_SERVER['REMOTE_ADDR'], true));
 	die("access denied");
 }
-?>
+?>

+ 151 - 71
sms/hook/sms_hook_thinq.php

@@ -107,7 +107,76 @@
 		end
 		event:fire();
 		to = extension;
-	elseif direction == "outbound" then
+		
+		--Send inbound SMS via email delivery
+		if (domain_uuid == nil) then
+			--get the domain_uuid using the domain name required for multi-tenant
+				if (domain_name ~= nil) then
+					sql = "SELECT domain_uuid FROM v_domains ";
+					sql = sql .. "WHERE domain_name = :domain_name and domain_enabled = 'true' ";
+					local params = {domain_name = domain_name}
+
+					if (debug["sql"]) then
+						freeswitch.consoleLog("notice", "[sms] SQL: "..sql.."; params:" .. json.encode(params) .. "\n");
+					end
+					status = dbh:query(sql, params, function(rows)
+						domain_uuid = rows["domain_uuid"];
+					end);
+				end
+		end
+		if (domain_uuid == nil) then
+			freeswitch.consoleLog("notice", "[sms] domain_uuid is nill, cannot send sms to email.");
+		else
+			sql = "SELECT v_contact_emails.email_address ";
+			sql = sql .. "from v_extensions, v_extension_users, v_users, v_contact_emails ";
+			sql = sql .. "where v_extensions.extension = :toext and v_extensions.domain_uuid = :domain_uuid and v_extensions.extension_uuid = v_extension_users.extension_uuid ";
+			sql = sql .. "and v_extension_users.user_uuid = v_users.user_uuid and v_users.contact_uuid = v_contact_emails.contact_uuid ";
+			sql = sql .. "and (v_contact_emails.email_label = 'sms' or v_contact_emails.email_label = 'SMS')";
+			local params = {toext = extension, domain_uuid = domain_uuid}
+
+			if (debug["sql"]) then
+				freeswitch.consoleLog("notice", "[sms] SQL: "..sql.."; params:" .. json.encode(params) .. "\n");
+			end
+			status = dbh:query(sql, params, function(rows)
+				send_to_email_address = rows["email_address"];
+			end);
+
+			--sql = "SELECT domain_setting_value FROM v_domain_settings ";
+			--sql = sql .. "where domain_setting_category = 'sms' and domain_setting_subcategory = 'send_from_email_address' and domain_setting_enabled = 'true' and domain_uuid = :domain_uuid";
+			--local params = {domain_uuid = domain_uuid}
+
+			--if (debug["sql"]) then
+			--	freeswitch.consoleLog("notice", "[sms] SQL: "..sql.."; params:" .. json.encode(params) .. "\n");
+			--end
+			--status = dbh:query(sql, params, function(rows)
+			--	send_from_email_address = rows["domain_setting_value"];
+			--end);
+			-- Tried setting the "from" address, above, but default email facility is overriding with global/domain-level default settings.
+			send_from_email_address = '[email protected]'  -- this gets overridden if using v_mailto.php
+			
+			if (send_to_email_address ~= nill and send_from_email_address ~= nill) then
+				subject = 'Text Message from: ' .. from;
+				emailbody = 'To: ' .. to .. '<br>Msg:' .. body;
+				if (debug["info"]) then
+					freeswitch.consoleLog("info", emailbody);
+				end
+				--luarun email.lua send_to_email_address send_from_email_address '' subject emailbody;
+				--replace the &#39 with a single quote
+					emailbody = emailbody:gsub("&#39;", "'");
+
+				--replace the &#34 with double quote
+					emailbody = emailbody:gsub("&#34;", [["]]);
+
+				--send the email
+					freeswitch.email(send_to_email_address,
+						send_from_email_address,
+						"To: "..send_to_email_address.."\nFrom: "..send_from_email_address.."\nX-Headers: \nSubject: "..subject,
+						emailbody
+						);
+			end
+		end 
+
+		elseif direction == "outbound" then
 		if (argv[3] ~= nil) then
 			to_user = argv[3];
 			to_user = to_user:gsub("^+?sip%%3A%%40","");
@@ -137,7 +206,7 @@
 		end
 		--Clean body up for Groundwire send
 		smsraw = body;
-		smstempst, smstempend = string.find(smsraw, 'Content%-lenght:');
+		smstempst, smstempend = string.find(smsraw, 'Content%-length:');
 		if (smstempend == nil) then
 			body = smsraw;
 		else
@@ -148,7 +217,8 @@
 				body = string.sub(smsraw, smst2end + 1);
 			end
 		end
-
+		body = body:gsub('%"','');
+		--body = body:gsub('\r\n',' ');
 
 		if (debug["info"]) then
 			if (message ~= nil) then
@@ -246,77 +316,87 @@
 			api_url = rows["default_setting_value"];
 		end);
 
-		if (carrier == "flowroute") then
-			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;
-		elseif (carrier == "twilio") then
-			if to:len() < 11 then
-				to = "1" .. to;
-			end
-			if outbound_caller_id_number:len() < 11 then
-				outbound_caller_id_number = "1" .. outbound_caller_id_number;
-			end
-		-- Can be either +1NANNNNXXXX or NANNNNXXXX
-			api_url = string.gsub(api_url, "{ACCOUNTSID}",  access_key);
-			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";
-		elseif (carrier == "teli") then
-			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";
-		elseif (carrier == "plivo") then
-			if to:len() <11 then
-				to = "1"..to;
-			end
-			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;
-		elseif (carrier == "bandwidth") then
-			if to:len() <11 then
-				to = "1"..to;
-			end
-			if outbound_caller_id_number:len() < 11 then
-				outbound_caller_id_number = "1" .. outbound_caller_id_number;
-			end
-			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 .."\"}'"		
-		elseif (carrier == "thinq") then
-			if to:len() < 11 then
-				to = "1" .. to;
-			end
-			if outbound_caller_id_number:len() < 11 then
-				outbound_caller_id_number = "1" .. outbound_caller_id_number;
-			end
-			--Get User_name
-			sql = "SELECT default_setting_value FROM v_default_settings ";
-			sql = sql .. "where default_setting_category = 'sms' and default_setting_subcategory = '" .. carrier .. "_username' and default_setting_enabled = 'true'";
-			if (debug["sql"]) then
-				freeswitch.consoleLog("notice", "[sms] SQL: "..sql.."; params:" .. json.encode(params) .. "\n");
-			end
-			status = dbh:query(sql, function(rows)
-				username = rows["default_setting_value"];
-			end);
-			cmd = "curl -X POST '" .. api_url .."' -H \"Content-Type:multipart/form-data\"  -F 'message=" .. body .. "' -F 'to_did=" .. to .."' -F 'from_did=" .. outbound_caller_id_number .. "' -u '".. username ..":".. access_key .."'"
-		elseif (carrier == "telnyx") then
-			if to:len() < 11 then
-				to = "1" .. to;
+		--Check for xml content
+		smstempst, smstempend = string.find(body, '<%?xml');
+		if (smstempst ~= nil) then freeswitch.consoleLog("notice", "[sms] smstempst = '" .. smstempst .. "\n") end;
+		if (smstempend ~= nil) then freeswitch.consoleLog("notice", "[sms] smstempend = '" .. smstempend .. "\n") end;
+		if (smstempst == nil) then 
+			-- No XML content, continue processing
+			if (carrier == "flowroute") then
+				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;
+			elseif (carrier == "twilio") then
+				if to:len() < 11 then
+					to = "1" .. to;
+				end
+				if outbound_caller_id_number:len() < 11 then
+					outbound_caller_id_number = "1" .. outbound_caller_id_number;
+				end
+			-- Can be either +1NANNNNXXXX or NANNNNXXXX
+				api_url = string.gsub(api_url, "{ACCOUNTSID}",  access_key);
+				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";
+			elseif (carrier == "teli") then
+				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";
+			elseif (carrier == "plivo") then
+				if to:len() <11 then
+					to = "1"..to;
+				end
+				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;
+			elseif (carrier == "bandwidth") then
+				if to:len() <11 then
+					to = "1"..to;
+				end
+				if outbound_caller_id_number:len() < 11 then
+					outbound_caller_id_number = "1" .. outbound_caller_id_number;
+				end
+				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 .."\"}'"		
+			elseif (carrier == "thinq") then
+				if to:len() < 11 then
+					to = "1" .. to;
+				end
+				if outbound_caller_id_number:len() < 11 then
+					outbound_caller_id_number = "1" .. outbound_caller_id_number;
+				end
+				--Get User_name
+				sql = "SELECT default_setting_value FROM v_default_settings ";
+				sql = sql .. "where default_setting_category = 'sms' and default_setting_subcategory = '" .. carrier .. "_username' and default_setting_enabled = 'true'";
+				if (debug["sql"]) then
+					freeswitch.consoleLog("notice", "[sms] SQL: "..sql.."; params:" .. json.encode(params) .. "\n");
+				end
+				status = dbh:query(sql, function(rows)
+					username = rows["default_setting_value"];
+				end);
+				cmd = "curl -X POST '" .. api_url .."' -H \"Content-Type:multipart/form-data\"  -F 'message=" .. body .. "' -F 'to_did=" .. to .."' -F 'from_did=" .. outbound_caller_id_number .. "' -u '".. username ..":".. access_key .."'"
+			elseif (carrier == "telnyx") then
+				if to:len() < 11 then
+					to = "1" .. to;
+				end
+				if outbound_caller_id_number:len() < 11 then
+					outbound_caller_id_number = "1" .. outbound_caller_id_number;
+				end
+				--Get delivery_status_webhook_url
+				sql = "SELECT default_setting_value FROM v_default_settings ";
+				sql = sql .. "where default_setting_category = 'sms' and default_setting_subcategory = '" .. carrier .. "_delivery_status_webhook_url' and default_setting_enabled = 'true'";
+				if (debug["sql"]) then
+					freeswitch.consoleLog("notice", "[sms] SQL: "..sql.."; params:" .. json.encode(params) .. "\n");
+				end
+				status = dbh:query(sql, function(rows)
+					delivery_status_webhook_url = rows["default_setting_value"];
+				end);
+				cmd ="curl -X POST \"" .. api_url .."\" -H \"Content-Type: application/json\"  -H \"x-profile-secret: " .. secret_key .. "\" -d '{\"from\": \"+" .. outbound_caller_id_number .. "\", \"to\": \"+" .. to .. "\", \"body\": \"" .. body .. "\", \"delivery_status_webhook_url\": \"" .. delivery_status_webhook_url .. "\"}'";
 			end
-			if outbound_caller_id_number:len() < 11 then
-				outbound_caller_id_number = "1" .. outbound_caller_id_number;
+			if (debug["info"]) then
+				freeswitch.consoleLog("notice", "[sms] CMD: " .. cmd .. "\n");
 			end
-			--Get delivery_status_webhook_url
-			sql = "SELECT default_setting_value FROM v_default_settings ";
-			sql = sql .. "where default_setting_category = 'sms' and default_setting_subcategory = '" .. carrier .. "_delivery_status_webhook_url' and default_setting_enabled = 'true'";
-			if (debug["sql"]) then
-				freeswitch.consoleLog("notice", "[sms] SQL: "..sql.."; params:" .. json.encode(params) .. "\n");
+			local handle = io.popen(cmd)
+			local result = handle:read("*a")
+			handle:close()
+			if (debug["info"]) then
+				freeswitch.consoleLog("notice", "[sms] CURL Returns: " .. result .. "\n");
 			end
-			status = dbh:query(sql, function(rows)
-				delivery_status_webhook_url = rows["default_setting_value"];
-			end);
-			cmd ="curl -X POST \"" .. api_url .."\" -H \"Content-Type: application/json\"  -H \"x-profile-secret: " .. secret_key .. "\" -d '{\"from\": \"+" .. outbound_caller_id_number .. "\", \"to\": \"+" .. to .. "\", \"body\": \"" .. body .. "\", \"delivery_status_webhook_url\": \"" .. delivery_status_webhook_url .. "\"}'";
-		end
-		if (debug["info"]) then
-			freeswitch.consoleLog("notice", "[sms] CMD: " .. cmd .. "\n");
-		end
-		local handle = io.popen(cmd)
-		local result = handle:read("*a")
-		handle:close()
-		if (debug["info"]) then
-			freeswitch.consoleLog("notice", "[sms] CURL Returns: " .. result .. "\n");
-		end
+		else
+			-- XML content
+			freeswitch.consoleLog("notice", "[sms] Body contains XML content, not sending\n");
+		end	
 --		os.execute(cmd)
 	end
 	

+ 12 - 5
sms/resources/templates/conf/chatplan/default.xml

@@ -7,12 +7,19 @@
                                 <!-- <action application="reply" data="Hello, you said: ${_body}"/> -->
                         </condition>
                 </extension>
-        </context>
-        <context name="internal">
-                <extension name="demo">
-                        <condition field="to" expression="^(.*)$">
+        </context>   
+        <context name="public">
+                <extension name="ten-digit">
+                        <condition field="to" expression="^(\d{10}.*)$">
+                        	    <action application="set" data="final_delivery=true"/>
                                     <action application="lua" data="app.lua sms outbound"/>
                         </condition>
                 </extension>
+                <extension name="other">
+                        <condition field="to" expression="^(.*)$">
+                                <action application="set" data="final_delivery=true"/>
+                                <!-- <action application="send"/> -->
+                        </condition>
+                </extension>
         </context>
-</include>
+</include>

+ 92 - 92
sms/root.php

@@ -90,103 +90,101 @@
 if (!class_exists('IP4Filter')) {
 	class IP4Filter {
 
-		private static $_IP_TYPE_SINGLE = 'single'; 
-		private static $_IP_TYPE_WILDCARD = 'wildcard'; 
-		private static $_IP_TYPE_MASK = 'mask'; 
-		private static $_IP_TYPE_CIDR = 'CIDR'; 
-		private static $_IP_TYPE_SECTION = 'section'; 
-		private $_allowed_ips = array(); 
-
-		public function __construct($allowed_ips) { 
-			$this->_allowed_ips = $allowed_ips; 
-		} 
-
-		public function check($ip, $allowed_ips = null) { 
-			$allowed_ips = $allowed_ips ? $allowed_ips : $this->_allowed_ips; 
-
-			foreach ($allowed_ips as $allowed_ip) { 
-				$type = $this->_judge_ip_type($allowed_ip); 
+		private static $_IP_TYPE_SINGLE = 'single';
+		private static $_IP_TYPE_WILDCARD = 'wildcard';
+		private static $_IP_TYPE_MASK = 'mask';
+		private static $_IP_TYPE_CIDR = 'CIDR';
+		private static $_IP_TYPE_SECTION = 'section';
+		private $_allowed_ips = array();
+
+		public function __construct($allowed_ips) {
+			$this->_allowed_ips = $allowed_ips;
+		}
+
+		public function check($ip, $allowed_ips = null) {
+			$allowed_ips = $allowed_ips ? $allowed_ips : $this->_allowed_ips;
+
+			foreach ($allowed_ips as $allowed_ip) {
+				$type = $this->_judge_ip_type($allowed_ip);
 				$sub_rst = call_user_func(array($this, '_sub_checker_' . $type), $allowed_ip, $ip);
 
-				if ($sub_rst) { 
-					return true; 
-				} 
-			} 
-
-			return false; 
-		} 
-
-		private function _judge_ip_type($ip) { 
-			if (strpos($ip, '*')) { 
-				return self :: $_IP_TYPE_WILDCARD; 
-			} 
-
-			if (strpos($ip, '/')) { 
-				$tmp = explode('/', $ip); 
-				if (strpos($tmp[1], '.')) { 
-					return self :: $_IP_TYPE_MASK; 
-				} else { 
-					return self :: $_IP_TYPE_CIDR; 
-				} 
-			} 
-
-			if (strpos($ip, '-')) { 
-				return self :: $_IP_TYPE_SECTION; 
-			} 
-
-			if (ip2long($ip)) { 
-				return self :: $_IP_TYPE_SINGLE; 
-			} 
-
-			return false; 
-		} 
-
-		private function _sub_checker_single($allowed_ip, $ip) { 
-			return (ip2long($allowed_ip) == ip2long($ip)); 
-		} 
-
-		private function _sub_checker_wildcard($allowed_ip, $ip) { 
-			$allowed_ip_arr = explode('.', $allowed_ip); 
-			$ip_arr = explode('.', $ip); 
-			for ($i = 0; $i < count($allowed_ip_arr); $i++) { 
-				if ($allowed_ip_arr[$i] == '*') { 
-					return true; 
-				} else { 
-					if (false == ($allowed_ip_arr[$i] == $ip_arr[$i])) { 
-						return false; 
-					} 
-				} 
-			} 
-		} 
-
-		private function _sub_checker_mask($allowed_ip, $ip) { 
-			list($allowed_ip_ip, $allowed_ip_mask) = explode('/', $allowed_ip); 
-			$begin = (ip2long($allowed_ip_ip) & ip2long($allowed_ip_mask)) + 1; 
-			$end = (ip2long($allowed_ip_ip) | (~ ip2long($allowed_ip_mask))) + 1; 
-			$ip = ip2long($ip); 
-			return ($ip >= $begin && $ip <= $end); 
-		} 
-
-		private function _sub_checker_section($allowed_ip, $ip) { 
-			list($begin, $end) = explode('-', $allowed_ip); 
-			$begin = ip2long($begin); 
-			$end = ip2long($end); 
-			$ip = ip2long($ip); 
-			return ($ip >= $begin && $ip <= $end); 
-		} 
-
-		private function _sub_checker_CIDR($CIDR, $IP) { 
-			list ($net, $mask) = explode('/', $CIDR); 
-			return ( ip2long($IP) & ~((1 << (32 - $mask)) - 1) ) == ip2long($net); 
-		} 
-
-	} 
+				if ($sub_rst) {
+					return true;
+				}
+			}
+
+			return false;
+		}
+
+		private function _judge_ip_type($ip) {
+			if (strpos($ip, '*')) {
+				return self :: $_IP_TYPE_WILDCARD;
+			}
+
+			if (strpos($ip, '/')) {
+				$tmp = explode('/', $ip);
+				if (strpos($tmp[1], '.')) {
+					return self :: $_IP_TYPE_MASK;
+				} else {
+					return self :: $_IP_TYPE_CIDR;
+				}
+			}
+
+			if (strpos($ip, '-')) {
+				return self :: $_IP_TYPE_SECTION;
+			}
+
+			if (ip2long($ip)) {
+				return self :: $_IP_TYPE_SINGLE;
+			}
+
+			return false;
+		}
+
+		private function _sub_checker_single($allowed_ip, $ip) {
+			return (ip2long($allowed_ip) == ip2long($ip));
+		}
+
+		private function _sub_checker_wildcard($allowed_ip, $ip) {
+			$allowed_ip_arr = explode('.', $allowed_ip);
+			$ip_arr = explode('.', $ip);
+			for ($i = 0; $i < count($allowed_ip_arr); $i++) {
+				if ($allowed_ip_arr[$i] == '*') {
+					return true;
+				} else {
+					if (false == ($allowed_ip_arr[$i] == $ip_arr[$i])) {
+						return false;
+					}
+				}
+			}
+		}
+
+		private function _sub_checker_mask($allowed_ip, $ip) {
+			list($allowed_ip_ip, $allowed_ip_mask) = explode('/', $allowed_ip);
+			$begin = (ip2long($allowed_ip_ip) & ip2long($allowed_ip_mask)) + 1;
+			$end = (ip2long($allowed_ip_ip) | (~ ip2long($allowed_ip_mask))) + 1;
+			$ip = ip2long($ip);
+			return ($ip >= $begin && $ip <= $end);
+		}
+
+		private function _sub_checker_section($allowed_ip, $ip) {
+			list($begin, $end) = explode('-', $allowed_ip);
+			$begin = ip2long($begin);
+			$end = ip2long($end);
+			$ip = ip2long($ip);
+			return ($ip >= $begin && $ip <= $end);
+		}
+
+		private function _sub_checker_CIDR($CIDR, $IP) {
+			list ($net, $mask) = explode('/', $CIDR);
+			return ( ip2long($IP) & ~((1 << (32 - $mask)) - 1) ) == ip2long($net);
+		}
+
+	}
 
 	function check_acl(){
 		global $db, $debug, $domain_uuid, $domain_name;
 
-		$acl = new IP4Filter();
-
 		//select node_cidr from v_access_control_nodes where node_cidr != '';
 		$sql = "select node_cidr from v_access_control_nodes where node_cidr != '' and node_type = 'allow'";
 		$prep_statement = $db->prepare(check_sql($sql));
@@ -198,7 +196,9 @@ if (!class_exists('IP4Filter')) {
 		foreach ($result as &$row) {
 			$allowed_ips[] = $row['node_cidr'];
 		}
-	
+
+		$acl = new IP4Filter($allowed_ips);
+
 		return $acl->check($_SERVER['REMOTE_ADDR'],$allowed_ips);
 	}
 }

+ 3 - 2
sms/sms.php

@@ -81,7 +81,8 @@ require_once "resources/paging.php";
 		$order_text = ($total_sms_destinations == $numeric_sms) ? "cast(destination as bigint)" : "destination asc";
 	}
 	else {
-		$order_text = "extension asc";
+		//$order_text = "extension asc"; //extension doesn't exist in this table 8/23/2018/jblack
+		$order_text = "destination asc";
 	}
 
 //get the extensions
@@ -98,8 +99,8 @@ require_once "resources/paging.php";
 	$prep_statement = $db->prepare(check_sql($sql));
 	$prep_statement->execute();
 	$sms_destinations = $prep_statement->fetchAll(PDO::FETCH_NAMED);
+//echo $sql;
 	unset ($prep_statement, $sql);
-
 //show the content
 	echo "<table width=\"100%\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n";
 	echo "  <tr>\n";

+ 32 - 21
sms/sms_delete.php

@@ -62,6 +62,7 @@ else {
 			$description = check_str($row["description"]);
 			$enabled = check_str($row["enabled"]);
 			$sms_destination_uuid = $row['sms_destination_uuid'];
+			$chatplan_detail_data = $row['chatplan_detail_data'];
 		}
 	}
 	else {
@@ -76,6 +77,7 @@ else {
 			$description = check_str($_POST["description"]);
 			$enabled = check_str($_POST["enabled"]);
 			$sms_destination_uuid = uuid();
+			$chatplan_detail_data = check_str($_POST["chatplan_detail_data"]);
 		if ($action == "add") {
 			$sql_insert = "insert into v_sms_destinations ";
 			$sql_insert .= "(";
@@ -84,7 +86,8 @@ else {
 			$sql_insert .= "domain_uuid, ";
 			$sql_insert .= "destination, ";
 			$sql_insert .= "enabled, ";
-			$sql_insert .= "description ";
+			$sql_insert .= "description, ";
+			$sql_insert .= "chatplan_detail_data ";
 			$sql_insert .= ")";
 			$sql_insert .= "values ";
 			$sql_insert .= "(";
@@ -93,34 +96,30 @@ else {
 			$sql_insert .= "'".$_SESSION['domain_uuid']."', ";
 			$sql_insert .= "'".$destination."', ";
 			$sql_insert .= "'".$enabled."', ";
-			$sql_insert .= "'".$description."' ";
+			$sql_insert .= "'".$description."', ";
+			$sql_insert .= "'".$chatplan_detail_data."' ";
 			$sql_insert .= ")";
 			$db->exec($sql_insert);
 			header( 'Location: sms.php') ;
-			
+
 		}
 	} elseif (count($_POST) > 0 && $action == "update") {
 			$destination = str_replace(' ','-',check_str($_POST["destination"]));
 			$carrier = check_str($_POST["carrier"]);
 			$description = check_str($_POST["description"]);
 			$enabled = check_str($_POST["enabled"]);
-			
+			$chatplan_detail_data = check_str($_POST["chatplan_detail_data"]);
+
 			$sql_insert = "update v_sms_destinations set";
-			$sql_insert .= "(";
-			$sql_insert .= "carrier, ";
-			$sql_insert .= "destination, ";
-			$sql_insert .= "enabled, ";
-			$sql_insert .= "description ";
-			$sql_insert .= ")";
-			$sql_insert .= "= ";
-			$sql_insert .= "(";
-			$sql_insert .= "'".$carrier."', ";
-			$sql_insert .= "'".$destination."', ";
-			$sql_insert .= "'".$enabled."', ";
-			$sql_insert .= "'".$description."' ";
-			$sql_insert .= ")";
+			$sql_insert .= " ";
+			$sql_insert .= "carrier = '".$carrier."', ";
+			$sql_insert .= "destination = '".$destination."', ";
+			$sql_insert .= "enabled = '".$enabled."', ";
+			$sql_insert .= "description = '".$description."', ";
+			$sql_insert .= "chatplan_detail_data = '".$chatplan_detail_data."' ";
 			$sql_insert .= "where sms_destination_uuid = '" . $sms_destination_uuid . "' and domain_uuid = '" . $_SESSION['domain_uuid'] . "'";
 			$db->exec($sql_insert);
+			error_log($sql_insert);
 			header( 'Location: sms.php') ;
 	}
 
@@ -176,7 +175,19 @@ else {
 	echo $text['description-carrier']."\n";
 	echo "</td>\n";
 	echo "</tr>\n";
-	
+
+
+
+	echo "<tr>\n";
+	echo "<td class='vncell' valign='top' align='left' nowrap='nowrap'>\n";
+	echo "    ".$text['label-chatplan_detail_data']."\n";
+	echo "</td>\n";
+	echo "<td class='vtable' align='left'>\n";
+	echo "    <input class='formfld' type='text' name='chatplan_detail_data' autocomplete='off' maxlength='255' value=\"$chatplan_detail_data\" >\n";
+	echo "<br />\n";
+	echo $text['description-chatplan_detail_data']."\n";
+	echo "</td>\n";
+	echo "</tr>\n";
 
 	if (permission_exists('sms_enabled')) {
 		echo "<tr>\n";
@@ -203,7 +214,7 @@ else {
 		echo "</td>\n";
 		echo "</tr>\n";
 	}
-	
+
 	echo "<tr>\n";
 	echo "<td class='vncell' valign='top' align='left' nowrap='nowrap'>\n";
 	echo "    ".$text['label-description']."\n";
@@ -217,9 +228,9 @@ else {
 
 	if ($action == "update") {
 		echo "		<input type='hidden' name='sms_destination_uuid' value='".$sms_destination_uuid."'>\n";
-		echo "		<input type='hidden' name='id' id='id' value='".$sms_destination_uuid."'>";	
+		echo "		<input type='hidden' name='id' id='id' value='".$sms_destination_uuid."'>";
 	}
-	
+
 	echo "</table>\n";
 	echo "</form>\n";
 

+ 46 - 16
sms/sms_hook_common.php

@@ -32,7 +32,7 @@
 */
 include "root.php";
 
-//luarun /var/www/fusionpbx/app/sms/sms.lua TO FROM 'BODY'
+//luarun /var/www/html/app/sms/sms.lua TO FROM 'BODY'
 
 $debug = true;
 
@@ -54,21 +54,22 @@ function route_and_send_sms($from, $to, $body) {
 
 				$to = intval(preg_replace('/(^[1])/','', $to));
 				$from = intval($from);
+				$body = preg_replace('([\'])', '\\\'', $body); // escape apostrophes
 				if ($debug) {
 					error_log("TO: " . print_r($to,true));
 					error_log("FROM: " . print_r($from,true));
 					error_log("BODY: " . print_r($body,true));
 				}
 
+				// Check for chatplan_detail in sms_destinations table
 				$sql = "select domain_name, ";
-				$sql .= "dialplan_detail_data, ";
-				$sql .= "v_domains.domain_uuid as domain_uuid ";
-				$sql .= "from v_destinations, ";
-				$sql .= "v_dialplan_details, ";
+				$sql .= "chatplan_detail_data, ";
+				$sql .= "v_sms_destinations.domain_uuid as domain_uuid ";
+				$sql .= "from v_sms_destinations, ";
 				$sql .= "v_domains ";
-				$sql .= "where v_destinations.dialplan_uuid = v_dialplan_details.dialplan_uuid ";
-				$sql .= "and v_destinations.domain_uuid = v_domains.domain_uuid";
-				$sql .= " and destination_number like :to and dialplan_detail_type = 'transfer'";
+				$sql .= "where v_sms_destinations.domain_uuid = v_domains.domain_uuid";
+				$sql .= " and destination like :to";
+				$sql .= " and chatplan_detail_data <> ''";
 
 				if ($debug) {
 					error_log("SQL: " . print_r($sql,true));
@@ -78,15 +79,44 @@ function route_and_send_sms($from, $to, $body) {
 				$prep_statement->bindValue(':to', "%{$to}%");
 				$prep_statement->execute();
 				$result = $prep_statement->fetchAll(PDO::FETCH_NAMED);
-				if (count($result) == 0) {
-					error_log("Cannot find a destination: " . print_r($result,true));
-					die("Invalid Destination");
+
+				if (count($result) > 0) {
+					foreach ($result as &$row) {
+						$domain_name = $row["domain_name"];
+						preg_match('/(\d{2,7})/',$row["chatplan_detail_data"],$match);
+						$domain_uuid = $row["domain_uuid"];
+						break; //limit to 1 row
+					}
 				}
-				foreach ($result as &$row) {
-					$domain_name = $row["domain_name"];
-					preg_match('/(\d{2,7})/',$row["dialplan_detail_data"],$match);
-					$domain_uuid = $row["domain_uuid"];
-					break; //limit to 1 row
+				else { // Fall back to destinations table for backwards compatibility
+					$sql = "select domain_name, ";
+					$sql .= "dialplan_detail_data, ";
+					$sql .= "v_domains.domain_uuid as domain_uuid ";
+					$sql .= "from v_destinations, ";
+					$sql .= "v_dialplan_details, ";
+					$sql .= "v_domains ";
+					$sql .= "where v_destinations.dialplan_uuid = v_dialplan_details.dialplan_uuid ";
+					$sql .= "and v_destinations.domain_uuid = v_domains.domain_uuid";
+					$sql .= " and destination_number like :to and dialplan_detail_type = 'transfer'";
+
+					if ($debug) {
+						error_log("SQL: " . print_r($sql,true));
+					}
+
+					$prep_statement = $db->prepare(check_sql($sql));
+					$prep_statement->bindValue(':to', "%{$to}%");
+					$prep_statement->execute();
+					$result = $prep_statement->fetchAll(PDO::FETCH_NAMED);
+					if (count($result) == 0) {
+						error_log("Cannot find a destination: " . print_r($result,true));
+						die("Invalid Destination");
+					}
+					foreach ($result as &$row) {
+						$domain_name = $row["domain_name"];
+						preg_match('/(\d{2,7})/',$row["dialplan_detail_data"],$match);
+						$domain_uuid = $row["domain_uuid"];
+						break; //limit to 1 row
+					}
 				}
 				unset ($prep_statement);
 

+ 0 - 0
sms/sms_mdr.php