Why you should work for a startup

Are you the tireless entrepreneur that has or will start many businesses and can never work for anyone? Or are you the kind that’s happy to work a career job? I’m neither, I work for a startup. I’m neither the samurai nor the rice picker. I’m like the samurai’s PA. And I’m here to tell you it’s a pretty cool gig. Jump on in, the water’s fine.

The benefits of working for (not founding) an early stage business:

  1. Reduced financial risk, get a modest salary, but still have some equity.
  2. Build something of true value and help “change the world”. The ability to do early stage product development, experiment and change things on a whim is awesome. This is what normally attracts people to start their own business but I get to do heaps of this (and in the past 6 months, more than the founders themselves).
  3. Get a taste of that edge-of-seat startup feeling without the immediate pressure the founders experience like when raising funds or doing presentations.

The best way to find such a job is not on Seek or other large job sites. What I did was get involved in the startup community a little and find those people that always seem to be working on great product ideas. On your part, I think it’s essential to demonstrate some level of being able to get shit done, whatever that means in your line of work. Now, this whole process can take a while. Even if you find a cool startup, they may not have the capacity to hire, or the timing is just not right. On the subject of getting shit done, your ability to keep yourself afloat until a good opportunity presents will surely hold you in good stead. But bottom line, I can’t give you the recipe for success, just take the opportunity when it comes.

In order for all of this to work you have to get equity in the company. This works both ways. If the owners aren’t willing or able to give equity, they aren’t incentivising you correctly. If you ask for high pay and no equity, you aren’t showing that you believe in the idea or are willing to share in at least some of the risk.

Joining a startup also helps concentrate talent. By joining a startup, you are helping solve the employment problem (no I didn’t say unemployment). You hear about unemployment all the time, but at least in Melbourne, in my experience, tech businesses are finding it hard to find good people. Everyone seems to have their own business, even if it’s just consulting. Young techos seem to be very concerned about their personal brand and missed opportunity to pursue their own ideas. But it’s so easy to start a business now which means everyone’s doing it. As a result, I worry that talent is spreading itself too thin, at least for product businesses. You have to have some faith that instead of starting a new business, that by joining another team, the outcome will be greater than the sum of its parts. At the end of the day, it’s better to be a small part of something big than a big part of nothing.

Is this all I will ever do? Of course not. I might go on to fail at another business idea in the future. Or make some more quick cash doing client work. But right now, the grass seems very green right here.

Plug warning (ie: you can stop reading now)

After all that, it’s time for action on your part and a shameless but genuine plug on my part. If you’re a big shot web developer who knows the intricate details of JavaScript, it’s time to apply for a job at BugHerd. An opportunity to kick ass from day one and to join the real startup culture (not the latte drinking one, although we do love one).

The BugHerd team: James, Alan, Matt, Vincent

Startup Hackathon 2011: the teams

This weekend I had the pleasure of witnessing the outcome of another successful startup weekend this time under the name Startup Hackathon organised by Amir Nissen, one of Melbourne’s prolific entrepreneurial activists. Nathan Sampimon and Steve Hopkins provided mentorship to the participants on how to brainstorm, focus and get a product built fast.

What I always like about startup camps is the ideas people come up with. The ideas varied from the simple ‘scratching your own itch’ ones to a few game changers, and the inevitable wacky ones! But because this was a developer event, it was always going to be the most interesting what the final results were in terms of getting an app working.

These were all the teams:

Rate Your Lecturer, an application for students to rate their lecturers and have the results sent back to the Uni. The application was fully working and I successfully rated a lecturer, not that I ever went to RMIT or took any lecture. While the demonstration lingered a little bit too long in the registration/login pages the presenter was good as they had a little fun with the audience. My award: best presentation.

Read a Chunk allows users to submit a book and have it sent to them by email at a set pace, for example, one page at a time. One of those simple ideas that was implemented on a weekend. I would really like to see this idea combined with content, so I don’t have to upload my own book but can buy a title. My award: best simple idea.

Stale Ale aims to provide a marketplace for alcoholic beverages that is past its due date. My award: best wild idea

Janus Jobs is aiming to provide a platform for job sharing. It has three audiences: employers that have sharable jobs, people that want to share their job and then users who want to share in someone’s job. The team appeared to be confident that this is could work and if anything that’s good spirit! My award: best big idea.

WhereDoIStart aims to help people overcome writer’s block by providing little snippets of information from across the internet. This is probably the application I thought was going to be too much work for a weekend but the team has demonstrated great ability not to get side tracked. My award: best developer focus.

BitBuyText provides a mobile interface to buy bitcoins instantly. Kind of surprised this didn’t exist yet! My award: most obvious idea.

Foghorn is an Android app that tries to wake you up by surprising you with new alarm sounds. Funny application with good name to match. One of those crazy mobile apps that may just stick. My award: funniest idea

