Fixing Postgres errors after an ungraceful shutdown on your Mac December 20, 2016

Every so often, I'm forced to shut down my Mac by holding down the power button. When this happens, PostgreSQL often doesn't shut down properly, and when my computer starts again it doesn't start automatically.

It turns out this is because there's a stale pid file kicking around inside your PostgreSQL var folder. To fix it, simply delete the postmaster.pid file. PostgreSQL will start automatically thereafter.

rm /usr/local/var/postgres/postmaster.pid

How to bind React component event handlers in ES6 December 20, 2016

When creating React components using ES6 class notation, you'll need to bind event handlers passed as props to this, or you'll find that the handlers will be bound instead to the DOM element.

There are a few ways to do this. You can reassign the bound handler in the constructor:

class MyComponent extends React.Component {
  render() {
    return (
      <div>
        <button onClick={this.onClick.bind(this)}>Click Me</button>
      </div>
    );
  }

  onClick(event) {
    alert("You clicked me!");
  }
}

This works fine, but now you have .bind(this) littering your otherwise elegant JSX.

To remedy that, you can use the fat arrow prototype method syntax:

class MyComponent extends React.Component {
  render() {
    return (
      <div>
        <button onClick={this.onClick.bind(this)}>Click Me</button>
      </div>
    );
  }

  onClick = (event) => {
    alert("You clicked me!");
  }
}

Except... now you have two separate syntaxes for declaring methods, which could make your code less readable and more confusing.

I think the most elegant way is to use the new double-colon (::) notation, which is a shortcut for calling .bind(this) on a given handler:

class MyComponent extends React.Component {
  render() {
    return (
      <div>
        <button onClick={::this.onClick}>Click Me</button>
      </div>
    );
  }

  onClick(event) {
    alert("You clicked me!");
  }
}

Now your caller is binding the method to this without an ugly .bind(this) call, and the method body isn't unnecessarily decorated with fat arrow notation.

Things I wish I'd known at 20 November 2, 2016

I'm turning 31 in less than two weeks. In tech nerd terms, that means I'm basically an ancient relic. There are a few things I wish I'd been told, and other things I was told but wish I had listened to. If you're a young aspiring geek about to excitedly enter a career in technology, maybe I can save you some heartache in your twenties.

  1. Programming is hard, but (usually) it's not an emergency. Enjoy yourself and don't sweat the day-to-day.
  2. Ideas are worthless. Execution is everything.
  3. Learn how to solve problems, not how to use the latest tech. No one ever hired a builder because they were really good at hammers. They hired them to build a house.
  4. Avoid lifestyle inflation. Live like you're middle class, even if you make six figures. (American median income: $51,939)
  5. Save six months' worth of expenses in a savings account as fast as you can.
  6. Keep your recurring expenses as low as possible. This means things like rent, debt payments, utilities, and your gym membership.
  7. Stay out of debt. If you're in debt, eat dog food and work until you're out.
  8. Remember your colleague with the big house and nice car probably makes about the same you do. Also remember they're probably stuck in their job paying for them. Choose mobility.
  9. Don't buy a house unless it's a really, really good deal. Even then, probably don't.
  10. Commuting to an office eats more of your salary than you think.
  11. Fall in love. It keeps you out of bars, in bed early, and attentive to your work.
  12. Eat lots of vegetables. Allocate time to cook.
  13. Invest in ergonomics. Stand at work.
  14. Listen to others unconditionally.
  15. Learn basic yoga postures. Practice them daily.
  16. Take frequent breaks while working.
  17. Drink lots of water.
  18. Avoid alcohol. Especially chronic use, since it becomes difficult to notice its negative effects when you're always hungover.
  19. Track every penny you earn and every penny you spend.
  20. Buy a small, inexpensive, efficient car.
  21. Run your household like a business with shareholders.
  22. You're going to be old and sexually undesirable someday. You're likely more attractive now than you'll be at the end. Enjoy that.
  23. Give to others spontaneously.
  24. Don't let your salaried job get in the way of your own dreams.
  25. Don't let your dreams be diluted by the day-to-day challenges of your salaried job.
  26. Don't let Apple tell you the things you need to buy.
  27. Chat and email aren't actual work.
  28. Choose clients and employers based on how you get along, not on how much you get paid.
  29. Symbols of status matter, but the symbols aren't your car, house, or clothes.
  30. Enrich yourself with knowledge and art. They're inexpensive hobbies and you'll always be fulfilled.
  31. Your parents are wrong about a lot of things. But they're also right about some. Choose your own path, but respect their guidance.
  32. The world is in peril. But it's always been that way.
  33. Gratitude is effective therapy.
  34. The best time to start has already past. But the second best time is right now.

So you're really good at hammers November 2, 2016

If you're about to hire a contractor to remodel your kitchen, you won't ask them if they're really good at hammering nails.

And if you hire a personal trainer, you're not going to be too interested in if they use the latest and greatest weight machines.

So why then, do software consultants often value themselves based on the tools they use? What value is it to your clients to know you have a theoretical knowledge of framework X, when framework Y is threatening its demise?

As your customer, I already know you can hammer nails. I want to know what kind of house you can build me. I want to know that, in the event nails suddenly become passé, you can deliver me a functional house using screws or bolts or glue.

More often than not, your hard skills don't matter. It's your meta-skill— your ability to learn new skills rapidly and under pressure—that is truly valuable.

Just like hard skills, meta-skills can be learned. Through conditioning, you can train your body and mind to be really good at learning. Here are some things that have worked for me.

  1. Spend an hour per day reading about the latest technologies in your discipline. Apply one of them to a side project. Ask your clients or employer if you can give a talk on one. If you think there's a new technology that could add value to your client's project, say so, and lobby to use it.

  2. Adopt a product-oriented mentality. Don't get caught in the weeds of implementation. Be sure to poke your head out to make sure what you're doing matches your product's overarching vision. Talk more and code less.

  3. Start with the solution in mind. If you're going to build a new feature, sketch it out first and ask for feedback. It's likely you're wrong in at least one of your assumptions. Better to make it wrong on a napkin than in code.

  4. Learn to distill everything in lists. Developers are communicators above all. If you are a capable analyst, you will excel no matter the toolset. Lists convey to your team and stakeholders an itemized vision of the future. They're easy to clarify and easy to change. And, they ultimately produce more value than the code that spawns from them.

  5. Don't be afraid of not doing it best way the first time. On a recent project, I was tasked with building a new user interface feature. I decided that, since React is eating the world of web interfaces, it was time we caught up with the times. My first release of the feature worked great for the user, but under the hood I neglected some of the best practices I would later learn. While we're still in the process of adopting those practices, my code is currently chugging along in production, adding value to the product. If we're to brave new frontiers, it's likely we'll end up backtracking along the way.

Technologies change, but your own meta-skill will keep you valuable for your entire life. Even if you're really good at hammers, make sure you know how to build a house.

Why I stopped drinking alcohol January 4, 2016

Disclaimer: The following is my personal account of stopping drinking. If you're a happy drinker, I don't want to alienate you. I was once a happy drinker myself. I wrote this post to help sort out my own feelings about alcohol with the hope it could inspire others. I hope it's not mistaken for preachy evangelism!

There are books about how to be a better lover. Books about how to improve your physique, how to eat healthier, how to live longer, how to become more in touch with your spirituality, how to get more organized, how to be happier.

I've read most of them.

I've read most of them, and sometimes while reading them I had a drink in my hand.

I've spent a significant amount of time on self improvement without ever seeing the elephant in the room: My use of alcohol (and cannabis, for that matter) were decaying my potential more than any of my other behaviors were.

But alcohol gives you courage. Alcohol doesn't give me courage. In the end, it makes me a coward. I feel ashamed. By morning, I feel remorse. Courage is the ability to take action in spite of fear. Alcohol doesn't make me courageous. It makes me reckless.

But surely alcohol relaxes you. But it made me tense to begin with. Drinkers aren't more relaxed than non-drinkers. According to popular culture, non-drinkers are uptight. But I've met a lot of uptight drunks. And I sure don't feel relaxed on a Saturday morning in the throes of a hangover.

But how will you socialize? The same way I always have. I'll just be sober instead. I'll go to bars with my friends. I'll order virgin cocktails. I'll drink soda water. Nothing will have changed, except I'll be in control of my actions. And I'll wake up with a smile.

