Created
May 3, 2016 17:03
-
-
Save loren138/d6dccf91950957049c229fa59e1d32b0 to your computer and use it in GitHub Desktop.
Validate Twilio TwilML SMS Request with Laravel (also a Twilio Controller for Laravel)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// Place in app/config/api.php | |
// You'll need to get your TWILIO authToken from https://www.twilio.com/user/account/monitor/getting-started | |
// and place it in your .env file (or directly in this file, but that's less secure) | |
return [ | |
'twilio' => [ | |
'authToken' => env('TWILIO_AUTHTOKEN') | |
] | |
]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Twilio Request Validator Class | |
* This file goes in app/Models/Twilio (or you can move it around and change the namespace) | |
* It requires that you have a file config/api.php | |
* Source: https://raw.githubusercontent.com/twilio/twilio-php/3d02ee1f1bde8e860e7dbfd9d2d0d2b7ca7d625c/Services/Twilio/RequestValidator.php | |
*/ | |
namespace App\Models\Twilio; | |
class RequestValidator | |
{ | |
// You might want to grab the current source for this class from | |
// https://raw.githubusercontent.com/twilio/twilio-php/master/Services/Twilio/RequestValidator.php | |
protected $AuthToken; | |
public function __construct($token) | |
{ | |
$this->AuthToken = $token; | |
} | |
public function computeSignature($url, $data = array()) | |
{ | |
// sort the array by keys | |
ksort($data); | |
// append them to the data string in order | |
// with no delimiters | |
foreach ($data as $key => $value) { | |
$url .= "$key$value"; | |
} | |
// This function calculates the HMAC hash of the data with the key | |
// passed in | |
// Note: hash_hmac requires PHP 5 >= 5.1.2 or PECL hash:1.1-1.5 | |
// Or http://pear.php.net/package/Crypt_HMAC/ | |
return base64_encode(hash_hmac("sha1", $url, $this->AuthToken, true)); | |
} | |
public function validate($expectedSignature, $url, $data = array()) | |
{ | |
return self::compare( | |
$this->computeSignature($url, $data), | |
$expectedSignature | |
); | |
} | |
/** | |
* Time insensitive compare, function's runtime is governed by the length | |
* of the first argument, not the difference between the arguments. | |
* @param $a string First part of the comparison pair | |
* @param $b string Second part of the comparison pair | |
* @return bool True if $a == $b, false otherwise. | |
*/ | |
public static function compare($a, $b) | |
{ | |
$result = true; | |
if (strlen($a) != strlen($b)) { | |
return false; | |
} | |
if (!$a && !$b) { | |
return true; | |
} | |
$limit = strlen($a); | |
for ($i = 0; $i < $limit; ++$i) { | |
if ($a[$i] != $b[$i]) { | |
$result = false; | |
} | |
} | |
return $result; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Http\Controllers\Shared; | |
use App\Models\Twilio\RequestValidator; | |
use Illuminate\Http\Request; | |
use App\Http\Controllers\Controller; | |
class TwilioController extends Controller | |
{ | |
public function postText(Request $request, JenzabarName $jenzabarName) | |
{ | |
$validator = new RequestValidator(config('api.twilio.authToken')); | |
if (!$validator->validate( | |
$request->header('X-Twilio-Signature'), | |
$request->getUri(), | |
$request->request->all() | |
)) { | |
return $this->textError( | |
'your request is invalid!' | |
); | |
} | |
$phone = $request->input('From'); | |
// Do something with the phone number? | |
$action = explode(' ', strtolower($request->input('Body'))); | |
$function = "action" . ucfirst($action[0]); | |
if (method_exists($this, $function)) { | |
return $this->$function($action, $id[0]['ID_NUM']); | |
} else { | |
return $this->textError('we could not understand your request.'); | |
} | |
} | |
public function actionReply($text, $id) | |
{ | |
$this->text('Hello.'); | |
} | |
public function textError($error) | |
{ | |
return $this->text('We were unable to process your request because '.$error); | |
} | |
public function text($text) | |
{ | |
$xml = '<?xml version="1.0" encoding="UTF-8"?>'."\n". | |
'<Response><Sms>'.$text.'</Sms></Response>'; | |
return response($xml, 200, ['Content-type' => 'text/xml']); | |
} | |
public function postVoice() | |
{ | |
$xml = '<?xml version="1.0" encoding="UTF-8"?>'."\n". | |
'<Response><Say voice="man" language="en">Thanks for calling.</Say></Response>'; | |
return response($xml, 200, ['Content-type' => 'text/xml']); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment