How resourceful are you ?

I heard Jason Calacanis on TechZing talking about this subject a while back. He mentioned that in an interview he’d ask people how they would solve a particular technical problem they hadn’t encountered before. The immediate answer was usually to search for it. Tech savvy readers are likely thinking the same thing. His reply to was to ask, “What if search engines are all down?” The point was to continue as far as the candidate would go before they gave up. Each response was looking for the candidate to offer a new option because the previously mentioned one is deemed unsuitable or unavailable. IRC? Wikipedia? Quora? Ask a Coworker? Manual? Office book? Library? Call the company? E-mail a friend? The premise is that people who are smart and get things done will be more resourceful and better able to list alternatives because they can become consumed by solving particular problems. Brainstorming and resourcefulness are (like much else) the products of practice.

I think this idea could be a useful filter for interviews and it lets you look for a certain kind of dogged persistence in a candidate that would be otherwise difficult to discern in a short interview process.

My twist on this idea for my own benefit is brainstorming and becoming more resourceful at customer development. What are the most effective ways to connect with customers and what concrete steps build those bridges? I’m betting on blogs, conferences/meetings, and SEO content. These are common avenues. What needs to be uncommon for success is resourcefulness. Persistence. Determination. Because bootstrapped startups fail only when you quit.

Node.js TLS connections, requests, servers, etc.

The first thing you’ll need to be aware of is that node.js is a fast moving project. This tutorial was written for node.js 0.4.2 but may work or be useful for later versions of node. Secondly, my code examples are in CoffeeScript which compiles to Javascript but has Python/Ruby-like syntax. I find the code to be cleaner and faster to write.

Next up are some administrative details. If you’re going to make TLS/SSL requests you’ll need to have or generate keys and certificates. I’ve included the basic commands to get you started without understanding this step because you need something running now. I understand.

openssl genrsa -out server.key 1024
openssl req -new -key key.pem -out csr.pem
openssl x509 -req -in csr.pem -signkey key.pem -out cert.pem

Fortunately creating a server that listens for TLS connections is quite simple. It is nearly exactly like creating a server that listens without the security using the net lib where here we require tls.

fs = require 'fs'
tls = require 'tls'

privatekey = fs.readFileSync 'server.key'
cert = fs.readFileSync 'cert.pem'
ca = fs.readFileSync 'cert.pem'

options = {key: privatekey, cert: cert, ca: ca}

tlsserver = tls.createServer options, (s) ->
                s.write "This is S(SL)parta!"
                s.pipe(s)
tlsserver.listen 8989

You may now be wondering what that hash with options is for. The key is used to encrypt and decrypt on the server side of the connection. The cert is a token used to verify the identity of a server and who runs it. Usually certs are signed by a third party like GoDaddy.com or Verisign. The ‘ca’ bit is the certificate authority which lists certificates that can be trusted without being signed by a trusted authority, trusted authorities to contact for such lists, or the default list of authorities to contact. If you’re using a self-signed certificate like the one I’ve generated you’ll want to include it in your ca string or you will get errors from openssl about self-signed certificates.

The server part of this equation is rather well documented. The client bit, however, is much less elucidated in the node docs. Problem solved.

tls = require 'tls'
fs = require 'fs'

crt = fs.readFileSync 'cert.pem'
ca = fs.readFileSync 'cert.pem'
options = {cert: crt, ca: ca}

s = tls.connect 8989, options, ->
        s.connected = true
        s.write 'Client Connected.'
        s.setEncoding 'utf-8'
        if s.authorizationError
                console.log 'Authorization Error: ' + s.authorizationError
        else
                console.log 'Authorized a Secure SSL/TLS Connection.'

s.on 'data', (d) ->
        console.log 'RCV:' + d

s.on 'error', (e) ->
        console.log error

Questions, suggestions, and comments are encouraged.

Django-Paypal standard subscriptions integration