You don't drink? That must be boring. No, actually. Sobriety is pretty awesome. I've had more profound life experiences in my last few weeks of sobriety than in the previous months using alcohol. When I'm not shorting my pleasure circuit, I'm forced to seek pleasure in real-life experiences. Friendship. Adventure. Life.

The alleged benefits of drinking alcohol are illusory justifications for the continued ingestion of an addictive substance.

They're the same justifications a junkie uses to get his next fix of heroin or a smoker uses to accept his purchase of another pack.

Well, no different except that we're all okay with our alcohol addictions until catastrophe strikes.

But I don't want to wait for catastrophe.

I don't want to spend the best years of my life slightly numbed. I want to feel the full breadth of my human experience. I've spent so many of those special occasions---the ones we're supposed to remember forever, the ones we're supposed to cherish---inebriated.

Alcohol impairs my judgment, costs me money, wastes my time, sabotages my health, numbs my experience, constricts my mind, and makes me ugly. It does all of these things without offering tangible benefits.

Drinking alcohol prevents me from being the best version of myself.

So I stopped.

The freelancer's guide to retirement savings accounts October 2, 2015

Do you have enough saved for retirement for your age?

When you're employed at a company, the details of retirement are largely "set-and-forget" if you want them to be. Your 401(k) deduction is made before you even get your paycheck and you can rest easy knowing your check next month will come reliably. But as freelancers, it's our responsibility to provide a fruitful retirement for ourselves.

Fortunately, there are still options for the self-employed among us who want to get a head start on saving for tomorrow.

Roth IRA

Roth IRA's are the secret sauce of retirement saving. With a Roth IRA, you can contribute up to $5,500 per year of after-tax ("take-home") money. But then, after age 59 1/2, you can make withdrawals from the account tax-free. This means that $10,000 invested in a Roth IRA will be $76,122.60 after 30 years of 7% growth, all available to you with no tax bill!

Want a great first small win on your way toward retirement savings excellence? Open a Roth IRA with Vanguard and contribute to the $5,500 limit each year.

Note that if your income exceeds $129,000 (if filing single), you are ineligible to contribute to a Roth IRA. Fortunately though, there exists a sneaky technique for converting a traditional IRA into a Roth called the Backdoor Roth IRA. Tax loopholes aren't just for corporate lobbyists anymore!

Traditional IRA

The traditional IRA is Roth's shy, modest cousin. With a traditional IRA, your tax incentives are swapped. You can contribute up to $5,500 per year, tax deductible in the year you contribute. But when you withdraw your funds after age 59 1/2, the gains will be subject to tax at your income tax rate.

The traditional IRA is a great choice if your income exceeds the $129,000 limit for a Roth IRA. It's also a good choice if you expect your retirement income to be lower than your current income. But if you're unsure and don't exceed the income limit for a Roth IRA, I'd stick with the Roth. It's likely the growth in your account will far exceed your contributions by the time you retire, so it's the more tax-advantaged choice.

Solo 401(k)

The Solo 401(k), or i401(k), is the best way to minimize your taxable income. With the i401(k), you can make employee contributions of up to $18,000 per year, plus an additional employer match of up to 25% of your employee's salary, up to a maximum of $53,000 per year. Plus, you can contribute up to 100% of your employee's salary.

Additionally, some i401(k) plans have a Roth option, meaning you can make an employee contribution of up to $18,000 after-tax dollars per year and make retirement withdrawals tax free.

Because your i401(k) contributions are distinct from your Roth IRA contributions, this means you can contribute up to $23,500 per year into accounts that grow tax free. That's huge.

The biggest caveat with an i401(k) is that you cannot plan to hire employees into your business—the plan isn't permitted in businesses with common-law employees.

When I found out about the i401(k) plan, my jaw dropped to the floor. So this is how people get rich!

Health Savings Account

Wait, what? I thought we were saving for retirement? We are, but there's a secret weapon. The Health Savings Account (HSA) is a special type of savings account available to U.S. taxpayers enrolled in a high-deductible health plan (HDHP). Like a traditional IRA or 401(k), funds contributed to an HSA are not subject to federal income tax upon deposit. Funds can be withdrawn at any time to pay for qualified medical expenses without a tax hit. HSA's can typically be invested in similar mutual funds as in an IRA.

Like it or not, we're going to have medical bills. According to Fidelity Investments, a 65-year-old couple retiring this year will need $240,000 to cover their future medical expenses. By regularly contributing to an HSA, you can take control of your retirement medical care while saving money on your IRS bill.

Note that in order to qualify for an HSA, you must have a high-deductible health plan. These plans typically don't cover routine medical expenses or preventative care. You'll want to weigh whether it makes sense to step down to an HDHP to qualify, or if you're saving enough using other retirement vehicles.

What Should You Do?

Because you're a freelancer with no employees and you want to maximize your tax deferral, I recommend using a Solo 401(k) and a Roth IRA. These accounts will grow tax-free, are relatively easy to set up, and allow contributing $23,500 in total contributions if you're filing single.

To open these accounts now, visit Vanguard:

Want to Learn More?

I've been fine-tuning my freelance business to build wealth and become financially independent, and I want to help you do the same! That's why I've been writing a book called The Freelancer's Guide to Money---a one-stop guide to making your freelance business work for your future.

From corporate structures to saving for retirement to budgeting and beyond, making your money work for you can be a complicated process. I want to show you how easy it can be to get control of your freelance business's money so you'll have enough money to retire with dignity.

Find Out More

Slack, the ultimate workday distractor August 29, 2015

Unless you're living under a rock, you've probably heard of or used Slack, the now wildly popular workplace chat application that's slowly killing IRC. It's uncommon for me to look over the shoulder of my peers and see another chat client these days. Slack's emphasis on collaboration, clarity, and fun make it the go-to choice for workplace chat. Slack attempts to replace email in the work setting by creating a realtime chat environment that gives teams an always-on channel for discussion.

Don't get me wrong: Slack is an incredible tool if you work in a fast-paced, customer-oriented environment. If you work in tech support, customer service, sales, or sysops, Slack is indispensible for staying on top of inbound alerts that help keep your business running day-to-day. But when you're a programmer, designer, writer, or other creative, it's imperative that you're granted several hours per day of uninterrupted flow.

Also make no mistake: Slack is an amazing chat application. It's the best I've ever used. It's intuitive, friendly, fun, and engaging. I love it.

But Slack represents a destructive psychological shift in the way we conduct creative work: The always-on always-available culture amplifies anxiety and destroys real productivity by putting our attention up for auction in a highly distracting and unactionable environment.

Always Available, Never In Focus

In Merlin Mann's famous Google Tech Talk about his Inbox Zero methodology for email processing, he explained how email has turned from a fun and exciting new medium of exchange into the reactive centerpiece of the modern desktop. At one time, checking your email was a once-per-day activity, something you did when you connected your 56k modem to the Internet for an hour. Now it has become an always-on communication center from which we draw our next actions and conduct our day-to-day tasks.

Not only does this always-on approach segment our attention from our most important work, but it provokes a sense of constant anxiety, wherein we believe we must respond to every message with ever-accelerating urgency. And that's exactly why I believe Slack is the ultimate productivity killer.

When there's an unspoken, implicit expectation that we'll be on Slack all day long, we begin to measure our personal productivity in terms of our response to chatter instead of in terms of the completion of our most critical tasks. We lose control of our time and what was once creative, intentional work turns into a constant stream of opinions, anecdotes, and noise.

Like Email, Slack Causes Anxiety

Studies show checking email frequently causes anxiety. By constantly feeding our brains new inputs about our responsibilities, we're effectively sending ourselves into a panic about whether or not the task we're currently attempting to complete is the most important.

Slack effectively puts this anxiety on overdrive. Sitting down to implement that new feature your investor is expecting next week? Too bad: Your teammate needs help defining requirements for another feature and sent you a private Slack message to ask you to help. With Slack, true heads-down focus and intention is a thing of the past. And you can forget losing yourself in your work: Slack will make sure you always have something more pressing (read: an opportunity for procrastination) to do.

Unlike Email, Slack Doesn't Have Threads

