1. 06:22 8th Nov 2012

    Notes: 10

    Making something people want - The GoCardless story

    I’m a co-founder of GoCardless, a direct debit payments company in London. This is the story of our first two years and the people we’ve met along the way.

    Making something no-one wants

    One startup I know very well in San Francisco was started by 3 ex-financiers. Their idea involved an industry in which none of the 3 had any experience - they wanted to build software to help building contractors bid for big construction projects.

    None of them knew how to code, so they specced up a “prototype” and engaged a web-development agency to build this “MVP”. Development was slower than hoped for, and the specs changed repeatedly, based on the evolving strategies of the founders and conversations they had with the “big players” in the industry. Almost 10 months later, this MVP was ready for a trial launch. Unfortunately, the product by this stage was so complex that it was almost impossible to use. Successful use of the product involved no fewer than 14-stages, involving 3-way communication between the bidder, the project-owners and referrals from previous projects.

    They’d spent so long story-boarding their product that they had a really good idea of how it would work once they’d achieved huge market penetration. According to their “vision”, all communication would be managed within the app, as everyone in the industry would be using it.

    They had some pretty great features that were novel for the industry at the time - sharing quotes electronically (step 8), exchanging &  signing contracts online (step 11) and eventually paying for the services (step 13) as part of the process. Unfortunately, it was impossible to use an individual component without completing all of the previous steps. Until they’d reached huge penetration amongst all 3 types of user, their product would be almost unusable.

    But, when looking back on the project, each of them professed that they thought they were building an MVP.

    The mistake they made was focussing too much on their “vision” or “strategy”, and not enough on the dirty, mundane work of making a product that addressed real needs or desires. Chances are that one or two of the 14 features were genuinely useful and would have made a fantastic starting point for a startup. Unfortunately, they were unable to work out which ones they were.

    Unless people are incredibly lucky, they’re often not making something people want.

    “Ideas for startups are worth something… but mainly as starting points”

    “An idea for a startup… is only a beginning. A lot of would-be startup founders think the key to the whole process is the initial idea, and from that point all you have to do is execute. Venture capitalists know better. If you go to VC firms with a brilliant idea that you’ll tell them about if they sign a nondisclosure agreement, most will tell you to get lost. That shows how much a mere idea is worth. The market price is less than the inconvenience of signing an NDA.”- Paul Graham, How to Start a Startup

    “Making something people want” is not the product or conclusion of your idea plus development time. It’s not the end result - it’s the process. “Making something people want” means prototyping, launching early (often by faking large parts of your service) and talking to users.

    It’s the fastest, most cost-effective way of finding that smallest “quantum of utility” - the kernel of an idea that solves a burning problem for a tiny subset of people. 

    In other words, it’s a way of ensuring you’re not wasting your time. 

    People

    There are two kinds of people who most commonly have this problem. 

    The first is the “Business Strategist”. He’s the “ideas guy” who goes to meetups to tell people about his gleaming vision for his startup. He’s a management consultant, a banker, a lawyer. He doesn’t want to get his hands dirty with actual customers, and he’s looking for developers to build his “MVP”.

    The other is the “Technical Purist”. He’s often got a Computer Science Degree (or several), he’s a fantastic developer and he’s worked at a big tech company or in a well-respected development agency. He develops against the nightly builds of the hottest new graph databases. Everything is test-driven and built to scale to tens of millions of users. He loves building stuff so much that he doesn’t want to waste any of his time actually talking to people or selling his product.

    At my company, GoCardless, we had a combination of both of these problems.

    During the summer of 2011, we were 6 months into our startup. We’d built a product the previous January and launched after just 3 weeks of development. Our “vision” was to solve group payments - we were a platform for sports teams & university societies to organise & collect money. We managed to convince about 20 or 30 of our friends & family to collect money for their various causes - from rowing clubs to stag parties. It worked ok - people we knew used the product, and some used it repeatedly. It was enough to show a glimmer of possibility, and it helped us get onto Y Combinator that summer.

    By June, growth was stagnant. We spoke to our users every day, asked them what additional features they wanted to see, and then we built them. From scratch, we built a set of customisable forms for collecting information from group members (wufuu, anyone?), advanced calendaring and reminder functions (doodle.com) and the most complex set of functionality for managing large sports clubs with multiple teams, roles and permissions that anyone could possibly imagine. Our solution to crappy growth was to split out time roughly 50:50 between building more features and debating the vision of our company.

    After an afternoon of meetings with pg & the other Y Combinator founders, we resolved to take a different approach. We’d give ourselves 2 weeks to see if we could make this thing work. We paused development entirely and spent all of our time cold-calling new potential customers. And since our payments platform was UK-only, this meant getting up at 3am East-Coast time.

    One particularly memorable conversation involved 20 minutes speaking to a man who ran a local village cricket club in the South-West of England. I’d empathised with the strains of running a sports club (I’d run one at university), and the terrible administrative burden it came with. We’d discussed the trials of collecting subscription fees and the social anxiety caused by chasing up over-due debts. So I moved to close him; “We’ve built a website to solve all of these problems - give me your email address and you can try it out.”

    “What,” he asked, “is an email address good for? Why would I have one of those?”

    “To communicate online,” I spluttered, “to use the internet!”

    “The internet? I don’t use the internet. Goodbye, sir” he concluded.

    Our problem, we discovered, was two-fold. One, that the mass-market didn’t appear ready for our product. It turned out that the most successful Irish sports-team management tool (teamer.net) is still based almost entirely on SMS. The second problem was more fundamental; we hadn’t really discovered our “quantum of utility”. We didn’t have that tiny kernel of a product that solved a really burning problem. Collecting money for sports teams is annoying, but it’s only a small part of a few people’s lives.

    On the other hand, it turned out that businesses faced the problem of collecting money every day. And for particular people within those businesses - the accounts receivable department - this was their entire job. The core of our product - a Direct Debit API - was an ideal solution to this burning problem.

    “In nearly every failed startup, the real problem was that customers didn’t want the product… The only way to make something customers want is to get a prototype in front of them and refine it based on their reactions.” - Paul Graham, How to Start a Startup

    To that quote I would add “and if it turns out that no-one cares, do something else”

    Most startups aren’t competing with other startups; they’re competing with no one giving a shit.

    A few years later…

    One of the founders of the construction startup (mentioned at the start of this article) came across another group of founders who looked like they were on the same path. This company had what seemed like a promising idea - an interesting take on loyalty-schemes & subscriptions for real-world products and services. Its non-technical founders were looking for a designer and a coder to build an iOS app & website, which would be their MVP. They’d planned out exactly how it would work when they’d achieved massive adoption.

    They had a long and frank discussion with the earlier founder. Heeding the words of warning, this company reformulated its plans. What was the bare minimum they needed to work out whether customers & businesses were interested? How could they simulate the benefits of their service without blowing tens of thousands of pounds on outsourced development?

    The founders decided to sell shop-by-shop in their local area, signing businesses up to their new “platform”, promising them new patrons & more repeat custom. They then quickly ran a local advertising campaign offering people great deals at their favourite cafes & bars. Instead of spending time & money building an app and a website, they simply distributed laminated cards printed with with unique IDs to their customers, and every morning took a paper lists to the local businesses with details of the discounts each person was entitled to. Every night, they’d collect the lists and manually enter the data back into an Excel spreadsheet. By the end of the month, the majority of the businesses reported remarkable increases in volume & cash-flow, in some cases up to 75% improvement. They used this proof to secure investment & build a team of developers and salespeople.

    Conclusions

    You should spend most of your time focussing on making something people want. This is a process, not a goal.

    If you’re worried you’re not making something people want, the solution is almost always the same - focus on what you’re shipping in the next month. Don’t obsess over long-term strategy, or stick dogmatically to a “vision”. Launch sooner than makes you comfortable. Fake as much of the service or product as you can to save time. Talk to your users to make sure you’re solving a burning problem. Once you have 20 or 30 regular users, do everything in your power to absolutely delight them.

    Ensure you’re making something people want. If you’re worried about this, ask them.

    Discuss this post on Hacker News

     
  2. 12:54 20th Apr 2012

    Notes: 14

    Reblogged from peternixey

    peternixey:

    I seem to have a lot of conversations recently with people who find themselves in the kitchen but without the means to cook anything.

    As a cook myself they often ask me how to go about finding themselves a chef who can cook something for them. I ask them why they want to do that and they tell…

     
  3. Don’t write tests - The Hidden Cost of TDD

    I’ve been following the TDD/testing debate with some interest; I work at an early-stage payments startup called GoCardless where we test religiously. We’re not dogmatic about whether the tests come first or not, but code doesn’t get deployed without full unit & acceptance tests. It’s saved our skins on more than one occasion

    I wanted to explore the benefits of testing and suggest some situations in which <heresy>testing may be counterproductive</heresy>  

    Testing - The Good Bits

    When you’re working as part of a team on a large codebase, comprehensive testing is invaluable. If you measure development velocity on a company-wide basis over the medium-long term, testing provides clear benefits.

    Engineers working on one part of the codebase don’t have to worry about their changes having unanticipated knock-on effects in another area. A good mix of unit tests and acceptance tests means that you can write & deploy code quickly, without a lengthly QA process.

    When stuff does break, unit tests allow you to identify the individual component that’s causing problems. It’s fantastic - at GoCardless, no code goes into production without comprehensive testing & peer code review.

    (If that sounds like a place you’d like to work, we’re hiring!)

    Testing slows down rapid prototyping

    Having said that, there are situations when comprehensive testing just isn’t the right solution. I’m not talking about whether tests should come before (TDD) or after writing code - there are situations where it might be beneficial to write no tests at all.

    The particular situation I have in mind is the ultra early-stage startup struggling to find traction. The number one priority in this situation is not to write beautiful code or solve hard technical problems in innovative ways; it’s to work out what people people want. You do this by iterating quickly & launching early - just as it’s often possible to fake a much more sophisticated or elegant solution by doing stuff manually, it’s also possible to write quick, scrappy code that works just about well enough.

    You’ll accumulate buckets of technical debt, but it’s generally ok. If you don’t find traction or “product-market-fit”, you declare bankruptcy on that technical debt and just move on to the next iteration.

    Once you’ve found traction, you’ll likely need to re-write your codebase, but that’s ok as well. At this point, you’ll have a much clearer idea of what the product actually does, so writing specs should be much simpler.

    As an addendum, I think this conundrum is one reason why outsourcing early-stage tech development is such a terrible idea - any decent web development shop will generally insist on writing comprehensive test suites, and they’ll react badly if the job spec changes dramatically every 2 weeks. But that’s sort of necessary when you’re writing code for an early-stage startup.

    Discuss this post at Hacker News !

     
  4. Home-Brew Customer Phone Support

    This is the technical part of a longer piece on “Automating Customer Service at a Startup” 

    DIY Phone Support

    We implemented a home-brew customer service phone line in a few hours with a basic Sinatra app on Heroku, using the Twilio-ruby gem to generate TwiML (saving us the pain of writing raw XML) and a simple Campfire gem called Tinder.

    require 'twilio-ruby'
    require 'tinder'
    require 'net/http'
    require 'uri'
    

    The idea was to query our private Campfire room to see which agents are available, then render the relevant TwiML to get Twilio to forward any inbound customer calls to the phone number associated with that agent. If the agent doesn’t pick up the call with 15 seconds, it should try the next available agent, until all agents are exhausted, at which point it should record a voicemail.

    known_agents = {
    "Tom Blomfield"   => "+4477XXXXXXXX",
    "Jim Beam"        => "+4477XXXXXXXX",
    "Fred Flintstone" => "+4477XXXXXXXX",
    # etc
    }
    
    campfire = Tinder::Campfire.new 'gocardless', :token => CAMPFIRE_TOKEN
    room = campfire.find_room_by_id CAMPFIRE_ROOM
    
    get '/start' do
      # Alert Campfire users that there's an incoming call
      room.speak "Incoming call from #{request["From"]}"
        
      response = Twilio::TwiML::Response.new do |r|
        r.Play "Welcome to GoCardless"
        r.Play "Please wait while we find someone to answer your call"
        r.Redirect "/call?user=0"
      end
      # Render the TwiML
      response.text
    end
    
    post '/call' do
      user_id = @params["user"].to_i
    
      # Query Campfire for available agents
      available_agents = known_agents.select do |name, phone| 
        room.users.map(&:name).include? name 
      end
    
      # Agent we're going to call
      agent_name   = available_agents.keys[user_id]
      agent_number = available_agents[agent_name]
    
      response = Twilio::TwiML::Response.new do |r|
        if agent_name
          r.Say "We're connecting you to #{agent_name}"
            
          # Alert Campfire users that we're calling someone
          room.speak "Calling #{agent_name} on #{agent_number}"
    
          # Tell Twilio to try to call the agent
          r.Dial agent_number, :callerId => '+44XXXXXXXXX', :timeout => 10
    
          # Fallback action if the agent doesn't answer
          r.Redirect "/call?user=#{user_id+1}"
        else
          # No agents left, redirect to voicemail
          r.Redirect "/voicemail"
        end
      end
      # Render the TwiML
      response.text
    end 
    

    One gotcha to be aware of is that Sinatra will evaluate the entire script when the server boots up; any variables you assign (eg, who’s in our Campfire room) will be set once, and used like constants. On the other hand, each “controller” method (eg get ‘/start’) takes a block; this block is evaluated every time Sinatra serves a page. That’s why we ask for room.users inside the post ‘/call’ block - it will make sure that the list of available agents is up to date.

    In reality, we tweaked the above script a little; looping through 5 or 6 different agents could get a little irritating for a customer, so we limited it to 1 re-try before diverting to voicemail.

    The voicemail script is pretty simple:

    post '/voicemail' do
      # Tell Campfire
      room.speak "No-one answered call from #{request["From"]}!"
    
      response = Twilio::TwiML::Response.new do |r|
        r.Say "Unfortunately no one is around to take your call"
        r.Say "Please leave a message and we'll get back to you"
        r.Record :action => "/goodbye", :timeout => 10
        r.Redirect "/goodbye" # if no message is left
      end
      response.text
    end
    
    post '/goodbye' do
      # Tell campfire
      room.speak "Voicemail from #{request["From"]}.
        #{@params["RecordingUrl"]}.mp3"
    
      response = Twilio::TwiML::Response.new do |r|
        r.Say "Thanks for your message"
        r.Say "We'll get back to you as soon as we can. Goodbye"
      end
      response.text
    end
    

    This records an voicemail that’s stored at on Twilio’s servers, and we output a link to the recording in Campfire. But to be certain that someone deals with the voicemail, we wanted to log it as a ticket in Zendesk:

    # Insert this into your "goodbye" block.
    
    # Create a zendesk ticket
    zendesk from: request["From"], recording: @params["RecordingUrl"]
    

    The “zendesk” method is just a simple http post to the ZenDesk API using ‘net/http’, which creates a new Zendesk ticket. There is a Zendesk ruby gem, but it wasn’t well supported at the time of writing.

    def zendesk(args)
      from = args[:from]
      recording = args[:recording]
    
      url = URI.parse "http://help.gocardless.com/tickets.json"
      req = Net::HTTP::Post.new(url.request_uri)
      req.body = {
        :ticket => {
          :subject => "New Voicemail from #{from}",
          :description => "New recording at #{recording}.mp3",
          :ticket_type_id => 33, # Zendesk code for voicemail!
        }
      }.to_json
      req.basic_auth ZENDESK_USERNAME, ZENDESK_PASSWORD
      req["Content-Type"]= "application/json"
      connection = Net::HTTP.new(url.host, url.port)
      response = connection.start do |http|
        timeout(5) { http.request(req) }
      end
    end
    

    That’s it!

    One thing to note - all the Campfire and Zendesk API calls are performed synchronously, which increases response time and can leave the caller waiting around. At the moment, it’s usually imperceptible, but we’ll eventually move the API calls to asynchronous methods, probably using Redis.

    To find out more about GoCardless, check out our site. If you’re a developer and want to play with Twilio & Campfire APIs at work, apply for a job! 

     
  5. 16:08

    Notes: 22

    Automating Customer Service at a Startup

    Customer service can make or break a company; it has been one of the key differentiators as a new generation of startups seeks to compete against incumbents. While people remember examples of awesome customer service, the opposite is also true.

    At GoCardless, we decided early on that we wanted customers to have a fantastic experience with the service, so that they’d hopefully tell their friends about it. Unfortunately, being a 5-person startup, we don’t have the luxury of a massive customer support team. What we do have, however, is access to a bunch of great tools that make running a startup much, much easier. These tools, combined with some really smart developers and the instinct to Automate Everything, results in a pretty great customer experience.

    I wanted to spend a little time going through those tools, and demonstrating how they can be combined with a sprinkling of API magic powder to produce something vastly greater than the sum of their parts. 

    With these super-charged tools, we find one full-time person can generally run customer support on their own, leaving the other 4 to work on the product. We’ve also consciously made the decision that everyone should do some customer support - even engineers. It really helps people stay in touch with what our customers are saying, and lets us react quickly as a team to common problems that emerge. 

    I should note that we can’t claim credit for this idea - it was stolen wholesale from a great talk the Wufoo guys gave at a Y Combinator dinner. 

    Campfire

    $12/month for basic version. As a relatively technical company, our Campfire rooms form the central communications hub for our company. It’s basically like hosted IRC with a few bells & whistles like file uploads & code snippet support. You can choose to make rooms public or private, and generate direct links that will enable customers to chat with you directly through their browser. We do most of our technical customer support through these rooms. And as a small community has built up, we find other developers helping with each others’ problems. Awesome! 

    A lot of other services have hooks that will send campfire messages into specified rooms via the API on certain events. For example, Github has a hook that sends new issues & commit messages into our private developer room. There are a few more custom-built ones that I’ll get onto later! 

    If you’re using ruby, I’d recommend checking out the Tinder gem, which provides a convenient wrapper to the REST API.

    I can also highly recommend hubot, a Campfire bot written in Node by the Github team. It’s very simple to write extensions to perform simple actions like trigger server deployments.

    Zendesk

    $24/month per agent for standard version. While pretty expensive, Zendesk offers a variety of free trials, particularly for startups. It helps companies run email-based customer service desks, turning inbound emails into “tickets” that can be responded to or re-assigned across available agents.

    It was the first customer service product we decided to use properly, and now forms the core of all of our written communication with customers - particularly email & twitter. It’s simple to add “tags” to tickets automatically or manually, so we can count the number of requests for “Repeat Billing” vs “European Rollout” at the end of every month. You can also get a bunch of metrics like response times & satisfaction rates, but at the moment we’re just focussing on keeping our heads above water!

    We considered using the in-built Campfire integration to alert our Campfire room of new tickets, but quickly realised this would be more annoying than useful as we approached 30-40 new tickets per day.

    Olark

    $15/month for 1 operator. Discounts for startups. This provides live text chat on our website - the little “Chat Now” box you see in the bottom-right of your screen at gocardless.com. I was initially really skeptical of Olark’s value, but after using it for a month, I’m a convert. You can see where a user has come from and stay with them as they navigate through your site (including notification of which page they’re currently viewing), which makes it super easy to solve problems step-by-step.

    With built-in Zendesk API integration, you can also save conversation transcripts in Zendesk as solved tickets and add “tags” to them - which makes running aggregated metrics really simple. It’s as simple as typing “!tag International” in the chat window. If you want to drill down even deeper, you can run metrics by page - eg 70% of queries from people viewing page X were about “Pricing”, whereas most people on page Y were looking for more information about “International Support”. 

    We generally use Adium or a GChat plugin to access Olark.

    Phone Support

    The one weak link was our phone support - we previously used a Skype number that forwarded to mobile phones. Unfortunately, we had a number of problems with the solution - call quality was really low, sometimes calls didn’t forward or just randomly dropped, and collecting voicemail was a nightmare. I’d looked at the Zendesk voice features, but they were only available in the US & Canada.

    Then, a couple of months ago, some guys from Twilio moved into an office nearby. I’d been wanting to try out their service for a while, so we decided to hack together a simple customer service phone app. A few hours later, we had a pretty decent phone system with voicemail.

    What’s more, we’ve built-in a tool to check who’s available in our private Campfire room to take the call. If someone doesn’t pick up, it will try one of our other agents idling in Campfire. It also talks to our Zendesk ticketing system, notifying us if someone leaves an mp3 voicemail, so that someone always follows up. Sweet!

    One small gripe is that voice-to-text transcription is terrible, to the point of being unusable. Maybe it’s my English accent, but I couldn’t get above a 50% accuracy rate. So we turned it off and stuck with voice recordings.

    A landline number costs almost nothing, but the call forwarding to our agents’ (right now, me & my co-founders!) mobiles comes in at $0.14/min, which isn’t cheap.

    I’ve posted the technical implementation details here

    Conclusion

    The key for us is that consumers can contact us however they like - phone, twitter, email or live chat - and we can respond quickly using tools that we’re familiar with. 

    Metrics are also really important - we want to be able to track the number of queries by channel and easily categorise them by subject matter. This allows us to fine-tune our landing pages to address frequently asked questions more directly and also prioritise new product development according to customer need. But it’s vital that this we can do this tagging either automagically or at least in-line with whatever we’re doing. The “!tag International Expansion” in Olark is a good example of this. As soon as you need to open a separate list of “Feature Requests” and add a +1 to a tally chart, people stop using it.

    The two weak points in this regard are Campfire and the Twilio voice app. For Campfire, we could do a text search on a month’s logs, or write a simple hubot extension (“!tag International”). With Twilio, I’ve still not come up with a good solution. Suggestions welcome!

    If you want to work at a startup that hacks Twilio & Campfire apps together during the week, check out our jobs page!

    Discuss this post at Hacker News

     
  6. 10:07 5th Feb 2012

    Notes: 20

    Automate Everything

    Performing manual, repetitive tasks enrages me. I used to think this was a corollary of being a programmer, but I’ve come to suspect (or hope) that this behaviour is inherent in being human.

    But being able to hack together scripts simply makes it much easier to go from a state of rage to a basic solution in a very small amount of time. As a side point, this is one of the reasons that teaching the basics of programming in schools is so important. It’s hard to think of any job which wouldn’t benefit from a few simple scripts to perform more automation.

    When we’re hiring, even for non-developer roles, we look for this kind of mentality - it’s extremely useful, especially when building a software businesses, if costs don’t scale linearly with revenue. The more we can invest up-front in automation, the less time our team has to spend on performing stupid, manual tasks. As we add more employees, the benefits are compounded. And less rage generally makes the workplace a much happier place.

    I encountered a practical example earlier this week. It was time to submit expense reports, and I could feel the rage starting to build up. For some reason, our accountant decreed that we had to fill in a spreadsheet, line-by-line, for every expense item. It looked a lot like this.

    Presumably, hundreds of millions of people have to do this every month, costing millions hours of lost productivity. And in most companies, it’s because a well-meaning HR or Finance person has said that It Must Be Done. But if that Finance person had a modicum of programming experience, they might be minded to try to find a better way. That’s is what I mean by hiring people with this kind of mentality. We don’t want anyone who’ll lump some stupid task on the rest of the team because they’ve not got the mindset to think about automation in a sensible way. Even if they can’t programme the solution themselves, they need to be able to figure out pretty quickly that a better solution must exist

    After briefly raging out, I decided to do something about this particular problem. 

    1 - quickly define the requirements;

    • Record details of every expense item including date, amount & description
    • Be able to query the list to produce reports (by month and/or person submitting the receipt)
    • Keep copies of receipts for HMRC

    2 - think about how receipts fit into our workflow at the moment, and the major problems

    • Receipts can be physical (till receipt for lunch) or electronic (Rackspace email)
    • They can pop up at random points in they day - not conveniently all at the same time every month
    • People have to store small pieces of paper for up to 30 days. Unreliable
    • People then have to spend an hour or two each month going through thousands of emails and hundreds of small pieces of paper to find the receipts, remember what they’re for, and write them down one-by-one. At least the spreadsheet auto-sums the amounts to a total… Inefficient!

    3 - Apply a modicum of brainpower to automate the pain-points.

    To avoid the unreliability of storing small pieces of paper and the inefficiency of examining thousands of emails, perhaps we could store them all in once place, electronically. This place could be an email account called something imaginative like “expenses@mycompany.com”. 

    To avoid having to go through each receipt one-by-one, perhaps some kind of machine could parse relevant information out of each email and persist it somehow. Perhaps a database might be useful. To produce the report, perhaps the database could output certain information based on some kind of structured query language. So that the people at HRMC don’t suffer an instantaneous and fatal brain-explosion when we send them the data, perhaps we could separate values with a comma, save them all in a file and advise HRMC to open the file with their preferred Microsoft spreadsheet program.

    As a side note; In the interests of not re-inventing the wheel, it’s generally a good idea to check if someone has solved this problem before. I decided to roll my own in this case because I was interested in learning about email handling after watching this great railscast from Ryan Bates. And because paying $9 per month per user for something I could probably write myself in a couple of hours seemed silly.

    Technical Details

    If you’re interested in the technical details, I used a ruby gem called Mailman, hosted on Heroku’s new cedar stack, to poll our POP3 mail server every minute. Attachments (pdfs, photos etc) are saved to AWS S3, and simple details of each receipt are stored in a postgres database. A Campfire gem called Tinder immediately alerts our company chat room that someone’s spent some of our hard-earned cash (just for amusement, really), and a very simple Rails app hosted on Heroku makes the data available in HTML or CSV, which can be queried by date-range or employee. 

    Emails are required to have a line similar to “Amount 12.50”. Running OCR on photos of receipts and detecting the right line to take the Bill total from seemed like too much effort. We might switch to mechanical turk if people find this step troublesome.

    If there’s any interest, I’m happy to stick the code on github.

    Conclusion

    Don’t put up with repetitive, manual tasks - automate them! It’s the jedi hacker way.

    If you want to come and work at a place which encourages you to hack on cool projects to improve your colleagues’ lives, check out our jobs page

    What kind of stuff do you automate? Discuss at Hacker News!

     
  7. Technical Interviews

    Over the last year, we’ve done dozens of interviews that involve some kind of technical element.  We’ve hired some great programmers, and we’re looking for more

    We’ve spent a some time thinking about how we run these technical interviews (as have others), so I wanted to touch on the kind of things we look for, and what the interview process at GoCardless looks like.

    CV & Github

    We ask everyone to provide a (brief) CV and links to their github account or other examples of code they’ve written. One page is usually sufficient - we want know about;

    • Education
    • Previous jobs & specific responsibilities
    • Passion for development outside work. This is the area where people can really shine. Tell us about a hack-weekend project, open-source project or technical conference presentation that you’ve given. 

    Product & Business Case Studies

    Even when interviewing for technical roles, we spend a fair amount of time talking about business & product issues. We think we can build a better company by working with people who are self-sufficient, take initiative and get stuff done.

    This doesn’t mean you need a degree in business microeconomics, but you should have thought about questions like “what impact might feature x have on sales conversion, customer churn or revenue-per-user?”

    Another favourite is “We have problem Y that is costing us £z per user. What are the technical solutions to this problem? And what are the business solutions? Which would you implement first, and why?”

    Technical Interviews

    This has been discussed at great length, but I wanted to throw in our two cents;

    We use a couple of simple programming exercises - usually involving some kind of choice between recursion or looping, with a discussion of which might be more useful & why.

    I personally think exercises like implementing Pascals triangle (where the candidate is given a definition of Pascal’s triangle, a choice of language and access to API documentation for that language) are really great negative filters that reveal whether a person can actually code.

    We’re looking for something like

    
      def pascal_loop(n)
        triangle = [[1]]
        (0..(n-2)).each do |i|
          this_row = [1]
          (1...triangle[i].size).each do |j|
            this_row << triangle[i][j-1..j].inject(:+)
          end
          triangle << (this_row << 1)
        end
        return triangle[n-1]
      end
    
    
    

    We also talk through various theory questions, focussing on concepts behind web programming (transfer protocols, request-response cycles, persisting data, caching), database & systems design. We also touch on algorithms, but I’m not sure how useful this is, particularly for someone without a formal CS degree. 

    How do you run technical interviews? Comments welcome.

    If you’re looking for a developer position in London, apply now!

    Discuss this post at Hacker News

     
  8. I hate meetings

    It will be no surprise to those I work with to hear that I’m not a big fan of meetings. I wanted to lay out a few problems we had with meetings, and the ways in which we’re trying to solve them.

    Startups Operate in Conditions of Extreme Uncertainty

    By definition, there’s always uncertainty at a startup. You need to work out what you’re making and whether anyone actually wants it.

    This uncertainty makes most people uncomfortable, which is natural. A tempting solution is to schedule meetings to debate this uncertainty endlessly, as if it can be made certain by the power of thought alone. This is particularly the case for people with backgrounds like mine, who spent time at university and jobs in which we were actively encouraged to theorise without seeking empirical evidence. Instead, work out how you can validate your assumptions as quickly as possible, and make that happen.

    You can sometimes gain empirical evidence on which to make a decision whilst expending a very small amount of time & energy.

    • The TripAdvisor 404 Test - Put a link to the new feature on your website, but “Before you build the darn thing … see how many people click it. It goes nowhere, it says broken link to the user [but] your log file says how many people [check it out]…It solves umpteen meetings worth of powerful debate and logical arguments.”
    • Dropbox’s Demo Video - A 3 minute demo video on Hackernews prompted 12,000 digs, and tens of thousands pre-registrations. This gave Drew Houston the validation he needed to spend another year creating a market-beating file-syncing & backup service.
    • An early-stage payments startup (not ours!) wondered whether merchants would use a monthly subscription billing service in addition to regular one-off payments. So they launched the service with a minimal back-end, knowing that if it took off, they’d have 30 days to build the functionality.

    You wear every hat

    Working at an early-stage startup, there are a thousand things to do. You’re the recruiter, HR person, accountant, office manager, receptionist, programmer & cleaner - and you have to make all the decisions associated with these roles. But it’s sometimes tempting to devote more time than necessary thinking about (and discussing!) these decisions.

    In reality, the only important question for early-stage startups is almost always ”does anyone want what we’re making?” Most of the other stuff doesn’t need to be decided yet. “What shall we put in our cashflow forecast?”, “Where’s our new office going to be?”, “In 3 years, what do we want our brand position to be?” They are all important questions, but probably not yet.

    If a decision doesn’t have any practical impact on what your team is doing this month, just postpone it (and the associated meetings). If you do eventually have to make the decision, you’ll have more information at your disposal. If you’re not spending the majority of your time trying to solve the one most important problem your business faces, it could be a sign that something’s wrong.

    Meetings kill productivity

    A lot of smart people have written extensively about this subject, and I don’t have much more to add. I reckon it takes me about an hour to really get up to full speed when developing something challenging, and it takes a minimum of 2-3 hours to produce anything meaningful. So a meeting halfway through an afternoon bazookas productivity for at least half a day.

    Some thoughts

    After a year of running our startup, we’ve come up with several ways of avoiding unnecessary meetings and keeping necessary meetings as brief as possible

    • Ask: Is this discussion going to result in a decision that practically impacts our priorities in the next 2 weeks? If not, postpone it.
    • Any discussion that goes over 5 minutes has to move to a meeting room. This isn’t because we like having meetings in meeting rooms; quite the opposite. If the discussion isn’t important enough to warrant disrupting the team, then postpone it.
    • Have one meeting every two weeks at which you review any of the longer-term decisions and make sure everyone on the team knows what the company is focussing on

    If you want to find out more about how we work, come and say hello

     
  9.  
  10. Syntax Highlighting on tumblr

    I’ve decided to write about various startup and ruby-related stuff. So syntax highlighting is pretty vital.

      
      def multiply(a,b)
        a * b
      end
    
    
    

    You can read about how to implement syntax highlighting here