Want to have a site with PayPal integration using Django with no fuss? That is just django-paypal’s game. I’ll show you how to integrate with Website Payments Standard in a jiffy.

pip install django-paypal

You are using pip, right? If not:

apt-get install python-setuptools
easy_install pip

Whew! Thats better. Let’s fix up your settings.py:

PAYPAL_RECEIVER_EMAIL = "yourbusinessaccount@example.com"

INSTALLED_APPS = ( ...,
  'paypal.standard.ipn',
  ...)

Now, you’ll have to add an entry in your urls.py for the Instant Payment Notifications (IPNs) from PayPal that let you know when people have paid:

urlpatterns = patterns('',
  ...
  url(r'^/something/hard/to/guess/, include('paypal.standard.ipn.urls')),
  ...
)

We need a view in views.py. That is easy too:

from django.conf import settings
...
def subscribe(request):
    # What you want the button to do.
    paypal_dict = {
    "cmd": "_xclick-subscriptions",
	"business": settings.PAYPAL_RECEIVER_EMAIL,
	"a1": "0",	                   # trial price
	"p1": 1,	                   # trial duration, duration of unit defaults to month
	"a3": "29.95",                     # yearly price
	"p3": 1,                           # duration of each unit (depends on unit)
	"t3": "Y",                         # duration unit ("M for Month")
    "src": "1",                        # make payments recur
	"sra": "1",                        # reattempt payment on payment error
	"no_note": "1",                    # remove extra notes (optional)
    "item_name": "PayPal Shows This To The User",
    "invoice": "101",
    "notify_url": "http://example.com/something/hard/to/guess/",
    "return_url": "http://example.com/thanks/",
    "cancel_return": "http://example.com/cancel/",
    "custom": request.user.username,   # put whatever data you need to track things here
    }

    # Create the instance.
    form = PayPalPaymentsForm(initial=paypal_dict, button_type="subscribe")

    context = {"form": form, "encoded_email" : urlquote(settings.PAYPAL_RECEIVER_EMAIL), "paid" : request.user.get_profile().paid}

The reason I’ve included the encoded_email in the view is related to the unsubscribe button we’ll setup in a minute. The button in that view will be a subscription. You can easily modify it to be a buy now button. See the README for django-paypal. If you browse the code on github and checkout paypal.standard.forms.py you can see all the possible options for buttons.

Now we can create the template and the (optional) unsubscribe button:

{% extends "base.html" %}

{% block content %}

{% if paid %}
<h2>Thank you! You are currently subscribed.</h2>
<p id="page-intro">You can cancel anytime online using your PayPal account or from this page.
	If you have any questions or problems please <a href="mailto:you@example.com">email us</a>.
	</p>

	<A HREF="https://www.paypal.com/cgi-bin/webscr?cmd=_subscr-find&alias={{ encoded_email }}" _fcksavedurl="https://www.paypal.com/cgi-bin/webscr?cmd=_subscr-find&alias={{ encoded_email }}"><IMG BORDER="0" SRC="https://www.paypal.com/en_US/i/btn/btn_unsubscribe_LG.gif"></A>
{% else %}
	<!-- Page Head -->
	<h2>Please subscribe to Example using PayPal.</h2>
	<p id="page-intro">You can cancel anytime online using your PayPal account or on this page.
		If you have any questions or problems please <a href="mailto:you@example.com">email us</a>.
		</p>

	{{ form.render }}
{% endif %}
{% endblock %}

Keying off of if the user has paid or not means we can use this template for subscribing or unsubscribing. Now go get paid!

WordPress, Ubuntu – Now

I recently found cause to setup some mini-sales sites according to advice I’ve seen from Tim Ferriss, Rob Walling, and others. If you need to get something up fast, cheap, and quick this is for you.

Login to the Rackspace Cloud site and create a new server instance with your favorite flavor of Ubuntu. I used Lucid Lynx 10.02.

ssh root@
apt-get update
apt-get install ufw mysql-server wordpress links

I grabbed Uncomplicated Firewall (ufw) to lockdown the box. It’s an simplified wrapper for iptables on Ubuntu. This will install wordpress to /usr/share/wordpress.

For my purposes (mini-sales site) I wanted the wordpress installation at the domain root. You might want it to be at /wordpress or another url. I’ll show it both ways here:

# Show apache2 where wordpress lives
#for wordpress at http://example.com/wordpress
ln -s /usr/share/wordpress /var/www/wordpress
# (site root and not /wordpress/)
rm -rf /var/www && ln -s /usr/share/wordpress /var/www
mkdir -p /usr/share/wordpress/wp-updates
mkdir -p /usr/share/wordpress/wp-updates/localhost

If you wanted it at http://example.com/wordpress you’d use line 3 only. Otherwise you need lines 5-7. Now we can install the database and wordpress itself:

# Install WordPress to db using the provided script
bash /usr/share/doc/wordpress/examples/setup-mysql -n wordpress localhost
/etc/init.d/apache2 restart

Now we need to install wordpress from localhost so we’re forced to use a text based browser. Load up links and fill in a blog name and email. The site will give you an admin login and password. Login using that username and password and navigate to Settings -> General. Change the WordPress Address and Blog Address domains to your URL: http://example.com. You’ll want to use http://example.com/wordpress/ if you didn’t install at the site root.

links http://localhost

Finally we can set the permissions and prep the site for being public (be sure to change example.com to your domain):

chown -R www-data /usr/share/wordpress
ln -s /etc/wordpress/config-localhost.php /etc/wordpress/config-example.com.php
/etc/init.d/apache2 restart

Voila! Use your local machine to navigate to your domain. Happy blogging/mini-sales sites.

Goals for Whitetail Software

In the last year I’ve created two full software products while I learned an incredible amount about software, persistence, business, marketing, deployment, and more. I’ve shifted my efforts from creating applications I think are cool to exploring markets I like by talking to customers and trying to pivot ideas toward what people really want or need. I read Eric Ries and Steve Blank among many others to develop my thinking along those lines. I plan to continue calling, emailing, and speaking with people in my market to improve my products and/or pivot to better ideas. The biggest way I’m going to push in this direction in 2011 is to attend conferences both as an attendee and exhibitor to try and connect with customers in multiple ways. I hope to leverage those trips into relationships and customers that give me real traction and word of mouth for the future. This leads in to the specific things I’d like to accomplish this year with Whitetail Software.

2011 Goals

  1. 10 Whitetail Scout (Harvest & Observation Records) Customers
  2. 100 Whitetail Census Surveys
  3. 2-3 posts per month on this blog and on Managing Whitetail
  4. Develop a product that helps people find hunting leases
  5. Integrate all products with Amazon Payments and PayPal
  6. Develop How-To and help videos for the products as a FAQ
  7. Begin a newsletter across Whitetail Software offerings
  8. Experiment with Census pricing and bundling
  9. Relaunch the improved version of Whitetail Scout
  10. Attend 2 or more industry conferences to talk to customers and prospects
  11. Experiment with Organic SEO Content at scale

Conditional on Feedback

  1. OSS project extracting my Mechanical Turk and trust system code into a Django app
  2. AJAX and new features for Whitetail Scout
  3. Develop a site that serves as a directory for the industry similar to Cattle Pages

I’m just getting started on my sojourn to build my own software enterprise from scratch but I have already learned quite a bit in a plethora of categories.  I think one important lesson that you can continually relearn is persistence. Things that have helped me stay the course include support from my wife, a long term perspective on the effort I put into Whitetail Software, and staying focused on the immediate and long term goals as motivation. I think knowing where you want to be in five years and what you think needs to happen this week to get closer to that are critical to accomplishing anything of scale. If you aim at nothing, you’ll hit it every time.