<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Jeff Douglas - Technology, Coding and Bears... OH MY! &#187; Appirio</title>
	<atom:link href="http://blog.jeffdouglas.com/category/appirio/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.jeffdouglas.com</link>
	<description>Get your head out of your #@! and into the clouds!</description>
	<lastBuildDate>Thu, 29 Jul 2010 19:04:52 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=abc</generator>
		<item>
		<title>Install My Salesforce Chatter for Android App on Your Phone</title>
		<link>http://blog.jeffdouglas.com/2010/06/24/install-my-salesforce-chatter-for-android-app-on-your-phone/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=install-my-salesforce-chatter-for-android-app-on-your-phone</link>
		<comments>http://blog.jeffdouglas.com/2010/06/24/install-my-salesforce-chatter-for-android-app-on-your-phone/#comments</comments>
		<pubDate>Thu, 24 Jun 2010 12:15:47 +0000</pubDate>
		<dc:creator>Jeff Douglas</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Appirio]]></category>
		<category><![CDATA[Google App Engine]]></category>
		<category><![CDATA[Salesforce]]></category>

		<guid isPermaLink="false">http://blog.jeffdouglas.com/?p=2706</guid>
		<description><![CDATA[Salesforce.com invited me to attend Cloudforce last Tuesday to demo my Salesforce Chatter for Android app. The reception was incredible and there is a big push to get a Salesforce.com app running on Android. Parker Harris (Co-founder &#038; EVP, Technology) even made the statement in the keynote that, &#8220;I do have a team working on [...]]]></description>
			<content:encoded><![CDATA[<p style="clear: both"><a href="http://blog.jeffdouglas.com/wp-content/uploads/2010/06/cloudforce-logo3.png" class="image-link" rel="lightbox[2706]"><img class="linked-to-original" src="http://blog.jeffdouglas.com/wp-content/uploads/2010/06/cloudforce-logo3-thumb.png" height="98" align="left" width="157" style=" display: inline; float: left; margin: 0 10px 10px 0;" /></a> Salesforce.com invited me to attend Cloudforce last Tuesday to demo my <a href="http://blog.jeffdouglas.com/2010/06/06/salesforce-chatter-for-android/" target="_blank">Salesforce Chatter for Android</a> app. The reception was incredible and there is a big push to get a Salesforce.com app running on Android. Parker Harris (Co-founder &#038; EVP, Technology) even made the statement in the keynote that, &#8220;I do have a team working on a native Android Chatter application that will be out later this year&#8230;.&#8221;. At that point, Narinder promptly tweeted:</p>
<p style="clear: both"><a href="http://blog.jeffdouglas.com/wp-content/uploads/2010/06/chatter-tweet.png" class="image-link" rel="lightbox[2706]"><img class="linked-to-original" src="http://blog.jeffdouglas.com/wp-content/uploads/2010/06/chatter-tweet-thumb.png" height="65" align="left" width="380" style=" display: inline; float: left; margin: 0 10px 10px 0;" /></a><br style="clear: both" /><br />Well that created a lot of buzz so over the last couple of days I&#8217;ve had an amazing number of people email, tweet and post chatter asking me how people can run the Chatter for Android app on their own phones. I checked with Kris Muller at salesforce.com and we&#8217;ve decided to let anyone install the app and try it out. The functionality is limited (you can only view the Chatter feed and post an update) and it is connected to a DE org so you can&#8217;t really screw anything up. If you install the app, <a href="http://blog.jeffdouglas.com/contact-me/" target="_blank">please drop me a line</a> and let me know what you think of it and if you have any suggestions.</p>
<p style="clear: both"><a href="http://blog.jeffdouglas.com/2010/06/06/salesforce-chatter-for-android/chatter-android-thumb-png/" rel="attachment wp-att-2624"><img src="http://blog.jeffdouglas.com/wp-content/uploads/2010/06/chatter-android-thumb-150x150.png" alt="" title="chatter-android-thumb.png" width="150" height="150" class="alignleft size-thumbnail wp-image-2624" /></a>So here&#8217;s a little background and how it get started. The application is combination of the Force.com platform, Google App Engine and a Google Android mobile handset. It utilizes Force.com Remote Access Applications with 3-legged OAuth for security allowing App Engine to fetch chatter feeds and post new status updates using the Force.com Web Services Connector running on App Engine. The Google App Engine app runs at <a href="ttps://chatter-android-demo.appspot.com" target="_blank">https://chatter-android-demo.appspot.com</a>.</p>
<p style="clear: both">The Android client makes a request to refresh it&#8217;s chatter feed and makes a call to <a href="https://chatter-android-demo.appspot.com/newsFeed" target="_blank">this endpoint</a> on App Engine. The WSC queries Salesforce for the chatter feed and returns the feed as a series of JSON objects. The Android client consumes the JSON objects and stores them in the local SQLite database. When the feed list is displayed on the Android client, the images are download lazily from App Engine when needed. You may see a slight lag while new threads are spawned and the images are downloaded. If the images do not display quickly, try scrolling through the list back and forth for them to display. Part of the roadmap is to store these images in the local database instead of downloading them each time.</p>
<p style="clear: both"><strong>Installation Instructions</strong></p>
<p>To install the app on your own phone:</p>
<p style="clear: both">
<ul style="clear: both">
<li>Download either the original <a href="http://chatter-android-demo.appspot.com/AndroidChatter.apk" target="_blank">2.1 application</a> or a <a href="http://chatter-android-demo.appspot.com/AndroidChatter16.apk" target="_blank">1.6+ version</a> that runs on older handsets to your desktop</li>
<li>On your phone, install eoeAppInstaller from the Android Market.</li>
<li>Mount your phone to your computer via your USB cable so that you can access the SD card on your phone from Finder.</li>
<li>Drop the .apk file into the root of your SD card</li>
<li>Unmount your phone and disconnect your USB cable</li>
<li>Go to Settings -> Applications and check &#8220;Unknown Sources&#8221; to allow installation of non-Market applications</li>
<li>Launch eoeAppInstaller and it should display the Salesforce Chatter app </li>
<li>Long press the app and select &#8220;Install this apk&#8221;</li>
</ul>
<p style="clear: both">When you launch the application, simply click anywhere on the white Android/Chatter logo to display the chatter feed. The first time you run the application there will be no chatter updates. You will need to hit Menu -> Refresh to populate the local database with updates. The app is currently set to only return the last 15 updates. The app runs as the user Scott Thompson and you cannot switch to a different user.</p>
<p style="clear: both">If you want to see Salesforce come to the Android platform, <a href="http://sites.force.com/ideaexchange/apex/ideaview?id=08730000000BrqVAAS" target="_blank">please vote for this idea</a>. </p>
<p><br class="final-break" style="clear: both" /></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jeffdouglas.com/2010/06/24/install-my-salesforce-chatter-for-android-app-on-your-phone/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Appirio $1 Million Dollar Cloudsourcing Guarantee</title>
		<link>http://blog.jeffdouglas.com/2010/04/23/appirio-1-million-dollar-cloudsourcing-guarantee/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=appirio-1-million-dollar-cloudsourcing-guarantee</link>
		<comments>http://blog.jeffdouglas.com/2010/04/23/appirio-1-million-dollar-cloudsourcing-guarantee/#comments</comments>
		<pubDate>Fri, 23 Apr 2010 10:35:56 +0000</pubDate>
		<dc:creator>Jeff Douglas</dc:creator>
				<category><![CDATA[Appirio]]></category>
		<category><![CDATA[Cloud Computing]]></category>

		<guid isPermaLink="false">http://blog.jeffdouglas.com/?p=2465</guid>
		<description><![CDATA[In case you missed this yesterday, Appirio announced, &#8220;Appirio will run your IT in the cloud, and save you at least a million dollars&#8221;! Yes, that is the proverbial, &#8220;put your money where your mouth is&#8221;. So what is &#8220;cloudsourcing&#8221;? Cloudsourcing means sourcing complete solutions to run your business on the cloud, through a combination [...]]]></description>
			<content:encoded><![CDATA[<p>In case you missed this yesterday, <a href="http://www.appirio.com/cloudsourcing/1milguarantee.php">Appirio announced</a>, &#8220;Appirio will run your IT in the cloud, and save you at least a million dollars&#8221;! Yes, that is the proverbial, &#8220;put your money where your mouth is&#8221;.</p>
<p>So what is &#8220;cloudsourcing&#8221;? Cloudsourcing means sourcing complete solutions to run your business on the cloud, through a combination of cloud applications, cloud platforms and cloud infrastracuture. Appirio guarantees $1 million in savings for qualified companies that &#8220;cloudsource&#8221; their entire IT to Appirio and the public cloud.</p>
<p>For more info and see if your company qualifies, <a href="http://www.appirio.com/cloudsourcing/1milguarantee.php">check out this page</a>.</p>
<p><span class="youtube">
<object width="480" height="295">
<param name="movie" value="http://www.youtube.com/v/KnFrApjDRcM&amp;color1=d6d6d6&amp;color2=f0f0f0&amp;border=0&amp;fs=1&amp;hl=en&amp;autoplay=0&amp;showinfo=0&amp;iv_load_policy=3&amp;showsearch=0?rel=1&amp;hd=1" />
<param name="allowFullScreen" value="true" />
<embed wmode="transparent" src="http://www.youtube.com/v/KnFrApjDRcM&amp;color1=d6d6d6&amp;color2=f0f0f0&amp;border=0&amp;fs=1&amp;hl=en&amp;autoplay=0&amp;showinfo=0&amp;iv_load_policy=3&amp;showsearch=0?rel=1&amp;hd=1" type="application/x-shockwave-flash" allowfullscreen="true" width="480" height="295"></embed>
<param name="wmode" value="transparent" />
</object>
</span><p><a href="http://www.youtube.com/watch?v=KnFrApjDRcM&fmt=18">www.youtube.com/watch?v=KnFrApjDRcM</a></p></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jeffdouglas.com/2010/04/23/appirio-1-million-dollar-cloudsourcing-guarantee/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Appirio Announces PS Connect at Google Campfire One</title>
		<link>http://blog.jeffdouglas.com/2010/03/10/appirio-announces-ps-connect-at-google-campfire-one/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=appirio-announces-ps-connect-at-google-campfire-one</link>
		<comments>http://blog.jeffdouglas.com/2010/03/10/appirio-announces-ps-connect-at-google-campfire-one/#comments</comments>
		<pubDate>Wed, 10 Mar 2010 14:28:34 +0000</pubDate>
		<dc:creator>Jeff Douglas</dc:creator>
				<category><![CDATA[Appirio]]></category>
		<category><![CDATA[Cloud Computing]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Salesforce]]></category>
		<category><![CDATA[The Internet Business]]></category>

		<guid isPermaLink="false">http://blog.jeffdouglas.com/?p=2307</guid>
		<description><![CDATA[Last night at Google Campfire One we demonstrated PS Connect, a new extension to our PS Enterprise product that allows service professionals to run their business directly from their Gmail inbox. We were the closing presentation for the night and you can view the video of the demo below. It&#8217;s roughly a 5 minute video [...]]]></description>
			<content:encoded><![CDATA[<p style="clear: both"><a href="http://blog.jeffdouglas.com/wp-content/uploads/2010/03/PSConnect2.gif" class="image-link" rel="lightbox"><img class="linked-to-original" src="http://blog.jeffdouglas.com/wp-content/uploads/2010/03/PSConnect2-thumb.gif" height="136" align="left" width="200" style=" display: inline; float: left; margin: 0 10px 10px 0;" /></a>Last night at <a href="http://code.google.com/campfire/">Google Campfire One</a> we demonstrated <a href="http://www.appirio.com/products/PSEconnect.php" target="_blank">PS Connect</a>, a new extension to our PS Enterprise product that allows service professionals to run their business <strong><em>directly from their Gmail inbox</em></strong>. We were the closing presentation for the night and you can view the video of the demo below. It&#8217;s roughly a 5 minute video and is really great!</strong></p>
<p style="clear: both">So what is PS Connect? PS Connect allows you to use Google Apps as a front end to cloud-based business applications. With our Gmail contextual gadgets you can take actions from inside your Gmail inbox instead of logging into multiple systems.</p>
<p>You can read the <a href="http://blog.appirio.com/2010/03/google-campfire-one-enterprise-apps-get.html" target="_blank">full announcement</a> on our website or get <a href="http://www.appirio.com/products/PSEconnect.php" target="_blank">more info on PS Connect</a>. If you&#8217;d like a deeper dive, you can even sign up for a <a href="http://thecloud.appirio.com/PSE-Demo.html" target="_blank">30 minute demo</a>.</p>
<p style="clear: both"><span class="youtube">
<object width="480" height="295">
<param name="movie" value="http://www.youtube.com/v/sO0gSFBlhrI&amp;color1=d6d6d6&amp;color2=f0f0f0&amp;border=0&amp;fs=1&amp;hl=en&amp;autoplay=0&amp;showinfo=0&amp;iv_load_policy=3&amp;showsearch=0?rel=1&amp;hd=1" />
<param name="allowFullScreen" value="true" />
<embed wmode="transparent" src="http://www.youtube.com/v/sO0gSFBlhrI&amp;color1=d6d6d6&amp;color2=f0f0f0&amp;border=0&amp;fs=1&amp;hl=en&amp;autoplay=0&amp;showinfo=0&amp;iv_load_policy=3&amp;showsearch=0?rel=1&amp;hd=1" type="application/x-shockwave-flash" allowfullscreen="true" width="480" height="295"></embed>
<param name="wmode" value="transparent" />
</object>
</span><p><a href="http://www.youtube.com/watch?v=sO0gSFBlhrI&fmt=18">www.youtube.com/watch?v=sO0gSFBlhrI</a></p></p>
<p><br class="final-break" style="clear: both" /></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jeffdouglas.com/2010/03/10/appirio-announces-ps-connect-at-google-campfire-one/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Appirio Company Retreat 2010</title>
		<link>http://blog.jeffdouglas.com/2010/01/28/appirio-company-retreat-2010/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=appirio-company-retreat-2010</link>
		<comments>http://blog.jeffdouglas.com/2010/01/28/appirio-company-retreat-2010/#comments</comments>
		<pubDate>Thu, 28 Jan 2010 14:05:35 +0000</pubDate>
		<dc:creator>Jeff Douglas</dc:creator>
				<category><![CDATA[Appirio]]></category>

		<guid isPermaLink="false">http://blog.jeffdouglas.com/2010/01/28/appirio-company-retreat-2010/</guid>
		<description><![CDATA[We had our first annual company retreat at the Boulder Resort in Phoenix AZ this week as a chance to recharge and focus on our goals for 2010. Since 75% of the company works virtually, it&#8217;s nice to get together with 150 of your closest friends. There as quite a bit of eating, drinking, laughing [...]]]></description>
			<content:encoded><![CDATA[<p style="clear: both"><a href="http://blog.jeffdouglas.com/wp-content/uploads/2010/01/boulders.png" class="image-link" rel="lightbox"><img class="linked-to-original" src="http://blog.jeffdouglas.com/wp-content/uploads/2010/01/boulders-thumb4.png" height="180" align="left" width="300" style=" display: inline; float: left; margin: 0 10px 10px 0;" /></a>We had our first annual company retreat at the Boulder Resort in Phoenix AZ this week as a chance to recharge and focus on our goals for 2010. Since 75% of the company works virtually, it&#8217;s nice to get together with 150 of your closest friends. There as quite a bit of eating, drinking, laughing and even some friendly public embarrassment of senior management. There were life-sized posters created, very &#8220;revealing&#8221; post cards delivered to everyone&#8217;s room and even an old karaoke video of one of the founders (Narinder) that popped up. The meeting is still underway today with sales and senior management and they are working hard. On the way out I heard reference to a management dodgeball game scheduled to settle some internal disputes.</p>
<p style="clear: both"><strong>Update</strong>: The photographer just posted some <a href="http://christinechangphoto.blogspot.com/2010/01/appirio-retreat.html">photos on her blog</a> that are really cool! I like her comment at the bottom of the page, so check that out as well.</p>
<p style="clear: both"><a href="http://blog.jeffdouglas.com/wp-content/uploads/2010/01/boulders2.jpg" class="image-link" rel="lightbox"><img class="linked-to-original" src="http://blog.jeffdouglas.com/wp-content/uploads/2010/01/boulders2-thumb1.jpg" height="207" align="right" width="275" style=" display: inline; float: right; margin: 0 0 10px 10px;" /></a>Even though the event was about having fun and reinforcing our <strong>great</strong> team culture, we did manage to get some work done. We outlined our goals for 2010, set some new strategies in motion and even unveiled some incredibly awesome new &#8220;stuff&#8221; that we will be rolling out this year (the first rule of Fight Club is&#8230;.?). One of our main topics was how do we keep our hardworking-funloving-cuttingedgetechnologydriven-smacktalking culture intact while essentially doubling the company each year. It&#8217;s nice to see that management </p>
<p style="clear: both"><a href="http://blog.jeffdouglas.com/wp-content/uploads/2010/01/photo.jpg" class="image-link" rel="lightbox"><img class="linked-to-original" src="http://blog.jeffdouglas.com/wp-content/uploads/2010/01/photo-thumb1.jpg" height="268" align="left" width="200" style=" display: inline; float: left; margin: 0 10px 10px 0;" /></a>One thing that we are very proud of is that we rolled out our new community involvement program that encourages and rewards employees for becoming involved in their community. We even kicked off the program with a team building event with an entire afternoon spent at the <a href="http://www.mcdowellsonoran.org/" target="_blank">McDowell Sonoran Conservancy</a> (yes, the desert) where we raked dirt, planted hundreds of cactus, moved rocks from point A to point B and generally made the desert a more presentable place. I think we actually outworked their expectations as we ran out of stuff plant, move and cleanse. I&#8217;m not sure how that happened.</p>
<p style="clear: both"><a href="http://www.appirio.com" target="_blank">Appirio</a> is a fantastic place to work and <a href="http://www.appirio.com/company/careers.php" target="_blank">we are always hiring</a> smart, hard-working people that love drinking the cloud computing koolaid. If you are interested, drop me a line or check out the link above.</p>
<p style="clear: both">
<p><br class="final-break" style="clear: both" /></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jeffdouglas.com/2010/01/28/appirio-company-retreat-2010/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Calling a REST Web Service (JSON) with Apex</title>
		<link>http://blog.jeffdouglas.com/2010/01/06/calling-a-json-rest-web-service-with-apex/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=calling-a-json-rest-web-service-with-apex</link>
		<comments>http://blog.jeffdouglas.com/2010/01/06/calling-a-json-rest-web-service-with-apex/#comments</comments>
		<pubDate>Wed, 06 Jan 2010 12:22:38 +0000</pubDate>
		<dc:creator>Jeff Douglas</dc:creator>
				<category><![CDATA[Apex]]></category>
		<category><![CDATA[Appirio]]></category>
		<category><![CDATA[Code Sample]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Salesforce]]></category>
		<category><![CDATA[Visualforce]]></category>

		<guid isPermaLink="false">http://blog.jeffdouglas.com/?p=1953</guid>
		<description><![CDATA[Cross-posted at the Appirio Tech Blog. Using JSON RESTful Web Services with Salesforce.com opens up your org to a number third-party integration opportunities (Google, Yahoo!, Flickr, bespoke, etc.). JSON support isn&#8217;t baked into the Force.com platform but Ron Hess at Salesforce.com has created a JSON parser which will do the heavy lifting for you. Last [...]]]></description>
			<content:encoded><![CDATA[<p>Cross-posted at the <a href="http://techblog.appirio.com/2010/01/calling-rest-web-service-json-with-apex.html" target="_blank">Appirio Tech Blog</a>.</p>
<p>Using JSON RESTful Web Services with Salesforce.com opens up your org to a number third-party integration opportunities (Google, Yahoo!, Flickr, bespoke, etc.). <a href="http://json.org" target="_blank">JSON</a> support isn&#8217;t baked into the Force.com platform but <a href="http://twitter.com/vnehess">Ron Hess</a> at Salesforce.com has created a <a href="http://code.google.com/p/apex-library/">JSON parser</a> which will do the heavy lifting for you.</p>
<p>Last month I wrote a <a href="http://blog.jeffdouglas.com/2009/12/04/calling-a-rest-web-service-with-apex/" target="_blank">blog post</a> and example of how to call a REST Web Service with Apex that returns and consumes XML. It was my intention to do the same demo using JSON, however, I ran into a small sang. I couldn’t get the Apex JSONObject parser to work. I tried on and off for a couple of days but couldn&#8217;t beat it into submission. I checked around the twitter-verse and no one reported much success using the JSON parser with complex objects. I <a href="http://blog.jeffdouglas.com/2009/12/28/problems-parsing-json-responses-with-apex/" target="_blank">finally cried &#8220;uncle&#8221;</a> and called Ron and asked for help. Ron was extremely responsive and over the course of a couple of days we worked worked through some of the <a href="http://code.google.com/p/apex-library/source/detail?r=13" target="_blank">parsing issues</a> and finally updated the Google project with the changes.</p>
<p><a href="https://jeffdouglas-developer-edition.na5.force.com/examples/RestDemoJson" target="_blank"><img src="http://blog.jeffdouglas.com/wp-content/uploads/2010/01/REST-Json.png" alt="" title="REST-Json" width="500" class="alignnone size-full wp-image-1966" /></a></p>
<p>I put together a small demo where you enter your address and the Apex code fetches the address and coordinates from the Google Maps . The service returns the data as a JSON object. <strong>You can <a href="https://jeffdouglas-developer-edition.na5.force.com/examples/RestDemoJson" target="_blank">run this example</a> on my Developer Site.</strong></p>
<p>To get started, you&#8217;ll need to <a href=" http://code.google.com/p/apex-library/source/browse/trunk/JSONObject/src/unpackaged/classes/JSONObject.cls" target="_blank">download the JSONObject class</a> and install it into a Developer org or Sandbox. Unfortunately there is no documentation for the parser so you have to extrapolate from the <a href="http://www.json.org/" target="_blank">json.org</a> website.</p>
<p>You&#8217;ll also need to <a href="http://code.google.com/apis/maps/signup.html" target="_blank">sign up for a Google Maps API key</a> in order to use their geocoding service. I would also recommend that you take a <a href="http://code.google.com/apis/maps/documentation/geocoding/#JSON" target="_blank">look at the docs</a> for Google Maps geocoding service.</p>
<p>Here is the Controller for the demo. The interesting stuff is in the getAddress() and toGeoResult() methods. In getAddress(), the user-entered address is used to construct the URL for the GET call to the geocoding service. Make sure you properly encode the address or you may receive undesirable results returned from Google. One thing to point out is line #58. Google is returning a line feed in their JSON response which causes the JSON parser to choke. I simply replace all like feeds with spaces and that did the trick. Ron was going to look into making this change to the JSONObject class in the near future.</p>
<p>I was also having some problems with the geocoding service so I hard-coded the returned JSON object for testing. I checked around and it seems to be a <a href="http://www.google.com/search?hl=en&#038;q=google+maps+620+error&#038;aq=f&#038;oq=&#038;aqi=g1" target="_blank">common problem</a> that the Google Maps API randomly returns 620 errors when overloaded. <strong>You might want to take a look at the <a href="http://maps.google.com/maps/geo?q=1600+Amphitheatre+Parkway,+Mountain+View,+CA&#038;output=json&#038;sensor=false" target="_blank">JSON response returned</a> for the hard-coded address.</strong> I will give you a little insight for the parsing process.</p>
<p>The toGeoResult() method parses the returned JSON response and populates the GeoResult object with the appropriate data. I chose this Google Maps example because it shows how to parse simple values, nested JSON objects and arrays. The coordinates for the address can either be returned as integers or doubles so I have to check each one.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
</pre></td><td class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> RestDemoJsonController <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">String</span> geoAddress <span style="color: #009900;">&#123;</span>get<span style="color: #339933;">;</span>set<span style="color: #339933;">;</span><span style="color: #009900;">&#125;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">String</span> address <span style="color: #009900;">&#123;</span>get<span style="color: #339933;">;</span>set<span style="color: #339933;">;</span><span style="color: #009900;">&#125;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">String</span> city <span style="color: #009900;">&#123;</span>get<span style="color: #339933;">;</span>set<span style="color: #339933;">;</span><span style="color: #009900;">&#125;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">String</span> state <span style="color: #009900;">&#123;</span>get<span style="color: #339933;">;</span>set<span style="color: #339933;">;</span><span style="color: #009900;">&#125;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">Boolean</span> useGoogle <span style="color: #009900;">&#123;</span>get<span style="color: #339933;">;</span>set<span style="color: #339933;">;</span><span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// google api key</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">String</span> apiKey <span style="color: #009900;">&#123;</span>get<span style="color: #339933;">;</span>set <span style="color: #009900;">&#123;</span> apiKey <span style="color: #339933;">=</span> <span style="color: #0000ff;">'ABQIAAAAlI0DHB0p0WGX35GrKEAzQhTwZth5GdZI-P7ekoe_gyhfzl1yZhRAYdM-hb7aEWu30fGchcvGuwuUqg'</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span> <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// method called by the Visualforce page's submit button</span>
    <span style="color: #000000; font-weight: bold;">public</span> PageReference submit<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
    	<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>address.<span style="color: #006633;">length</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    		ApexPages.<span style="color: #006633;">addMessage</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> ApexPages.<span style="color: #006633;">message</span><span style="color: #009900;">&#40;</span>ApexPages.<span style="color: #006633;">severity</span>.<span style="color: #006633;">ERROR</span>,<span style="color: #0000ff;">'Address cannot be blank'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    	<span style="color: #009900;">&#125;</span>
    	<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>city.<span style="color: #006633;">length</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    		ApexPages.<span style="color: #006633;">addMessage</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> ApexPages.<span style="color: #006633;">message</span><span style="color: #009900;">&#40;</span>ApexPages.<span style="color: #006633;">severity</span>.<span style="color: #006633;">ERROR</span>,<span style="color: #0000ff;">'City cannot be blank'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    	<span style="color: #009900;">&#125;</span>
    	<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>state.<span style="color: #006633;">length</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    		ApexPages.<span style="color: #006633;">addMessage</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> ApexPages.<span style="color: #006633;">message</span><span style="color: #009900;">&#40;</span>ApexPages.<span style="color: #006633;">severity</span>.<span style="color: #006633;">ERROR</span>,<span style="color: #0000ff;">'State cannot be blank'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    	<span style="color: #009900;">&#125;</span>
&nbsp;
    	<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>ApexPages.<span style="color: #006633;">hasMessages</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
	    	geoAddress <span style="color: #339933;">=</span> getAddress<span style="color: #009900;">&#40;</span>address,city,state<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    	<span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// call the geocoding service</span>
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">String</span> getAddress<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> street, <span style="color: #003399;">String</span> city, <span style="color: #003399;">String</span> state<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
		<span style="color: #003399;">String</span> json<span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #666666; font-style: italic;">// hard-coded returned JSON response from Google</span>
		<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>useGoogle<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			json <span style="color: #339933;">=</span> <span style="color: #0000ff;">'{  &quot;name&quot;: &quot;1600 Amphitheatre Parkway, Mountain View, CA&quot;,  &quot;Status&quot;: {    &quot;code&quot;: 200,    &quot;request&quot;: &quot;geocode&quot;  },  &quot;Placemark&quot;: [ {    &quot;id&quot;: &quot;p1&quot;,    &quot;address&quot;: &quot;1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA&quot;,    &quot;AddressDetails&quot;: {   &quot;Accuracy&quot; : 8,   &quot;Country&quot; : {      &quot;AdministrativeArea&quot; : {         &quot;AdministrativeAreaName&quot; : &quot;CA&quot;,         &quot;SubAdministrativeArea&quot; : {            &quot;Locality&quot; : {               &quot;LocalityName&quot; : &quot;Mountain View&quot;,               &quot;PostalCode&quot; : {                  &quot;PostalCodeNumber&quot; : &quot;94043&quot;               },               &quot;Thoroughfare&quot; : {                  &quot;ThoroughfareName&quot; : &quot;1600 Amphitheatre Pkwy&quot;               }            },         '</span><span style="color: #339933;">+</span>
			<span style="color: #0000ff;">'   &quot;SubAdministrativeAreaName&quot; : &quot;Santa Clara&quot;         }      },      &quot;CountryName&quot; : &quot;USA&quot;,      &quot;CountryNameCode&quot; : &quot;US&quot;   }},    &quot;ExtendedData&quot;: {      &quot;LatLonBox&quot;: {        &quot;north&quot;: 37.4251466,        &quot;south&quot;: 37.4188514,        &quot;east&quot;: -122.0811574,        &quot;west&quot;: -122.0874526      }    },    &quot;Point&quot;: {      &quot;coordinates&quot;: [ -122.0843700, 37.4217590, 0 ]    }  } ]}	'</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #666666; font-style: italic;">// call the geocoding service live</span>
		<span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
&nbsp;
			HttpRequest req <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> HttpRequest<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			Http http <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Http<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #666666; font-style: italic;">// set the method</span>
			req.<span style="color: #006633;">setMethod</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'GET'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #666666; font-style: italic;">// generate the url for the request</span>
			<span style="color: #003399;">String</span> url <span style="color: #339933;">=</span> <span style="color: #0000ff;">'http://maps.google.com/maps/geo?q='</span><span style="color: #339933;">+</span> EncodingUtil.<span style="color: #006633;">urlEncode</span><span style="color: #009900;">&#40;</span>street,<span style="color: #0000ff;">'UTF-8'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">+</span><span style="color: #0000ff;">',+'</span>
				<span style="color: #339933;">+</span> EncodingUtil.<span style="color: #006633;">urlEncode</span><span style="color: #009900;">&#40;</span>city,<span style="color: #0000ff;">'UTF-8'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">+</span><span style="color: #0000ff;">',+'</span>
				<span style="color: #339933;">+</span> EncodingUtil.<span style="color: #006633;">urlEncode</span><span style="color: #009900;">&#40;</span>state,<span style="color: #0000ff;">'UTF-8'</span><span style="color: #009900;">&#41;</span>
				<span style="color: #339933;">+</span><span style="color: #0000ff;">'&amp;output=json&amp;sensor=false&amp;key='</span><span style="color: #339933;">+</span>apiKey<span style="color: #339933;">;</span>
			<span style="color: #666666; font-style: italic;">// add the endpoint to the request</span>
			req.<span style="color: #006633;">setEndpoint</span><span style="color: #009900;">&#40;</span>url<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #666666; font-style: italic;">// create the response object</span>
			HTTPResponse resp <span style="color: #339933;">=</span> http.<span style="color: #006633;">send</span><span style="color: #009900;">&#40;</span>req<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #666666; font-style: italic;">// the geocoding service is returning a line feed so parse it out</span>
			json <span style="color: #339933;">=</span> resp.<span style="color: #006633;">getBody</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">replace</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'<span style="color: #000099; font-weight: bold;">\n</span>'</span>, <span style="color: #0000ff;">''</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #009900;">&#125;</span>
&nbsp;
		<span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span>
			JSONObject j <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> JSONObject<span style="color: #009900;">&#40;</span> json <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #000000; font-weight: bold;">return</span> toGeoResult<span style="color: #009900;">&#40;</span>j<span style="color: #009900;">&#41;</span>.<span style="color: #006633;">toDisplayString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span>JSONObject.<span style="color: #006633;">JSONException</span> e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #000000; font-weight: bold;">return</span> <span style="color: #0000ff;">'Error parsing JSON response from Google: '</span><span style="color: #339933;">+</span>e<span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// utility method to convert the JSON object to the inner class</span>
	<span style="color: #000000; font-weight: bold;">private</span> GeoResult toGeoResult<span style="color: #009900;">&#40;</span>JSONObject resp<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
		GeoResult geo <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> GeoResult<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span>
&nbsp;
			geo.<span style="color: #006633;">address</span> <span style="color: #339933;">=</span> resp.<span style="color: #006633;">getValue</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Placemark'</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">values</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span>.<span style="color: #006633;">obj</span>.<span style="color: #006633;">getValue</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'address'</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">str</span><span style="color: #339933;">;</span>
			geo.<span style="color: #006633;">keys</span> <span style="color: #339933;">=</span> resp.<span style="color: #006633;">keys</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			geo.<span style="color: #006633;">name</span> <span style="color: #339933;">=</span> resp.<span style="color: #006633;">getString</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'name'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			geo.<span style="color: #006633;">statusCode</span> <span style="color: #339933;">=</span> resp.<span style="color: #006633;">getValue</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Status'</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">obj</span>.<span style="color: #006633;">getValue</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'code'</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">num</span><span style="color: #339933;">;</span>
&nbsp;
			<span style="color: #666666; font-style: italic;">// set the coordinates - they may either be integers or doubles</span>
			geo.<span style="color: #006633;">coordinate1</span> <span style="color: #339933;">=</span> resp.<span style="color: #006633;">getValue</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Placemark'</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">values</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span>.<span style="color: #006633;">obj</span>.<span style="color: #006633;">getValue</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Point'</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">obj</span>.<span style="color: #006633;">getValue</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'coordinates'</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">values</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span>.<span style="color: #006633;">num</span> <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">NULL</span> <span style="color: #339933;">?</span> resp.<span style="color: #006633;">getValue</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Placemark'</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">values</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span>.<span style="color: #006633;">obj</span>.<span style="color: #006633;">getValue</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Point'</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">obj</span>.<span style="color: #006633;">getValue</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'coordinates'</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">values</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span>.<span style="color: #006633;">num</span>.<span style="color: #006633;">format</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">:</span> resp.<span style="color: #006633;">getValue</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Placemark'</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">values</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span>.<span style="color: #006633;">obj</span>.<span style="color: #006633;">getValue</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Point'</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">obj</span>.<span style="color: #006633;">getValue</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'coordinates'</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">values</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span>.<span style="color: #006633;">dnum</span>.<span style="color: #006633;">format</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			geo.<span style="color: #006633;">coordinate2</span> <span style="color: #339933;">=</span> resp.<span style="color: #006633;">getValue</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Placemark'</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">values</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span>.<span style="color: #006633;">obj</span>.<span style="color: #006633;">getValue</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Point'</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">obj</span>.<span style="color: #006633;">getValue</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'coordinates'</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">values</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span>.<span style="color: #006633;">num</span> <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">NULL</span> <span style="color: #339933;">?</span> resp.<span style="color: #006633;">getValue</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Placemark'</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">values</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span>.<span style="color: #006633;">obj</span>.<span style="color: #006633;">getValue</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Point'</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">obj</span>.<span style="color: #006633;">getValue</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'coordinates'</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">values</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span>.<span style="color: #006633;">num</span>.<span style="color: #006633;">format</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">:</span> resp.<span style="color: #006633;">getValue</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Placemark'</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">values</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span>.<span style="color: #006633;">obj</span>.<span style="color: #006633;">getValue</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Point'</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">obj</span>.<span style="color: #006633;">getValue</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'coordinates'</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">values</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span>.<span style="color: #006633;">dnum</span>.<span style="color: #006633;">format</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			geo.<span style="color: #006633;">coordinate3</span> <span style="color: #339933;">=</span> resp.<span style="color: #006633;">getValue</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Placemark'</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">values</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span>.<span style="color: #006633;">obj</span>.<span style="color: #006633;">getValue</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Point'</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">obj</span>.<span style="color: #006633;">getValue</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'coordinates'</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">values</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span>.<span style="color: #006633;">num</span> <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">NULL</span> <span style="color: #339933;">?</span> resp.<span style="color: #006633;">getValue</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Placemark'</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">values</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span>.<span style="color: #006633;">obj</span>.<span style="color: #006633;">getValue</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Point'</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">obj</span>.<span style="color: #006633;">getValue</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'coordinates'</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">values</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span>.<span style="color: #006633;">num</span>.<span style="color: #006633;">format</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">:</span> resp.<span style="color: #006633;">getValue</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Placemark'</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">values</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span>.<span style="color: #006633;">obj</span>.<span style="color: #006633;">getValue</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Point'</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">obj</span>.<span style="color: #006633;">getValue</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'coordinates'</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">values</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span>.<span style="color: #006633;">dnum</span>.<span style="color: #006633;">format</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">Exception</span> e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #666666; font-style: italic;">// #fail</span>
		<span style="color: #009900;">&#125;</span>
&nbsp;
		<span style="color: #000000; font-weight: bold;">return</span> geo<span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// inner class</span>
	<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">class</span> GeoResult <span style="color: #009900;">&#123;</span>
&nbsp;
		<span style="color: #000000; font-weight: bold;">public</span> Set<span style="color: #339933;">&lt;</span>string<span style="color: #339933;">&gt;</span> keys<span style="color: #339933;">;</span>
		<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">Integer</span> statusCode<span style="color: #339933;">;</span>
		<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">String</span> name<span style="color: #339933;">;</span>
		<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">String</span> coordinate1<span style="color: #339933;">;</span>
		<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">String</span> coordinate2<span style="color: #339933;">;</span>
		<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">String</span> coordinate3<span style="color: #339933;">;</span>
		<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">String</span> address<span style="color: #339933;">;</span>
		<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">String</span> toDisplayString<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #000000; font-weight: bold;">return</span> address <span style="color: #339933;">+</span> <span style="color: #0000ff;">' ['</span>
			<span style="color: #339933;">+</span> coordinate1 <span style="color: #339933;">+</span> <span style="color: #0000ff;">', '</span>
			<span style="color: #339933;">+</span> coordinate2 <span style="color: #339933;">+</span> <span style="color: #0000ff;">', '</span>
			<span style="color: #339933;">+</span> coordinate3 <span style="color: #339933;">+</span> <span style="color: #0000ff;">'] - Status: '</span>
			<span style="color: #339933;">+</span> statusCode<span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>The Visualforce page is fairly simple and presents the user with a form to enter their address. If the geocoding services is experiencing issues, the user can check &#8220;Use hard-coded Google JSON response?&#8221; and the Controller with use the hard-coded JSON response instead of making the GET call to the geocoding service. Once submitted, the address is processed and the outputPanel is rerendered with the resulting address and coordinates.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
</pre></td><td class="code"><pre class="java" style="font-family:monospace;"><span style="color: #339933;">&lt;</span>apex<span style="color: #339933;">:</span>page controller<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;RestDemoJsonController&quot;</span> tabStyle<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;Contact&quot;</span><span style="color: #339933;">&gt;</span>
	<span style="color: #339933;">&lt;</span>apex<span style="color: #339933;">:</span>sectionHeader title<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;Google Maps Geocoding&quot;</span> subtitle<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;REST Demo (JSON)&quot;</span><span style="color: #339933;">/&gt;</span>
&nbsp;
     <span style="color: #339933;">&lt;</span>apex<span style="color: #339933;">:</span>form <span style="color: #339933;">&gt;</span>
     <span style="color: #339933;">&lt;</span>apex<span style="color: #339933;">:</span>pageBlock <span style="color: #339933;">&gt;</span>
&nbsp;
          <span style="color: #339933;">&lt;</span>apex<span style="color: #339933;">:</span>pageBlockButtons <span style="color: #339933;">&gt;</span>
              <span style="color: #339933;">&lt;</span>apex<span style="color: #339933;">:</span>commandButton action<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;{!submit}&quot;</span> value<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;Submit&quot;</span>
                   rerender<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;resultsPanel&quot;</span> status<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;status&quot;</span><span style="color: #339933;">/&gt;</span>
          <span style="color: #339933;">&lt;/</span>apex<span style="color: #339933;">:</span>pageBlockButtons<span style="color: #339933;">&gt;</span>
          <span style="color: #339933;">&lt;</span>apex<span style="color: #339933;">:</span>pageMessages <span style="color: #339933;">/&gt;</span>
&nbsp;
          <span style="color: #000000; font-weight: bold;">This</span> example calls the Google <span style="color: #003399;">Map</span> geocoding REST service <span style="color: #009900;">&#40;</span>JSON<span style="color: #009900;">&#41;</span> with the address
          you provide below.<span style="color: #339933;">&lt;</span>p<span style="color: #339933;">/&gt;</span>
&nbsp;
          Sometimes the geocoding services stops responding due to service availability. <span style="color: #000000; font-weight: bold;">If</span> you are receiving errors
          with the returned JSON object, you can check the <span style="color: #0000ff;">&quot;Use hard-coded JSON response&quot;</span> to use a returned JSON
          response hard<span style="color: #339933;">-</span>coded into the controller from the Googles address.<span style="color: #339933;">&lt;</span>p<span style="color: #339933;">/&gt;</span>
&nbsp;
          <span style="color: #339933;">&lt;</span>apex<span style="color: #339933;">:</span>pageBlockSection <span style="color: #339933;">&gt;</span>
               <span style="color: #339933;">&lt;</span>apex<span style="color: #339933;">:</span>pageBlockSectionItem <span style="color: #339933;">&gt;</span>
                    <span style="color: #339933;">&lt;</span>apex<span style="color: #339933;">:</span>outputLabel <span style="color: #000000; font-weight: bold;">for</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;address&quot;</span><span style="color: #339933;">&gt;</span>Address<span style="color: #339933;">&lt;/</span>apex<span style="color: #339933;">:</span>outputLabel<span style="color: #339933;">&gt;</span>
                    <span style="color: #339933;">&lt;</span>apex<span style="color: #339933;">:</span>inputText id<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;address&quot;</span> value<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;{!address}&quot;</span><span style="color: #339933;">/&gt;</span>
               <span style="color: #339933;">&lt;/</span>apex<span style="color: #339933;">:</span>pageBlockSectionItem<span style="color: #339933;">&gt;</span>
          <span style="color: #339933;">&lt;/</span>apex<span style="color: #339933;">:</span>pageBlockSection<span style="color: #339933;">&gt;</span>
&nbsp;
          <span style="color: #339933;">&lt;</span>apex<span style="color: #339933;">:</span>pageBlockSection <span style="color: #339933;">&gt;</span>
               <span style="color: #339933;">&lt;</span>apex<span style="color: #339933;">:</span>pageBlockSectionItem <span style="color: #339933;">&gt;</span>
                    <span style="color: #339933;">&lt;</span>apex<span style="color: #339933;">:</span>outputLabel <span style="color: #000000; font-weight: bold;">for</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;city&quot;</span><span style="color: #339933;">&gt;</span>City<span style="color: #339933;">&lt;/</span>apex<span style="color: #339933;">:</span>outputLabel<span style="color: #339933;">&gt;</span>
                    <span style="color: #339933;">&lt;</span>apex<span style="color: #339933;">:</span>inputText id<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;city&quot;</span> value<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;{!city}&quot;</span><span style="color: #339933;">/&gt;</span>
               <span style="color: #339933;">&lt;/</span>apex<span style="color: #339933;">:</span>pageBlockSectionItem<span style="color: #339933;">&gt;</span>
          <span style="color: #339933;">&lt;/</span>apex<span style="color: #339933;">:</span>pageBlockSection<span style="color: #339933;">&gt;</span>
&nbsp;
          <span style="color: #339933;">&lt;</span>apex<span style="color: #339933;">:</span>pageBlockSection <span style="color: #339933;">&gt;</span>
               <span style="color: #339933;">&lt;</span>apex<span style="color: #339933;">:</span>pageBlockSectionItem <span style="color: #339933;">&gt;</span>
                    <span style="color: #339933;">&lt;</span>apex<span style="color: #339933;">:</span>outputLabel <span style="color: #000000; font-weight: bold;">for</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;state&quot;</span><span style="color: #339933;">&gt;</span>State<span style="color: #339933;">&lt;/</span>apex<span style="color: #339933;">:</span>outputLabel<span style="color: #339933;">&gt;</span>
                    <span style="color: #339933;">&lt;</span>apex<span style="color: #339933;">:</span>inputText id<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;state&quot;</span> value<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;{!state}&quot;</span><span style="color: #339933;">/&gt;</span>
               <span style="color: #339933;">&lt;/</span>apex<span style="color: #339933;">:</span>pageBlockSectionItem<span style="color: #339933;">&gt;</span>
          <span style="color: #339933;">&lt;/</span>apex<span style="color: #339933;">:</span>pageBlockSection<span style="color: #339933;">&gt;&lt;</span>br<span style="color: #339933;">/&gt;</span>
&nbsp;
          <span style="color: #339933;">&lt;</span>apex<span style="color: #339933;">:</span>pageBlockSection <span style="color: #339933;">&gt;</span>
               <span style="color: #339933;">&lt;</span>apex<span style="color: #339933;">:</span>pageBlockSectionItem <span style="color: #339933;">&gt;</span>
                    <span style="color: #339933;">&lt;</span>apex<span style="color: #339933;">:</span>outputLabel <span style="color: #000000; font-weight: bold;">for</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;useGoogle&quot;</span><span style="color: #339933;">&gt;</span>Use hard<span style="color: #339933;">-</span>coded Google JSON response<span style="color: #339933;">?&lt;/</span>apex<span style="color: #339933;">:</span>outputLabel<span style="color: #339933;">&gt;</span>
                    <span style="color: #339933;">&lt;</span>apex<span style="color: #339933;">:</span>inputCheckbox id<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;useGoogle&quot;</span> value<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;{!useGoogle}&quot;</span><span style="color: #339933;">/&gt;</span>
               <span style="color: #339933;">&lt;/</span>apex<span style="color: #339933;">:</span>pageBlockSectionItem<span style="color: #339933;">&gt;</span>
          <span style="color: #339933;">&lt;/</span>apex<span style="color: #339933;">:</span>pageBlockSection<span style="color: #339933;">&gt;&lt;</span>br<span style="color: #339933;">/&gt;</span>
&nbsp;
          <span style="color: #339933;">&lt;</span>apex<span style="color: #339933;">:</span>actionStatus id<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;status&quot;</span> startText<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;Fetching map...&quot;</span><span style="color: #339933;">/&gt;</span>
          <span style="color: #339933;">&lt;</span>apex<span style="color: #339933;">:</span>outputPanel id<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;resultsPanel&quot;</span><span style="color: #339933;">&gt;</span>
          		<span style="color: #339933;">&lt;</span>apex<span style="color: #339933;">:</span>outputText value<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;{!geoAddress}&quot;</span><span style="color: #339933;">/&gt;&lt;</span>br<span style="color: #339933;">/&gt;</span>
          <span style="color: #339933;">&lt;/</span>apex<span style="color: #339933;">:</span>outputPanel<span style="color: #339933;">&gt;</span>
&nbsp;
     <span style="color: #339933;">&lt;/</span>apex<span style="color: #339933;">:</span>pageBlock<span style="color: #339933;">&gt;</span>
     <span style="color: #339933;">&lt;/</span>apex<span style="color: #339933;">:</span>form<span style="color: #339933;">&gt;</span>
&nbsp;
<span style="color: #339933;">&lt;/</span>apex<span style="color: #339933;">:</span>page<span style="color: #339933;">&gt;</span></pre></td></tr></table></div>

<p><strong>Unit Testing</strong></p>
<p>Writing unit tests for callouts can present a challenge. Scott Hemmeter has a really good article entitled <a href="http://sfdc.arrowpointe.com/2009/05/01/testing-http-callouts/" target="_blank">Testing HTTP Callouts</a> which should provide you with some useful techniques. You should also check out <a href="http://wiki.developerforce.com/index.php/An_Introduction_to_Apex_Code_Test_Methods" target="_blank">An Introduction to Apex Code Test Methods</a> on the developerforce wiki.</p>
<p>I also found this <a href="http://jsonviewer.stack.hu/">nifty JSON viewer</a> which makes debugging less painful.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jeffdouglas.com/2010/01/06/calling-a-json-rest-web-service-with-apex/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Performing Lookups and Transformations with Talend</title>
		<link>http://blog.jeffdouglas.com/2009/12/22/performing-lookups-and-transformations-with-talend/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=performing-lookups-and-transformations-with-talend</link>
		<comments>http://blog.jeffdouglas.com/2009/12/22/performing-lookups-and-transformations-with-talend/#comments</comments>
		<pubDate>Tue, 22 Dec 2009 21:34:11 +0000</pubDate>
		<dc:creator>Jeff Douglas</dc:creator>
				<category><![CDATA[Appirio]]></category>
		<category><![CDATA[Salesforce]]></category>

		<guid isPermaLink="false">http://blog.jeffdouglas.com/?p=1874</guid>
		<description><![CDATA[I recently did a video on how to use Talend Open Studio to import data into Salesforce.com. One of the missing features in the video was transforming data via lookups. Luckily Ward Loving just posted a fantastic tutorial on the Appirio Tech Blog showing how to do lookups to other input files or databases while performing [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://jeffdonthemic.files.wordpress.com/2009/12/talend-logo.jpeg" rel="lightbox[1874]"><img class="alignleft size-full wp-image-1876" style="padding-right:10px;" title="talend-logo" src="http://jeffdonthemic.files.wordpress.com/2009/12/talend-logo.jpeg" alt="" width="179" height="67" /></a>I recently did a <a href="http://blog.jeffdouglas.com/2009/12/02/video-talend-open-studio/" target="_blank">video</a> on how to use Talend Open Studio to import data into Salesforce.com. One of the missing features in the video was transforming data via lookups. Luckily Ward Loving just posted a fantastic <a href="http://techblog.appirio.com/2009/12/performing-lookups-and-transformations.html" target="_blank">tutorial on the Appirio Tech Blog</a> showing how to do lookups to other input files or databases while performing transformations on your data with basic Java expressions.</p>
<p>You can <a href="http://techblog.appirio.com/2009/12/performing-lookups-and-transformations.html" target="_blank">read the entire article</a> on the Appirio Tech Blog.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jeffdouglas.com/2009/12/22/performing-lookups-and-transformations-with-talend/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Dreamforce &#039;09 Hackathon Coverage</title>
		<link>http://blog.jeffdouglas.com/2009/12/08/df09-hackathon-coverage/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=df09-hackathon-coverage</link>
		<comments>http://blog.jeffdouglas.com/2009/12/08/df09-hackathon-coverage/#comments</comments>
		<pubDate>Tue, 08 Dec 2009 13:26:10 +0000</pubDate>
		<dc:creator>Jeff Douglas</dc:creator>
				<category><![CDATA[Appirio]]></category>
		<category><![CDATA[Salesforce]]></category>

		<guid isPermaLink="false">http://blog.jeffdouglas.com/?p=1849</guid>
		<description><![CDATA[Dana Le posted recap of the DF09 Hackathon with the results of the competition. Joe Krutulis and James Eitzmann (both from Appirio; just check out the shirt!) won the intermediate category with a really cool geo location Twitter app (just what the world needs &#8212; another Twitter app). Kyle Roche and I came in second [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://jeffdonthemic.files.wordpress.com/2009/12/runner.png" rel="lightbox[1849]"><img class="alignleft size-full wp-image-1850" style="padding-right:10px;" title="Runner" src="http://jeffdonthemic.files.wordpress.com/2009/12/runner.png" alt="" width="320" height="169" /></a>Dana Le posted <a href="http://blog.sforce.com/sforce/2009/12/dreamforce-09-hackathon-coverage.html" target="_blank">recap of the DF09 Hackathon</a> with the results of the competition.</p>
<p><a href="http://twitter.com/joe_krutulis" target="_blank">Joe Krutulis</a> and <a href="http://www.linkedin.com/pub/james-eitzmann/4/961/766" target="_blank">James Eitzmann</a> (both from Appirio; just check out the shirt!) won the intermediate category with a really cool geo location Twitter app (just what the world needs &#8212; another Twitter app).</p>
<p><a href="http://www.kyleroche.com" target="_blank">Kyle Roche</a> and I came in second in the advanced category with our Twilio app. Colin Loretz rocked the house and won the day with his Basecamp integration app. Good times were had by all!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jeffdouglas.com/2009/12/08/df09-hackathon-coverage/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Force.com Demo with Twilio</title>
		<link>http://blog.jeffdouglas.com/2009/11/28/force-demo-with-twilio/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=force-demo-with-twilio</link>
		<comments>http://blog.jeffdouglas.com/2009/11/28/force-demo-with-twilio/#comments</comments>
		<pubDate>Sat, 28 Nov 2009 03:35:52 +0000</pubDate>
		<dc:creator>Jeff Douglas</dc:creator>
				<category><![CDATA[Apex]]></category>
		<category><![CDATA[Appirio]]></category>
		<category><![CDATA[Salesforce]]></category>
		<category><![CDATA[Visualforce]]></category>

		<guid isPermaLink="false">http://blog.jeffdouglas.com/?p=1768</guid>
		<description><![CDATA[Cross-posted at the Appirio Tech Blog. During Dreamforce 09 Kyle Roche and I participated in the Developer Hackathon. We hacked-up an application using Force.com and Twilio for inbound and outbound calling. We were only allotted two hours so we were not able to finish off the application during the hackathon. Here is the final demo [...]]]></description>
			<content:encoded><![CDATA[<p>Cross-posted at the <a href="http://techblog.appirio.com/2009/11/forcecom-demo-with-twilio.html" target="_blank">Appirio Tech Blog</a>.</p>
<p>During Dreamforce 09 <a href="http://www.kyleroche.com" target="_blank">Kyle Roche</a> and I participated in the <a href="http://developer.force.com/hackathon" target="_blank">Developer Hackathon</a>. We hacked-up an application using Force.com and <a href="http://www.twilio.com" target="_blank">Twilio</a> for inbound and outbound calling. We were only allotted two hours so we were not able to finish off the application during the hackathon.</p>
<p>Here is the final demo with all of the major working pieces. The application has two major parts:</p>
<ol>
<li>Kyle&#8217;s part (much harder and more glamourous) uses the <a href="http://developer.force.com/codeshare/projectpage?id=a06300000059aEWAAY" target="_blank">Twilioforce</a> toolkit to make outbound calls from a contact in Salesforce. The user clicks the contact&#8217;s phone number and the Force.com platform makes an outbound call to the contact using Twilio. Once the contact picks up Twilio then calls the phone number on the user&#8217;s record and connects the two calls together.</li>
<li>My part of the application uses Twilio with a Sites application for inbound calling. The person calls a phone number that reads a script generated from a Force.com Sites page. The greeting welcomes the person, plays an MP3 and then prompts them to records a message. After they are finished with the message it posts the results to another Sites page with attaches the message to the contact&#8217;s record in Salesforce. It looks up the contact record based upon the incoming phone number.</li>
</ol>
<p>Here&#8217;s a video of the final application and the code for my part is below. I may be easier to view it at <a href="http://www.youtube.com/watch?v=fLhEY6IrTjc" target="_blank">YouTube</a> so you can see it at a lager size.</p>
<p><span class="youtube">
<object width="480" height="295">
<param name="movie" value="http://www.youtube.com/v/fLhEY6IrTjc&amp;color1=d6d6d6&amp;color2=f0f0f0&amp;border=0&amp;fs=1&amp;hl=en&amp;autoplay=0&amp;showinfo=0&amp;iv_load_policy=3&amp;showsearch=0?rel=1&amp;hd=1&amp;w=550" />
<param name="allowFullScreen" value="true" />
<embed wmode="transparent" src="http://www.youtube.com/v/fLhEY6IrTjc&amp;color1=d6d6d6&amp;color2=f0f0f0&amp;border=0&amp;fs=1&amp;hl=en&amp;autoplay=0&amp;showinfo=0&amp;iv_load_policy=3&amp;showsearch=0?rel=1&amp;hd=1&amp;w=550" type="application/x-shockwave-flash" allowfullscreen="true" width="480" height="295"></embed>
<param name="wmode" value="transparent" />
</object>
</span><p><a href="http://www.youtube.com/watch?v=fLhEY6IrTjc&fmt=18">www.youtube.com/watch?v=fLhEY6IrTjc</a></p></p>
<p>The code for Kyle&#8217;s part is somewhat similar to the <a href="http://techblog.appirio.com/2009/11/twilioforce-click-to-call-demo.html" target="_blank">Click to Call demo</a> he posted on the Appirio Tech Blog. Here&#8217;s the code for my part of the application. The Twilio phone number is setup so that when you call it, it reads the script from the Answer_Call Visualforce Sites page below. Twilio reads the &lt;Say&gt; script and then plays the mp3 in the &lt;Play&gt; section. It then record a message for 5 seconds and posts the results to Record_Call.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="java" style="font-family:monospace;"><span style="color: #339933;">&lt;</span>apex<span style="color: #339933;">:</span>page showHeader<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;false&quot;</span> contentType<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;text/xml&quot;</span><span style="color: #339933;">&gt;</span>
<span style="color: #339933;">&lt;</span>Response<span style="color: #339933;">&gt;</span>
    <span style="color: #339933;">&lt;</span>Say<span style="color: #339933;">&gt;</span>Thank you <span style="color: #000000; font-weight: bold;">for</span> calling the hackathon hotline. <span style="color: #006633;">Leave</span> a message after the monkey tone.<span style="color: #339933;">&lt;/</span>Say<span style="color: #339933;">&gt;</span>
    <span style="color: #339933;">&lt;</span>Play<span style="color: #339933;">&gt;</span>http<span style="color: #339933;">:</span><span style="color: #666666; font-style: italic;">//demo.twilio.com/hellomonkey/monkey.mp3&lt;/Play&gt;</span>
    <span style="color: #339933;">&lt;</span>Record maxLength<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;5&quot;</span> action<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;http://kyle-twilio-developer-edition.na7.force.com/Record_Call&quot;</span> <span style="color: #339933;">/&gt;</span>
<span style="color: #339933;">&lt;/</span>Response<span style="color: #339933;">&gt;</span>
<span style="color: #339933;">&lt;/</span>apex<span style="color: #339933;">:</span>page<span style="color: #339933;">&gt;</span></pre></td></tr></table></div>

<p>Most of the work in the Record_Call Visualforce page is done by the RecordCallController Apex Controller. When the page initially loads, the saveMessage() method is called in the Apex script below. The page is rendered and Twilio reads the &lt;Say&gt; script and then plays the recording back to the caller.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
</pre></td><td class="code"><pre class="java" style="font-family:monospace;"><span style="color: #339933;">&lt;</span>apex<span style="color: #339933;">:</span>page controller<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;RecordCallController&quot;</span> action<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;{!saveMessage}&quot;</span>
	showHeader<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;false&quot;</span>
	contentType<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;text/xml&quot;</span><span style="color: #339933;">&gt;</span>
<span style="color: #339933;">&lt;</span>Response<span style="color: #339933;">&gt;</span>
    <span style="color: #339933;">&lt;</span>Say<span style="color: #339933;">&gt;</span>Thanks <span style="color: #000000; font-weight: bold;">for</span> howling <span style="color: #009900;">&#123;</span><span style="color: #339933;">!</span>callerName<span style="color: #009900;">&#125;</span>. <span style="color: #006633;">Take</span> a listen to your message.<span style="color: #339933;">&lt;/</span>Say<span style="color: #339933;">&gt;</span>
    <span style="color: #339933;">&lt;</span>Play<span style="color: #339933;">&gt;</span><span style="color: #009900;">&#123;</span><span style="color: #339933;">!</span>recordingUrl<span style="color: #009900;">&#125;</span><span style="color: #339933;">&lt;/</span>Play<span style="color: #339933;">&gt;</span>
    <span style="color: #339933;">&lt;</span>Say<span style="color: #339933;">&gt;</span>Goodbye<span style="color: #339933;">&lt;/</span>Say<span style="color: #339933;">&gt;</span>
<span style="color: #339933;">&lt;/</span>Response<span style="color: #339933;">&gt;</span>
<span style="color: #339933;">&lt;/</span>apex<span style="color: #339933;">:</span>page<span style="color: #339933;">&gt;</span></pre></td></tr></table></div>

<p>The RecordCallController Apex Controller does all of the heavy lifting. The constructor grabs the URL of the recording that is posted back as well as the caller&#8217;s phone number. The constructor then tries to find the contact associated with the caller&#8217;s phone number. The saveMessage() method inserts a record into Twilio_Message__c custom object so that the message can be replayed back from the contact&#8217;s related list. If a contact was not found by the caller&#8217;s phone number, we should probably create a task to create a new contact at a later time.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
</pre></td><td class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> with sharing <span style="color: #000000; font-weight: bold;">class</span> RecordCallController <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> Contact contact <span style="color: #009900;">&#123;</span>get<span style="color: #339933;">;</span>set<span style="color: #339933;">;</span><span style="color: #009900;">&#125;</span>
    <span style="color: #000000; font-weight: bold;">private</span> ID callerId <span style="color: #009900;">&#123;</span>get<span style="color: #339933;">;</span>set<span style="color: #339933;">;</span><span style="color: #009900;">&#125;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">String</span> recordingUrl <span style="color: #009900;">&#123;</span>get<span style="color: #339933;">;</span>set<span style="color: #339933;">;</span><span style="color: #009900;">&#125;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">String</span> callerName <span style="color: #009900;">&#123;</span>get<span style="color: #339933;">;</span>set<span style="color: #339933;">;</span><span style="color: #009900;">&#125;</span>
&nbsp;
     <span style="color: #666666; font-style: italic;">// initialize the controller</span>
    <span style="color: #000000; font-weight: bold;">public</span> RecordCallController<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
    	<span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span>
&nbsp;
			recordingUrl <span style="color: #339933;">=</span> ApexPages.<span style="color: #006633;">currentPage</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getParameters</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'RecordingUrl'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
			List<span style="color: #339933;">&lt;</span>Contact<span style="color: #339933;">&gt;</span> callers <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span>select id, name from contact where
				twilio_number__c <span style="color: #339933;">=</span> <span style="color: #339933;">:</span>ApexPages.<span style="color: #006633;">currentPage</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getParameters</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Caller'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
			<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>callers.<span style="color: #006633;">size</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&gt;</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				contact <span style="color: #339933;">=</span> callers.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
				callerName <span style="color: #339933;">=</span> contact.<span style="color: #003399;">Name</span><span style="color: #339933;">;</span>
				callerId <span style="color: #339933;">=</span> contact.<span style="color: #006633;">Id</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
				callerName <span style="color: #339933;">=</span> <span style="color: #0000ff;">'Unknown Caller'</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
&nbsp;
    	<span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">Exception</span> e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #003399;">System</span>.<span style="color: #006633;">debug</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'====================== exception: '</span><span style="color: #339933;">+</span>e<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    	<span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> PageReference saveMessage<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
    	<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>contact <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
	   		<span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span>
&nbsp;
	          Twilio_Message__c m <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Twilio_Message__c<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	          m.<span style="color: #006633;">contact__c</span> <span style="color: #339933;">=</span> contact.<span style="color: #006633;">Id</span><span style="color: #339933;">;</span>
	          m.<span style="color: #006633;">message__c</span> <span style="color: #339933;">=</span> recordingUrl<span style="color: #339933;">;</span>
	          insert m<span style="color: #339933;">;</span>
&nbsp;
			<span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">Exception</span> e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				<span style="color: #003399;">System</span>.<span style="color: #006633;">debug</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'====================== exception: '</span><span style="color: #339933;">+</span>e<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
&nbsp;
    	<span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
    		<span style="color: #666666; font-style: italic;">// create a follow up task if contact was not found</span>
    	<span style="color: #009900;">&#125;</span>
&nbsp;
    	<span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://blog.jeffdouglas.com/2009/11/28/force-demo-with-twilio/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>NOW I Get Chatter!!</title>
		<link>http://blog.jeffdouglas.com/2009/11/20/now-i-get-chatter/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=now-i-get-chatter</link>
		<comments>http://blog.jeffdouglas.com/2009/11/20/now-i-get-chatter/#comments</comments>
		<pubDate>Fri, 20 Nov 2009 22:08:33 +0000</pubDate>
		<dc:creator>Jeff Douglas</dc:creator>
				<category><![CDATA[Appirio]]></category>
		<category><![CDATA[Salesforce]]></category>

		<guid isPermaLink="false">http://blog.jeffdouglas.com/?p=1715</guid>
		<description><![CDATA[As part of Appirio I was exposed to Chatter before the public announcement. I have to admit that when I originally first saw it I wasn&#8217;t really impressed. I understand that people, applications, documents, etc. can Chatter but to me it seemed just like another social network that I would have to check in addition [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://jeffdonthemic.files.wordpress.com/2009/11/chatter-logo.png" rel="lightbox[1715]"><img class="alignleft size-full wp-image-1717" style="padding-right:10px;" title="chatter-logo" src="http://jeffdonthemic.files.wordpress.com/2009/11/chatter-logo.png" alt="" width="243" height="179" /></a>As part of <a href="http://www.appirio.com" target="_blank">Appirio</a> I was exposed to <a href="http://www.salesforce.com/chatter" target="_blank">Chatter</a> before the public announcement. I have to admit that when I originally first saw it I wasn&#8217;t really impressed. I understand that people, applications, documents, etc. can Chatter but to me it seemed just like another social network that I would have to check in addition to Twitter, LinkedIn and Facebook. Even when Marc Benioff publically unveiled Chatter I was still luke warm to the technology.</p>
<p>The light bulb finally clicked when our CMO and Head of R&amp;D, Narinder Singh, demoed our Social PS Enterprise in the Day 2 Keynote. It was by far the best demo at <a href="http://dreamforce.appirio.com" target="_blank">Dreamforce 09</a> and I had a number of non-Appirio people tell me so. In the demo Narinder showed how he could enter a new timecard and the project would Chatter that its status had gone from green to yellow. That&#8217;s awesome in itself but the real magic was when he updated a spreadsheet in Google Docs and the project Chattered that it was now back on schedule. A number of people mentioned to me that there was a audible gasp when he pulled this off.</p>
<p><span class="youtube">
<object width="425" height="355">
<param name="movie" value="http://www.youtube.com/v/Xu-2ZgrmBhs&amp;color1=d6d6d6&amp;color2=f0f0f0&amp;border=0&amp;fs=1&amp;hl=en&amp;autoplay=0&amp;showinfo=0&amp;iv_load_policy=3&amp;showsearch=0?rel=1&amp;w=550" />
<param name="allowFullScreen" value="true" />
<embed wmode="transparent" src="http://www.youtube.com/v/Xu-2ZgrmBhs&amp;color1=d6d6d6&amp;color2=f0f0f0&amp;border=0&amp;fs=1&amp;hl=en&amp;autoplay=0&amp;showinfo=0&amp;iv_load_policy=3&amp;showsearch=0?rel=1&amp;w=550" type="application/x-shockwave-flash" allowfullscreen="true" width="425" height="355"></embed>
<param name="wmode" value="transparent" />
</object>
</span><p><a href="http://www.youtube.com/watch?v=Xu-2ZgrmBhs">www.youtube.com/watch?v=Xu-2ZgrmBhs</a></p></p>
<p>We have a really <a href="http://www.appirio.com/products/SvcsResource_PSEsocial.php" target="_blank">great demo of Social PS Enterprise</a> on the Appirio site if you are interested in taking another look.</p>
<p>I&#8217;m really interested to see how they implement role and record based security to the Chatter that is broadcast. I&#8217;m also hoping that someone like <a href="http://www.kyleroche.com/" target="_blank">Kyle Roche</a> writes a client app that combines Chatter, Twitter and Facebook. Perhaps TweetDeck or Tweetie can be persuaded.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jeffdouglas.com/2009/11/20/now-i-get-chatter/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Salesforce.com Robot for Google Wave</title>
		<link>http://blog.jeffdouglas.com/2009/11/13/salesforce-robot-for-google-wave/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=salesforce-robot-for-google-wave</link>
		<comments>http://blog.jeffdouglas.com/2009/11/13/salesforce-robot-for-google-wave/#comments</comments>
		<pubDate>Fri, 13 Nov 2009 13:24:39 +0000</pubDate>
		<dc:creator>Jeff Douglas</dc:creator>
				<category><![CDATA[Appirio]]></category>
		<category><![CDATA[Salesforce]]></category>
		<category><![CDATA[Wave]]></category>

		<guid isPermaLink="false">http://blog.jeffdouglas.com/?p=1687</guid>
		<description><![CDATA[Cross-posted at the Appirio Technology Blog This is a small Google Wave robot that interacts with Salesforce.com to display contacts, accounts and opportunities. The robot is currently a work in progress as I&#8217;ve been busy with other work projects, getting ready for Dreamforce 09 and working on a Twilioforce demo. If you have any ideas [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://jeffdonthemic.files.wordpress.com/2009/09/wavelogo.png" rel="lightbox[1687]"><img class="alignleft size-thumbnail wp-image-1251" style="padding-right:10px;" title="wavelogo" src="http://jeffdonthemic.files.wordpress.com/2009/09/wavelogo.png?w=150" alt="wavelogo" width="150" height="150" /></a>Cross-posted at the <a href="http://techblog.appirio.com/2009/11/salesforcecom-robot-for-google-wave.html" target="_blank">Appirio Technology Blog</a></p>
<p>This is a small Google Wave robot that interacts with Salesforce.com to display contacts, accounts and opportunities. The robot is currently a work in progress as I&#8217;ve been busy with other work projects, getting ready for <a href="http://dreamforce.appirio.com" target="_blank">Dreamforce 09</a> and working on a <a href="http://techblog.appirio.com/2009/11/twilioforce-twilio-library-for-forcecom.html" target="_blank">Twilioforce</a> demo. If you have any ideas for future functionality or comments, please let me know.</p>
<p>The robot is currently hooked up to my developer account but you are free to add it to a wave and try out the functionality for yourself. Simply follow the video and add the robot (<strong>sfdcwavebot@appspot.com</strong>) to your contacts.</p>
<p style="text-align:center;">You can <a href="http://www.youtube.com/watch?v=6TBZBVGrQX4" target="_blank">watch this at full size</a> at YouTube.</p>
<p><span class="youtube">
<object width="425" height="355">
<param name="movie" value="http://www.youtube.com/v/6TBZBVGrQX4&amp;color1=d6d6d6&amp;color2=f0f0f0&amp;border=0&amp;fs=1&amp;hl=en&amp;autoplay=0&amp;showinfo=0&amp;iv_load_policy=3&amp;showsearch=0?rel=1&amp;w=550" />
<param name="allowFullScreen" value="true" />
<embed wmode="transparent" src="http://www.youtube.com/v/6TBZBVGrQX4&amp;color1=d6d6d6&amp;color2=f0f0f0&amp;border=0&amp;fs=1&amp;hl=en&amp;autoplay=0&amp;showinfo=0&amp;iv_load_policy=3&amp;showsearch=0?rel=1&amp;w=550" type="application/x-shockwave-flash" allowfullscreen="true" width="425" height="355"></embed>
<param name="wmode" value="transparent" />
</object>
</span><p><a href="http://www.youtube.com/watch?v=6TBZBVGrQX4">www.youtube.com/watch?v=6TBZBVGrQX4</a></p></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.jeffdouglas.com/2009/11/13/salesforce-robot-for-google-wave/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
