June 30, 2012

Using Twilio to extend the functionality of Siri

Siri is great for playing music from your iPhone. But if you don’t have the song on your library, Siri can’t go and play it on Spotify, Pandora, Grooveshark, or any of the other players (for now). But if Siri can send a text message to a Twilio number (which I called “Siri Tunes” in my address book), that number can reply with a message linking to an mp3 that can be opened in QuickTime. Watch the demo of the application:

I love building Twilio applications. Contact me if you’re interested having a Twilio application created.

June 20, 2011

Mobile Time Tracking using Twilio and Freshbooks

I use Freshbooks to manage all of my invoicing. I manage projects, log hours, and it allows me to keep a careful track of my business. I’m lucky enough to be connect to the internet when I’m working, but for some companies working out in the field, keeping track of hours has been mostly done on pencil and paper.

I built an application integrating Twilio and Freshbooks to solve this problem. Watch the video below to see my Twilio and Freshbooks time tracking system.

How it works

Since you can only submit a completed time log to FreshBooks, the initial clock in call is stored in a database on a separate server. When the user calls back to clock out, it compares the clock out time with the saved clock in time, and then totals up the hours worked. After we know how many hours were worked, the full time log gets submitted to FreshBooks.

Altogether, I mashed up a few different technologies, including:

  • Twilio Voice API
  • Twilio Transcription API
  • FreshBooks API
  • PHP
  • MySQL

If you’re interested in using this for your company, shoot me a message and I’d be happy to set it up for you, or let you license out the code.

April 2, 2011

Twilio + WhitePages API = Win

I’m currently working on a Twilio application that requires a complete caller ID lookup system. The caller ID that comes on most phones is very basic, and uses something called CNAM (Caller NAMe). Twilio has a simple CNAM function built in that costs $0.01 per query, but CNAM gives pretty skimpy data. These queries only give one line of info and if the person is using a cellphone, it’s likely only going to give you something like “Wireless Caller” or “Cingular Wireless Customer.”

Thank god for the WhitePages API.

It took me quite awhile to find the API, but when I did I let off a big fist pump. Currently their API is in beta, and only allows you to make 200 calls a day (Pro Tip: build up your own database with all the calls you make to save on repete queries). After a quick whois on whitepages.com, I got their office number in Seattle and next thing I know I’m speaking with Jim Nuccitelli, the director in charge of their API. Jim helped push my application along and told me about some upcoming advances in their API (Spoiler: awesomeness to come).

So, I’ve ripped apart their API and am using it to look up info on incoming numbers through Twilio. Below is a PHP function that does a WhitePages lookup for a ten digit phone number and returns an array with the following:

  • First Name
  • Middle Name
  • Last Name
  • Street Address
  • City
  • State
  • Zip
  • Business Name
  • Phone Type (Cell, home, business, etc)
  • Carrier
function phoneNumberLookup($number){
	// $number should be 10 digits, eg] 4565551337
	$apiKey = "XXXXXXXXXXXXXXX";
	$url = "http://api.whitepages.com/reverse_phone/1.0/?phone=$number;api_key=$apiKey";

	global $whitePages;
	$whitePages = array(
	"wpFirstName" => "",
	"wpMiddleName" => "",
	"wpLastName" => "",
	"wpAddressFullStreet" => "",
	"wpAddressCity" => "",
	"wpAddressState" => "",
	"wpAddressZip" => "",
	"wpBusinessName" => "",
	"wpPhoneType" => "",
	"wpCarrier" => ""
	);

	function contents($parser, $data){
		global $nextVar, $whitePages;
		if( ($nextVar != '') && (trim($data) != '') && ($whitePages[$nextVar] == '') ){
			$whitePages[$nextVar] = $data;
		}
	}

	function startTag($parser, $data){
		global $nextVar;
		switch ($data) {
			case "WP:FIRSTNAME":
				$nextVar = 'wpFirstName';
				break;
			case "WP:MIDDLENAME":
				$nextVar = 'wpMiddleName';
				break;
			case "WP:LASTNAME":
				$nextVar = 'wpLastName';
				break;
			case "WP:FULLSTREET":
				$nextVar = 'wpAddressFullStreet';
				break;
			case "WP:CITY":
				$nextVar = 'wpAddressCity';
				break;
			case "WP:STATE":
				$nextVar = 'wpAddressState';
				break;
			case "WP:ZIP":
				$nextVar = 'wpAddressZip';
				break;
			case "WP:BUSINESSNAME":
				$nextVar = 'wpBusinessName';
				break;
			case "WP:TYPE":
				$nextVar = 'wpPhoneType';
				break;
			case "WP:CARRIER":
				$nextVar = 'wpCarrier';
				break;
		}
	}

	function endTag($parser, $data){
	}

	$xml_parser = xml_parser_create();
	xml_set_element_handler($xml_parser, "startTag", "endTag");
	xml_set_character_data_handler($xml_parser, "contents");

	$fp = fopen($url, "r");
	$data = fread($fp, 80000);

	if(!(xml_parse($xml_parser, $data, feof($fp)))){
		die("Error on line " . xml_get_current_line_number($xml_parser));
	}

	xml_parser_free($xml_parser);
	fclose($fp);

	return $whitePages;

}

Since the WhitePages API requires numbers to be in 10 digit format, I’ve also got a tiny function to sanitize a number for this format.

function phoneFormatTenDigits($number){
	// takes numbers like +14565551337, or (456) 555-1337 and turns them to 4565551337
	$number = preg_replace('[\D]', '', $number); // gets rid of all non-digits
	if( substr($number, 0, 1) == '1' ){
		$number = substr($number, 1); // gets rid of the first digit if it's a 1
	}
	return $number;
}

If you used this, say thanks by tweeting out this page.

March 20, 2011

Scrub against temporary email addresses

Validating a user’s email addresses is a must, but most developers just pop in the first premade validation function they find without actually evaluating how effective it is.

Most canned functions simply:

  • Check for the @ symbol
  • Check if the domain has a “dot something” at the end

More advanced ones:

  • Check if the domain is actually registered via cURL or PHP functions like dns_get_record and checkdnsrr
  • Check if the TLD exists (against a list of all known ICANN TLDs)
  • Check for existing accounts with the same email, minus periods and pluses (for services like Gmail where bbqsauce@gmail.com, b.b.q.sauce@gmail.com, and bbq.sauce+tastesgood@gmail.com go to the same inbox)

Still, I have never seen a script to filter against disposable email services. Disposable email services allow users to generate a temporary email addresses in a single click. I’ve used mailinator.com over a dozen times to register for a site that I only want to use once. I never have seen a site filter against it.

So here comes Brian to the rescue, giving all you validation junkies a huge list I complied of 119 disposable email domains to check against. If you prefer, you can download this list as a PHP array.

Disposable Email Domains

mailinator.com
thisisnotmyrealemail.com
mailmetrash.com
mytrashmail.com Continue Reading →