Susurri is a working prototype that I had build for TADHack 2016 Kuala Lumpur. By utilizing the Cisco Tropo service to create a platform to let people leave a message with password protected. Then others can retrieve and listen to the message as long as they have the password.
Below is the one-page slide that I had shared in the TADHack presentation.
Tropo can support multiple programming languages, from Groovy, JavaScript, PHP, python to Ruby. For this prototype, PHP is used and since is using demo account, SIP is used for testing and demo. A gentle reminder on Tropo service, it support wide range of country but not all, Malaysia is one of the country which Tropo not supported.
Hereby I will share the code for Susurri, hope you enjoy your hacking on Tropo!
Tropo Script
<?php /********************************* * Configuration *********************************/ $GETSESSIONEP="http://FQDN/v3/getsession.php"; $UDPATERECORDEP="http://FQDN/v3/updateRecord.php"; $SEARCHRECORDEP="http://FQDN/v3/searchRecord.php"; $RECORDFTPBASEURI="ftp://FQDN/"; $RECORDUSER="records@FQDN"; $RECORDPASSWORD="secret"; $RECORDHTTPBASEURI="http://FQDN/records/"; /********************************* * Variable *********************************/ $revision=48; $menuResult = 0; $numberOfRetry = 3; $passcode = 0; $recordId = 0; $recordFileName=""; $callerId=$currentCall->callerID." [".$currentCall->callerName."]"; /********************************* * Logic *********************************/ // Asking user for action, create a message or listen to message $menuResult = ask("Welcome to susurri ".$revision."! May I help you? Press 1 for creating a secret message, press 2 for listening to the secret message.", array("choices" => "1,2", "timeout"=>5.0, "mode"=>"dtmf", "attempts"=> $numberOfRetry, "onBadChoice" => "badChoiceFCN") ); if ($menuResult->value==1) { //Create message // Create an record in DB $getSessionRespJson = myCurl($GETSESSIONEP); $getSessionRespArry = json_decode($getSessionRespJson,true); // Check for error if ($getSessionRespArry['id'] != 'error') { $recordId = $getSessionRespArry['id']; $recordFileName = $recordId.".wav"; say("Please start to speak your message after the beep sound."); // Record user voice record("Please press the hash key to stop recording.", array( "beep"=>true, "terminator"=>"#", "asyncUpload"=>true, "maxTime"=>60, "recordURI"=>$RECORDFTPBASEURI. $recordFileName, "recordPassword"=>$RECORDPASSWORD, "recordUser"=>$RECORDUSER )); // Ask for password $passcodeResult = ask("Please provide 5 digits passcode for your message.", array("choices" => "[5 DIGITS]", "timeout"=>5.0, "mode"=>"dtmf", "attempts"=> $numberOfRetry, "onBadChoice" => "badChoiceFCN") ); $passcode = $passcodeResult->value; // Update DB record $getUpdateRespJson = myCurl($UDPATERECORDEP."?id=".urlencode($recordId). "&passcode=".urlencode($passcode)."&soundfilename=".urlencode($recordFileName). "&callerid=".urlencode($callerId)); $getUpdateRespArry = json_decode($getUpdateRespJson,true); // Check for update status if ($getUpdateRespArry['result'] == 'success') { say("Your record ID is ".$recordId. " and passcode is "); // Speak by digit by digit rather as whole numeric say_as($passcode,"digits"); } else { say("Internal error on case 4"); } } else { // If error say("Internal error on case 3"); } } else if ($menuResult->value==2) { // Listen to a message // Asking user for passcode $listenPasscodeResult = ask("You have choose to listen a secret message, please enter 5 digits passcode.", array("choices" => "[5 DIGITS]", "timeout"=>5.0, "mode"=>"dtmf", "attempts"=> $numberOfRetry, "onBadChoice" => "badChoiceFCN") ); $listenPasscode = $listenPasscodeResult->value; say("You have provide the passcode as "); // Speak by digit by digit rather as whole numeric say_as($listenPasscode,"digits"); // Search for recording from database $searchRecordRespJson = myCurl($SEARCHRECORDEP."?passcode=".urlencode($listenPasscode)); $searchRecordRespArry = json_decode($searchRecordRespJson,true); if ($searchRecordRespArry['result'] == 'found') { // If found, playback the recording say("Message will start play in 2 seconds."); wait(2000); say($RECORDHTTPBASEURI.$searchRecordRespArry['soundFile']); } else if ($searchRecordRespArry['result'] == 'notfound') { say("Message with provided passcode not found."); } else { say("Internal error on case 5"); } } else { say("Internal error on case 2"); } say("Thank you for using Susurri."); wait(1000); /********************************* * UTILS *********************************/ // Call back function if user input is not recognize function badChoiceFCN($event) { say("Sorry, your input is not recognize."); } // Speak by digit by digit rather as whole numeric function say_as($value, $type) { $ssml_start = "<?xml version='1.0'?><speak>"; $ssml_end="</say-as></speak>"; $ssml ="<say-as interpret-as=\"vxml:$type\">$value"; $complete_string = $ssml_start . $ssml . $ssml_end; say($complete_string); } // CURL function myCurl($url) { // Initiate curl $ch = curl_init(); // Disable SSL verification curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // Will return the response, if false it print the response curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // Set the url curl_setopt($ch, CURLOPT_URL,$url); // Execute $response=curl_exec($ch); // Closing curl_close($ch); return $response; } ?>;
Server Side Script
base.php - Establish DB connection
<?php $servername = "localhost"; $username = "username"; $password = "password"; $dbname = "susurri"; // Create connection $conn = new mysqli($servername, $username, $password, $dbname); // Check connection if ($conn->connect_error) { die("Connection failed: " . $conn->connect_error); } ?>;
getsession.php - Create a record in database and return id
<?php include 'base.php'; $sql = "INSERT INTO records (createdBy) VALUES ('admin')"; if ($conn->query($sql) === TRUE) { echo "{\"id\":\"". $conn->insert_id."\"}"; } else { echo "{\"id\":\"error\"}"; } $conn->close(); ?>;
searchrecord.php - Search record in database
<?php include 'base.php'; $passcode=$_REQUEST['passcode']; $sql = "SELECT soundFile FROM records WHERE passcode=".$passcode; $result =$conn->query($sql); if ($result->num_rows > 0) { while($row = $result->fetch_assoc()) { echo "{\"result\":\"found\", \"soundFile\":\"".$row["soundFile"]."\"}"; break; } } else { echo "{\"result\":\"notfound\"}"; } $conn->close(); ?>;
updaterecord.php - Update record in database
<?php include 'base.php'; $id=$_REQUEST['id']; $passcode=$_REQUEST['passcode']; $soundFilename=$_REQUEST['soundfilename']; $callerId=$_REQUEST['callerid']; $sql = "UPDATE records SET passcode=\"".$passcode."\", soundFile=\"".$soundFilename."\", callerId=\"".$callerId."\" WHERE id=".$id; if ($conn->query($sql) === TRUE) { echo "{\"result\":\"success\"}"; } else { echo "{\"result\":\"fail\"}"; } $conn->close(); ?>;
schema.sql - Database schema
CREATE TABLE IF NOT EXISTS `records` ( `id` int(11) NOT NULL AUTO_INCREMENT, `createdAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `createdBy` varchar(255) DEFAULT NULL, `passcode` varchar(20) DEFAULT NULL, `soundFile` varchar(255) DEFAULT NULL, `callerId` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `passcod` (`passcode`) ) ENGINE=MyISAM
No comments:
Post a Comment