In Slack, you can organize your team's discussions into channels, but that's hardly a substitute for the hard lines drawn by operating within threads in email. If Slack truly replaces email, how do I reach Slack Zero? When I'm scanning Slack for any actionable information, I end up re-scanning conversations numerous times to find the discussion I'm looking for. Email and project management tools don't beget that problem. They're threaded and that's the way discussion about specific tasks and projects should be.

None of this is to say that realtime chat doesn't have a place in the workplace. But I do think using Slack in place of a more rigid communication medium is a sure recipe for losing your mind.

Solution? Check Slack Twice Per Day

That's why I'm making a commitment to checking Slack as infrequently as I check my email: Once in the mid-morning and once near the end of the day.

When we reduce the number of inputs vying for our attention during our workday, we are better equipped to focus on what we've already deemed our day's priorities. Let's turn off Slack, turn off email, and get to work.

Your best candidates demand to work remotely July 30, 2015

Tuesday morning. It's 6:32am. You yawn. You stretch and turn over on your side. No alarm woke you up. You, like most highly-productive people like waking early. You rise, stretch again, and don your bathrobe. You go into the kitchen. You press play on a podcast, leisurely cook yourself a healthy breakfast, eat, and then make coffee. It's 7:41am.

You sit at your desk and decide on your first task. You work, with no interruptions, for 1 hour and 54 minutes. It's 9:35.

Most people are still stuck in traffic, but you just clocked nearly 2 hours of completely uninterrupted work.

You take a break to stretch and make some more coffee. You check your email, because you know checking your email before you complete your most important task of the day is the best way to ensure it won't get done. You process all your email. Inbox zero. It's 10:00.

You have a brief, 5-minute meeting with your team members. You do this every morning. Once the call is over, you work again, with laser-focus, for another hour.

It's lunch time. You make a healthy salad for lunch. You spent only 28% of what it would have cost to buy a comparable lunch at a restaurant. You take your time washing the dishes.

You decide you'd like to take a walk. You take a leisurely half-hour walk around the neighborhood. You remember you need to buy some toiletries, so you stop at the grocery store.

When you return to your house, you sit for another two hours of uninterrupted work. Your superior is thrilled with your output. You are thrilled with being able to work on your terms.

It's 4:35. You turn off your computer and go spend time with your family and friends.

If you work remotely, it's likely you're familiar with the lifestyle I portrayed above. Thousands of programmers, designers, writers and other creative professionals are working remotely and enjoying the fruits of a self-driven, telecommute lifestyle. And thousands of companies are reaping the benefits of sourcing the best talent by allowing them to work on their own terms.

The Best Will Demand It

If your organization doesn't allow remote work, it's not attracting the best talent, because the best talent will demand to work remotely.

Remote work is becoming more common, and your best talent isn't having a hard time finding employment with remote-friendly employers.

The best talent has invested in creating a home workspace tailored to their personal tastes. They have created the ideal place for their productivity to flourish, and you didn't spend a dime. They've created systems that enhance their unique work style and culture.

Your best candidates are self-motivated, outcome-oriented people. Why would someone self-motivated and outcome-oriented want to spend their entire day in an office? They want to be spending their days productive when they can be, and enjoying life when they run out of steam.

They recognize the finite nature of time, which is why they strive to do excellent work for you while reserving the right to enjoy mid-day leisure.

Creative knowledge work is unlike the industrial and clerical work that came before it. There is no longer a linear correlation between hours worked and productivity. A programmer who works eight hours in a row will not produce twice as much as a programmer who works four hours in a row. I have personally found that I reach my productivity ceiling at around four hours' work in a day. Why are you requiring your team to stick around for eight hours straight?

A Broader Base of Talent

According to Payscale, the median salary for a senior web developer in San Francisco is $102,157. In Seattle, it's $83,903. That's an $18,254 difference, and they're happy to split it with you.

If you're hiring for a San Francisco company and you source your developers from the north, you could incentivize your candidates with a $9,127 salary increase over their local Seattle options, and save $9,127 per year compared to hiring someone in San Francisco. It's a win-win scenario for both you and your new hire.

With hyper-specialization becoming more common for technical workers, hiring outside your local metropolitan area also means you're able to find talent with experience that better matches your organization's needs.

When you offer a relocation package, you incur the additional risk that your new hire won't be the star player you thought they'd be. You'll have lost the airfare, the moving expenses, and the time spent interviewing and training them. When you hire remotely, your hiring costs are minimal.

Commuting is Expensive

In America, the average commute to work is 25.5 minutes. That's 51 minutes per day, or 4 hours and 15 minutes per week. That equates to a 10% pay cut: 4 hours of unpaid time for every 40 spent working. But that's not the worst of it.

The average per-mile cost of operating a sedan in America is $0.60. Assuming a 30-mile round-trip commute, that's $18 per day, or $90 per week spent commuting, in addition to the opportunity cost of the lost time!

Consider an average-salaried San Francisco senior web developer. They make $102,157 per year. Assuming they work 50 weeks per year, for 40 hours per week, that means their effective hourly rate is $51. When we apply their effective $51 hourly rate to their time spent commuting, their opportunity cost lost to commuting is 4.25 hours × $51 = $216.75 per week. That's an annual cost of $10,837.50. Add the cost of operating the car, and their effective salary dropped $15,337.50.

Commuting has turned your candidate's $102,157 salary into $86,819. That's a 15% effective pay cut. Armed with this knowledge, how many of your best and brightest candidates do you think would agree to a daily commute?

Conclusion

Remote workers enjoy a lifestyle that cannot be valued in dollars. They are high-output, self-motivated professionals who recognize the opportunity costs associated with mandatory office hours, and so they seek employment with firms that also recognize these costs. The life of a remote worker is richer and less restrictive. This richness and freedom will translate into better work for you.

Using jQuery Deferred to wait for multiple Backbone models to save July 28, 2015

Backbone's Model implementation is great for most things, but one thing I've had a hard time with is waiting for multiple models to save before proceeding. Backbone offers a success callback like this:

model.save
  success: ->
    alert("We did it!")

You could also use the sync callback like this:

model.on 'sync', ->
  alert("We did it!")
model.save()

But what about when you want to wait for multiple models to finish saving, all with their own asynchronous requests?

Don't Nest It. Chain It!

The jQuery Deferred object is a chainable utility object that can register multiple callbacks to relay the success or failure state of an asynchronous operation. Lucky for us, Backbone's model.save() method returns a jqXHR object, which implements the Deferred API. This means that instead of writing this:

model.save
  success: ->
    alert("We did it!")

We can write this:

model.save().done(-> alert("We did it!"))

That's a nice bit of syntactic sugar, but it still doesn't address our original problem: How can we wait for multiple models to save, and then fire the callback to alert the user?

Tell Me When You're All Done

jQuery.when allows us to combine multiple Deferred objects into one aggregate Deferred object, such that we can chain callbacks to be executed only when all the objects have resolved.

For sake of example, let's say we have a collection of 3 Backbone models we'd like to save:

collection = new MyCollection([{name: "Steve"}, {name: "Dave"}, {name: "Tom"}])

Remember that Backbone's model.save() returns a jqXHR object, which acts as a Deferred. So we can run:

xhrs = collection.map (model) -> model.save()

This will create an array xhrs containing the jqXHR objects for each individual save operation. To alert the user when all of them complete, we can use jQuery.when:

jQuery.when(xhrs...).done(-> alert("All of them are saved!"))

Note: The splat (...) syntax above is required to split the xhrs array into separate arguments. This had me stumped---without the splat, jQuery treats the array as a single Deferred object, which obviously doesn't execute the callbacks in the same manner as multiple jqXHR objects.

And Tell Me When One of You Failed

We can also use Deferred's fail() method to alert the user that one or more of the save operations failed:

jQuery.when(xhrs...).
  done(-> alert("We succeeded!")).
  fail(-> alert("We failed."))

Conclusion

The jQuery Deferred API is a powerful way to elegantly wait for the completion of asynchronous operations in your Backbone application. While it's tempting to resort to workarounds like using setTimeout to wait an arbitrary amount of time for operations to complete, using jQuery.when means you don't introduce race conditions into your application.

If you have any questions or if something isn't working as described above, please leave me a comment. I'll try my best to answer as soon as I can.

How to authenticate Instagram in a command line application July 23, 2015

Instagram

