You are currently browsing the tag archive for the ‘Salesforce’ tag.
In this tutorial we will go from zero to ninja speed in approximately ten minutes. If you have problems approaching ninja speed, it is probably because you are in ruby version management hell, gem dependency hell, or any other number of hells that brave would-be ninjas are occasionally trapped in. Should you end up here, prayer and Google may help you.
Step one: Create your rails app.
rails new ninjaspeed
Step two: Add the database.com and helper gem to your GEMFILE (this will be in the ninjaspeed directory)
gem 'databasedotcom' gem 'databasedotcom-rails'
Also add the postgres gem (you aren’t using the db on Heroku but need it anyways) and a gem to handle precompiled javascript (for the JQuery Mobile):
gem 'pg' gem 'therubyracer'
Step three: Install the new gems
sudo bundle install
Step four: Add scaffolding for a new resource that corresponds to a resource in Salesforce
rails generate scaffold_controller Lead FirstName:String LastName:String Company:String
Add an entry in your routes.rb file
resources :leads
Rails is straight up MVC, and you just created a controller and a view. Check out your app/controllers and app/views folders to see them. Salesforce/Database.com will be your Model.
Step five: Deploy this baby to Heroku
git init git add . git commit -m "i love databasedotcom" heroku create git push heroku master heroku addons add:piggyback_ssl
Step six: Take the new funky fantastic name you got and enable remote access in Salesforce
Login to salesforce. Go to Setup -> Develop -> Remote Access -> New Enter the address of your app (e.g. https://stormin'-samurai-558.herokuapp.com) You will get a client key (this is also the client_id) and your client secret
Step seven: Add your salesforce credentials to a file in the config folder called databasedotcom.yml
databasedotcom.yml #### client_id: 3MVG..... client_secret: 1323224123... username: mysalesforceusername@login.com password: passwordPlusSecToken host: login.salesforce.com <-- use test.salesforcecom if using a sandbox debugging: true
Step eight: Connect your app to Salesforce
Add this to your app/controllers/leads_controller
LeadsController < ApplicationController include Databasedotcom::Rails::Controller
In the same file you need to add a few more required fields. Navigate to the create method and add three lines:
def create
@lead = Lead.new(params[:lead])
# ADD ME
@lead['OwnerId'] = '005U0000000IekIIAS' <-- ownerId here is the Id of the User you want the Lead associated with
@lead['IsConverted'] = false
@lead['IsUnreadByOwner'] = true
# END
Thanks to some backend magic, the databasedotcom-rails gem automatically initializes the client you need to connect to salesforce so you don’t have to worry about it.
Step eight: Add in a jQuery mobile stylesheet so this doesn’t look super ghetto (optional)
Navigate to app/views/layouts/application.html.erb and edit these lines to the header:
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.0/jquery.mobile-1.0.min.css" /> <script src="http://code.jquery.com/jquery-1.6.4.min.js"></script> <script src="http://code.jquery.com/mobile/1.0/jquery.mobile-1.0.min.js"></script>
Put the yield tag in the body in a div like so:
<div data-role="page"> <%= yield %> </div>
For your apps/views/leads/new.html.erb, divide into a couple of sections
<div data-role="header"> Lead form </div> <div data-role="content"> <%= render 'form' %> </div> <div data-role="footer"> If you want it </div>
Navigate to config/environments/production.rb, find the config.assets.compile, and set it to true (turn on the live compiliation of assets)
config.assets.compile = true
Step nine: Remove extra stuff from your _form.html.erb/strong
This is all you need:
<%= form_for(@lead) do |f| %>
<div class="field">
<%= f.label :FirstName %><br />
<%= f.text_field :FirstName %>
</div>
<div class="field">
<%= f.label :LastName %><br />
<%= f.text_field :LastName %>
</div>
<div class="field">
<%= f.label :Company %><br />
<%= f.text_field :Company %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Step ten: Deploy to Heroku
git add . git commit -m "I love databasedotcom even more now" git push heroku master
Navigate to yourapp.heroku.com/lead/new, and presto-chango, a mobile-enabled submission form that hooks up to Salesforce.
You can also view leads in the system by navigating to yourapp.heroku.com/leads
Also, if you want to add in validation (and I suggest it) you can do this client-side rather than serverside.
Oh, and in case you were wondering the source code for all this is available on Github.
If you are already in “The Cloud” or promoting “The Cloud” you may not need this post (but may want to skip to the end for the comments on how to explain the “The Cloud” to those not yet in the stratosphere).

What is “The Cloud” ? Most people have heard of it. Most people seem to be somewhat confused as to what it is. Is it simply the internet touched up with some marketing fluff? Some grand new innovation encompassing technology, too new and cool to fully explain? Or simply a way to cut down on costs by putting all of your precious data on other people’s servers?
I think with this, as with other terms that are frequently used for marketing purposes, it is helpful to examine the history and evolution of the term. In this case, my presentation will be somewhat speculative since I’m not certain about all of the historical aspects, nor do the early inventors in the corporate world seem likely to want to help document it. That said, let’s begin.
“The Cloud” includes services such as Gmail. However, as far as I can tell it only began to be used when companies (like one of my favorites, Appirio), were replacing internal (e.g. Exchange) servers with “Cloud” services like Gmail. What do I take from this? “The Cloud” did not exist when individuals chose to store much of their information on servers that they did not control. “The Cloud” came into existence when companies with often large numbers of internal servers dedicated to various purposes began trusting other companies enough to put their data on servers operated by these other companies.
Of course, this falls into various categories, commonly described as Platform as a Service, Infrastructure as a Service, Software as a Service. In a certain sense, each is fairly straight forward, although certain categories overlap with other services that existed before “The Cloud.” For example,
“Software as a Service” is not really any different from a web application. In fact, after a fair bit of time the only difference I’ve figured out is that “Software as a Service” emphasizes the possibility of integration with a data and infrastructural layer that exists across distinct software instances.
Contenders in this area which have entries at multiple layers are Google, Salesforce, Amazon, Microsoft, Apple, and (to a lesser extent) Engine Yard — although it is also worth mentioning the many companies (and non-profits, universities, etc.) which maintain expensive internal servers and are still waiting to move over to the “Cloud” due to concerns about reliability, being locked-in, etc.
How to explain this shift to less computer literate friends or co-workers? Maybe the best way is “The Cloud is companies putting information in the internet.” If they have a bit more time, perhaps show them a video like this one (sometimes a bit of “fluff” is necessary when you have clouds floating around).
This week I :
(1) Wrote and deployed a Sinatra App to Heroku to test Jeff Douglas’s code. It works! Link.
(2) Leveraged the Cinch framework to write an IRC Bot for the #salesforce IRC channel on Freenode. Please say hello to “Saasy” in the #salesforce channel and see what it can do.
(3) Wrote and deployed a simple Rails app (v. 3) to Heroku which displays the log from the IRC Bot (link edited 2/28/11).
Here are some takeaways:
(1) Getting started with Ruby can be a bit tough. There are often versioning issues and incompatibilities which can take a long time to solve. I was switching back between different versions of Ruby, Rails, and various gems — often finding that documentation was out of date. You also need to spend a fair amount of time on the command line, which can be difficult for folks used to a super IDE.
(2) Writing with Ruby is fun. Of course, there is a learning curve with anything, but there is a lot of syntactical sugar that makes writing Ruby one of my favorite things to do (once I get the hang of it).
(3) Heroku is awesome. I’ve written a couple Rails apps before but deployment was kind of pain. No longer! Heroku is super fun and super easy.
(4) The Ruby community is great. Even if sorting through blogs to find up-to-date instructions is not the most fun activity, there is tons of information out there and also lots of helpful people on various IRC channels (#heroku #ruby #cinch #rubyonrails).
So why not get started? For resources I highly highly recommend Peepcode, as well as the “Pickaxe”. For a (if you are doing Rails stuff, also the Agile Guide). For a quirkier, quicker, and in many ways more delightful (if not as comprehensive) approach, check out Why’s Guide to Ruby and learn the meaning of chunky bacon.
Special thanks to Domink Honnef, who provided helpful advice and put up with my safe harbor statement testing on the #cinch-bots channel, as well as aliasweird, apothecary, and others who made helpful suggestions re: the irc bot in #salesforce.
I’ve been bothered for awhile that when you search for advantages for developing on the Force.com Platform one of the first Google results is a thread on a forum listing many perceived disadvantages from a development perspective. Even worse, because of the rapid development of the platform many of the disadvantages listed are no longer correct. In this post I will discuss both advantages and disadvantages relating to development on the Force.com platform.
Advantages
(1) Quick access to Salesforce’s existing 82,400 company user base ( which has money to spend ) through the AppExchange (only a $300 listing fee).
(2) Piggy back off Salesforce’s powerful existing functionality, including:
- User management and authentication
- Administrative interface
- Reporting and analytics
- Dynamic API
- Toolkits and integrations for other languages and platforms(3) PaaS offering allows you not to worry about server maintenance or architecture
(4) Governor limits and test code coverage enforce some degree of best practice
(5) Security, both because of code review and because of high degree of control on the platform (see #2)
(6) Java-like syntax speeds learning curve for new developers
(7) Native “Visualforce” elements allow quick and easy information output
(8) Active community. Lots of information out there and active participation from Salesforce staff
(9) Object metadata can be leveraged for powerful functionality
(10) Actively under development (Big things underway with VMForce).
Disadvantages
(1) APEX is not a fully featured language
-Lots of things you might wish were there aren’t
- You will have to port them yourself or make outbound webservice calls(2) Hard to know if you will really make money
- Hard to impossible to find revenue numbers for the AppExchange
- Per-user licensing creates a pretty linear margin on license fees (as opposed to potentially exponential on a metered system like GAE or EC2).
- Data based pricing makes it pricy for folks with lots of data(3) Debugging can be extraordinarily slow:
- No real debugger
- Places where you don’t even have a debug log (not enabled, in a managed package, reached the limit, or weird errors that don’t leave an entry).
- Unfixed bugs or quirks on the platform that you wouldn’t expect (i.e. undocumented differences between commandLink and commandButton).(4) Ideaexchange and other reporting tools tend to be admin focused
and geared towards new features, not fixes or better developer tools(5) Governor limits sometimes make sense, but at other times they can be very difficult and prevent what would be best practice. Very easy to get in a place where you are trapped by a governor limit and very hard to know ahead of time whether or not any given practice you will take there (unless you already have a lot of time playing “dodge the governor limit” ). These are doubly a problem when it comes to test coverage.
(6) Developer tools continue to be somewhat lacking (even though the Force.com IDE runs in Eclipse you can’t use many of the Java focused extensions and build time is slow).
Incorrect Criticisms
(1) WRONG: There is no namespacing or packaging.
RIGHT: Namespace and packaging exist but are controlled via metadata (and unfortunately do not allow different folders in the Force.com IDE default view).
(2) WRONG: Security model is restrictive
RIGHT: A restrictive security model can be a robust security model. There are layers of complexity and in this case complexity equals customizability and power.
(3) WRONG: Difficult to convert SObjects to JSONObjects
RIGHT: JSONObject implementation makes this fairly simple.
(4) WRONG: Governor limits are terrible
RIGHT: Governor limits makes sense given the Force.com architecture (although they can be limiting and frustrating at times)
(5) WRONG: Support is poor
RIGHT: It is not realistic to expect excellent free developer support and if you want developer-focused support you should be willing to pay for the Premier offering.
My Recommendations
Do:
There may be some pain, but you should be okay developing small to mid-size apps on the Force.com platform, and you will do even better if you learn some Tips and Tricks and/or minimize coding in APEX (i.e. convert everything to JSON and do your processing in Javascript). I’d also recommend against trying to do anything too creative or with going in with expectations that are too high.
Don’t:
Don’t try to develop an enterprise app of significant size or scope on the platform. Even if the OEM pricing looks attractive, there is a good chance you will end up sinking ever deeper in a quagmire of multiplying unexplained buggy behavior and insurmountable governor limits (note: this recommendation may change with VMForce).
Takeaway
Part of the necessity here is understanding where PaaS is today, and the reality is that while PaaS as a service beyond IaaS, while developing rapidly, is not yet a platform ready for development of large enterprise ready apps. It is fine for extensions of existing technology, but be wary if you try for much more than this. This does not reflect poorly on Salesforce.com as they have been pushing the envelope on what is possible with all the force available to them. There are at the moment very many useful and potentially profitable things that can be done with the platform and if you have the time and resources, I strongly suggest doing them (or at least getting your feet wet while waiting for things to develop further).
Special thanks to Wes Nolte and Alex Sutherland for suggestions and corrections, as well as attendees at the Philadephia Dev Meetup (@botoscloud, @cashion, @matschaffer).
This is primarily an extension of the Force.com for Google App Engine Java Setup Guide which addresses problems specific to getting things running on Os X. There are also a couple of other problems you might have that I will also attempt to address.
First, get the two files you will need. (1) the latest version of the wsc-gae jar, at the moment wsc-gae-16_0.jar (available at the codeshare) (2) the partner library jar (also available at the codeshare).
Additionally, you can generate second jar for yourself from the partner wsdl or the enterprise wsdl. Since we want to refer to all of our custom Sobjects explicitly, we will use the enterprise wsdl (which can be downloaded from Setup->Develop->API in your Salesforce account).
To generate the enterprise library you need a recent version of Java (1.6) with the JVM. If you aren’t sure type “java -version” in the terminal. Here’s what we get:
Now all you need to do is run the following:
java -classpath wsc-gae-16_0.jar:JAVA_HOME/Classes/classes.jar com.sforce.ws.tools.wsdlc enterprise.wsdl.xml ./myProject_enterprise_lib.jar
Note the several differences from the example at the wiki article:
(1) A colon (‘:’) instead of a semi-colon (‘;’)
(2) Classes.jar instead of tools.jar (which is also located in a different directory)
(3) You must specify a directory for the generated jar
Fail to do any of these three and things will go horribly wrong.
Here is the full statement on our system:
java -classpath wsc-gae-16_0.jar:/System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Classes/classes.jar com.sforce.ws.tools.wsdlc enterprise.wsdl.xml ./myProject_enterprise_lib.jar
The rest of this is straight from the wiki article with a couple notes:
(1) Install Eclipse and the Google Eclipse Plugin. NOTE: You will probably also want to register an application name so you can deploy to the Google App Engine later.
(2) Create a New Web Application Project
(3) Now, add the jar files we downloaded and generated above to your application’s WEB-INF/lib folder. NOTE: if you accidentally use what you think is a more recent version (for instance the wsc-17_0.jar) you will likely get strange errors like Java.net.Proxy, java.lang.UnsupportedOperationException, 500 Server Error, etc. Moreover, even if you remove the jar file the errors may not go away and you may have to restart with a whole new project.
(4) Add the example servlet class. NOTE: Make sure you append your security token to your password. This example also depends on having the partner library as your jar. If you want to use the Enterprise WSDL use the following:
package com.joeldietz.chatterwave;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.http.*;
import java.util.logging.*;
import com.sforce.ws.*;
import com.sforce.soap.enterprise.*;
import com.sforce.soap.enterprise.sobject.Account;
@SuppressWarnings("serial")
public class HelloWorldEnterpriseServlet extends HttpServlet {
private static final Logger log = Logger.getLogger(HelloWorldEnterpriseServlet.class.getName());
private String username = " ";
private String password = " "; // <-- password plus security token here
private EnterpriseConnection connection;
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
resp.setContentType("text/html");
resp.getWriter().println("Hello, world. this is a test 35");
PrintWriter t = resp.getWriter();
getConnection( t, req);
if ( connection == null ) { return; }
QueryResult result = null;
try {
result = connection.query( "select id, name, phone from Account order by LastModifiedDate desc limit 10 ");
} catch (ConnectionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for (int i=0;i<result.getRecords().length;i++) {
Account a = (Account)result.getRecords()[i];
String name = a.getName();
t.println("<li>"+ name + "</li>");
}
}
void getConnection(PrintWriter out, HttpServletRequest req) {
try {
// build up a ConnectorConfig from a sid
String sessionid = req.getParameter("sid");
String serverurl = req.getParameter("srv");
if ( connection == null ) {
out.println("<p>new connection needed</p>");
// login to the Force.com Platform
ConnectorConfig config = new ConnectorConfig();
if ( sessionid != null && serverurl != null) {
config.setServiceEndpoint(serverurl);
config.setSessionId(sessionid);
config.setManualLogin(false);
out.println("using session from query string");
} else {
config.setUsername(username);
config.setPassword(password);
}
connection = Connector.newConnection(config);
out.println( connection.getConfig().getSessionId() );
out.println( connection.getConfig().getServiceEndpoint() );
} else {
out.println("<p> reuse existing connection");
out.println( connection.getConfig().getSessionId() );
}
log.warning("Connection SID " +connection.getConfig().getSessionId());
} catch ( ConnectionException ce) {
log.warning("ConnectionException " +ce.getMessage());
out.println( ce.getMessage() + " s " + ce.getClass() );
}
}
}
Now we can try this out by running the servlet as a web application (Run -> Run As -> Web Application). You may also want to go into the run configurations and change the server port on the server tab if you are running other Google App Engine enabled web applications. If you registered your application before at Google App Engine, you can also try right clicking on your project then Google -> Deploy to App Engine. Presto, your application should be live and ready at applicationname.appspot.com.
When you run it you should get a message like this:
Next up: Google Wave Robot API v.2 + Enterprise WSDL + Salesforce Chatter


