Making An Applet

Hello Monkey v1.3

To finish up our applet we’re going to implement the functionality to add multiple phone numbers to check against and have different actions for each phone number. This is very similar to the menu applet where you can have as many or as few options as you would like.

In order to achieve this, we first need to add a new element to our table in the ui.php file. This element is where the add and remove buttons will go. Next we need to modify the row in the table body, we’ll add a foreach loop that will add the neccessarry table rows with the phone numbers that will be screened as well as the actions to be taken if the caller matches. Also a table footer has been added, this contains a dummy row in it that has blank information. Using javascript we’ll use this dummy row to create new rows in the body as necessary. As you can also see we’ve changed the names of the inputs and the dropzones to arrays. We’ll use the phone numbers entered in as keys, and the dropzone values have been changed to choices.

<?php 
$keys = AppletInstance::getValue('keys[]', array('1','2','3','4'));
$choices = AppletInstance::getValue('choices[]');
?>

<div class="vbx-applet monkey-applet">
	<h2>Create A Custom Message</h2>
	<p>Enter in a custom message that your callers will be greeted by.</p>
	<textarea class="medium" name="prompt-text"><?php 
		echo AppletInstance::getValue('prompt-text') 
	?></textarea>
	
	<br />
	
	<h2>Call Screening Options</h2>
	<table class="vbx-menu-grid options-table">
	<thead>
		<tr>
			<td>Number To Screen</td>
			<td>&nbsp;</td>
			<td>Action if caller matches</td>
			<td>Add &amp; Remove</td>
		</tr>
	</thead>
	<tbody>
	<?php foreach($keys as $i=>$key): ?>
		<tr>
			<td>
				<fieldset class="vbx-input-container">
					<input type="text" class="small" value="<?php echo $key ?>" name="keys[]"/>
				</fieldset>
			</td>
			<td>&nbsp;</td>
			<td>
				<?php echo AppletUI::dropZone('choices['.($i).']', 'Drop item here'); ?>
			</td>
			<td>
				<a href="" class="add action">
					<span class="replace">Add</span></a> <a href="" class="remove action"><span class="replace">Remove</span>
				</a>
			</td>
		</tr>
	<?php endforeach; ?>
	</tbody>
	<tfoot>
		<tr class="hide">
			<td>
				<fieldset class="vbx-input-container">
					<input type="text" class="small" value="" name="keys[]"/>
				</fieldset>
			</td>
			<td>&nbsp;</td>
			<td>
				<?php echo AppletUI::dropZone('new-choices[]', 'Drop item here'); ?>
			</td>
			<td>
				<a class="add action" href="">
					<span class="replace">Add</span>
				</a>
				<a class="remove action" href="">
					<span class="replace">Remove</span>
				</a>
			</td>
		</tr>
	</tfoot>
	</table>

	<h3>Fallback Action</h3>
	<p>This action will be executed if the caller is unknown.</p>
	<?php echo AppletUI::DropZone('fallback'); ?>
</div>
jQuery(function($) {
	// Disable all the template row inputs
	$('.monkey-applet tr.hide input').attr('disabled', 'disabled');

	//This function will create a new row for the table based off 
	// the template in the footer
	$('.monkey-applet .action.add').live('click', function(event) {
		event.preventDefault();
		var row = $(this).closest('tr'),
			wrapper = $(this).parents('.monkey-applet'),
			newRow = $('tfoot tr', wrapper).html();
		
		newRow = $('<tr>' + newRow + '</tr>')
			.show()
			.insertAfter(row);
		
		$('.flowline-item', newRow).droppable(Flows.events.drop.options);
		$('td', newRow).flicker();	
		$('.flowline-item input', newRow).attr('name', 'choices[]');
		$('input.small', newRow).attr('name', 'keys[]');
		
		$('input:visible:first', newRow).removeAttr('disabled').focus();
		$(event.target).parents('.options-table').trigger('change');
		return false;
	});

	//This function removes rows with an animation
	$('.monkey-applet .action.remove').live('click', function() {
		var row = $(this).closest('tr'),
			bgColor = row.css('background-color');
			
		row.animate({
				backgroundColor : '#FEEEBD'
			}, 'fast')
			.fadeOut('fast', function() {
				row.remove();
			});

		return false;
	});
	
	
	$('.monkey-applet .options-table').live('change', function() {
		$('tbody tr', this).first()
			.find('.action.remove').hide();
	});

	$('.monkey-applet .options-table').trigger('change');
});

Finally we need to expand our TwiML to work with our new UI elements. We’re going to create an associative array using the phone number that will be screened as the key, and the value of the dropzone will be the value. We can easily create an associative array using this function, AppletInstance::assocKeyValueCombine(). Now when we need to check what we should do with the caller we can simply use the phone number as the key and see if there is an applet we need to direct the caller to, if there isn’t the fallback option will be used.

<?php
$response = new TwimlResponse;

$choices = AppletInstance::getDropZoneUrl('choices[]');
$keys = AppletInstance::getValue('keys[]');

foreach($keys AS $i=> $key) {
	$keys[$i] = normalize_phone_to_E164($key);
}

$menu_items = AppletInstance::assocKeyValueCombine($keys, $choices);
$fallback = AppletInstance::getDropZoneUrl('fallback');
$text = AppletInstance::getValue('prompt-text');
$caller = normalize_phone_to_E164($_REQUEST['Caller']);

$response->say($text);

if(!empty($menu_items[$caller])) {
	$response->redirect($menu_items[$caller]);
}
else {
	$response->redirect($fallback);
}

$response->respond();

Now when someone calls and this applet is used it will greet them with your custom message and check if the number has a custom option for it, if not the fallback option will be used.

If you’re interested in expanding your Hello Monkey applet besure to check out the Applet API page.

Hello Monkey v1.2