Thursday, November 10, 2011

Ruby Concurrency Realities


At B'more On Rails I recently presented a new talk I've been refining called "Ruby Concurrency Realities". The slides and research links are below (I also drew heavily on the Ruby docs and the Pickaxe book):

Sunday, November 6, 2011

Looking to meet some early customers


I'm looking to meet some potential early adopters for two awesome software products I've been working on this year. If you know someone who fits into either category and could make an introduction (my email is mike@subelsky.com) I would be very grateful:
  1. People who spend money on online and offline marketing and would like to measure it more precisely than they do now (to figure out the best way to use their marketing budget).
  2. People who own or manage retail stores. I'm looking for stores that have electronic records and would like to get reports from that data that help make the business more profitable (e.g. who are the most reliable suppliers, what are the optimal levels of stock of various items, what is the seasonal demand for each item in my inventory). I'm particularly interested in small retail networks of around ten stores (big enough to have a lot of data, small enough to not have nice software that makes sense of it).

thanks!

Friday, November 4, 2011

Preparing audio files for Apple's HTTP Streaming protocol and uploading them to S3

I've been getting inquiries about how I prepare MP3 files for Apple's HTTP Streaming protocol and uploading them to S3 which I mentioned while discussing my PhoneGap example. I thought I would post a gist of the rake task I use to help people get started. The whole process is explained on Apple's site.

You'll need to install mediafilesegmenter and mediastreamvalidator from Apple (which I weirdly can't find now but may be part of Lion at this point). If you need to downsample the audio quality like I do, you'll also need ffmpeg and libmp3lame.

Thursday, October 20, 2011

How to setup credit card payments for your web application

Implementing credit card payment systems has been one of my least favorite coding projects, but things have gotten much nicer since I first started. I'm just starting again with my new company, and I will be continuously updating this post with my progress. I'm hoping to capture every single decision I've made to help other people get going and also as a reference for myself the next time I need to do this.

10/20/11: Choosing a Merchant Account and Gateway

After looking at a few different payment gateways, I've decided to try Braintree, mostly because of their awesome-looking, well-documented Ruby gem, but also because I've seen them at various Ruby/Rails events (speaking and sponsoring), and because I've heard good things about them from Figure53 and friends at LivingSocial. I also really like their "transparent redirect" feature, where credit card numbers never enter our system at all.

We also need a merchant account to go with the gateway. Since we're doing all of our banking with BB&T so we've decided to get a merchant account with them as well. Their rates seem competitive (much cheaper than Braintree's merchant account, probably because they have to partner with a bank and are charging a markup over the bank's fees). We also want to deepen our business relationship with the bank vs. shopping around for the absolute cheapest rates (something that can be done with FeeFighters).

We're doing the paperwork with BB&T right now. Next step will be to start integrating the braintree gem into our codebase, creating the payment screens in our system, etc.

10/25/11: Considering a Switching to Stripe

After posting the above, Gabriel Weinberg and other friends on Twitter suggested I check out a Braintree competitor, Stripe. Stripe seems to offer even more of a "one-stop shop" for payment systems than Braintree, and it has similar Ruby bindings and "transparent signup" features. So for me it comes down to pricing. A commenter from FeeFighters also suggested their Samurai gateway.

Both Stripe and Samurai look great when your volume is relatively small: their lack of monthly fees means your processing costs are lower. I'm building a subscription-based app, so I removed Samurai from consideration; not having to write a bunch of proration code, not having to worry about accidentally billing someone twice, etc., is a huge benefit of Braintree and Stripe. I'm sure Samurai will add it soon.

Once you get up to higher volumes, Stripe and Samurai become more expensive than Braintree plus a merchant account. I did some spreadsheet modeling and determined that using Braintree plus our BB&T merchant account becomes cost effective once we have 50 customers, which is about as many as we would need to really have traction.

I'm tempted to use the cheaper short-term solution now, but since I don't want to have to switch this around later once we get to 50 customers, I've decided to stick with Braintree and our own merchant account.

I also considered using Authorize.net, which seems slightly cheaper than Braintree, but the overall look and feel of their website is not developer friendly. Whereas all of the other sites I've mentioned look like they've put a big priority on making the developer happy.