Instagram uses OAuth to authenticate, meaning it can be kind of a drag to use its API if you don't want to build a web application. Building the simplest interface you can build to achieve your application's goals is one of the best ways to streamline your development process. And the simplest and cheapest interface is often the command line.

But because the OAuth handshake requires a web callback to operate, it can be cumbersome to build this authentication into a command line application. Below, I'll show you how to do it with only a little bit of annoyance.

Create an Instagram API Client

First, you'll want to go ask Instagram nicely for an API Client ID so you can get access to the Instagram API. Go to their developer portal and click 'Manage Clients' to add a new one.

When asked for URL's, feel free to use non-existent domains. I use guilded.dev for mine.

In the Security tab, be sure to uncheck "Disable implicit OAuth". This will allow you to connect to the API without requiring an explicit server-side post, meaning we can hijack the access token from the callback URL:

Uncheck 'Disable implicit OAuth'

Make a Firm Handshake

So what are you to do when you can't redirect your terminal window to Instagram so you can authorize your account? A little bit of copy-pasta. Here's what we're going to do:

  1. Generate an Instagram authorization URL and ask the user to paste it into their browser.
  2. The user will authenticate their Instagram account like usual. They'll be redirected to our dummy Redirect URI.
  3. We'll prompt the user for their newly-issued access token. Because we unchecked "Disable implicit OAuth" in our Instagram client configuration, the access token will be appended to the redirect URI. We'll ask them kindly to copy and paste it into the terminal.
  4. We'll be authenticated to Instagram in the terminal!
require 'instagram'

Instagram.configure do |config|
  config.client_id = "YOUR CLIENT ID"
  config.client_secret = "YOUR CLIENT SECRET"
end

# Generate an Instagram authorization URL
puts "Visit the Instagram OAuth URL below to get started:\n"
puts "" + ::Instagram.authorize_url(
  redirect_uri: "http://guilded.dev/instagram/callback"
  response_type: 'token'
)

# Prompt the user for their newly-issued access token.
puts "Enter the access token at the end of the redirect URL.\nYou'll find it after the '#access_token=' in the URL."
access_token = gets.strip

# Create an Instagram client with the access token.
client = Instagram.client(access_token: access_token)

Now you should have an authenticated Instagram client. Use the Ruby Instagram API as usual:

for media_item in client.user_recent_media
  puts media_item.images.thumbnail.url
end

Store Your Access Token

Of course, requiring entering the access token each time we use our Instagram command line application is going to annoy our user. What if we could store the access token on the first authentication so we could use it for subsequent runs?

For this example, we'll store the access token in a file called .instagram-access-token. Depending on your application, you might want to use an existing YAML configuration file or another method.

require 'instagram'

# Configure the Instagram gem the same way we did above:
Instagram.configure do |config|
  config.client_id = settings.instagram_client_id
  config.client_secret = settings.instagram_client_secret
end

# If there's an access token saved to the file, then read it.
if File.exists?(".instagram-access-token")
  access_token = File.read(".instagram-access-token")
else
  # Otherwise, generate one
  puts "Visit the Instagram OAuth URL below to get started:\n"
  puts "" + ::Instagram.authorize_url(
    redirect_uri: "http://guilded.dev/instagram/callback"
    response_type: 'token'
  )

  # Prompt the user for their newly-issued access token.
  puts "Enter the access token at the end of the redirect URL.\nYou'll find it after the '#access_token=' in the URL."
  access_token = gets.strip

  # And save the token to the file for the next use:
  File.open(".instagram-access-token", 'w') do |file|
    file.write(access_token)
  end
end

# Create an Instagram client with the access token.
client = Instagram.client(access_token: access_token)

As you can see above, we first check to see if there's an access token saved in our .instagram-access-token file. If there is, we skip the handshake process altogether. If not, we initiate the handshake.

Note that for the purposes of simplifying the example, I've left out some error handling for invalid access tokens. You'll want to verify that the access token stored is valid and go through the handshake process again if you cannot connect.

Conclusion

Building a command line application for Instagram is fairly easy, assuming you're able to build the authentication in a way that doesn't confuse your user. If you're just building a tool for personal use, this is a great way to create real value without incurring the burden of building a full-blown web application.

If you have questions or if something is unclear, please leave a comment below and I'll do my best to answer you.