Last active
October 13, 2015 04:18
-
-
Save TMcManus/4138718 to your computer and use it in GitHub Desktop.
Twilio Usage Trigger Manager and Subaccount Circuit Breaker
This file contains hidden or 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 | |
/** | |
* ### Subaccount Circuit Breaker Script ### | |
* This script is designed to make a subaccount suspend itself in response to | |
* a Usage Trigger firing a callback. You can learn about Usage Triggers here: | |
* https://www.twilio.com/docs/api/rest/usage-triggers | |
* | |
* Why would you want to do this? In some cases suspending a subaccount based on high, | |
* unexpected usage can be a good thing. Coding errors and fraud can both cause spikes | |
* in undesired usage. Setting this script up might help you to sleep better at night. | |
* | |
* The good news is that subaccount suspension is reversible, so if things do go wrong | |
* you should be able to fix them. | |
*/ | |
/** | |
* First we need to include the official Twilio PHP Helper Library, which can be found at: | |
* https://github.com/twilio/twilio-php | |
* Download the Zip file and copy the 'Services' folder to the same directory as this file. | |
*/ | |
require_once('Services/Twilio.php'); | |
/** | |
* Insert the credentials for the subaccount you plan on suspending when a trigger fires. | |
* The credentials for your subaccounts can be found by visiting: | |
* https://www.twilio.com/user/account/subaccounts | |
* Clicking 'View Subaccount' for your chosen account, and then visiting: | |
* https://www.twilio.com/user/account | |
*/ | |
$SUBACCOUNT_SID = 'ACXXXXXXX'; // The Account SID for the Subaccount | |
$SUBACCOUNT_AUTH_TOKEN = 'YYYYYYYYY'; // The Auth Token for the Subaccount | |
/** | |
* The callback URL. Basically, the public address of this file. This is used to for the | |
* Request Validation further down We're hard wiring this for reliability, but you can | |
* also set this value dynamically with information from your enviroment. | |
*/ | |
$url = 'https://example.com/circuit-breaker.php'; | |
// Phone numbers for sending SMS | |
$from_number = '+14245551234'; // This must be a US Twilio phone number in your subaccount | |
$to_number = '+18085559876'; // This is the phone number where you want to be alerted | |
/** | |
* Suspending a subaccount is a scary thing, so we're going to use Twilio's Request | |
* Validation to make sure the callback is actually coming from Twilio. You can | |
* learn more about Twilio's Request Validation here: | |
* http://www.twilio.com/docs/security#validating-requests | |
*/ | |
$validator = new Services_Twilio_RequestValidator($SUBACCOUNT_AUTH_TOKEN); | |
$signature = $_SERVER["HTTP_X_TWILIO_SIGNATURE"]; | |
if ($validator->validate($signature, $url, $_POST)) { | |
error_log("Confirmed to have come from Twilio. {$_POST['IdempotencyToken']}"); | |
$client = new Services_Twilio($SUBACCOUNT_SID, $SUBACCOUNT_AUTH_TOKEN); | |
/** | |
* The following two sections are designed to send an SMS if the subaccount is | |
* suspended so that you can investigate. First we are going to retrieve the Usage | |
* Trigger's 'FriendlyName', if available. | |
*/ | |
try{ | |
$usage_trigger = $client->account->usage_triggers->get($_POST['UsageTriggerSid']); | |
$usage_trigger_name = $usage_trigger->friendly_name; | |
} catch (Exception $e) { | |
$usage_trigger_name = $_POST['UsageTriggerSid']; | |
} | |
/** | |
* Send an SMS. It's important to catch errors here because the API may return a | |
* status other than 201 if the $to_number is unreachable. | |
*/ | |
try{ | |
$client->account->sms_messages->create( | |
$from_number, $to_number, | |
"Usage Trigger '{$usage_trigger_name}' just fired. Suspending subaccount." | |
); | |
} catch (Exception $e){ | |
error_log("SMS failed to send: {$e->getMessage()}"); | |
} | |
/** | |
* This is the code to actually suspend the account. Please note, you SHOULD NOT | |
* edit this code to make 'suspended' into 'closed'. Account suspension is | |
* reversible, closing an account is not reversible. | |
*/ | |
$client->account->update(array('Status' => 'suspended')); // Again, NOT 'closed' | |
/** | |
* If you've gotten to this point, you've made it so that your subaccount can no | |
* longer make requests to the API. To reactivate it, you'll need to use your | |
* Master Account. Go to the following page, click on "Switch To Master", then | |
* click the "Make Request" button to reactivate: | |
* https://www.twilio.com/user/account/developer-tools/api-explorer#POST/2010-04-01/Accounts/[AccountSid].[format]?Status=active | |
*/ | |
} |
This file contains hidden or 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 Usage Trigger Manager ### | |
* This is a very simple example of managing Usage Triggers. The API docs are located at: | |
* http://www.twilio.com/docs/api/rest/usage-triggers | |
* | |
* Please note that this is intended as an example, and as such little effort has been | |
* put into securing the application. This code allows a user to make account changes | |
* without being authenticated, it is a good idea to put this behind some sort of login, | |
* in a secure environment, or only use it on your local server. | |
*/ | |
/** | |
* Include twilio-php, the official Twilio PHP Helper Library, which can be found at | |
* https://github.com/twilio/twilio-php | |
* Download the Zip file and copy the 'Services' folder to the same directory as this file. | |
*/ | |
require_once('Services/Twilio.php'); | |
/** | |
* This is the only part you need to change! Insert your Twilio Account credentials: | |
* https://www.twilio.com/user/account | |
*/ | |
$ACCOUNT_SID = 'ACXXXXXXXXXXXX'; //Your Account SID | |
$AUTH_TOKEN = 'YYYYYYYYYYYYY'; //Your Auth Token | |
$client = new Services_Twilio($ACCOUNT_SID, $AUTH_TOKEN); | |
// These POSTs are coming from the form on the bottom of this page. They create Usage Triggers. | |
if ($_POST['usage_category'] && $_POST['trigger_value'] && $_POST['callback_url']) { | |
$client->account->usage_triggers->create ( | |
// Required Params | |
$_POST['usage_category'], | |
$_POST['trigger_value'], | |
$_POST['callback_url'], | |
// Optional Params | |
array( | |
'Recurring' => $_POST['recurring'], | |
'TriggerBy' => $_POST['trigger_by'], | |
) | |
); | |
} | |
// These POSTs come from the 'Delete' button. They delete Usage Triggers. | |
if ($_POST['delete']) { | |
$client->account->usage_triggers->delete($_POST['delete']); | |
} | |
/** | |
* This section is will print a simple table which shows which Usage Triggers are | |
* currently in effect on the account. It will also display a UI for creating | |
* new Usage Triggers. | |
*/ | |
$existingTriggers = $client->account->usage_triggers; | |
?> | |
<!DOCTYPE HTML> | |
<html> | |
<head> | |
<title>Twilio Usage Trigger Manager</title> | |
<link href="http://twitter.github.com/bootstrap/assets/css/bootstrap.css" rel="stylesheet"> | |
</head> | |
<body> | |
<div class="container"> | |
<table class="table table-hover table-condensed"> | |
<tr> | |
<th>Usage Trigger SID</th> | |
<th>Recurring</th> | |
<th>Category</th> | |
<th>Trigger By</th> | |
<th>Trigger Value</th> | |
<th>Callback Url</th> | |
<th>Action</th> | |
</tr> | |
<tbody> | |
<?php | |
foreach ($existingTriggers as $trigger){ | |
echo " | |
<tr> | |
<td>{$trigger->sid}</td> | |
<td>{$trigger->recurring}</td> | |
<td>{$trigger->usage_category}</td> | |
<td>{$trigger->trigger_by}</td> | |
<td>{$trigger->trigger_value}</td> | |
<td>{$trigger->callback_url}</td> | |
<td><form action='' method='post'> | |
<input type='hidden' name='delete' value='{$trigger->sid}'/> | |
<input class='btn btn-danger' type='submit' value='Delete'/> | |
</form> | |
</td> | |
</tr>";} ?> | |
</tbody> | |
</table> | |
<hr/> | |
<h2>Add a Trigger</h2> | |
<form action="" method="post"> | |
<label for="usage_category">Usage Category:</label> | |
<select id="usage_category" name="usage_category"> | |
<option value="sms">SMS</option> | |
<option value="calls">Calls</option> | |
</select> | |
<label for="trigger_by">Trigger By:</label> | |
<select id="trigger_by" name="trigger_by"> | |
<option value="usage">Usage</option> | |
<option value="count">Count</option> | |
<option value="price">Price</option> | |
</select> | |
<label for="trigger_value">Trigger Value:</label> | |
<input type="text" id="trigger_value" name="trigger_value"> | |
<label for="recurring">Recurring:</label> | |
<select id="recurring" name="recurring"> | |
<option value="">Not Recurring</option> | |
<option value="daily">Daily</option> | |
<option value="monthly">Monthly</option> | |
<option value="yearly">Yearly</option> | |
</select> | |
<label for="callback_url">Callback URL:</label> | |
<input type="text" id="callback_url" name="callback_url"><br> | |
<input type="submit" value="Submit"class="btn" /> | |
</form> | |
</div> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment