Menu

Colin Devroe

Reverse Engineer. Blogger.

Creating Summit: The current summit view

This post is the first in a series of posts about my experience building and designing Summit. This post focuses on just one view within the application; the current summit view.

The idea for Summit came nearly 4 years ago as far as I can tell. I’ve hunted around for scraps of paper, digital notes, code snippets to see if I can come up with an exact date but I’ve been unable to. And it has been fits and starts for several years.

When Kyle Ruane and I started on the idea we first thought the UI would be a bit more game-like. I envisioned a 3D model of the current mountain you were hiking that would progress the person up the summit in first-person towards each goal. This was altogether too much work, and far too difficult given my unfamiliarity with the platform. Kyle’s suggestion – again, many years ago – was to use a low poly look. He would craft a low poly representation of the summit and we could allow the user to move around in it, perhaps even spin it around, zoom in-and-out, etc.

I pulled that thread for a very short time before giving up. Remember, we started toying with the idea of Summit before Swift was released. So I was trying to draw this UI with Obj-C. Something I’m even more terrible at than Swift.

Here is what one attempt at drawing progress lines using Obj-C looked like back 4 years ago or so. I took this screenshot in June 2014 and was already labeling it “historical junk” in my files.

The red triangles were goals to meet, the blue line was your path, and the white line was your progress so far. My goal was to overlay this on top of the low poly art that Kyle drew. This was inspired by maps like this. (copied here for archival purposes)

This worked but was not that easy to pull of, introduced more complexity than we needed, and so we quickly shelved the idea until we got more familiar with the platform.

In tandem I began constructing a simple web UI to start cataloging steps from a phone. This was purely to get used to writing code that would track user’s steps, show stats, work on our step algorithm (the code that determines how far up Mount Everest a single step walking in a downtown city parking lot gets you), etc.

It went this way for a few years. I would open up a code editor and begin working on the pieces of Summit; the progress UI, the algorithm, the code to read from a user’s step count or HealthKit or Apple Watch.

In June 2017, when I picked up this project on my own to take on since Kyle had moved away, I decided I needed a simpler approach to the UI. In part because Kyle is the design genius but also in part because I wanted to get as quickly to shipping an app as I possibly could. I prefer to iterate on ideas with user feedback than to work on something in a silo for years. I wanted a way to show the summit, or some visual from the summit, but yet also show one’s progress. And I also still needed multiple goals per summit.

Here are a few drawings from this summer.

See, I’m not an artist. Admittedly, though, this wasn’t an attempt to draw anything beautiful but rather to get a general idea for all of the views I needed to pull off the layout. I needed some labels, some buttons, navigation, etc.

The long goal buttons was really “a punt” on my part. I gave up trying to get Xcode’s Storyboard feature to properly align a changing number of goal buttons (since each summit has a different number of goals) in a way that worked with each device size. It was very frustrating. So I began to go down this path of having them just be full-width, flat buttons.

But then I ran into Brian Voong on YouTube. In most of his video tutorials he suggests forgoing the Storyboard feature and using code to create the UI. Though I didn’t want to lose the progress I had made, I’m so glad that I took his advice. Writing UI directly in Swift is far, far easier (for me)  and seemingly more powerful than using Storyboards.

This revelation allowed me to go back to a drawing I did a month earlier. This one:

On the left, the elements needed, on the right, a rough sketch of a much more minimal and airy design of the current summit view. The goal buttons have varying distances between them relative to how far apart they are in real life (I’m still working on getting this right in the app).

Using Swift I was able to make this happen much easier than Storyboards.

The above is one of the very first swings at this view. It had all of the elements I wanted. And I’ve been iterating on this specific design ever since. I wish I had the hundreds of iterations saved but I don’t.

Here is what the most recent iteration looks like with goal buttons that are easier to determine your progress and other tweaks to make the UI more consistent.

This is the design for this view I’ve settled with for now. I have plans to iterate on this current design for some time before, perhaps, taking a whole new swing at it. Perhaps my skills will grow to the point that I feel confident going back to Kyle’s low poly idea. But, I’m pleased with how it has come along so far.

Developers, Let me tell you about Microsoft (audio)

I’ve been writing about Microsoft’s moves for the last three years. This week everything has come together and I’ve been writing my first multi-platform application using C# and Visual Studio. In this long rant I go on and on about how Microsoft needs to spread the word about what they are up to.

Links for this bit:

Download.

I’ve spent most of the day writing JavaScript (fun!) which was an opportunity to try out ES 2018, the MDN docs, and laugh while reading Eevee’s take on the latest JavaScript spec updates.

What’s new in WSL in Windows 10

Tara Raj for Microsoft:

We’ve been documenting many of these new features and improvements on this blog over the last few months, but we’ve often been asked for a single document listing all the new improvements, and with FCU (version 1709, build 16299.15) shipping on October 17th 2017, we thought it was time to publish a list these improvements!

We’re coming up on our first year of using Windows Subsystem for Linux (WSL) at Condron Media. I mentioned in January of this year that we’ve been using it pretty extensively. Since then Tucker Hottes has been getting the insider updates (or, beta updates) of Windows 10 and has enjoyed the incredibly fast pace that Microsoft’s teams are on. If you look at the linked blog post you’ll see the improvements are myriad.

A request: If you’re a developer using Windows 10 and know about WSL do Microsoft a favor and let other Windows-using developers know. Tucker and I are always amazed at the number of developers that have no idea about WSL still. In fact, just yesterday we met one and made sure to tell them about it.

To put this in perspective; Tucker is on Windows 10 and I’m on macOS. Yet, we use nearly the same development environment, configuration, tools, etc. This allows us to collaborate in a way that was previously much more difficult. Microsoft is doing great work on WSL and more developers need to know.

A unique color for every address in the world

A recent, yet-to-be-announced client project had me designing a mobile app interface that dealt a lot with showing locations and events that are happening at certain locations (how is that for vague? sorry).

While I utilized the brand’s colors to represent certain sections of the app I wanted the app to have tons of colors in order to portray a sense of fun throughout the app. But how could I incorporate pinks and yellows and bright greens without the overall brand disappearing?

After toying with a few design ideas I had an idea to create a unique color for every address in the world. This would result in two benefits; first, each location was then branded as a color, and second, every user would see that location as the same color. If I were a user of the app here in the US and I flew to Spain and looked at a location for an event  there, I would see the same exact colors representing that address as the person that lived in Spain and created that event.

Since I wasn’t to be the developer of the mobile application I wanted to avoid the possible pushback this idea might receive from that team. I didn’t want to add burden to the other people on the project by showing a design mockup and a set of requirements and then walking away. I wanted it to have zero overhead for the developers.

One of the solutions I discarded was generating a random color each time an event location was added to the service and then store the color for that address in a database. While this solution is relatively simple to implement it was no good. It adds more work for the developers and they have to maintain the datastore indefinitely. Several other ideas with the same caveats came to mind and I quickly tossed them into the bin.

Once I eliminated all of the ways I didn’t want to solve this problem – the solution came pretty quickly.

Since every address is already unique, I just needed to find a way to represent an address that could be turned into a color. In other words, I wanted the address itself to represent a unique color. And I wanted to do it in realtime as the application’s UI loaded.

So I jumped into JavaScript and began working it out. Here is what I settled on:

This solution allows for just over 16.5 million colors. Far more than this app will likely require during its lifespan.

Here is a demo of the process and if you view the source you can see the code at work. It is fairly simple to follow.

Oh, there was an issue that I ran into with this solution that was fun to solve. If the background color that was generated was too dark the text became hard to read. So digging around I found a way to determine the luminosity of the background color and thus change the text to something a bit lighter in those instances. That too is shown in the demo.

I was then able to repurpose this demo code and give production-ready code to the developer that is going to ship in the app. When that ships I’ll write more about it.

I can work on anything I want

One of the most enjoyable aspects of working on your own project is that there is so much to do. That may seem strange, why would I want to have so much to do? But if you look at it a different way it becomes a much more enjoyable experience.

Whenever I sit down to work on my pet project, a new iOS app, I can choose what I’m in the mood to work on. Perhaps I’m in the mood to work on the branding, editorial, licensing, or marketing? Or, would I prefer to hunker down into some Swift programming and refine the datastore, algorithms, animations, speed, etc of the app? Or perhaps I’d like to identify key strategic partners for my product launch or look through beta user feedback or do some artwork?

You see the point? Yes, there is a lot to do. And it can seem overwhelming if you allow it to be. But, no matter what type of mood I’m in I can make some progress on the project nearly every single day. And I’m having a ball so far.

Presenting at the July NEPA.js Meetup

Earlier this week my Condron Media cohort Tucker Hottes and I presented at the July NEPA.js Meetup. Our presentation was about automation and all of the things we can automate in our lives personally and professionally. And also how we employ automation in our workflows for creating applications and web sites using our own task management suite.

Here are just a few examples of reproducible tasks that you can automate that perhaps you haven’t thought about:

  • Your home’s temperature
  • Applying filters to multiple photos at once
  • Social media posts
  • Combining many files together into one
  • Deleting unused files
  • Calendar events

There are countless others. Perhaps you’re doing some of these things now. You might set a reminder for yourself to clean the bathroom every Tuesday. Or, your using a Nest to control your home’s temperature based on your preferences.

But there may be others that you’re not doing. Posting regularly to social media can seem daunting to some. But automating those posts can make it much easier to set aside time to schedule the posts and then go about your day. Or editing photos or video may never happen because you don’t have time to go through them all and edit each one individually. But these are tasks that can be automated.

We showed a quick demonstration of automating the combining of multiple text files using Grunt. There are a lot of ways something like this can be useful. Combining multiple comma-separated value (CSV) files that are reports from many retail locations, web development, and others.

Then Tucker provided a list of all the tasks we do when we get a new client at Condron Media. The full list can take a person up to 1.5 hours to “start” working on that customer’s project. So we’ve begun working whittling away at that list of tasks by using another task manager called Gulp. We call this suite of automation tasks Bebop – after one of the thugs from Teenaged Mutant Ninja Turtles.

Bebop is separated into the smallest tasks possible so that we can combine those tasks into procedures. Creating new folders, adding Slack channels, sending Slack messages, spinning up an instance of WordPress, adding virtual hosts to local development environments, etc. etc. Bebop can then combine these tasks in any order and do them much quicker than a human can clicking with a mouse. We estimate it will take 1 minute to do what took 1.5 hours once Bebop is complete.

Another benefit of automating these types of tasks is that you can nearly eliminate human error. What if someone types in the wrong client name or forgets a step in the process? Bebop doesn’t get things wrong. Which saves us a lot of headaches.

Here is the example Gulp task that we created to demo Bebop to the NEPA.js group.

We then asked the group to take 5 minutes and write down what they would like to automate in their lives. The answers ranged from making dog food to laundry to simple development and environmental tasks. Every one in attendance shared at least one thing they’d like to automate.

Tucker and I had a blast presenting but we enjoyed this final session the most. Similar to my event suggestions to Karla Porter earlier this year, I find that the more a group interacts with one another the more I personally get out of a meetup or conference. Presentations can be eye opening but personal connections and calm discussions yield much fruit for thought.

Thanks to everyone that showed up. I think we had 14 or 15 people. The NEPA.js community is active, engaged, and I’m very happy that it is happening in Scranton.

Observations on building my first iOS app in Swift

In early June I decided I wanted to learn iOS app development using Swift.

I’ve made a lot of progress over the last month, building two apps that I can use on my own phone, and one app that I’m now in beta testing via TestFlight with a few friends. Over the last month I’ve made some observations on the process of building an iOS app, the Swift programming language, Xcode, iOS frameworks, and the various other bits needed to make an app. I thought I’d take the time to jot those down.

These are in no particular order:

  • Swift is growing on me rather quickly. The idea behind Swift has always interested me, but I hadn’t really given it a try until now. Like any new language you need to work with it for a time before some of the things that you may not like about it, you end up seeing the wisdom in.
  • I’m very glad I waited until Swift 3 before trying it in earnest. The tutorials I’ve come across for earlier versions make it clear the language has matured in a short period of time.
  • Using Storyboards in Xcode is not intuitive whatsoever. I know many people avoid them altogether (from what I’ve seen on YouTube). Unless you watch someone build a Storyboard you’d likely never, ever just figure it out.
  • iOS frameworks are bulky. It is no wonder so many apps are so big. Just including one or two frameworks for my very simple first app ballooned the app to over 15Mb.
  • That being said, iOS frameworks are very useful. With just a few lines of code you can get something working quickly.
  • Playgrounds are very useful to learn Swift.
  • The Playgrounds compiler can become stuck rather easily. Especially if you paste in a bunch of code from your project to mess around with and get it to work. I’ve had to restart Xcode several times.
  • Xcode has crashed on me a few times over the last month. Crashes on macOS (and also most Apple apps) are very rare. So to be working on something so fragile seems out-of-character. Especially with how simple my apps are currently.
  • Auto Layout baffles me still. I have a working UI for one of my apps that works across multiple device screen sizes. But it is far from what I’d want to ship with. I’ve watched a lot of videos on how to use Auto Layout but I still can’t make heads or tails of it. I’m waiting for the moment it clicks.
  • The connection between labels and buttons and other UI elements in your Storyboard and your Controller class is far too fragile. You should be able to rename things, delete things, move them around without completely blowing everything up and starting over. Example: If I CNTRL+Drag a label onto my Controller and create an Reference Outlet for it… I should be able to rename that Outlet without needing to CNTRL+Drag again. I don’t know how, but somehow.
  • Did I mention that Auto Layout baffles me still?
  • Building and deploying an app to iTunes Connect in order to add to the App Store or Test Flight is an entirely un-Apple-like experience. There is no Step 1, Step 2, Step 3 type of workflow. Similar to Storyboards it is not something you can figure out – you must watch or read to learn. It feels like it was never designed by a Product person.
  • Building an app that resides on a device like the iPhone is an amazing experience. While I’ve always been able to load my web apps on a phone, and I’ve built some apps that use a WebView to deploy across multiple platforms, this is the first time I feel like I’m touching my app when I use it. There is nothing that comes close to native UI.
  • Also, building an app that requires no connection to the web has been really fun. It is so fast! I’d like to move forward by trying my best to keep HTTP request at zero or as low as possible.
  • The amount of information an iOS device knows at any given time is pretty amazing. It can know (with the user’s permission) where it is, what altitude it is at, which way it is pointing, how many times the person’s heartbeat that day, what it is looking at, etc. etc. Amazing to play with these features.
  • The Xcode IDE is really incredible to use. You may not remember a framework’s properties but you can just begin typing a reasonable word and expect that Xcode will figure out what you’re trying to accomplish. Also, if you happen to write older syntax because you’re following an out-of-date tutorial, it will automatically convert it to the most recent syntax.

Overall I’ve had a positive experience learning to build an iOS app on my own. Going from having an app in TestFlight to shipping an app feels like preparing to cross a desert on foot. But, I’m enjoying my experience so I’m going to trudge forward to do so.

I hope to ask for public beta testers of the app in a few weeks or a month.

How do you get work?

Aspiring freelancers always ask this question. Lara Schenck answers:

I tell people I’m looking for work. Then, while I wait for referrals, I do a bunch of stuff for free. That includes talking at meetups, doing free workshops, and writing blog posts. Finally, I cross my fingers and have faith that it will come when I need it. It’s a very exact science, let me tell you.

This formula works. Yet, so many freelancers do not believe it and so they prioritize based on the fear of not getting work if they “waste” time blogging, designing logos for nonexistent companies and putting them in their portfolio, or writing code for open source projects on GitHub. The clear way to get work is to share work.

Hacking rather than waiting

Yesterday afternoon Sarah Pressler retweeted Jono Young’s request for a plugin that would add a submenu to the WordPress’ Admin with the current pages for the site under the Pages menu. This would reduce the number of clicks to get to the page editor.

I was waiting for an upload to finish and I thought, given the code I have laying around from other projects, I’d be able to supply Jono with something passable for what he needed. Though it is far from what I would recommend using, it is a start.

Here is what I did:

  • I used get_pages to get a list of WordPress pages the were published.
  • While looping through each page I used add_submenu_page to add the page titles under the Pages menu
  • I used JavaScript to replace the HREF attribute on the links to link to the page editor

That last step is the hacky part in my opinion. add_submenu_page() asks for a function name to call to build the page for the menu item when it is clicked. In other words, for each item on the Admin menu there is a corresponding function that will show you the page that it results in. But I didn’t want to create a new page, I wanted the link to go to the page editor.

I dug around for five minutes or so and I didn’t see an apparent way to change the links for the page titles (though I’m sure there is a better way if I had the time to continue looking) and so after the page loads I use JavaScript to replace the attributes with links to the page editor.

Nowhere near perfect but, in a pinch, it is one step closer to what Jono wanted. Hopefully he or someone else can build upon and it make something a little more reliable and less hacky.

You can see the source on Github.

How can I get into programming?

Linus Torvalds in 2004 on the Linux Kernel Mailing List (LKML):

To me, the biggest thing with small patches is not necessarily the patch
itself. I think that much more important than the patch is the fact that
people get used to the notion that they can change the kernel – not just
on an intellectual level (“I understand that the GPL means that I have the
right to change my kernel”), but on a more practical level (“Hey, I did
that small change”).

Over the years I’ve been asked many times “how can I get into programming?” and my answer has always been to contribute to some open source code. The benefits are manifold.

  • Sense of accomplishment (like Linus brought out)
  • Exposure to someone else’s code (you can learn a lot this way)
  • Helps you get comfortable with criticism (esp. if the codebase is managed by several people)
  • Learn to collaborate (have a team before you have a team)
  • Give yourself some publicity (the number 1 way to get work is to show your work)

So, get in there and get started.

Building a single page web site using an Excel spreadsheet

Need something like this? Consider hiring me for your next project.

I was recently asked by a client if I could use an existing Excel spreadsheet and create a single-page web site from it. This way, their team would be able to use the work they’ve already done and the data they’ve already keyed in and wouldn’t need to do double the work.

I could have built an data import tool that used the Excel data and reformatted it for WordPress or another content management system, but after asking a few questions I figured the simplest and most cost-effect approach was to use the Excel spreadsheet as the datastore.

It sounded fun. So I gave it a shot.

Here is what I came up with. It is a bit simple, arguably a bit crude, and wouldn’t work for anything terribly complex or for a high-traffic site, but, it works for them and that is all that matters.

Let’s start out with a simple example spreadsheet. Let’s say you have the following data for your soccer team in Excel.

Excel Soccer Team Example

In this case you have four columns; Name, Age, Jersey Number, Goals. How can you get those to display in a web page? Using PHPExcel, which I’ve used on several client projects, you can read from and write to an Excel spreadsheet fairly easily using PHP. Using the above data as an example, the code might look like this.

// Load PHPExcel, then load Excel spreadsheet
include 'lib/PHPExcel/IOFactory.php';
$objPHPExcel = PHPExcel_IOFactory::load($file);

// Read the Sheet data, create Array
$sheetData = $objPHPExcel->getActiveSheet()->toArray(null,true,true,true);

$players = array(); // Array used to store player information

// Go through each row one-by-one
foreach( $sheetData as $row ) :

  // If Column A is not empty or null, or "Name" (this will avoid having a player with column names)
  if ( !empty($row[A]) && $row[A] != 'NULL' && $row[A] != 'Name' && $row[A] != '' ) :
    $players[] = array( 'name' => $row[A], 'age' => $row[B], 'jersey_number' => $row[C], 'goals' => $row[D] );
  endif;

endforeach;

Let’s walk through this code quickly. First, we load the PHPExcel IOFactory, which lets us read from Excel. Then we load the Excel file. $file, in this case, would be the full path to the Excel spreadsheet you’d like to load. Then, we create an array out of each row of data in the sheet. Once we have that, we simply loop through each row and create a “Player” out of each one.

You’ll notice the way I avoided adding a Player with the column names is to check to see if $row[A] == "Name". You could also skip the first row depending on where in the spreadsheet your soccer team’s information is. But this is just an example.

Now that you have this Player array, you could use this information anywhere on your page by creating a simple for loop to go through them and write the list of player and their information.

Let me give one more example. This represents what my client needed much more closely.

What if you had variable names in Column A and wanted the values of those variables to come from Column B? Here is an example spreadsheet where this might apply.

Excel spreadsheet example profile

Here is what the code may look like for this…

// Load PHPExcel, then load Excel spreadsheet
include 'lib/PHPExcel/IOFactory.php';
$objPHPExcel = PHPExcel_IOFactory::load($file);

// Read the Sheet data, create Array
$sheetData = $objPHPExcel->getActiveSheet()->toArray(null,true,true,true);

$person = array(); // Array used to store person information

// Go through each row one-by-one
foreach( $sheetData as $row ) :

  // If Column A is not empty or null
  if ( !empty($row[A]) && $row[A] != 'NULL' && $row[A] != '' ) :

    // Remove spaces in Column A to use as array key and value being Column B
    // Example A:'Person Country' B:'USA' becomes $person[person_country]='USA';
    if ( !empty($row[B]) && $row[B] != 'NULL' && $row[B] != '' ) :
      $person[str_replace( ' ', '_', strtolower(trim($row[A])) )] = trim($row[B]);
    endif;
    
  endif;

endforeach;

The subtle differences here, from the example above, is that $row[A] becomes the array key, and $row[B] becomes the value. By doing this, the person’s profile information is now easily printed anywhere on the page using <?php echo $person['age']; ?>

This simple Excel-powered approach becomes very powerful for someone with no web language skills. They can open an Excel spreadsheet, edit the values, and the web page changes.

Need something like this? Consider hiring me for your next project.

On rebranding

Over on our company blog we published our recipe for rebranding a company. Here’s a snippet on how our outsider view is an advantage:

Our suggestions and feedback come with no internal bias, no politics, no fear of losing our jobs, and certainly no fear of sounding stupid. We’re experts at dumb ideas. Out of dumb ideas come fruitful discussions, fun tangents, and exhausting possibilities.

If you need that sorta thing, reach out.

Three Toe: A simple SMS autoresponder on top of the Twilio API

If you find yourself needing something like this, why not hire me to make it for you?

A friend of mine somewhat recently became a licensed realtor. One thing that surprised him was the lack of technology being used in his workplace. Though not a technologist himself, he enjoys an efficient workflow such as using a tablet and managing documents digitally. So whenever he’s asked to complete a transaction using piles of paper and copy machines and so forth, it obviously gets under his skin.

For the last several months we’ve been trying to find ways that I can use my various talents (finite though they may be) to make his work easier or even improve the chances he’ll be successful in a sale. We’ve had a few conversations and personally I’ve been brainstorming and keeping notes and scratching out ideas.

Some of the ideas I’ve had are more expensive and involved while others are more simple and can be done inexpensively. One more expensive and involved idea is shooting drone footage of lakeside homes to help differentiate the listing. I hope to get a chance to shoot some drone footage soon. (hire me?)

One idea that, thanks to Twilio, is very easy and inexpensive to do is writing a SMS autoresponder to send property information to a would-be-buyer. And since I’ve wanted an excuse to play with Twilio this was my chance.

Here is the idea; A buyer pulls up in front of a house that they may be interested in. In the front yard, the listing agency’s sign would have a phone number that the buyer could send a code to and get information about the property.

It turns out that writing this on top of the Twilio API is very simple. (Coincidentally they IPO’d yesterday, their stock spiked 90%, and they wrote code live from the NYSE trading floor. Pretty good day for them yesterday.)

Here is what you need:

  • A Twilio account (you can use a free trial account to get started)
  • A phone number (you can purchase one from Twilio for $1/month or a short code for $1,000/month)
  • A server to host Three Toe

Let me just state right up front; using Twilio will cost money but it is very inexpensive. You get charged for each message received and each message sent. So in our example of a buyer texting a code and getting a response that is 1 round trip that costs just about a penny and a half (at current prices). A penny to send a home buyer a link to a beautiful web site of the home they want is a no-brainer.

Here is how Twilio works:

  1. Potential buyer sends a text message to your Twilio-powered number
  2. Twilio receives that text, creates a “POST” with general information about the sender (phone number, location, and contents of message, etc.)
  3. Twilio then sends that information to your app via a “webhook”
  4. Your app parses the response, and can do anything you want. In our case, we’re using Twilio to send a message back to the sender with information based on the code they sent

Theoretically you could use this simple service to do just about anything. You could ask for their email address and subscribe them to your newsletter. You could send back a YouTube video. You could keep a log of their phone number in a database and an agent could follow up with them at a later date. You could call the sender and read an audio message back to them with background music.  Or, you could first call the agent in charge of the property and then call the sender back and connect the two together.

But I didn’t do any of that. All I wanted to do for this service was set up an easy way to allow my friend the realtor to create an auto response for the code the potential buyer sent.

Here is the app works:

  1. Twilio sends a webhook POST and it is received by Three Toe.
  2. Using the contents of the message (e.g. “T0001”) it looks in a “responses” directory for a TXT file with that same name.
    1. If that TXT file is found, it responds to the sender with its contents.
    2. If that TXT file is not found, it responds with something like “There is no information available for this property.”

Very, very simple.

To add a new “code” that the application will respond to my friend the realtor just needs to add a new TXT file to the “responses” directory. Or, alternatively, I plan on creating a very simple form that will allow him to list and edit the responses and add new ones.

Here is the code: I’ve shared the basic application on GitHub in hopes that someone else can put it to use or even help improve it.

I’m fully aware that there are thousands of open source versions of this same sort of thing. In fact, this is basically what Twilio would likely use as their example code for others to learn from. I made this simply to scratch our itch and to get familiar with the Twilio API. It was fun to hack around with.

If you find yourself needing something like this, why not hire me to make it for you?

Update on June 28th, 2016: I’ve tagged version 0.2.1 on Github which includes a new configuration area to make it dead simple to create, edit, and delete codes and responses.

Update on June 29th, 2016: I’ve tagged version 0.3.0 on Github which includes a Bootstrap-style theme for the configuration area. This makes it easy to update codes and responses on mobile devices.

I have a few planned features for Three Toe that I’ll likely be able to build as extensions. I’ve already sold three copies of this simple app (with slight modifications) and some of the features needed by those customers will be making their way back into the repo. Fun app to hack away on.

Migrating Subscriptions from one Stripe account to another

One of my recent client programming projects (hire me here) was to help a company migrate all customers, cards, plans, and subscriptions from one Stripe account to another as a result of an acquisition. I hadn’t needed to do anything like this in the past and I ended up fumbling my way through a few of the steps. So, I thought it worth the effort to jot down the process.

Here is a graphic of the overall process with notes to follow below.

Stripe Migration

I made some notes along the way during this project. Using the numbers above, here is the process step-by-step and some things you’ll want to keep in mind before you begin.

  1. Send an email to support@stripe.com to request Customer and Card migration from Account A to Account B.
    • Remember that both accounts need to be activated
    • Stripe cannot transfer live accounts into test accounts (a shame)
  2. Stripe transfers Customer and Card information from Account A to Account B
    • Stripe cannot “schedule” this transfer for an exact date or time
    • Stripe can run the migration more than once should new Customers be added
    • Customer IDs are retained from one account to another
    • Card IDs cannot be retained
    • Stripe will not migrate Plans or Subscriptions
  3. Transfer Plans from Account A to Account B
    • Retain all plan information (recommended)
    • The most crucial piece to keep the same is plan_id
    • You may want to make adjustments to “Statement Description” at this time if the business name has changed
  4. Transfer Active Subscriptions from Account A to Account B
    • There is no need to transfer cancelled or inactive accounts
    • During the transfer, request Subscription on Account A to cancel at period end
    • Create a new Subscription on Account B based on plan_id, using billing_cycle_anchor will allow the Subscription on Account B to begin the moment the Subscription on Account A is cancelled
  5. (not in graphic) Verify all Plan and Subscription information has been moved

Whether you’re using Stripe’s excellent API to migrate your Plans and Subscriptions or doing it manually via their admin the process is basically the same. The customer I was working with had nearly 5,000 customers and over 1,000 active Subscriptions on 4 Plans. So writing a script to do this saved huge amounts of time.


Aside: How do you calculate whether or not it is worth building a script to do this or doing it yourself via Stripe’s admin? Well, the pessimistic view would be something like this comic from the always excellent XKCD re: automation. However, the more practical approach is this comic from XKCD titled Is It Worth The Time?


How did I write the code? Depending on your exact needs and your familiarity in different languages you may want to find a completely different approach to the one I took. However, I’m a PHP guy, this is what I did.

