Ruby Scripting

Profile
by Jess Brown

As a rails developer, I spend a majority of my time in rails. This is fine, because I love rails, but it's nice to write something outside of rails from time to time...in particular, a ruby script.

Stripe Transfer

My client was recently acquired and needed to migrate their stripe account to another stripe account. Stripe will handle transferring customers and cards, but it's up to you to transfer the rest. The client's app was a SaaS app and heavily made use of subscriptions. The account had thousands of subscriptions that needed to be ported over to the new account.

Using the Stripe gem and the api, I was able to transfer them over without much trouble.

require 'stripe'
require 'pry-debugger'

MODE = :live

def old_stripe_key
  # live
  # key = "xxx"
  # test
  key = "xxx"
  key
end

def new_stripe_key
  # live
  # key = "xxx"
  # test
  key = "xxx"
  key
end

def old_customers
  Stripe::Customer.all({limit: 10}, old_stripe_key)
end

def new_customers
  Stripe::Customer.all({ limit: 100 }, new_stripe_key)
end

def migrate(customers)
  puts "The End" && return if customers.data.empty?
  puts customers.data.count
  sync_customers(customers.data)
  migrate(Stripe::Customer.all({ limit: 100, starting_after: customers.data.last.id }, old_stripe_key))
end

def sync_customers(customers)
  customers.each do |customer|
    File.open('sync.log', 'a') { |file| file.write("\n#{customer.id} ") }
    puts customer.id
    subscriptions = customer.subscriptions
    if subscriptions.data.any?
      subscriptions.data.each do |subscription|
        File.open('sync.log', 'a') { |file| file.write("#{subscription.id}") }
        puts subscription.id
        plan_id = subscription.plan.id
        current_period_end = subscription.current_period_end
        if MODE == :test
          new_customer = Stripe::Customer.create(
            { :description => "clone #{customer.id}" },
            new_stripe_key
          )
        else
          new_customer = Stripe::Customer.retrieve(customer.id, new_stripe_key)
        end
        unless new_customer.subscriptions.data.map(&:id).include?(subscription.id)
          new_customer.subscriptions.create(:plan => plan_id, :billing_cycle_anchor => current_period_end, :prorate => false)
          subscription.delete unless MODE == :test
        end
      end
    end
  end
end

def print_active_subscriptions(customers)
  puts "The End" && return if customers.data.empty?
  puts customers.data.count
  active_subscriptions_for(customers.data)
  print_active_subscriptions(Stripe::Customer.all({ limit: 100, starting_after: customers.data.last.id }, customers.api_key))
end

def active_subscriptions_for(customers)
  customers.each do |customer|
    subscriptions = customer.subscriptions
    if subscriptions.data.any?
      subscriptions.data.each do |subscription|
        puts "#{customer.id} #{subscription.id}"
      end
    end
  end
end

As you can see it's a crude but straightforward script. We didn't have a lot of time to implement it so I just hashed it out rather procedurally.

A couple of the challenges were:

1. How to jump back and forth from the old stripe account and new account

Typically you see api gems do something like

  connection = API::Connection.new(:api_key => 'xxx')
  # Then
  connection.customers.all

But I didn't see how to get this type of instance with the stripe api. However, Stripe has great support and Brian Collins helped me out with how to pass the api_key. It's the last argument in the constructor, which means if you're passing options like in the all method, you have to wrap those options in {}.

2. How to run a test on non-live data