11/4/11: Finished Initial Integration
I had a fairly easy time integrating the code with Braintree's sandbox. I was greatly helped by this testing technique that uses the wonderful VCR gem, so I could run my integration tests against real Braintree responses without having to hit their API every time. I also found inspiration from Braintree's example Ruby applications.

I'm using the Transparent-Redirect customer creation method to create a customer and store their credit card in the vault (so the credit card number never touches my systems at all; the only thing we store is a payment token referring to the credit card stored by Braintree).  In a separate step I use the subscription creation API to create the monthly recurring charge.

My biggest struggle was in figuring out how to wrap the transparent-redirect response from Braintree in an ActiveModel-compliant object, so that when the user entered invalid data I could render the form like any other Rails form, with inline errors and so forth. I came up with a hack which I'm a little too embarrassed to post here but if you want it email me. In hindsight I should have just used this custom form builder.

Tuesday, October 18, 2011

Why I Won't Sign Your NDA


I'm mostly writing this so I can forward this link to the next person who has a cool startup idea but wants me to sign an NDA.

Here are excellent summaries of why programmers do not want to sign NDAs under normal circumstances when talking about a startup:

http://mixergy.com/why-i-wont-sign-your-nda/
http://www.joelonsoftware.com/articles/fog0000000071.html
http://dashes.com/anil/2010/05/one-more-time-no-ndas.html

Speaking personally, asking for an NDA makes you appear as if your startup is more obsessed with secrecy and official process than with going out and kicking ass. It makes me think that your company is probably led by a person who does not understand hacker culture, and is not in a position to have read any of the above articles.

Also, any programmer who has a blog gets emailed all the time about startup opportunities from people who don't ask for NDAs. Why should I bother with yours? I realize some ideas are valuable and worth protecting, but given the nature of the web it's very unlikely that you alone have stumbled onto something that valuable. (It's more likely that you'll be turning a mediocre but promising idea into something super valuable after you spend some time building something cool)

Wednesday, September 21, 2011

Is making software a craft and/or an art form?

I'm leading a Betascape panel this Saturday called "Art & Code", described as "a panel of smart software creators discussing their careers and to what extent modern making software has become a craft and an art form."

This topic has been much on my mind as I contemplate how we should be training future software makers (vs. future computer scientists and software engineers). Below are the questions I will be posing to the panelists: I'd love to hear your answers in the comments! I'll incorporate anything I learn in this post into the panel, so if you think of other questions I should ask, please tack them on as well.
  • There are many metaphors out there for what we do (crafts person, artisan, engineer, scientist, etc). How do you think of yourself?
    • What aspects of making software feel like an art form to you?
    • What aspects of making software do not feel like an art form to you?
    • When you are designing or writing code, what does it feel like? Is there a performance aspect to your work?
    • What is the most valuable training you received that helps you as a designer or coder today?
    • What is the most valuable training you've experienced on your own? What's been the best self-teaching experience you've had?
    By the way, the Betascape schedule looks really awesome. You should totally plan to come to Baltimore for this, and here's how to buy a ticket!

    Saturday, September 10, 2011

    Using Goliath as an API Proxy

    I recently set up a proxy server using Goliath, a new asynchronous web server from Postrank Labs. I'm building an app that allows users to provision phone numbers from Twilio. To find numbers, I was making calls on the user's behalf to Twilio's AvailablePhoneNumber API. Since our server wasn't doing anything with the data except passing it back to the client, I wondered if it might be easier to setup a web proxy which rewrites the browser's request for data by adding private API credentials to each request, and passes the data through without doing any sort of processing.

    Then I read Gabe Weinberg's post on cool Nginx hacks where he describes this exact technique under the heading "Proxy external JSON calls". Unfortunately this app is hosted on Heroku so my solution is a little more involved than changing an Nginx config. Goliath turned out to be perfect for it, though:

    That code takes requests for Local or TollFree numbers, signs them with my Twilio credentials, and proxies the connection. I have it running on an isolated Heroku app on a separate domain from the rest of my app (since the original app is not running on Goliath) which is why I'm using the JSONP middleware (so the browser can make JSONP requests for this data, avoiding cross-site security restrictions). Twilio gives pretty good error messages in the body of its response which is why I'm returning 200 for all requests. The client can inspect the returned data to see if there were problems with the request.

    By the way the Procfile that run this code on Heroku is simply:

    web: bundle exec ruby lib/twilio.rb -sv -p $PORT -e prod