I started by doing a search on Github for “Stripe Migration” (always worth starting here) which led me to this set of simple scripts from Nyalex for migrating Plans and Subscriptions on Stripe from one account to another. This likely saved me 5 to 10 hours of development. (Thanks Nyalex!) I then reached out to him on Twitter to let him know I was about to use his script. We had a nice conversation that helped me to get my head around how his scripts worked.

My modifications to Nyalex’s script were fairly minimal but vital. Since he hadn’t used the scripts in some time they fell out-of-date with Stripe’s latest API version. So I had to make some subtle updates to account for those. Also, the client was using Easy Digital Downloads, a WordPress ecommerce plugin, as their backend so I had to write a few SQL queries to update the Subscription IDs in EDD’s customer table as the process ran. I plan on writing a Pull Request for Nyalex so that I can help keep his set of scripts up-to-date for future uses.

There were, of course, a few hiccups when running the scripts.

First, the client’s server would time out if I tried to process all 4,800 accounts at once. Each account creates several Stripe API calls (about 7) so even with Stripe’s limit of 100 accounts at-a-time that is still a hefty 700 API calls. So understandably I had to find the right number that the server’s setup could handle without choking. I also slimmed down the number of API calls slightly from the default. I did this by creating some mock API calls for the cancel and create Subscription calls and let the script run a few times until I found the right number. For this particular client it was 20 accounts at a time being processed. Which meant the script ran over 200 times to complete the process. Because I was purposefully doing this manually, rather than setting up the script to run end-over-end, this process took a little over an hour.

Second, prior to creating those mock calls I accidentally duplicated a few subscriptions for 23 accounts and needed to go back and manually cancel them all before re-running the script. I recommend not doing this. Again, it is a drawback that Stripe cannot migrate live Accounts as Test accounts so that you can do test runs on this sort of thing but it is understandable.

And, lastly, I didn’t properly create a log file for all of the transfers as they were done so I had to manually save the output of Nyalex’s script to a text file. I think I’d like to update the scripts to create a log file of old subscription ID, customer email address, and new subscription ID at the very least. This would have saved me a lot of time and would give me a “back up” of sorts should any customers have been missed. Also, since the scripts only attempt to migrate active Subscriptions it would have been nice to extend the scripts to log inactive Customers too just as a double-check that those Customers were looked at.

Overall this was an interesting project to take on and I’m hoping that my knowledge from this project will get reused in the future. If you need to migrate from one Stripe account to another please reach out.

Observations on using a standing desk

I’ve used a standing desk on-and-off for a few years.

In 2011 I stood for a week before giving up. At the time I claimed that I wasn’t able to focus on my work as well while standing as I was while sitting. Reading that now confuses me as I believe standing is far more conducive to focus than sitting. I think it is because I didn’t push through the initial discomfort of standing. If I had, I’m sure I wouldn’t have had an issue with focus.

In 2014-2015 I tried again and ended up standing for 4 months straight. The first two weeks, I recall, were very hard on my feet and knees. But it was after those initial two weeks that I really began to see the benefits of standing all day (or, at least most of the day). Once those first two weeks of discomfort were over I ended up putting in my longest continuous stretch of using a standing desk. I had to sit down because I injured my ankle playing basketball and could not stand.

I tried standing again earlier this year just prior to moving from a dedicated office to my home office. And I likely would have stuck with it. But once at home I didn’t try standing again until this past week. I hadn’t even thought about it.

This time has been a bit different. I’ve had nearly no discomfort that I’ve had to push through and I’ve noticed an increase of focus almost immediately.

In the past I’ve said that my productivity increases while standing. I’m now not so sure that is the best way to describe it. It isn’t that I get less done when I’m sitting down but I am able to be fully alert and feel no “lull” that I have to push myself through each day. When I have a deadline, I’m going to work like crazy to meet it whether I’m standing or sitting. However, there is a time period each day where I feel less alert or focused or in the mood to work when I’m sitting at a desk. Whereas when I’m standing I feel like I never have that lull in my day.

I still do not own an adjustable desk. I’ve looked at a few but have never made the investment. Sitting all day is definitely bad for your body. Standing all day is also bad. I hope to find the right adjustable desk for me in the near future and give it a whirl.