Ping2HQ is a beautiful application that lets you track others. Could be used by parents to see where their kids are but also for hospitals to see where ambulances may be at. While there are a lot of similar apps out there, full credit to the team on what they have built in a weekend. It is an intuitively designed application leveraging the good looks of the Aristo jQuery library and the Google Maps API. The demonstration included someone walking out with their iPhone emitting their location. My award: best application design

Exhort.me tries to fix the age old problem of boredom. With a simple app, they attempt to crowdsource things to do given some of your interests. My award: best simple application

Teaddict, a site where you can find the next place to drink the best tea, with integration into existing social networks. They leveraged WordPress plugins to achieve a fully working social web application.

(If anyone knows the URLs of the applications below please let me know, would love to try them)

LookingAtYouNow tries to leverage the favourite MX (Melbourne’s free publication for public transport) section to the internet where people publicly comment on others. We can now see what stalkers actually get up to!

Compare2Save promises to show you places around you where you can get products the cheapest.

FindMyTime will help you plan your due dates of your assignments around your other tasks.

This weekend was exclusively for students and if I can compare startup camps for students and let’s call it ‘the older crowd’, is that students tend to be much less inhibited by convention. This has showed both in the choice of ideas as well as the implementation. Another interesting difference: I don’t think any application was built using one of the popular MVC frameworks for the web, which surprised me somewhat; in contrast I think almost every app from StartupCamp Sydney IV was built in Ruby on Rails. [Update: Ping2HQ used the Java based Play! framework]

Finally, the best part of this particular event was that it was only for developers. Being a developer myself and yes I’m totally biased, let me just say that this was a great idea. Developers will be (if not already) the core of every new business. Yes, I know, you also need to be able to sell. But you need something to sell. The age where you can sell snow to Eskimos is well and truly over and you need to have products that people love. It all starts with the people that can actually build something, no passengers!

Congratulations to all the organisers, participants and sponsors for creating another memorable startup event!

 

Pusher.com for real-time client updates

Pusher.com is a service that applications can use to send real-time updates to web clients to have things update automatically. And it’s awesome. Here’s why:

  1. It’s easy to implement on the server side
  2. It’s easy to implement on the client side
  3. It scales your application for you

What would you use it for? Creating instantly updating chat clients. Showing activity on a map as it happens. Showing when people sign in or out of a service. Interactive games. Live dashboards.

You can just play around for as long as you need with the free sandbox plan.

Implement it on the server side (Ruby on Rails):

gem 'pusher' # add to Gemfile
Pusher['test_channel'].trigger('my_event', 'my data string')

Implement it on the client side:

<script src="http://js.pusherapp.com/1.8/pusher.min.js" type="text/javascript"></script>
<script type="text/javascript">
  var key = ''; // Found in your Pusher sandbox account
  var pusher = new Pusher(key);
  var channel = pusher.subscribe('test_channel');
  channel.bind('my_event', function(data) {
    alert(data);
   });
</script>

Invoking the Pusher code from the server side will now show a Javascript alert on all clients that have a page open with the above Javascript on it.

Pusher’s technology is based on HTML5 WebSockets. There are obviously other WebSockets based libraries and services but there is a distinct advantage to Pusher’s implementation. First of all, Pusher implements a fall-back using Flash. The combination of these two technologies means it will work on pretty much any browser. Pusher also has a great debugging tool which lets you see who is listening and what data is sent on the channel.

Whether you have 5 users listening on the channel or 5,000 it does not matter. You only write to the channel once and any client listing will receive the event. All you need to do is pay Pusher some more money as your application gains more users, but hopefully it means lots of users are using your application.

So as you can see, Pusher is pretty awesome, because it will make your application more awesome! I’m excited say that today’s BugHerd release makes use of it to push task updates to other users in the project.

Developing in NetSuite — what it’s really like!

The NetSuite platform allows customizations via 3rd party code. This is a review of what development for NetSuite is all about.

Language

NetSuite solely uses JavaScript, referred to by NetSuite as SuiteScript. Using JavaScript on the client side most developers would be familiar with, but NetSuite also uses it on the server side. A lot of business logic can therefore be run either on the client or server side, or both. Although seemingly beneficial, in practice there will be few occasions where this will prove useful. The positive is that the NetSuite core libraries are identical on the server and client side, so it’s easier to learn.

As an example, let’s look at the API to get the contents of a remote URL: nlapiRequestURL. This API connects to the url passed in as parameter and returns an object containing details of the response. For SuiteScripts, this API is available in client and server scripts, which is kind of cool because cross site scripting limitations mean you can’t do this kind of thing on the client side directly. So what NetSuite does is pass it through the server (behind the scenes) when it’s called from the client side. It’s one less thing for developers to worry about, it’s just that the request will take longer.