Stripe gives you a great testing environment, but for our scenario (we would have customers in both accounts with identical ID's) we couldn't mimic the live setup(you cannot specify ID's when creating customers). So while in test mode, what I chose to do was just clone the customer instead of finding them in the new account. And by passing in the old customer id to the description, I could easily locate the new customer to compare subscriptions.

if MODE == :test
  new_customer = Stripe::Customer.create(
      { :description => "clone #{customer.id}" },
      new_stripe_key
    )
else
  new_customer = Stripe::Customer.retrieve(customer.id, new_stripe_key)
end

3. Setting up the subscription

First off, we had to recreate our plans with the same id in the new account. Typically this won't be a problem to manually do, because you'll likely only have a handful of plans. Just make sure to get the exact id and price (unless you're changing prices). Next we want to make sure the customer doesn't see a change in their billing. If they were billed on the 7th of last month, then their next billing should be the 7th. Also Stripe will automatically prorate a subscription, so you don't want that to happen (because their already paid for the whole period on their last billing). The solution was pretty easy:

  new_customer.subscriptions.create(
                        :plan => plan_id, 
                        :billing_cycle_anchor => current_period_end, 
                        :prorate => false)

Set prorate to false and the billing_cycle_anchor to the date of current_period_end of the old subscription, and the plan to the plan_id of the old subscription.

Summary

It seemed to work well. When we first ran the script on the live data, we only did a few:

pry> customers = old_customers.data[13..14]
pry> sync_customers customers

That's when we discovered we had a setting in Stripe of notify the customer if a subscription was canceled. Oops! Glad we caught that before running it on thousands of customers.

Also you can see that there are two methods at the end to print out all of the active subscriptions. We used this in a before and after snapshot to make sure our numbers added up.

The script could probably be written a little more ruby like but for a quick job, it worked out OK.

What do you think? How would you have done it?

Stripe HowTo

Fear and Intimidation

Profile
by Jess Brown

This week I started working on a new project. Like all projects, especially existing ones, it can be a little overwhelming in the beginning.

The emotional side of the brain...

Some projects I'm even intimidated. This new project was one that I was particularly impressed with. It was using a lot of newer technologies I had not used (luckily I was mostly aware enough to know 'of' them). It had tons of models, used all kinds of services, a new database I actually hadn't heard of, multiple API's I had never used, etc, etc.

When I get on projects like this, thoughts creep in to my head, "the previous developers are way more advanced that I am...what if I can't make it work, my client will think I'm not qualified when it takes me forever to figure things out." The list goes on.

The logical side??

However, when I think back to projects that have come up like this in the past, I look back and remember how much fun they were to "figure out". I see how much I learned and developed as a programmer. I say to myself, "you know, I always figure things out"...there's never been a time when I just gave up and couldn't complete a job.

Also I'm not sure why I do this (and I'm hope I'm not the only one), but I put too much pressure on myself and expect to be able to just look at github repo and know exactly how it all works. I'm supposed to within a few hours of tinkering, figure out what took other developers years to build. Why do we do that? If start a new book, I don't expect to know what happens at the end. It takes time to become familiar with the business logic, the stories, flow, the methods the previous developers used, etc. The tests and code should tell a story, but you have to read the story to understand it and make contributions to it.

So I conclude...

A programmer's job is to solve problems and figure things out. That doesn't mean you're not going to feel overwhelmed and intimidated at times. If you don't, you're probably not challenging yourself enough. I encourage you like I encourage myself, embrace the challenge, be thankful for the opportunity to level up and remember, you're a hacker, you'll figure it out!

Expectations

Profile
by Jess Brown

Expectations are a strange thing. Maybe because they're relative and hard to guess for other people.

Recently my family and I headed off for our annual summer vacation. You'll probably agree with me that check in times for rentals are getting absurd. Check ins used to be around 1-2p, but then moved to 3, then 4 and this year our check in was at 5p! The day is nearly over.

However, many times, especially when dealing with private owners, you can request and get an early check in time. We'd done this the previous year with the same owner and were told our condo should be ready around 3p. Well, we arrived around 3:30 and the room wasn't ready. "Should be ready shortly, we'll send you a text." Shouldn't be long we expect, so we decided to head to the grocery and get some things we needed for the week. We got back around 4:30. Still no text. We call again. "Nope, still not ready, we'll send you a text." By this time, my 3 and 7 year old boys are going crazy after being up since 6a, driving in the car for 7hrs and expecting to be in the pool way before this. Our groceries are wasting away and we're hanging out in a parking deck for our vacation. 5:10p still no text (10 minutes after the check in time).

I was getting cranky myself and I began thinking about expectations. If we'd only known we couldn't get into the room until after 5, we could have planned to do something entertaining or just arrived later. Everything would have been cool and no one would be at the end of their rope.

Expecting one thing and getting something else sucks. It especially sucks when this happens repeatedly.

I think about this a lot in business. A business always wants to please it's customers, so they typically over promise and under deliver. A previous boss was an exception to this. He would tell customers if an order was placed by 1p it would be shipped the same day, but he told his staff that orders placed by 4p should be shipped the same day. His motto was under promise and over deliver.

That's what I strive for in consulting. It's so easy and enticing to tell a customer you'll have their work done for them by next week when in reality it's going to be longer. It's really difficult to get it right and I've messed it up plenty. For one, it's really hard to know when you'll have the time to work on something. Development work is never turnkey. There are always customizations and different implementation for every business scenario. Secondly, you don't want to seem slow. At least, I want to please the customer.

But, I always go back to my vacation and think, if they'd just told us it'd be a little after 5 until we could get in, we would have been much happier because we got what we expected.

Over the last couple of years, I've gotten better about under promising and over delivering. I'm sure I still miss my client's expectations at times, but I hope to continue to improve the experience daily.

Working On Assembly Made

Profile
by Jess Brown

Assembly Made: What is it?

A month or so ago I found out about a cool new platform called Assembly Made. The idea is pretty simple and works like this: Someone has an idea for a business and they post it to Assembly Made. The idea gains traction and popularity by people discussing the business plan, market, potential, customers, etc. Then, if there's enough interest, the community starts to develop it. Almost anyone can contribute. Apps need all sorts of skills to be built: copyrighting, photography, design, code, ops, etc. A core team is established to provide direction and create tasks for the project. Each task is valued a certain amount of "coins" and when someone completes the task, they are awarded the coins. The amount of coins you have for a project determine your equity stake in the business and also determine your share in the profit sharing system. Assembly keeps 5% of the equity and the project owner is reserved 5% of the equity. The rest is earned by the contributors.

This is really an interesting idea and I can't wait to see how it will play out as new products are built and launched. No one knows how successful (or not) this concept of crowd sourcing the development of software will be. As with any business, especially a startup, many of these businesses could fail and never get a single customer. So is it worth your time? I think so and here's why.

Working with great people

There are some great people working on Assembly products. If you've never worked on a team or just want to get some experience with the experienced, then this is an easy way to to do it.

Learning

Whenever you work with other people, especially with others as good or better than your own skill level, then you're learning shoots through the roof. I always learn so much working others.

It's easy to get started

It's really easy to get started. The Assembly staff is always around to answer questions, hop on chat, screenshare, pair, help you get setup etc. They also do a good job of breaking down tasks so they're small enough that anyone can get started. Example: anyone can edit copy, right? And once you get started, the next tasks are much easier.

Working with actual projects

As a consultant, most of my experience is with building products for clients. I love open source and think it's very important to contribute and give back, but it's never been easy for me and probably others too. Lots of open source projects are tools, libraries, gems, engines, etc that are a lot more complicated than 90% of a typical rails app. So I found working with a actual product (which, in my observation, is what the majority of Assembly projects are) more up my alley.

Work at your own pace / commitment level

Because the tasks are broken down in to small stories, it's really easy to work a little or a lot. Some weeks I have more time than others and can spend a whole day working on Assembly. Other weeks I only have a few hours and some weeks, I have no time at all. When you decide to work on a task, there's a button that click "work on this task" that reserves it so others know you're working on it. Only reserve a task when you're ready to work on it and can get it done in a reasonable time, because there could be others that are able and willing to get it done too.

Boost your portfolio

If you're a creative, your portfolio is crucial in helping you win projects, clients, or jobs. Adding projects you've worked on from Assembly will likely bring the status and allure of your portfolio up. Clients will be impressed with the work that you and you team have produced and may be more willing to hire you for your next big project. All projects are open sourced, so it's easy to share your contributions.

Connections / Networking

Already mentioned is working with others to improve your skills, but working with others will also lead to new relationships, friendships, connections and networking opportunities. If you're a developer, a designer may notice your work and want to work with you on their next project. An entrepreneur may notice your feedback on discussions and want to hire you for their next project. A core team member may recommend you for a job within their company. Assembly is a great place to meet and work with other creatives like you.

Summary

In addition to all of the "side" benefits, I do like the core product. There's a simple profit sharing plan, contributions are automatically calculated when commits are merged in, and it's a nice way to invest in startups and take ownership of a business. Hopefully, the real reason you decide to work on a project is because you believe in the product and feel it will be profitable while solving a problem. However, these other benefits are totally valuable in their own right.

A few weeks ago I joined a friend from Atlanta, Patrick Van Stee (who works for Assembly) and we drove to Greenville, SC to join up with Matthew Smith to work on one of the Assembly projects called Helpful (now you know where the photo above came from :-) Besides being a fun "work" trip, it was a great opportunity to work with Patrick (who is a talented developer) and Matthew (a well known and talented designer). Had it not been for Assembly, I probably would have never gotten the chance.

Go checkout Assembly and find something to work on!

Generosity In Tech

Profile
by Jess Brown

I recently spoke at Tech Talent South which is a school that teaches an intensive course on Ruby on Rails. After meeting the students, I learned that most in this particuar class were not only new to rails, but were mostly new to the tech industry.

My presentation was about independent consulting and how I make a living doing it. I shared a lot of things I was a little uncomfortable sharing (income, struggles, advantages, disadvantages, etc). I wanted to be honest, open, and helpful.

I'm not quite sure why I was chosen to speak, but my reasoning for going was I wanted to do what I could to help others...just as so many have helped me in my career. During the presentation one of the topics I spoke about was generosity and giving back and how awesome our industry is at sharing and helping others.

I've never seen another industry that shares like we do. Our sharing through open source (Rails), blogging, (Rails Tips), teaching (Rails Tutorial), willingness to help one another with a troubling issue (Pair With Me), conference speakers (Ben Orenstein), screencasts (RailsCasts), sponsors (Mailchimp), workshops (LessMoney), organizations (RailsGirls) and more. Startup incubators like Atlanta Tech Village and FourAthens continually echo the idea of paying it forward. These are just a very small set of examples that are close to me. There are tons and tons more.

When I first got into this industry, I always wondered why people would share something so valuable. Why would people give away their secrets, knowledge, and experience for others to profit?

I recently read a blog post by Seth Godin about Generosity. It may be the best way to answer the question. It was so short and sweet, I can quote it here:

The generosity boomerang

Here's conventional wisdom:

Success makes you happy. Happiness permits you to be generous.

In fact, it actually works like this:

Generosity makes you happy. Happy people are more likely to be successful.

I really believe that is how it is within technology circles, especially on the creative side of things. Technology people are generous, they are happy and they are successful.

I'm reminded of an acronym we have in Christianity: JOY. It goes like this...The path to Joy is focusing on

J-esus  
O-thers  
Y-ou  

I expect other religions have a parallel idea. Whichever way you look at it, there's a connection between helping others, happiness, and success. What are you waiting for...Go be generous!