<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Perspectives on Salesforce.com</title>
	
	<link>http://sfdc.arrowpointe.com</link>
	<description>Authored by Scott Hemmeter of Arrowpointe Corp, this blog is written from the perspective of a Salesforce.com solution provider and contains information on Arrowpointe's AppExchange products as well as tips, findings, sample code, functionality wishes, etc.</description>
	<lastBuildDate>Thu, 24 Jun 2010 06:02:39 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<feedburner:info uri="perspectivesonsalesforcecom" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><geo:lat>33.811566</geo:lat><geo:long>-117.829194</geo:long><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://sfdc.arrowpointe.com/feed" /><feedburner:emailServiceId>PerspectivesOnSalesforcecom</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><feedburner:feedFlare href="http://add.my.yahoo.com/rss?url=http%3A%2F%2Fsfdc.arrowpointe.com%2Ffeed" src="http://us.i1.yimg.com/us.yimg.com/i/us/my/addtomyyahoo4.gif">Subscribe with My Yahoo!</feedburner:feedFlare><feedburner:feedFlare href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http%3A%2F%2Fsfdc.arrowpointe.com%2Ffeed" src="http://www.newsgator.com/images/ngsub1.gif">Subscribe with NewsGator</feedburner:feedFlare><feedburner:feedFlare href="http://feeds.my.aol.com/add.jsp?url=http%3A%2F%2Fsfdc.arrowpointe.com%2Ffeed" src="http://o.aolcdn.com/favorites.my.aol.com/webmaster/ffclient/webroot/locale/en-US/images/myAOLButtonSmall.gif">Subscribe with My AOL</feedburner:feedFlare><feedburner:feedFlare href="http://www.bloglines.com/sub/http://sfdc.arrowpointe.com/feed" src="http://www.bloglines.com/images/sub_modern11.gif">Subscribe with Bloglines</feedburner:feedFlare><feedburner:feedFlare href="http://www.netvibes.com/subscribe.php?url=http%3A%2F%2Fsfdc.arrowpointe.com%2Ffeed" src="http://www.netvibes.com/img/add2netvibes.gif">Subscribe with Netvibes</feedburner:feedFlare><feedburner:feedFlare href="http://fusion.google.com/add?feedurl=http%3A%2F%2Fsfdc.arrowpointe.com%2Ffeed" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare href="http://www.pageflakes.com/subscribe.aspx?url=http%3A%2F%2Fsfdc.arrowpointe.com%2Ffeed" src="http://www.pageflakes.com/ImageFile.ashx?instanceId=Static_4&amp;fileName=ATP_blu_91x17.gif">Subscribe with Pageflakes</feedburner:feedFlare><feedburner:browserFriendly>This is an XML content feed. It is intended to be viewed in a newsreader or syndicated to another site.</feedburner:browserFriendly><item>
		<title>force.com Workbench 3.0</title>
		<link>http://feedproxy.google.com/~r/PerspectivesOnSalesforcecom/~3/L3KGTI9dfTA/</link>
		<comments>http://sfdc.arrowpointe.com/2010/06/23/force-com-workbench-3-0/#comments</comments>
		<pubDate>Thu, 24 Jun 2010 06:02:39 +0000</pubDate>
		<dc:creator>Scott Hemmeter</dc:creator>
				<category><![CDATA[Tips]]></category>

		<guid isPermaLink="false">http://sfdc.arrowpointe.com/?p=816</guid>
		<description><![CDATA[The Force.com Workbench is a very handy thing to use when you need quick access to an org and want to see meta data or do some ad-hoc querying. It&#8217;s PHP code that you can run on your own web server and it describes itself as:
Workbench is a powerful, web-based suite of tools designed for [...]]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://wiki.developerforce.com/index.php/Workbench" target="_blank">Force.com Workbench</a> is a very handy thing to use when you need quick access to an org and want to see meta data or do some ad-hoc querying. It&#8217;s PHP code that you can run on your own web server and it describes itself as:</p>
<blockquote><p>Workbench is a powerful, web-based suite of tools designed for adminstrators and developers to interact with Salesforce.com organizations via the Force.com APIs. Workbench includes robust support for the Force.com Partner, Bulk, Metadata, and Apex APIs that allows users to describe, query, manipulate, and migrate both data and metadata in Salesforce.com organizations directly in their web browser with a simple and intuitive user interface. Workbench also provides many advanced features for testing and troubleshooting the Force.com APIs, such as customizable SOAP headers, debug logs for API traffic, backward compatibility testing with previous API versions, and single sign-on integration within the Salesforce application.</p></blockquote>
<p>I would highly recommend it.  You can download it from its <a href="http://code.google.com/p/forceworkbench/" target="_blank">Google Code site</a>.  If you want to see it in action now, I always keep the latest version running on the arrowpointe.com domain at <a href="http://force.arrowpointe.com" target="_blank">http://force.arrowpointe.com</a>.  You are welcome to use it there if you&#8217;d like to.</p>
<img src="http://sfdc.arrowpointe.com/?ak_action=api_record_view&id=816&type=feed" alt="" /><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/PerspectivesOnSalesforcecom?a=L3KGTI9dfTA:EaZ1KrLp0Ew:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/PerspectivesOnSalesforcecom?i=L3KGTI9dfTA:EaZ1KrLp0Ew:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/PerspectivesOnSalesforcecom/~4/L3KGTI9dfTA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://sfdc.arrowpointe.com/2010/06/23/force-com-workbench-3-0/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://sfdc.arrowpointe.com/2010/06/23/force-com-workbench-3-0/</feedburner:origLink></item>
		<item>
		<title>Map as Lookup Field</title>
		<link>http://feedproxy.google.com/~r/PerspectivesOnSalesforcecom/~3/9UkH1DSnCf8/</link>
		<comments>http://sfdc.arrowpointe.com/2010/06/22/map-as-lookup-field/#comments</comments>
		<pubDate>Tue, 22 Jun 2010 08:48:52 +0000</pubDate>
		<dc:creator>Scott Hemmeter</dc:creator>
				<category><![CDATA[Arrowpointe Products]]></category>
		<category><![CDATA[Configuration]]></category>
		<category><![CDATA[Geopointe]]></category>
		<category><![CDATA[Tips]]></category>

		<guid isPermaLink="false">http://sfdc.arrowpointe.com/?p=813</guid>
		<description><![CDATA[This was also posted to the new Arrowpointe Product blog. We are moving all product specific information to that new blog and keeping this blog focused on developer related information. Please subscribe (rss, email) 
Geopointe has a number of under-the-cover features (and more to come) that allow you to integrate with the application.  One such [...]]]></description>
			<content:encoded><![CDATA[<p style="line-height: 1.5em; font-size: 80%;"><em>This was also posted to the new Arrowpointe <a href="http://www.arrowpointe.com/blog">Product blog</a>. We are moving all product specific information to that new blog and keeping this blog focused on developer related information. Please subscribe (<a href="http://www.arrowpointe.com/feed" target="_blank">rss</a>, <a href="http://feedburner.google.com/fb/a/mailverify?uri=Arrowpointe&amp;loc=en_US" target="_blank">email</a>) </em></p>
<p><a href="http://www.arrowpointe.com/getmaps" target="_blank">Geopointe</a> has a number of under-the-cover features (and more to come) that allow you to integrate with the application.  One such feature is the ability to use the map as a means of populating a Lookup field.</p>
<p>Below is a video showing this feature in action.</p>
<div style="text-align: center; margin: 10px 0px;">(for best results, choose an HD viewing option after starting the video and use full-screen mode)<br />
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="640" height="385" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube-nocookie.com/v/84Sc35fZ1dU&amp;hl=en_US&amp;fs=1&amp;rel=0&amp;hd=1" /><param name="allowfullscreen" value="true" /><embed type="application/x-shockwave-flash" width="640" height="385" src="http://www.youtube-nocookie.com/v/84Sc35fZ1dU&amp;hl=en_US&amp;fs=1&amp;rel=0&amp;hd=1" allowscriptaccess="always" allowfullscreen="true"></embed></object></div>
<h2>Enabling the Feature</h2>
<p>The feature is enabled through the use of a Custom Button that simply passes additional parameters across in the URL.  The URL in the video example is:</p>
<pre style="padding-left: 30px;">/apex/geopointe__Map?</pre>
<pre style="padding-left: 30px;">Id={!Account.Id}</pre>
<pre style="padding-left: 30px;">&amp;wbRecordId={!Account.Id}</pre>
<pre style="padding-left: 30px;">&amp;wbField=Related_Account__c</pre>
<pre style="padding-left: 30px;">&amp;wbLookupObject=Account</pre>
<pre style="padding-left: 30px;">&amp;wbButtonText={!URLENCODE("Relate This Account to " &amp; Account.Name)}</pre>
<h2>Let&#8217;s break it down</h2>
<pre><strong>/apex/geopointe__Map?</strong></pre>
<pre><strong>Id={!Account.Id}</strong></pre>
<p>The above is the URL from the button included with the application. It is required to sent the user to the proper page in the proper context.</p>
<pre><strong>&amp;wbRecordId={!Account.Id}</strong></pre>
<p>wbRecordId is the ID of the record we will be writing back to.</p>
<pre><strong>&amp;wbField=Related_Account__c</strong></pre>
<p>wbField is the field on that record we will be populating.</p>
<pre><strong>&amp;wbLookupObject=Account</strong></pre>
<p>wbLookupObject is the object type that we will be searching for and populating the lookup field for.</p>
<pre><strong>&amp;wbButtonText={!URLENCODE("Relate This Account to " &amp; Account.Name)}</strong></pre>
<p>wbButtonText is optional, but can be included if you want to customize the button&#8217;s text. It is recommended to use the URLENCODE function when specifying your text, especially if you are merging in data from the system.</p>
<img src="http://sfdc.arrowpointe.com/?ak_action=api_record_view&id=813&type=feed" alt="" /><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/PerspectivesOnSalesforcecom?a=9UkH1DSnCf8:tGeRUwOiG1k:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/PerspectivesOnSalesforcecom?i=9UkH1DSnCf8:tGeRUwOiG1k:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/PerspectivesOnSalesforcecom/~4/9UkH1DSnCf8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://sfdc.arrowpointe.com/2010/06/22/map-as-lookup-field/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://sfdc.arrowpointe.com/2010/06/22/map-as-lookup-field/</feedburner:origLink></item>
		<item>
		<title>Introducing Geopointe</title>
		<link>http://feedproxy.google.com/~r/PerspectivesOnSalesforcecom/~3/GOQv2vJDvCE/</link>
		<comments>http://sfdc.arrowpointe.com/2010/06/07/introducing-geopointe/#comments</comments>
		<pubDate>Mon, 07 Jun 2010 17:09:37 +0000</pubDate>
		<dc:creator>Scott Hemmeter</dc:creator>
				<category><![CDATA[Arrowpointe Maps]]></category>
		<category><![CDATA[Arrowpointe Products]]></category>
		<category><![CDATA[Geopointe]]></category>

		<guid isPermaLink="false">http://sfdc.arrowpointe.com/?p=799</guid>
		<description><![CDATA[This was also posted to the new Arrowpointe Product blog. We are moving all product specific information to that new blog and keeping this blog focused on developer related information. Please subscribe (rss, email) 
We are pleased to announce the release of our newest application, Geopointe.  Geopointe integrates Force.com with Google Maps and MapQuest [...]]]></description>
			<content:encoded><![CDATA[<p style="line-height: 1.5em; font-size: 80%;"><em>This was also posted to the new Arrowpointe <a href="http://www.arrowpointe.com/blog">Product blog</a>. We are moving all product specific information to that new blog and keeping this blog focused on developer related information. Please subscribe (<a href="http://www.arrowpointe.com/feed" target="_blank">rss</a>, <a href="http://feedburner.google.com/fb/a/mailverify?uri=Arrowpointe&#038;loc=en_US" target="_blank">email</a>) </em></p>
<p>We are pleased to announce the release of our newest application, Geopointe.  <strong>Geopointe integrates Force.com with Google Maps and MapQuest </strong>and is the premier Force.com geo/mapping solution providing numerous ways for end-users, administrators and developers to take advantage of geo data and maps.</p>
<div style="text-align: center;"><img class="aligncenter size-full wp-image-414" title="gp_sampleMap" src="http://www.arrowpointe.com/wp-content/uploads/gp_sampleMap.png" alt="" width="352" height="200" /></div>
<p>Highlights of Geopointe include (but is not limited to):</p>
<ul>
<li>Map any Salesforce object</li>
<li>Perform proximity searching (show me what&#8217;s nearby me)</li>
<li>Create custom data sets (queries), both personal and public ones</li>
<li>Export your results to CSV (Excel) or KML (Google Earth)</li>
<li>Obtain multi-point driving directions</li>
<li>The Visualizer helps create dashboard-like summaries of your data</li>
<li>Automated, Scheduled Geocoding processes your data at 1000+ records per minute</li>
<li>Get cleansed address data</li>
<li>Contains an &#8220;API&#8221; with global Apex methods, Visualforce Components and the ability to extend the application using custom buttons.</li>
<li>All existing Arrowpointe Maps customers get a free license transfer to Geopointe for the same user count and expiration date as their current license with a goal to get users off of Arrowpointe Maps and onto Geopointe.</li>
</ul>
<p>To learn more, you can:</p>
<ul>
<li>Visit the <a href="http://www.arrowpointe.com/getmaps" target="_blank">AppExchange Listing</a></li>
<li>Visit the <a href="http://www.arrowpointe.com/maps" target="_blank">product page</a> on our website</li>
<li>Visit the <a href="http://youtube.com/arrowpointe" target="_blank">YouTube Channel</a></li>
<li>Follow us on <a href="http://twitter.com/arrowpointe" target="_blank">Twitter</a></li>
<li>&#8220;Like&#8221; Arrowpointe on <a href="http://www.facebook.com/arrowpointe" target="_blank">Facebook</a></li>
</ul>
<div style="text-align: center; margin: 10px 0px; font-size: 80%;">(for best results, choose an HD viewing option after starting the video and use full-screen mode)<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="640" height="385" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube-nocookie.com/v/bljtY_Dz7jk&amp;hl=en_US&amp;fs=1&amp;rel=0" /><param name="allowfullscreen" value="true" /><embed type="application/x-shockwave-flash" width="640" height="385" src="http://www.youtube-nocookie.com/v/bljtY_Dz7jk&amp;hl=en_US&amp;fs=1&amp;rel=0" allowscriptaccess="always" allowfullscreen="true"></embed></object></div>
<img src="http://sfdc.arrowpointe.com/?ak_action=api_record_view&id=799&type=feed" alt="" /><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/PerspectivesOnSalesforcecom?a=GOQv2vJDvCE:TDDo7oYm4YY:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/PerspectivesOnSalesforcecom?i=GOQv2vJDvCE:TDDo7oYm4YY:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/PerspectivesOnSalesforcecom/~4/GOQv2vJDvCE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://sfdc.arrowpointe.com/2010/06/07/introducing-geopointe/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://sfdc.arrowpointe.com/2010/06/07/introducing-geopointe/</feedburner:origLink></item>
		<item>
		<title>Reorganizing</title>
		<link>http://feedproxy.google.com/~r/PerspectivesOnSalesforcecom/~3/1AULAXjy26o/</link>
		<comments>http://sfdc.arrowpointe.com/2010/05/20/reorganizing/#comments</comments>
		<pubDate>Thu, 20 May 2010 17:13:56 +0000</pubDate>
		<dc:creator>Scott Hemmeter</dc:creator>
				<category><![CDATA[Site Info]]></category>
		<category><![CDATA[The Community]]></category>

		<guid isPermaLink="false">http://sfdc.arrowpointe.com/?p=776</guid>
		<description><![CDATA[I&#8217;ve been reorganizing the way blogs and social media will be used for Arrowpointe and wanted to inform you about what&#8217;s changing.  A new application is being launched very soon and, once it is, I will be picking up the pace and getting back to the business of blogging.
Website Redesign
The Arrowpointe website was recently redesigned [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been reorganizing the way blogs and social media will be used for Arrowpointe and wanted to inform you about what&#8217;s changing.  A new application is being launched very soon and, once it is, I will be picking up the pace and getting back to the business of blogging.</p>
<p><strong><span style="text-decoration: underline;">Website Redesign</span></strong><br />
The <a href="http://www.arrowpointe.com" target="_blank">Arrowpointe website</a> was recently redesigned (new logo too).  There, you will find links to all that I am explaining in this post.  (you can also get a bit of preview information about the new application that will be launched)</p>
<p><strong><span style="text-decoration: underline;">Blogs</span></strong><br />
I have decided to separate content into 2 separate blogs.</p>
<ul>
<li><strong>Developer Blog </strong>- This blog (<a href="http://sfdc.arrowpointe.com/subscribing-to-this-site/">subscribe</a>) will be focused on broader force.com topics such as news, developer tips, etc., as opposed to Arrowpointe-specific product information.</li>
<li><strong>Company/Product Blog</strong> &#8211; A <a href="http://www.arrowpointe.com/blog" target="_blank">new blog was created</a> on the company site that will focus on company news and announcements regarding <a href="http://www.arrowpointe.com/products" target="_blank">Arrowpointe&#8217;s applications</a>. While I transition, I will cross-post across the blogs, but over time product information will be put onto the company/product blog. You can subscribe to that blog via <a href="http://www.arrowpointe.com/feed" target="_blank">rss</a> or <a href="http://feedburner.google.com/fb/a/mailverify?uri=Arrowpointe&amp;loc=en_US" target="_blank">email</a>.</li>
</ul>
<p><strong><span style="text-decoration: underline;">Social Media</span></strong></p>
<ul>
<li>Our <a href="http://www.youtube.com/arrowpointe" target="_blank">You Tube channel</a> will be the best location to get video about our applications.</li>
<li>Our <a href="http://www.facebook.com/arrowpointe">Facebook page</a> is a great place to find a collection of all our content from the web.</li>
<li>Our <a href="http://twitter.com/arrowpointe" target="_blank">Twitter feed</a> will collect notifications about all our postings around the web as well as informal commentary about force.com, life on the web and other information that may be of interest.  Our Facebook feed will post to Twitter, but not the other way around.</li>
</ul>
<img src="http://sfdc.arrowpointe.com/?ak_action=api_record_view&id=776&type=feed" alt="" /><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/PerspectivesOnSalesforcecom?a=1AULAXjy26o:G9FGdZJojTk:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/PerspectivesOnSalesforcecom?i=1AULAXjy26o:G9FGdZJojTk:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/PerspectivesOnSalesforcecom/~4/1AULAXjy26o" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://sfdc.arrowpointe.com/2010/05/20/reorganizing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://sfdc.arrowpointe.com/2010/05/20/reorganizing/</feedburner:origLink></item>
		<item>
		<title>Spam Check Statistics</title>
		<link>http://feedproxy.google.com/~r/PerspectivesOnSalesforcecom/~3/vVv_mgT1tcU/</link>
		<comments>http://sfdc.arrowpointe.com/2010/04/09/spam-check-statistics/#comments</comments>
		<pubDate>Fri, 09 Apr 2010 17:32:29 +0000</pubDate>
		<dc:creator>Scott Hemmeter</dc:creator>
				<category><![CDATA[Arrowpointe Products]]></category>
		<category><![CDATA[Spam Check]]></category>

		<guid isPermaLink="false">http://sfdc.arrowpointe.com/?p=760</guid>
		<description><![CDATA[
Arrowpointe has an application on AppExchange called Spam Check.  The application has tools to fight spam from getting into your Salesforce system.
All of Arrowpointe&#8217;s web-to-lead and web-to-case forms use it.  Below are the overall statistics since getting it setup.
95 spams caught, 64 legitimate submissions, and an overall accuracy rate of 93.711%.




Spam
Not Spam
Missed Spam
False Positives




2010-04
3
0
0
0


2010-03
8
10
1
1


2010-02
6
3
2
0


2010-01
3
10
0
0


2009-12
19
6
0
1


2009-11
23
6
0
0


2009-10
0
6
0
0


2009-09
1
9
0
0


2009-08
31
7
4
0


2009-07
1
7
1
0



You can run [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><img class="size-full wp-image-695 aligncenter" title="SpamCheck-AppExchange-Banner" src="http://sfdc.arrowpointe.com/wp-content/images/SpamCheck-AppExchange-Banner.jpg" alt="" width="500" height="61" /></p>
<p>Arrowpointe has an application on <a href="http://www.arrowpointe.com/getspamcheck">AppExchange</a> called <strong>Spam Check</strong>.  The application has tools to fight spam from getting into your Salesforce system.</p>
<p>All of Arrowpointe&#8217;s web-to-lead and web-to-case forms use it.  Below are the overall statistics since getting it setup.</p>
<h2><span style="color: #000000;">95</span><span style="font-weight: normal;"><span style="color: #000000;"> spams caught</span></span><span style="color: #000000;">, 64</span><span style="font-weight: normal;"><span style="color: #000000;"> legitimate submissions,</span></span><span style="color: #000000;"> </span><span style="font-weight: normal;"><span style="color: #000000;">and an overall accuracy rate of</span></span><span style="color: #000000;"> 93.711%.</span></h2>
<table style="margin: 0 auto;" border="1" cellspacing="0" cellpadding="3">
<thead>
<tr style="text-align: right;">
<th style="background-color: #fff;"></th>
<th>Spam</th>
<th>Not Spam</th>
<th>Missed Spam</th>
<th>False Positives</th>
</tr>
</thead>
<tbody>
<tr>
<th>2010-04</th>
<td style="text-align: center;">3</td>
<td style="text-align: center;">0</td>
<td style="text-align: center;">0</td>
<td style="text-align: center;">0</td>
</tr>
<tr>
<th>2010-03</th>
<td style="text-align: center;">8</td>
<td style="text-align: center;">10</td>
<td style="text-align: center;">1</td>
<td style="text-align: center;">1</td>
</tr>
<tr>
<th>2010-02</th>
<td style="text-align: center;">6</td>
<td style="text-align: center;">3</td>
<td style="text-align: center;">2</td>
<td style="text-align: center;">0</td>
</tr>
<tr>
<th>2010-01</th>
<td style="text-align: center;">3</td>
<td style="text-align: center;">10</td>
<td style="text-align: center;">0</td>
<td style="text-align: center;">0</td>
</tr>
<tr>
<th>2009-12</th>
<td style="text-align: center;">19</td>
<td style="text-align: center;">6</td>
<td style="text-align: center;">0</td>
<td style="text-align: center;">1</td>
</tr>
<tr>
<th>2009-11</th>
<td style="text-align: center;">23</td>
<td style="text-align: center;">6</td>
<td style="text-align: center;">0</td>
<td style="text-align: center;">0</td>
</tr>
<tr>
<th>2009-10</th>
<td style="text-align: center;">0</td>
<td style="text-align: center;">6</td>
<td style="text-align: center;">0</td>
<td style="text-align: center;">0</td>
</tr>
<tr>
<th>2009-09</th>
<td style="text-align: center;">1</td>
<td style="text-align: center;">9</td>
<td style="text-align: center;">0</td>
<td style="text-align: center;">0</td>
</tr>
<tr>
<th>2009-08</th>
<td style="text-align: center;">31</td>
<td style="text-align: center;">7</td>
<td style="text-align: center;">4</td>
<td style="text-align: center;">0</td>
</tr>
<tr>
<th>2009-07</th>
<td style="text-align: center;">1</td>
<td style="text-align: center;">7</td>
<td style="text-align: center;">1</td>
<td style="text-align: center;">0</td>
</tr>
</tbody>
</table>
<p>You can run a free 30 day trial of Spam Check simply by installing the application from the <a href="http://www.arrowpointe.com/getspamcheck" target="_blank">AppExchange</a>. Once installed, you will receive emails on how to get it <a href="http://www.arrowpointe.com/spamcheck101" target="_blank">setup</a>.</p>
<img src="http://sfdc.arrowpointe.com/?ak_action=api_record_view&id=760&type=feed" alt="" /><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/PerspectivesOnSalesforcecom?a=vVv_mgT1tcU:4bU_znwK3Ys:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/PerspectivesOnSalesforcecom?i=vVv_mgT1tcU:4bU_znwK3Ys:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/PerspectivesOnSalesforcecom/~4/vVv_mgT1tcU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://sfdc.arrowpointe.com/2010/04/09/spam-check-statistics/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://sfdc.arrowpointe.com/2010/04/09/spam-check-statistics/</feedburner:origLink></item>
		<item>
		<title>Arrowpointe’s Aloha Apps</title>
		<link>http://feedproxy.google.com/~r/PerspectivesOnSalesforcecom/~3/VPKGCwMRqbk/</link>
		<comments>http://sfdc.arrowpointe.com/2010/04/09/arrowpointes-aloha-apps/#comments</comments>
		<pubDate>Fri, 09 Apr 2010 17:07:57 +0000</pubDate>
		<dc:creator>Scott Hemmeter</dc:creator>
				<category><![CDATA[AppExchange]]></category>
		<category><![CDATA[Arrowpointe Maps]]></category>
		<category><![CDATA[Arrowpointe Products]]></category>
		<category><![CDATA[Auto vCard]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[Spam Check]]></category>

		<guid isPermaLink="false">http://sfdc.arrowpointe.com/?p=751</guid>
		<description><![CDATA[
Salesforce just announced an update to AppExchange where they designate apps as &#8220;Aloha Apps&#8221;.  Aloha Apps are a new &#8220;all-you-can-app&#8221; category of apps that don’t count against customer org limits (apps/tabs/objects), no matter which salesforce.com edition you’re using.
A number of Arrowpointe applications are in the Aloha category.

Arrowpointe Maps &#8211; map your Salesforce data!
Auto vCard &#8211; Import [...]]]></description>
			<content:encoded><![CDATA[<div>
<p><img class="alignleft size-full wp-image-752" title="alohaapps" src="http://sfdc.arrowpointe.com/wp-content/images/alohaapps.png" alt="" width="143" height="55" />Salesforce just <a href="http://sites.force.com/blogs/ideaView?c=09a30000000D9xo&amp;id=08730000000H3wEAAS" target="_blank">announced</a> an update to AppExchange where they designate apps as &#8220;Aloha Apps&#8221;.  Aloha Apps are <em>a new &#8220;<strong>all-you-can-app&#8221;</strong> category of apps that don’t count against customer org limits (apps/tabs/objects), no matter which salesforce.com edition you’re using</em>.</p>
<p>A number of <a href="http://www.arrowpointe.com/getallapps" target="_blank">Arrowpointe applications</a> are in the Aloha category.</p>
<ul>
<li><a href="http://www.arrowpointe.com/getmaps" target="_blank">Arrowpointe Maps</a> &#8211; map your Salesforce data!</li>
<li><a href="http://www.arrowpointe.com/getvcard" target="_blank">Auto vCard</a> &#8211; Import a record (e.g. lead or contact) into your local address book with 1 click.</li>
<li><a href="http://www.arrowpointe.com/getspamcheck" target="_blank">Spam Check</a> &#8211; Stop Spam from entering your Salesforce system and wasting your users&#8217; time.</li>
</ul>
</div>
<p>If you install any of the above apps, they will not count towards your app/object/tab limits:</p>
<img src="http://sfdc.arrowpointe.com/?ak_action=api_record_view&id=751&type=feed" alt="" /><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/PerspectivesOnSalesforcecom?a=VPKGCwMRqbk:H5h6tVLNbaE:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/PerspectivesOnSalesforcecom?i=VPKGCwMRqbk:H5h6tVLNbaE:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/PerspectivesOnSalesforcecom/~4/VPKGCwMRqbk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://sfdc.arrowpointe.com/2010/04/09/arrowpointes-aloha-apps/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://sfdc.arrowpointe.com/2010/04/09/arrowpointes-aloha-apps/</feedburner:origLink></item>
		<item>
		<title>Endpoint for Debugging HTTP Callouts</title>
		<link>http://feedproxy.google.com/~r/PerspectivesOnSalesforcecom/~3/2FE8yhwvH0o/</link>
		<comments>http://sfdc.arrowpointe.com/2010/02/16/endpoint-for-debugging-http-callouts/#comments</comments>
		<pubDate>Tue, 16 Feb 2010 16:39:05 +0000</pubDate>
		<dc:creator>Scott Hemmeter</dc:creator>
				<category><![CDATA[APEX Code]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Visualforce]]></category>

		<guid isPermaLink="false">http://sfdc.arrowpointe.com/?p=743</guid>
		<description><![CDATA[When I use Apex to make HTTP callouts to other web services (e.g. Google Checkout, PayPal, Shopify, MapQuest, etc), it is often a game of trial and error to get things right.  Oftentimes, I get errors from the recipient that my request is invalid and, for the life of me, I cannot see the [...]]]></description>
			<content:encoded><![CDATA[<p>When I use Apex to make HTTP callouts to other web services (e.g. Google Checkout, PayPal, Shopify, MapQuest, etc), it is often a game of trial and error to get things right.  Oftentimes, I get errors from the recipient that my request is invalid and, for the life of me, I cannot see the problem.</p>
<p>To help me debug, I keep a test endpoint in my DE orgs that I make callouts to in order to get a good look at what I am sending.  It&#8217;s a simple Visualforce page that I expose over Sites to act as a fake endpoint while I do development.  When developing a callout, I will often use this endpoint in the beginning to organize the parameters and then periodically throughout development to debug.</p>
<p>The page is simple.</p>
<pre class="brush: java">
&lt;apex:page controller=&quot;Endpoint_Controller&quot; cache=&quot;false&quot; showHeader=&quot;false&quot; sidebar=&quot;false&quot; action=&quot;{!init}&quot;&gt;
&lt;pre&gt;
&lt;apex:outputText escape=&quot;false&quot; value=&quot;{!debugInfo}&quot;&gt;&lt;/apex:outputText&gt;
&lt;/pre&gt;
&lt;/apex:page&gt;
</pre>
<p>Depending upon my need, I will add/remove the action=&#8221;{!init}&#8221; parameter from the page because I have it in there to write the {!debugInfo} variable to a Task for later review (kind of like using a task as a mini-debug log).  I don&#8217;t always need it turned on, so that parameter comes and goes.</p>
<p>My controller, with test method, is:</p>
<pre class="brush: java">
public without sharing class Endpoint_Controller {

public String debugInfo {get; set;}{

debugInfo = &#039;&#039;;

if (ApexPages.currentPage() != null){
// Incoming Headers
debugInfo += &#039;\n***ALL INCOMING HEADERS ***\n&#039;;
for (string key: ApexPages.currentPage().getHeaders().keySet()){
if (ApexPages.currentPage().getHeaders().get(key) != null){
debugInfo += key + &#039; = &#039; + ApexPages.currentPage().getHeaders().get(key) + &#039;\n&#039;;
}
}

// Incoming Parameters
debugInfo += &#039;\n***ALL INCOMING PARAMETERS ***\n&#039;;
for (string key: ApexPages.currentPage().getParameters().keySet()){
if (ApexPages.currentPage().getParameters().get(key) != null){
debugInfo += key + &#039; = &#039; + ApexPages.currentPage().getParameters().get(key) + &#039;\n&#039;;
}
}

// Other Page Reference Stuff
debugInfo += &#039;\n***OTHER PAGE REFERENCE INFO ***\n&#039;;
debugInfo += &#039;Anchor: &#039; + ApexPages.currentPage().getAnchor() + &#039;\n&#039;;
debugInfo += &#039;URL: &#039; + ApexPages.currentPage().getUrl() + &#039;\n&#039;;
}

}

public Endpoint_Controller(){}

public PageReference init() {

Task t = new Task();
t.Subject = &#039;Endpoint Invoked&#039;;
t.Description = debugInfo;
t.ActivityDate = Date.Today();
insert t;

return null;

}

static testMethod void Endpoint_Controller_test() {

// Set the page reference and pass through some parameters
PageReference thePage = Page.Endpoint;
thePage.getParameters().put(&#039;param1&#039;,&#039;1&#039;);
thePage.getParameters().put(&#039;param2&#039;,&#039;2&#039;);
Test.setCurrentPage(thePage);

// Run the init function to have it handle the web to lead submission
Endpoint_Controller ep = new Endpoint_Controller();
ep.init();
}
}
</pre>
<p>What does it do?  Well, it simply gathers up all the headers, page parameters and other useful info and outputs it in a readable way.  I sent a test request to one of my pages and this is what the page produced (and logged to a task in that org):</p>
<blockquote><p>
***ALL INCOMING HEADERS ***<br />
Accept = application/xml;charset=UTF-8<br />
Cache-Control = no-cache, max-age=0<br />
CipherSuite = RC4-MD5 TLSv1 128-bits<br />
Content-Type = application/xml;charset=UTF-8<br />
Host = testorg.secure.force.com<br />
Pragma = no-cache<br />
SFDC_STACK_DEPTH = 1<br />
User-Agent = SFDC-Callout/18.0<br />
X-Forwarded-For = 10.226.8.134<br />
X-Salesforce-Forwarded-To = na7.salesforce.com<br />
X-Salesforce-SIP = 204.14.234.8</p>
<p>***ALL INCOMING PARAMETERS ***<br />
param1 = value1<br />
param2 = value2<br />
param3 = value3</p>
<p>***OTHER PAGE REFERENCE INFO ***<br />
Anchor: null<br />
URL: /apex/Endpoint?param1=value1&#038;param2=value2&#038;param3=value3
</p></blockquote>
<p>I also construct debugInfo variables in my Production system to capture the receipt of incoming calls to Sites pages I have exposed (e.g. Google Checkout talks to my Salesforce org via a Sites page).  I will usually have a custom setting that I can turn on/off so I have an easy way to turn off the creation of those activities.</p>
<img src="http://sfdc.arrowpointe.com/?ak_action=api_record_view&id=743&type=feed" alt="" /><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/PerspectivesOnSalesforcecom?a=2FE8yhwvH0o:3lifn6eAlBU:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/PerspectivesOnSalesforcecom?i=2FE8yhwvH0o:3lifn6eAlBU:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/PerspectivesOnSalesforcecom/~4/2FE8yhwvH0o" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://sfdc.arrowpointe.com/2010/02/16/endpoint-for-debugging-http-callouts/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<feedburner:origLink>http://sfdc.arrowpointe.com/2010/02/16/endpoint-for-debugging-http-callouts/</feedburner:origLink></item>
		<item>
		<title>Using Aggregate Functions</title>
		<link>http://feedproxy.google.com/~r/PerspectivesOnSalesforcecom/~3/rN1GAl0pgO0/</link>
		<comments>http://sfdc.arrowpointe.com/2010/02/10/using-aggregate-functions/#comments</comments>
		<pubDate>Wed, 10 Feb 2010 17:51:05 +0000</pubDate>
		<dc:creator>Scott Hemmeter</dc:creator>
				<category><![CDATA[APEX Code]]></category>
		<category><![CDATA[Releases]]></category>
		<category><![CDATA[Spring '10]]></category>
		<category><![CDATA[Tips]]></category>

		<guid isPermaLink="false">http://sfdc.arrowpointe.com/?p=732</guid>
		<description><![CDATA[In Spring &#8216;10 Salesforce released new Apex functionality for aggregate functions.  Prior to this feature being available, one would have to perform a large query, loop through it and perform calculations themselves to do things like count records, sum values, get the max value, etc.  Now, you can do it in one simple, fast query!
The [...]]]></description>
			<content:encoded><![CDATA[<p>In <a href="http://sites.force.com/features/ideaHome?c=09a30000000DCUV" target="_blank">Spring &#8216;10</a> Salesforce released new Apex functionality for <a href="http://sites.force.com/ideaexchange/ideaView?c=09a30000000D9xt&amp;id=08730000000BrorAAC" target="_blank">aggregate functions</a>.  Prior to this feature being available, one would have to perform a large query, loop through it and perform calculations themselves to do things like count records, sum values, get the max value, etc.  Now, you can do it in one simple, fast query!</p>
<p>The <a href="http://www.salesforce.com/us/developer/docs/api/index_Left.htm#StartTopic=Content%2Fsforce_api_calls_soql_select_agg_functions.htm|SkinName=webhelp" target="_blank">API Guide</a> has all the details about how to perform aggregate functions in SOQL, but at a high-level, they (along with the GROUP BY clause) let you do things like:</p>
<ul>
<li>Get a <strong>count</strong> of Accounts grouped by Industry &amp; State</li>
<li>Get the <strong>avg</strong> Opportunity amount grouped by Calendar Month</li>
<li>Get the <strong>sum</strong> of Custom Object $ field grouped by Account</li>
<li>etc.</li>
</ul>
<p>Get the idea?  The functions you have available are COUNT(), COUNT_DISTINCT(), AVG(), SUM(), MIN(), MAX().  Think of these like you would the Columns To Total in a summary report.</p>
<p>You can also use the GROUP BY clause in your query to summarize your data by other fields.  Think of it like a Summary Report grouping.</p>
<p>The best way to learn it is to put it into practice.  To do so, I am going to &#8220;upgrade&#8221; the code from my <a href="http://sfdc.arrowpointe.com/2008/10/31/campaign-member-summary-using-google-charts/" target="_blank">Campaign Member Summary using Google Charts</a> post.  The goal is to create a chart that looks like below:</p>
<p><img class="aligncenter size-full wp-image-462" title="vfcampaignchart" src="http://sfdc.arrowpointe.com/wp-content/images/vfcampaignchart.png" alt="" width="457" height="238" /></p>
<p>The <strong>original controller</strong> used the following code to build the count of records per Campaign Member Status:</p>
<pre class="brush: java">
// List of valid Campaign Member Statuses for the Campaign
List&lt;CampaignMemberStatus&gt; list_cms = [select Id, Label from CampaignMemberStatus where CampaignId = :camp.id];

// Loop through each Campaign Member Status, get a count of Campaign Members and add it to the items list
for (CampaignMemberStatus cms:list_cms) {
integer Count = [select count() from CampaignMember where CampaignId = :camp.id AND Status = :cms.Label];
if (Count &gt; 0) {
items.add(new ChartDataItem(cms.Label, Count.format()));
}
}
</pre>
<p>The code above works just fine, but has some issues.  The main issue is that we are performing a query inside a for() loop.  Bad!  If a Campaign had more than 20 statuses, the code would fail. Also, this is a performance hit because we have to perform as many queries as there are member statuses.  Enter aggregate functions.</p>
<p>The <strong>improved controller</strong> changes the query to work like this.</p>
<pre class="brush: java">
// Get all the data in one query
AggregateResult[] groupedResults = [select Status, count(Id) from CampaignMember where CampaignId = :camp.id group by status];

// Loop through the query and add chart items
for (AggregateResult ar : groupedResults) {
     items.add(new ChartDataItem( String.valueOf(ar.get(&#039;Status&#039;)), String.valueOf(ar.get(&#039;expr0&#039;))));
}
</pre>
<p>Now we are doing everything we need in 1 query.  Even if we had 1000 different member statuses, it wouldn&#8217;t matter.  We should never hit a governor limit with this code and performance has also been improved.  Some important things to note in making this change and in understanding aggregate functions:</p>
<ul>
<li>Your controller class should be on API version 18.0 or higher.  18.0 is the Spring &#8216;10 release and that&#8217;s when these functions were introduced.</li>
<li>The results of a query with aggregate functions should result in a AggregateResult[] collection.</li>
<li>The get() method is used to retrieve data from an AggregateResult object (used inside the loop when looking at a single result)</li>
<li>To get the value from a field your are grouping by (i.e. doesn&#8217;t have a function for it), use .get(&#8216;fieldName&#8217;).  In the above example, I use this to get the Status value I am grouping by.</li>
<li>To get the value from a field that has an aggregate function, use .get(&#8216;expr#&#8217;), where # is the index number for that field.  A query can have multiple functions in it so you need to specify which function you are grabbing and you do so by its index number.  For you non-programmers out there, remember that <strong>counting starts at 0</strong>.   In the above example, I use this to get the count(id) value.  Since I only have 1 aggregate function in my query, i get it using .get(&#8216;expr0&#8242;) where 0 is the index number for my function result.</li>
<li>The get() method returns an Object type so you will need to use the appropriate valueOf() method to put it into the data type you need.</li>
</ul>
<p><strong>NOTE</strong>: As of writing this post, the IDE was not yet upgraded to 18.0 so I had to do this work inside the browser and I used the new-ish Deploy functionality from inside Salesforce to migrate the change from Sandbox to Production.</p>
<img src="http://sfdc.arrowpointe.com/?ak_action=api_record_view&id=732&type=feed" alt="" /><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/PerspectivesOnSalesforcecom?a=rN1GAl0pgO0:8XdHefjDzTo:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/PerspectivesOnSalesforcecom?i=rN1GAl0pgO0:8XdHefjDzTo:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/PerspectivesOnSalesforcecom/~4/rN1GAl0pgO0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://sfdc.arrowpointe.com/2010/02/10/using-aggregate-functions/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		<feedburner:origLink>http://sfdc.arrowpointe.com/2010/02/10/using-aggregate-functions/</feedburner:origLink></item>
		<item>
		<title>AppExchange Best of ‘09 Awards</title>
		<link>http://feedproxy.google.com/~r/PerspectivesOnSalesforcecom/~3/ien3LUCSLA8/</link>
		<comments>http://sfdc.arrowpointe.com/2009/12/15/appexchange-best-of-09-awards/#comments</comments>
		<pubDate>Wed, 16 Dec 2009 01:03:10 +0000</pubDate>
		<dc:creator>Scott Hemmeter</dc:creator>
				<category><![CDATA[AppExchange]]></category>
		<category><![CDATA[Arrowpointe Maps]]></category>
		<category><![CDATA[Arrowpointe Products]]></category>
		<category><![CDATA[Auto vCard]]></category>
		<category><![CDATA[Info Center]]></category>
		<category><![CDATA[Spam Check]]></category>
		<category><![CDATA[User Adoption Dashboard]]></category>

		<guid isPermaLink="false">http://sfdc.arrowpointe.com/?p=724</guid>
		<description><![CDATA[Salesforce is currently running their Best of &#8216;09 AppExchange awards.  The awards are solely based upon 2009 4-star and 5-star reviews.  If you use an Arrowpointe application, I encourage you to leave a review.  In addition to helping with awards, it&#8217;s the best way to give me your feedback and to help fellow Salesforce users [...]]]></description>
			<content:encoded><![CDATA[<p>Salesforce is currently running their Best of &#8216;09 AppExchange awards.  The awards are solely based upon 2009 4-star and 5-star reviews.  If you use an Arrowpointe application, I encourage you to leave a review.  In addition to helping with awards, it&#8217;s the best way to give me your feedback and to help fellow Salesforce users know what&#8217;s quality and what is not.</p>
<p>Links to the Arrowpointe AppExchange listings are below:</p>
<ul>
<li><a href="http://www.arrowpointe.com/getmaps" target="_blank">Arrowpointe Maps</a></li>
<li><a href="http://www.arrowpointe.com/getvcard" target="_blank">Auto vCard</a></li>
<li><a href="http://www.arrowpointe.com/getspamcheck" target="_blank">Spam Check</a></li>
<li><a href="http://www.arrowpointe.com/getinfocenter" target="_blank">Info Center</a></li>
<li><a href="http://www.arrowpointe.com/getuad" target="_blank">User Adoption Dashboard</a></li>
</ul>
<p>Thank you for your feedback!</p>
<img src="http://sfdc.arrowpointe.com/?ak_action=api_record_view&id=724&type=feed" alt="" /><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/PerspectivesOnSalesforcecom?a=ien3LUCSLA8:d-9KZuM9xQw:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/PerspectivesOnSalesforcecom?i=ien3LUCSLA8:d-9KZuM9xQw:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/PerspectivesOnSalesforcecom/~4/ien3LUCSLA8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://sfdc.arrowpointe.com/2009/12/15/appexchange-best-of-09-awards/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://sfdc.arrowpointe.com/2009/12/15/appexchange-best-of-09-awards/</feedburner:origLink></item>
		<item>
		<title>Associate Email to Salesforce Task to Opportunity</title>
		<link>http://feedproxy.google.com/~r/PerspectivesOnSalesforcecom/~3/HrFhzF5Op5o/</link>
		<comments>http://sfdc.arrowpointe.com/2009/10/06/associate-email-to-salesforce-task-to-opportunity/#comments</comments>
		<pubDate>Tue, 06 Oct 2009 23:32:48 +0000</pubDate>
		<dc:creator>Scott Hemmeter</dc:creator>
				<category><![CDATA[APEX Code]]></category>
		<category><![CDATA[Tips]]></category>

		<guid isPermaLink="false">http://sfdc.arrowpointe.com/?p=714</guid>
		<description><![CDATA[I use the Email to Salesforce functionality every single day.  This feature allows you to get a random email address similar to emailtosalesforce@0235ffdsdfsad98dvfj4i549540njh3.in.salesforce.com (this is just a sample) that you bcc on emails and Tasks get created in your system that are auto-associated to your Leads/Contacts.
There is an option to associate the Task to Opportunities, [...]]]></description>
			<content:encoded><![CDATA[<p>I use the Email to Salesforce functionality every single day.  This feature allows you to get a random email address similar to <em>emailtosalesforce@0235ffdsdfsad98dvfj4i549540njh3.in.salesforce.com</em> (this is just a sample) that you bcc on emails and Tasks get created in your system that are auto-associated to your Leads/Contacts.</p>
<p>There is an option to associate the Task to Opportunities, but instead of creating a Task and associating it to the Lead/Contact AND the Opportunity, 2 tasks are created: one against the Lead/Contact and another against the Opportunity.  I have no idea why it was designed this way, but it was.  Given that, I don&#8217;t use the option to associate the Task to Opportunities.</p>
<p>After months of manually assigning to Opportunities after I send the email, I got fed up and wrote a trigger that senses an email to salesforce record and auto associates it to the nearest Open Opportunity.  I thought I&#8217;d share it with y&#8217;all.</p>
<p>This code assumes the following:</p>
<ul>
<li>You are using Email to Salesforce</li>
<li>You have the Email to Salesforce option for Leads &#038; Contacts enabled and the one for Opportunities disabled</li>
<li>You associate Contacts to your Opportunities via the OpportunityContactRole object</li>
</ul>
<p><strong>Trigger</strong></p>
<pre class="brush: java">
trigger Tasks on Task (before insert) {

	// BEFORE INSERT
	if(Trigger.isBefore &amp;&amp; Trigger.isInsert){
		Tasks t = new Tasks();
        t.AssociateOpportunity(Trigger.new);
    }

}
</pre>
<p><strong>Class</strong></p>
<pre class="brush: java">
public class Tasks {

    // Default Constructor
    public Tasks()
    {
    }

    // Associates a new Task generated by Email to Salesforce to an open opportunity, if one exists for the Account
    public void AssociateOpportunity(Task[] tasks)
    {

    	/***************
        * Variables
        ***************/
		list&lt;Task&gt; l_Tasks = new list&lt;Task&gt;(); // Tasks we&#039;ll be updating
		set&lt;ID&gt; s_ContactIDs = new set&lt;ID&gt;(); // Set of Contact IDs

		/***************
        * Initial Loop
        ***************/
		for(Task t:tasks) {

			// Add Task to working list and collect the Contact ID
			if (t.WhatId == null &amp;&amp; t.Subject.startsWith(&#039;Email:&#039;) &amp;&amp; t.WhoId != null) {
				// only for Contacts
				if (String.valueOf(t.WhoId).startsWith(&#039;003&#039;)){
					l_Tasks.add(t);
					s_ContactIDs.add(t.WhoId);
				}
			}

		}

		/***************
        * Create Maps
        ***************/
        // Maps Contact ID to an Opportunity ID
		map&lt;ID, ID&gt; map_cID_to_oID = new map&lt;ID, ID&gt;();
			// Query for the Contact&#039;s Open Opportunities. Sort by CloseDate DESC so the Task gets assigned to the earliest Opportunity as it loops
			for (OpportunityContactRole ocr:[select Id, OpportunityId, ContactId
											 from OpportunityContactRole
											 where ContactId in :s_ContactIDs
											 AND Opportunity.IsClosed = false
											 order by Opportunity.CloseDate DESC
											 ]) {
				map_cID_to_oID.put(ocr.ContactId, ocr.OpportunityId);
			}

		/***************
        * Process Records
        ***************/
		for (Task t:l_Tasks) {

			// If the Contact has an Opportunity mapped to it, update the Task with that Opportunity
			if (map_cID_to_oID.get(t.WhoId) != null) {
				t.WhatId = map_cID_to_oID.get(t.WhoId);
			}

		}
    }

}
</pre>
<p><strong>Test Class</strong></p>
<pre class="brush: java">
@isTest
private class Tasks_Test {

    static testMethod void AssociateOpportunity_Test() {

        // Create a Lead
        Lead l = new Lead();
	        l.FirstName = &#039;Test&#039;;
	        l.LastName = &#039;Lead&#039;;
	        l.Company = &#039;Test Company&#039;;
	        l.Email = &#039;leademail@example.com&#039;;
        insert l;

        // Create an Account
        Account a = new Account();
        	a.Name = &#039;Test Account&#039;;
        insert a;

        // Create a Contact
        Contact c = new Contact();
	        c.FirstName = &#039;Test&#039;;
	        c.LastName = &#039;Contact&#039;;
	        c.AccountId = a.Id;
	        c.Email = &#039;contactemail@example.com&#039;;
        insert c;

        // Create Opportunities
        list&lt;Opportunity&gt; l_Opps = new list&lt;Opportunity&gt;();
        Opportunity o = new Opportunity();
        	o.AccountId = a.id;
        	o.Name = &#039;Test Opportunity&#039;;
        	o.CloseDate = date.today();
        	o.StageName = &#039;Qualified&#039;;
        	o.Description = &#039;Test Opportunity Description&#039;;
        l_Opps.add(o);

        Opportunity o2 = new Opportunity();
        	o2.AccountId = a.id;
        	o2.Name = &#039;Test Opportunity&#039;;
        	o2.CloseDate = date.today().addDays(30);
        	o2.StageName = &#039;Qualified&#039;;
        	o2.Description = &#039;Test Opportunity Description&#039;;
        l_Opps.add(o2);

        Opportunity o3 = new Opportunity();
        	o3.AccountId = a.id;
        	o3.Name = &#039;Test Opportunity&#039;;
        	o3.CloseDate = date.today().addDays(60);
        	o3.StageName = &#039;Closed Won&#039;;
        	o3.Description = &#039;Test Opportunity Description&#039;;
        l_Opps.add(o3);

        insert l_Opps;

        // Create Opportunity Contact Roles
        list&lt;OpportunityContactRole&gt; l_Ocr = new list&lt;OpportunityContactRole&gt;();
    	OpportunityContactRole ocr1 = new OpportunityContactRole();
    		ocr1.ContactId = c.id;
    		ocr1.OpportunityId = o.id;
			ocr1.IsPrimary = true;
			ocr1.Role = &#039;Decision Maker&#039;;
		l_Ocr.add(ocr1);

		OpportunityContactRole ocr2 = new OpportunityContactRole();
    		ocr2.ContactId = c.id;
    		ocr2.OpportunityId = o2.id;
			ocr2.IsPrimary = true;
			ocr2.Role = &#039;Decision Maker&#039;;
		l_Ocr.add(ocr2);

		insert l_Ocr;

        /* Create Tasks for Test Cases */
        list&lt;Task&gt; l_Tasks = new list&lt;Task&gt;();

        // Task associated to Lead, not Contact
        Task t1 = new Task();
        	t1.Subject = &#039;Email: something&#039;;
        	t1.Status = &#039;Completed&#039;;
        	t1.WhoId = l.id;
        	t1.ActivityDate = Date.today();
    	l_Tasks.add(t1);

    	// Task with wrong subject
    	Task t2 = new Task();
        	t2.Subject = &#039;something&#039;;
        	t2.Status = &#039;Completed&#039;;
        	t2.WhoId = c.id;
        	t2.ActivityDate = Date.today();
    	l_Tasks.add(t2);

    	// Task with no WhoId
    	Task t3 = new Task();
        	t3.Subject = &#039;something&#039;;
        	t3.Status = &#039;Completed&#039;;
        	t3.ActivityDate = Date.today();
    	l_Tasks.add(t3);

    	// Task with a What ID already
    	Task t4 = new Task();
        	t4.Subject = &#039;something&#039;;
        	t4.Status = &#039;Completed&#039;;
        	t4.WhoId = c.id;
        	t4.WhatId = o2.id;
        	t4.ActivityDate = Date.today();
    	l_Tasks.add(t4);

    	// Task that should get triggered fully
    	Task t5 = new Task();
        	t5.Subject = &#039;Email: something&#039;;
        	t5.Status = &#039;Completed&#039;;
        	t5.WhoId = c.id;
        	t5.ActivityDate = Date.today();
    	l_Tasks.add(t5);

    	insert l_Tasks;

 		/* Asserts */

 		// Task 1 should not have a What ID populated
 		Task t = [select Id, WhoId, WhatId from Task where Id = :t1.id limit 1];
 		system.assertEquals(t.WhatId, null);

 		// Task 2 should not have a What ID populated
 		t = [select Id, WhoId, WhatId from Task where Id = :t2.id limit 1];
 		system.assertEquals(t.WhatId, null);

 		// Task 3 should not have a What ID populated
 		t = [select Id, WhoId, WhatId from Task where Id = :t3.id limit 1];
 		system.assertEquals(t.WhatId, null);

 		// Task 4 should have the same What ID it had originally populated
 		t = [select Id, WhoId, WhatId from Task where Id = :t4.id limit 1];
 		system.assertEquals(t.WhatId, o2.id);

 		// Task 5 is the one that should&#039;ve had the Opportunity ID auto populated
 		t = [select Id, WhoId, WhatId from Task where Id = :t5.id limit 1];
 		system.assertEquals(t.WhatId, o.id);

    }
}
</pre>
<p>Let me know if you have any suggestions.</p>
<img src="http://sfdc.arrowpointe.com/?ak_action=api_record_view&id=714&type=feed" alt="" /><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/PerspectivesOnSalesforcecom?a=HrFhzF5Op5o:nI9v1w4K3e4:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/PerspectivesOnSalesforcecom?i=HrFhzF5Op5o:nI9v1w4K3e4:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/PerspectivesOnSalesforcecom/~4/HrFhzF5Op5o" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://sfdc.arrowpointe.com/2009/10/06/associate-email-to-salesforce-task-to-opportunity/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://sfdc.arrowpointe.com/2009/10/06/associate-email-to-salesforce-task-to-opportunity/</feedburner:origLink></item>
		<item>
		<title>Spam Check is Live on AppExchange</title>
		<link>http://feedproxy.google.com/~r/PerspectivesOnSalesforcecom/~3/OYXX2VImjYU/</link>
		<comments>http://sfdc.arrowpointe.com/2009/09/15/spam-check-is-live-on-appexchange/#comments</comments>
		<pubDate>Tue, 15 Sep 2009 15:48:44 +0000</pubDate>
		<dc:creator>Scott Hemmeter</dc:creator>
				<category><![CDATA[AppExchange]]></category>
		<category><![CDATA[Arrowpointe Products]]></category>
		<category><![CDATA[Spam Check]]></category>

		<guid isPermaLink="false">http://sfdc.arrowpointe.com/?p=694</guid>
		<description><![CDATA[
I am pleased to announce that Spam Check is now live on the AppExchange.
Spam Check lets your Salesforce system evaluate your data to see if it’s Spam. It contains built-in support for incoming Web-to-Lead and Web-to-Case data and also has global Apex methods that allow developers to incorporate Spam checks in their applications (e.g. a [...]]]></description>
			<content:encoded><![CDATA[<div style="margin: 0pt auto; width: 500px;"><img class="alignnone size-full wp-image-695" title="SpamCheck-AppExchange-Banner" src="http://sfdc.arrowpointe.com/wp-content/images/SpamCheck-AppExchange-Banner.jpg" alt="SpamCheck-AppExchange-Banner" width="500" height="61" /></div>
<p>I am pleased to announce that <a href="http://www.arrowpointe.com/spamcheck" target="_blank"><strong>Spam Check</strong></a> is now <a href="http://www.arrowpointe.com/getspamcheck" target="_blank"><strong>live on the AppExchange</strong></a>.</p>
<p>Spam Check lets your Salesforce system evaluate your data to see if it’s Spam. It contains built-in support for incoming <strong>Web-to-Lead</strong> and <strong>Web-to-Case</strong> data and also has <strong>global Apex methods</strong> that allow developers to incorporate Spam checks in their applications (e.g. a custom Salesforce Site).  This application delivers a solution for a <a href="http://ideas.salesforce.com/article/show/29238/Web_2_Lead___webform_spam" target="_blank">popular idea from the community</a>.</p>
<p>Spam Check uses <a href="http://www.akismet.com/" target="_blank">Akismet</a>, the leading spam evaluation service used on tens of thousands of blogs and websites everyday. Akismet gets its intelligence from the vast community that uses it everyday.  Spam Check allows you to contribute to it and make it more intelligent for the whole community and for your Salesforce system specifically.</p>
<p>Install it from <a href="http://www.arrowpointe.com/getspamcheck" target="_blank">the AppExchange</a> to start a <strong>free, no obligation 30-day trial</strong>.   Once installed, you will get an email pointing you to the <a href="http://www.arrowpointe.com/spamcheck101" target="_blank">Spam Check Setup Guide</a>.</p>
<p>For more information, please visit the <a href="http://www.arrowpointe.com/spamcheck" target="_blank">Spam Check page </a>on our website or its <a href="http://www.arrowpointe.com/getspamcheck" target="_blank">AppExchange listing</a>.</p>
<img src="http://sfdc.arrowpointe.com/?ak_action=api_record_view&id=694&type=feed" alt="" /><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/PerspectivesOnSalesforcecom?a=OYXX2VImjYU:q5tGMweP1qk:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/PerspectivesOnSalesforcecom?i=OYXX2VImjYU:q5tGMweP1qk:D7DqB2pKExk" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/PerspectivesOnSalesforcecom/~4/OYXX2VImjYU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://sfdc.arrowpointe.com/2009/09/15/spam-check-is-live-on-appexchange/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://sfdc.arrowpointe.com/2009/09/15/spam-check-is-live-on-appexchange/</feedburner:origLink></item>
	</channel>
</rss>