Client side

Using JavaScript makes client side development very powerful. Because JavaScript can be used to manipulate the Document Object Model, a developer can do just about anything such as including external JavaScript from other websites. As an example, this is how we created this TotalCheck address validation integration. But because NetSuite uses neither jQuery nor Prototype, it either means going back to basics, or you need to include jQuery yourself.

Server side

On the server side, the NetSuite core libraries are very basic, apart from all the built-in APIs to manipulate the NetSuite data, helper libraries, such as an XML parser, are not built in. Also, because NetSuite is fairly unique in using JavaScript on the server side, you will also struggle to find many helpful community open source libraries. Nowadays backend developers are spoilt by frameworks such as Ruby on Rails or Django and have all the tools at their disposal such as geo-location libraries, XML parsers, image processing, and integrations with 3rd party services such as Amazon S3. Nothing like that will be available for JavaScript.

Script types

NetSuite has these four main types of scripts: Client, User Event, Scheduled, Suitelet. There are more types but these 4 will highlight all the possibilities of the platform.

Client scripts are exactly what you’d think, they run on the client side. You can write code on a set of events which happen on a client form: page init, field change, save, etc. These handlers are intended to perform custom input validation but you can do very advanced client side stuff as there is no limit to what JavaScript can be executed.

User Event scripts run on the server side, in response to records being opened or saved. The script runs on the server side. In particular the “Before Save” handler is useful as you can use it to make further modifications to records when they are updated.

Scheduled scripts can be run on the server at scheduled intervals. Apart from the obvious use case, to run certain checks on a daily basis, these types of scripts are also used to deal with script governance. A script is only allowed to take a certain amount of time and resources. So if your script has been running for too long, you can write code to handle this elegantly by rescheduling itself immediately. This doesn’t mean it executes over several days: when a script invokes a scheduled script it is run almost immediately again, this just seems to be the way NetSuite manages the server load.

Suitelets are also server side scripts and behave like web apps. This script type allows you to build up custom pages and forms, and handle GET/POST requests from them. NetSuite has a library which lets you build up a NetSuite-style form in your Suitelet, but you can also create custom HTML output.

Governance

All script types enforce governance, which means you can only use a limited number of resources per script execution. This is to prevent scripts running on the NetSuite servers from taking too long or putting too much of a load on the server. For client scripts there are also governance limits, which apply to the APIs which interact with the server side.

Development environment

When you want to develop an app for NetSuite, you can get a free development environment. The environment seems to be fully functional and it comes with accounts for two developers. When you are ready to release your code you can create a bundle using SuiteBundler. You can control where to deploy your bundle or you can even make it publicly available.

Trade-offs

So, on one hand developing in NetSuite is quite powerful. There is really not much that cannot be done. But like many things in NetSuite, this comes at the trade-off of ease of use. In terms of the development framework, this means it doesn’t have some of the features that mature platforms nowadays offer out of the box, such as:

  • No source code version and release management. This is sorely missing from NetSuite. To make a change to your code, you upload a new version of a file to the file library. When you collaborate with other developers this can cause problems. You need to implement your own deployment strategy while your app is under development.
  • No testing framework. Modern, mature frameworks have us spoilt with all the tools to do coverage testing, automated unit testing and regression testing. NetSuite offers nothing of the sort, which is especially painful given that JavaScript is not a compiled language.
  • No ability to store application values. Something like the registry on Windows. There is no ability to store for example simple name/value pairs. The only way to store persistent data is by creating records.
  • Lack of server side libraries. I’ve named some examples before. Not having the in-built ability to for example parse XML is something you can work around but it just means more work to build apps. Partly because JavaScript is the server side language, there are no communities providing libraries either.

Summary

If as a developer you are choosing a platform to develop for, NetSuite is not an obvious choice. Be prepared to read a lot and spend a lot of time developing things from scratch. But if you are being asked to create an app for a customer who already uses NetSuite, what the client asks for is almost certainly possible, because there are almost no limits to what can be customized. But with power comes great responsibility.

Upgrading a Rails project from 2.3.x to 3.0.0

In order to upgrade your Ruby on Rails project to 3.0.0, rather than recreate your whole project structure and moving your app files across, I found it to be easier to update some of the files. Follow the instructions in this post to update your existing project to Rails 3.

Note to replace Project with the name of your project everywhere.

  • Create file ./config.ru
require ::File.expand_path('../config/environment',  __FILE__)
run Project::Application
  • Create file ./config/application.rb, if you use any observers, move them from environment.rb to this file
require File.expand_path('../boot', __FILE__)
require 'rails/all'
Bundler.require(:default, Rails.env) if defined?(Bundler)
module Project
  class Application < Rails::Application
    #config.active_record.observers = (move from environment.rb)
    config.autoload_paths += %W(#{config.root}/lib)
    config.encoding = "utf-8"
    config.filter_parameters += [:password]
  end
end
  • Replace contents of ./config/boot.rb with
require 'rubygems'
gemfile = File.expand_path('../../Gemfile', __FILE__)
begin
  ENV['BUNDLE_GEMFILE'] = gemfile
  require 'bundler'
  Bundler.setup
rescue Bundler::GemNotFound => e
  STDERR.puts e.message
  STDERR.puts "Try running `bundle install`."
  exit!
end if File.exist?(gemfile)
  • Create file ./Gemfile, taking note of the gems you currently include in ./config/environment.rb
source 'http://rubygems.org'
gem 'rails', '3.0.0'
#gem 'sqlite3-ruby', :require => 'sqlite3'
gem 'pg'
# gem 'aws-s3', :require => 'aws/s3'
# gem "will_paginate", "~> 3.0.pre2"
# gem 'fastercsv'
  • Replace contents of ./config/environment.rb with
require File.expand_path('../application', __FILE__)
Project::Application.initialize!
  • Rework ./config/environments/development.rb
Project::Application.configure do
  config.cache_classes = false
  config.whiny_nils = true
  config.consider_all_requests_local = true
  config.action_view.debug_rjs = true
  config.action_controller.perform_caching = false
  config.action_mailer.raise_delivery_errors = false
  config.active_support.deprecation = :log
  config.action_dispatch.best_standards_support = :builtin
end
  • Rework ./config/environments/production.rb
Project::Application.configure do
  config.cache_classes = true
  config.consider_all_requests_local = false
  config.action_controller.perform_caching = true
  config.action_dispatch.x_sendfile_header = "X-Sendfile"
  config.serve_static_assets = false
  config.i18n.fallbacks = true
  config.active_support.deprecation = :notify
end
  • Rework ./config/environments/test.rb
Project::Application.configure do
  config.cache_classes = true
  config.whiny_nils = true
  config.consider_all_requests_local = true
  config.action_controller.perform_caching = false
  config.action_dispatch.show_exceptions = false
  config.action_controller.allow_forgery_protection = false
  config.action_mailer.delivery_method = :test
  config.active_support.deprecation = :stderr
end
  • Create file ./config/initializers/secret_token.rb
Project::Application.config.secret_token = '(copy from old session_store.rb)'
  • Rework file ./config/initializers/session_store.rb
Project::Application.config.session_store :cookie_store, :key => '(copy from old session_store.rb)'
  • Create file ./config/initializers/site_keys.rb
REST_AUTH_SITE_KEY = '(any moderately long, unpredictable text)'
REST_AUTH_DIGEST_STRETCHES = 10
  • Create file ./script/rails
#!/usr/bin/env ruby
APP_PATH = File.expand_path('../../config/application',  __FILE__)
require File.expand_path('../../config/boot',  __FILE__)
require 'rails/commands'
  • Rework the file ./config/routes.rb
Project::Application.routes.draw do
  resources :users
  namespace :admin do
    resources :users
  end
  match '/login' => 'sessions#new', :as => :login
  match ':controller(/:action(/:id(.:format)))'
end
  • Delete the file ./config/initializers/new_rails_defaults.rb
  • Update ./Rakefile
require File.expand_path('../config/application', __FILE__)
require 'rake'
Project::Application.load_tasks

Now, the fun starts. Update any gems and plugins as needed. The standard Rails forms used the error_messages method, you can either install the compatibility gem or rework the forms (recommended) like so:

Where you previously had:

<%= f.error_messages %>

insert this code:

<% if @product.errors.any? %>
  <div id="error_explanation">
    <h2><%= pluralize(@product.errors.count, "error") %> prohibited this product from being saved:</h2>
    <ul>
      <% @product.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
    </ul>
  </div>
<% end %>

Speeding up XML parsing in Salesforce

When making integrations, it is common to needing to parse XML as external application’s API’s almost always return XML (Web Services or REST).

Before Salesforce’s Spring ’10 edition, XML parsing wasn’t built into the platform, and we used Ron Hess’ XMLDom classes. There was a distinct disadvantage to this library because parsing a large XML document could result in the number of script statements (200,000 per request) being exceeded.

In Spring ’10, there is a new XML stream parser, and because it’s built-in, the class methods do not count towards your script statements used. Now, the XMLStreamReader class doesn’t even closely match the XMLDom class signature, but in the Salesforce developer newsletter there was mention of a Fast XML library by TechGerm.

The new wrapper library was easy to migrate to, and even though the initial test results actually increased the script statements, a quick conversation with the author soon fixed that!

Source code will be posted here soon.

Thanks again go to TechGerm for creating this wrapper library, if you currently have a Salesforce application which uses XMLDom, it’s the fastest way to migrate it and reduce script statements used.