This is How I Want Social to Work

I think that solving the dual problems of privacy and noise in social networking applications are very difficult. Personally I don’t think any of the major players (Facebook, Twitter, Google+) have tackled these problems entirely successfully. I did a little thinking and if I built a social network today, here’s how I would tackle the graph.

Let’s say that I just signed up for the network. As part of the sign up process I would be asked to create Topics that I might post about. By default there would be two topics pre-populated: Personal and Work. In addition, the app would suggest that I add other topics that I might be interested and give examples such as Technology or Fashion. It would also say “hey don’t worry, you can always create topics while you post”.

So far so good. Now, whenever I share something I’m encouraged to select topics from those I have already posted about. I can also create a new topic on the fly just by typing its name. “Golly gee, this sounds an awful lot like Google’s Circles” you might be thinking if you were a 1950s era television character. Wait for it, here comes the payoff.

Now I want to connect to people on the network. When I click “Follow” I’m greeted with a dialog box that says “For which topics do you want to follow X?” and presents me with a list of all of the topics that X has posted about (or I can say “all”). For my close family members I follow all topics, for friends I follow their “Personal” topic, for coworkers I follow their “Work” topic and for everyone else I follow the topics that I think I’ll enjoy reading from them, maybe “Funny” or “Ruby” or any number of other things.

This is the best solution I’ve thought of to the “noise” problem with social networks. Right now I pretty much use Twitter for work and, well, I don’t really use Facebook much but if I did it would be for personal stuff. I don’t want to bore my friends with programming observations and I don’t want to bore my coworkers with personal observations. This system makes me certain that anyone looking at my posts has pro-actively decided that they are interested in hearing from me about that.

The final piece of this puzzle is privacy. I would also have the ability to create private topics that require my approval before someone can follow me on. When someone subscribes to “all” of my topics they can check a box to request permission for private topics as well, which I can approve or deny on an individual basis. Private topics are not explicitly listed out nor are they revealed when I post to them (in this way private topics are much like Circles).

There it is, my best attempt to describe a system that maximizes privacy control, minimizes noise, and creates as small a burden as possible. The only time that this requires “work” is that I need to tag each post I make with topics, and when I follow someone I have to decide which topics I want to follow them about.

Pros/Cons

Here are some of the advantages that I see to a system like the one described above:

  • I believe that this solves the noise problem better than any existing system. Being able to subscribe to a subset of a user’s posts allows for specialized content without alienating followers who are interested in something else.
  • Brands would be able to leverage this to their advantage as well. I could follow my favorite brands, blogs, etc. but only on the types of stories that would interest me.
  • Gets us a little closer to “one network to rule them all” instead of needing to create a dichotomy between our personal and public lives.
  • Since I’m encouraged to tag every post I make, lots of semantic data can be gathered about posts and used to make content discovery and other serendipity work on the system.

Of course, there are drawbacks as well, some surmountable some less so:

  • The biggest problem is that people have to tag their posts accurately or none of this matters. It requires more work when I share and friction there is definitely a problem.
  • What happens when people create new topics? I would imagine something like the Twitter interactions pane that would say “X posted about new topic Y, do you want to follow it?”, but this would have to be tuned to be user friendly.
  • Users may feel tempted to follow all topics just out of fear of “missing something.”

I’m putting this out there because I’m both wondering if anything like it exists and if there are huge glaring problems with it that I’m not considering. If this isn’t the right model for social, what is?


Free-to-Play Could Crash the Gaming Industry

This post is part of my Where Games Are Going series in which I talk about the future of one of my favorite industries: video gaming.

ET Didn't Help

At the same time that digital distribution is poised to level the playing field more than ever before for independent developers, another trend has the potential to cause a crash the likes of which hasn’t been seen since 1983. And it’s all Zynga’s fault.

These days you can’t throw a rock in the gaming community without hitting someone who is talking about the brave new world of Free To Play. Everyone is taking a look at the hand-over-fist cash generated by the addiction engines pumped out by Zynga (no, I won’t call them games) and wants their piece of the pie. From the expected ranks of big publishers like EA to some of gaming’s most respected brands like Blizzard and Valve, everyone is exploring “alternative monetization” for games.

But, you might say, won’t these alternative monetization strategies just lead to more people playing games and more games being made? If games are cheaper (or even free) isn’t that better for everyone? The answer is no.

Free-to-play and in-game purchase models break the incentives associated with game development. Sure, it can be done in a tactful manner and, in some cases, may even lead to a bigger audience for a great game. I haven’t played it, but I hear that League of Legends handles free vs. paid players in a very fair way. The problem is that once your money comes not from an up-front or monthly fee but from in-game purchases, you are no longer incentivized as a developer to make the game as fun as possible. Instead, you are incentivized to make players make as many in-game purchases as possible.

We don’t have to make up a worst case scenario for how this could end up, it already exists. Games like FarmVille are, quite literally, addiction engines. They are fine-tuned to draw a player in and build an obligation to continue playing and then an obligation to continue purchasing. The problem is that there isn’t really a game underneath all the addiction; it’s just a psychologically tuned profit machine.

In-game purchases might actually be more profitable in the short term. If you can convince people that they aren’t spending as much when they actually end up spending more, you’re going to make money. The problem is that in the long term people will come to realize that they are “playing” these games but not actually having, you know, fun. If the industry focuses on this model as much as I fear it is gearing up to do, the realization that games aren’t fun anymore could have sweepingly negative impact on the industry as a whole.

The video game crash of 1982 was precipitated by a glut of mediocre-to-bad titles and little information to know which ones were good and which were bad. The gaming crash of 2015 might happen after developers have stopped making games fun in the quest to make them microtransactionally profitable. Casual and hardcore gamers alike could end up feeling jaded and alienated by an industry that treats them like marks instead of players, and if that happens gaming as a whole will suffer greatly.

Personally I loathe the idea of in-game purchases. I don’t want my experience playing a game to be marred by thinking about the price of my fun. “Gee, would I have $2.99 more fun if I bought this Vorpal Sword right now?” It’s not that I’m price-sensitive, it’s that I explicitly play games to escape the pocket-conscious decision-making of the rest of my daily life and now I’m being slapped in the face with it every five minutes.

I care deeply about the gaming industry. I believe that video games helped to shape my logical thinking and problem-solving, and I know that my interest in them precipitated my interest in computers and technology as a whole which has become a passionate and fulfilling career for me. So when I talk about this problem, it’s not because I think that there is something seriously wrong with games now. I just think that many in the industry are being fooled by this mirage of a free-to-play future, and I implore these people to think twice before signing up to willfully misalign their incentive to simply make a great game.

Calling Infringement Theft is Dangerous

Note: I actually submitted this as an op-ed piece to the New York Times which is why it’s far less technically voiced than my normal work. Unfortunately looks like I’m not getting picked up there, so I’ll just have to stand on my own soap box.

One day, Terry walked into a popular record store, slid a CD into his back pocket, and left the store without paying. The same day, Ian visited his favorite file sharing website and downloaded an album (as it happens, the same one that Terry shoplifted) without purchasing it or obtaining permission from the artist. If you think that these two cases sound almost identical, then you have likely fallen prey to a spreading and dangerous misnomer that has become nearly pervasive: conflating theft and copyright infringement.

In the story above, Terry has committed theft, a criminal offense under state laws. In legal terms, theft is taking the property of someone else without consent and with the intent to permanently deprive them of the property. Ian, however, is not guilty of theft but rather copyright infringement: he has created an unlicensed copy of a copyrighted work. By downloading an album from a file sharing service he has not taken it from anywhere but rather duplicated it. While each person is entitled to his or her own opinion as to the difference in morality or ethics between the two, one thing is clear: from a legal perspective these are very different illegal actions.

Theft is a criminal offense and is punishable by a wide array of remedies including jail time. Copyright infringement, on the other hand, is a civil infraction and can incur a lawsuit but cannot be prosecuted as a criminal offense (some instances of copyright infringement do warrant criminal punishment, but not as theft). The difference between criminal and civil infractions in our legal system is great: criminal infractions must be tried with the famous burden of proof of “beyond a reasonable doubt” while civil infractions are tried in court with a burden of “a preponderance of the evidence” (that the party is more likely guilty than not). The difference in burden is attributable to the weight of punishment: one cannot be jailed for a civil infraction, only fined.

Copyrighted works such as books, movies, songs, and even software are all protected by federal law for the purpose of encouraging their creation. “Intellectual Property” is the term given to these types of works and, in the United States, we have three means of protecting intellectual property: copyrights, trademarks, and patents. Intellectual property is something that cannot be stolen because it is, by definition, intangible. You might say that someone “stole your idea” but what you really mean is that someone copied your idea. How can someone have stolen your idea if it’s still in your head? I can understand how this confusion comes about, but while it may feel like a technicality it is actually a very important distinction.

I’m not surprised when representatives of copyright holders call infringement theft; it is to their direct benefit to create a direct equivalency between intellectual property rights and real property rights. What continues to shock me is seeing this confusion trickle its way into the vocabulary of everyone from Harvard law professors to members of Congress. It is frightening to think that this misnomer is being used by the very people who are currently debating laws regarding copyright infringement with sweeping ramifications.

My plea is simply this: stop thinking that these two terms are interchangeable and using them as such. Sure, “stealing” and “theft” are shorter and sound a lot more sensationalistic and juicy when one is talking about the issue of copyright infringement. But please at least use a term like “piracy” if you want a one-word term for the behavior. It may not be any more accurate but it doesn’t share the same effect of confusing everyday people about our legal system. Until there is a law decreeing that copyright infringement is a criminal offense punishable in the same manner as theft, one thing is certain: theft and copyright infringement are NOT the same thing.

P.S. I started a Tumblr to record these misnomers, feel free to submit one if you see it.


Should we eliminate gendered pronouns?

Today I was typing up another blog post and had to use him/her as a gender neutral pronoun reference. This is something that’s always bugged me as it’s awkward to write and awkward to read. “They” is not a suitable alternative because it’s plural and therefore grammatically incorrect in a singular context.

That got me thinking: why do we have gendered pronouns at all? After reading the recent post “It’s OK to be Neither” I’m wondering if there could be a positive cultural impact from completely eliminating gendered pronouns from language. I’m not proposing what we should standardize on, but if the English language didn’t have gendered pronouns, it would:

  1. Solve the annoying he/she him/her pronoun problem.
  2. Make the language non-deterministic for those who believe that gender is a spectrum.
  3. Remove a subtle but foundational part of our language that encourages gender as a vitally important differentiator.

I’m not generally an alarmist when it comes to vocabulary. I think that words only have power when we allow them to. That being said, it would be interesting to see the landscape of our society if this change were implemented.

  • Would it make the issue of the marriage of same-sex couples seem less “different” from the norm?
  • Would workplace and friend networks be more likely to cross gender lines?
  • Would children raised without gendered pronouns be more likely not to discriminate based on gender?

I don’t have answers to any of these questions, I just think it’s an interesting topic to ponder. All of this being said, gender differences are a part of our lives and in many ways can and should be celebrated. But referential tags can be troublesome and this is one that’s literally baked into the language. Maybe it shoudn’t be…what do you think?


Where Games Are Going: Consoles as App Platforms

I’ve been an avid gamer since, well, ever. Like many developers, an interest in video games (and creating them) is what first lured me to the world of programming. While I’m not a part of the game industry I follow it closely and have greatly enjoyed discovering such online video series as All Your History Are Belong To Us and Extra Credits this year. “Where Games Are Going” posts simply represent my observations and predictions about gaming and its future. This time, we’re going to talk about the next generation of consoles.

The current generation of consoles (Xbox 360, PS3, Wii) is going to be the last generation in which physical media (discs, carts, what-have-you) are the primary way in which new games are acquired. This is a large trend that can be seen especially in Microsoft’s full downloadable games which include AAA titles from this year, not just the older/smaller titles to which downloadable games have traditionally been relegated.

The company that wins the next generation console war will be the one who most wholeheartedly adopts the App Store model, specifically meaning a simple distribution system open to any and all developers with a constant revenue share model. I believe that Microsoft is currently best positioned to make this happen: Xbox Live is still far and away the most comprehensive console gaming community, they’ve shown that they’re willing to pull in this model with Xbox Live Indie Games, and they have Windows Phone 7 and Windows App Stores either here or on the way. That’s not to say that there aren’t a few kinks left to figure out:

  1. Big Publishers Will Resist. The next generation of consoles is going to see content created by a single guy pitted directly against content created by a seasoned team of 100. Big established publishers will fight hard to keep themselves separate to avoid competition from smaller developers but, ultimately, they will lose. They’ve already had to accept this on iOS and Android devices, they will eventually accept it on consoles as well.
  2. Price Will Be A Problem. A recent post on Signal vs. Noise called the physical disc/digital content price gap the Lazy Tax, but in reality the problem is monolithic price control. Microsoft and publishers alike are going to have to radically alter the game price structure to work in the new market. Games will either have to drastically lower in price at the outset or aggressively discount after the first few months. Otherwise, there will be a big swell of frustration from the gamers who are accustomed to the used and on-sale markets for getting their games. One way to get around this (but it isn’t pretty) would be to have unique unlock codes that can be purchased for games and sold by retailers. This would allow Amazon et al to discount games more like they do currently.
  3. Non-Games Will Be Huge. The next generation of gaming consoles aren’t just going to be for games. This is already obvious with the huge push for video that Microsoft has done on the Xbox 360 but it will become even more so as the consoles from all major players will open their doors to non-game content. Even Nintendo, traditionally focused exclusively on gaming, is rumored to be jumping on the app train.
  4. Google and Apple Will Enter the Fray. The interesting side effect of consoles becoming app platforms is that they will suddenly face competition from the existing app platforms of Apple and Google. Each platform will have to work hard to differentiate itself from the pack.

I think the next generation of consoles will be very interesting and there’s a lot that remains to be seen. Perhaps even more interesting, I think the next next gen will come from disruptive game streaming services like OnLive. As actually fast connectivity gets cheaper and more available it will make a lot more sense to stream games from big gaming rigs in the sky than to outlay a pile of cash on a home console. Once this happens, game platforms will go ubiquitous, no longer tied to any one device. Expect to be able to play full Xbox 1080 games on your Windows Phone and (maybe) even your iOS or Android device.


Why I Rarely Read Books

I don’t really read books these days. I read plenty of blogs and web development related things via Google Reader, but I almost never just sit down and read something in my free time. Sometimes I’m filled with guilt about it: surely I should be reading more, enriching my life and whatnot. But then I realized that it’s not because I hate reading that I don’t do it often, it’s because reading is anti-social.

I spend a large portion of my life reading and writing text from and to a computer screen. When I’m ready to put down the computer I’m also ready to have some actual face-to-face interaction with people. Reading is just about the only form of common leisure activity that can’t be enjoyed simultaneously by more than one person (unless one is reading aloud or being read aloud to).

Video games, board games, concerts, and even to a lesser extent movies and television are all social experiences. When I’m playing video games with my family and friends we also chat about this and that in gameplay lulls. Board games have always been social and my collection continues to grow. Movies and TV aren’t quite as social but during commercial breaks (Hulu, of course, not actual television which I abandoned years ago) or afterwards there is a new shared experience to talk about. Most forms of entertainment are about creating that shared experience. Reading is not.

Reading is an isolating experience: you have to concentrate on the story and separate yourself from the rest of the world. So I still read when I’m on a plane or alone on a business trip, when I find myself both without company and uninspired to be hacking on open source or another side project. Sometimes my wife and I even read aloud to each other when we’re both really interested in a book (or manga series). But I rarely read books these days, and I’m starting to feel ok about that.


Announcing OmniAuth BrowserID

I’ve been following the progress of Mozilla’s BrowserID for some time now, and I’m a big fan. Having dove much deeper than most into the quagmire of fragmented authentication I’ve reached the same conclusion that Mozilla has: ultimately, authentication is a function that should belong to the user agent.

What is BrowserID?

BrowserID is a Single Sign-on service for the web, much like you can implement using OpenID or even Facebook or Twitter. However, BrowserID is fantastic for its simplicity: as an implementation of a simple “verified email” protocol, it is simply a way to be able to obtain the email of a user (and know that it’s verified).

For now, this works via a Javascript authentication flow on a website that Mozilla is maintaining. However, the future of this technology is that you would verify your email directly within your browser and would then be able to sign in to supported websites using your browser itself.

But, you ask, why do we want authentication in the browser? Browsers are called User Agents for a reason: they are simply tools that help connect you to the content of the internet that interests you. And a lot of that content right now requires you to manage dozens of different passwords and store sensitive login information with a third party. BrowserID doesn’t entirely solve this problem in its nascent web-based form, but once it is integrated into the browser itself BrowserID becomes a single, secure way to access content on the internet.

BrowserID + OmniAuth

I want BrowserID to succeed, and it will only succeed if people start using it. To that end, I’ve created OmniAuth BrowserID, a simple OmniAuth strategy that works with the BrowserID protocol. You can use it in your application like this:

# in Gemfile
gem 'omniauth-browserid'

# in application
use OmniAuth::Builder do
  provider :browser_id
end

That’s it! Now send your users to /auth/browser_id and they will be able to sign in using the BrowserID service. Of course you may prefer to implement your own Javascript flow. That’s fine, too, just take a look at the project README for more information about customizing the flow.

BrowserID is an important idea and whether Mozilla’s implementation is ultimately the one that gets adopted it’s high time we started moving authentication to where it belongs: in the user agent.


Implementing DRY Magic Methods in Ruby

As a new developer to Ruby you might wonder how certain methods seem to be magically available without being strictly defined. Rails’s dynamic finders (e.g. find_by_name) are one example of this kind of magic. It’s very simple to implement magic such as this in Ruby, but it’s also easy to implement things in a way that doesn’t entirely mesh with standard Ruby object expectations.

Your Friend method_missing

The way that many magic methods are implemented is by overriding method_missing. This special method in Ruby is automatically called by the interpreter whenever a method is called that cannot be found. The default behavior of method_missing is to raise a NoMethodError letting the user know that the method that was called does not exist. However, by overriding this behavior we can allow the user to call methods that aren’t strictly defined but rather programatically determined at runtime. Let’s look at a simple example:

class Nullifier
  def method_missing(*args)
    nil
  end
end

nullifier = Nullifier.new
nullifier.some_method     # => nil
nullifier.foo(:bar, :baz) # => nil

Here we simply told method_missing to immediately return nil, regardless of the method name or arguments passed. This essentially means that, for this class, any method call that is not defined on Object (the default superclass for new classes) will return nil.

While this example is certainly interesting, it doesn’t necessarily give us more use in the real world. Let’s take another example that actually does something useful. Let’s make a hash that allows us to access its keys by making method calls:

class SuperHash < Hash
  def method_missing(method_name, *args)
    if key?(method_name.to_s)
      self[method_name].to_s
    else
      super
    end
  end
end

h = SuperHash.new
h['abc'] = 'def'
h.abc            # => 'def'
h.something_else # => NoMethodError

This behavior gives us something pretty simple yet powerful: we have manipulated the foundation of the class to give us runtime methods. There’s a problem, though: using method_missing alone is only half the story.

Quack Check With respond_to?

In Ruby, you can call respond_to? with a symbol method name on any object and it should tell you whether or not that method exists on the object in question. This is part of what makes Ruby’s duck-typing work so well. So in our example, we also want to be able to know if a method is there using respond_to?. So let’s add a new override for the respond_to? method of our example above:

class SuperHash < Hash
  def respond_to?(symbol, include_private=false)
    return true if key?(symbol.to_s)
    super
  end
end

Well, that was easy enough. Now our SuperHash will return hash keys based on method_missing and even tell you if the method is there with respond_to?. But there’s still one more thing we can do to clean things up a bit: notice how we have repeated functionality in that we check key? in both methods? Now that we have a respond_to? we can use that as a guard for method_missing to make it more confident:

class SuperHash < Hash
  def method_missing(method_name, *args)
    return super unless respond_to?(method_name)
    self[method_name].to_s
  end
end

Wait, that can’t be right, can it? Can we just assume that we can call the key like that? Of course! We already know that no existing method was called if method_missing is activated. That means that if respond_to? is true but no existing method was called, there must be a key in our hash that caused respond_to? to return true. Therefore we can confidently assume that the key exists and simply return it, removing the conditional and cleaning up the method_missing substantially.

Now that you know how method_missing and respond_to? can work together to add functionality to an object at runtime, you have a powerful new tool in your metaprogramming arsenal. Enjoy it!


OmniAuth 1.0: Auth for All

Today I’m happy to announce that OmniAuth version 1.0.0 has been released into the wild. The result of more than a month of heavy development, the newest version of OmniAuth brings along with it a slate of new features, a whole new structure, and the tools to let OmniAuth be your only authentication library. The one thing that hasn’t changed is OmniAuth’s mission: to assume nothing about how your app works and what you want to do with authentication.

Breaking up the Band

OmniAuth was first written to abstract the common parts of authentication to external service providers like Twitter and Facebook. It launched as a small collection of gems that each contained many strategies (for instance, the oa-oauth gem contained Twitter and LinkedIn strategies). As OmniAuth’s popularity grew five strategies became fifty-five. Releases became fewer and further between because of the overhead of managing pull requests and issues for dozens of strategies.

No more. Starting with OmniAuth 1.0, each and every OmniAuth strategy will live in its own gem. The downside of this for end users is that you will have a few more lines to declare in your Gemfiles. The upsides, however, are numerous:

  1. There is no longer a gatekeeper to releasing an OmniAuth strategy. Just build a gem, release it, and link it from the new strategy list wiki page.
  2. Individual strategies are free to make releases as often as they’d like. Users don’t have to wait for a massive OmniAuth patch or minor release to pick up fixes for changing APIs or other improvements.
  3. With a lean, focused core OmniAuth itself will be able to release more frequently and adapt itself to the needs of strategy authors.

As a final note about structural gem changes, OmniAuth 1.0 marks the beginning of strict semantic versioning for the project. For end users, this doesn’t mean much. For strategy authors, that means that you can safely declare your dependency on ~> 1.0.

Identity for OmniAuth

As I began using OmniAuth in my day-to-day coding, I began to crave the flexibility of OmniAuth in even traditional authentication scenarios. I wanted a way to leverage the same unassuming, simple authentication structure even when my users logged in via username and password. Today, I’m happy to announce the first official release of omniauth-identity, an OmniAuth strategy that bridges the gap between traditional auth and OmniAuth.

With omniauth-identity you can quickly and easily set up internal identity management for your app that behaves exactly like other OmniAuth strategies. The library is simple but its implications are powerful: you can now treat internal and external authentication exactly the same in your application.

OmniAuth now ships with a Developer strategy that is essentially “fake authentication” you can use as a placeholder until you determine your app’s real authentication strategies. Combined with the potential of Identity, authentication no longer has to be that annoying “first thing” you have to do before you can get down to the real business of building your app. Just drop in OmniAuth, use the Developer strategy, and implement other strategies down the road when it works for the timeline of your app. This is how I’ll be building all my apps from now on, and since OmniAuth is just Rack middleware even Sinatra and other non-Rails apps can use the same techniques.

For more information on how to use omniauth-identity, see the README on GitHub.

Strategy Builders: Better Docs, Better Tools

For the 1.0 release in addition to all of the new features and structure I also tried to significantly improve the documentation for the project, especially for those who are interested in building a strategy. You can see the results of those efforts on the OmniAuth wiki which is the official repository of all documentation for OmniAuth.

Along with better documentation for developers OmniAuth 1.0 also brings along a more declarative DSL for building strategies. The new strategy API gives developers clear ways to implement consistent functionality and makes everything cleaner across the board. For more information on the tools available for strategy developers, take a look at the Strategy Contribution Guide.

App Developers: Consistency, Dynamic Strategies

While many of the improvements in OmniAuth are structural and made for strategy developers, there’s also some great stuff available for everyday users of OmniAuth! Here’s some highlights of new features that work across all strategies:

Auth Hash. Some small tweaks have been made to the omniauth.auth hash that is returned after authentication completes. For one, you can now access keys using method accessors (e.g. env['omniauth.auth'].info.name. The user_info key has also been renamed simply to info. The schema can be considered a stable part of the public API and any breaking changes will trigger a major version release (you can rely on OmniAuth 1.9 to support the same schema as 1.0).

Options Everywhere. As of OmniAuth 1.0, strategy authors are encouraged to make all strategy configuration happen through the options hash that is passed in on initialization. You will still have strategies that have additional arguments (such as consumer keys and secrets) for convenience, but even those can be configured instead by passing in a single options hash. This means that every configurable aspect of the strategy is handled at runtime, which brings us to the next improvement.

Better Dynamic Strategies. OmniAuth 1.0 makes it easy to dynamically alter strategies for each request using the new, universally available setup phase. Simply set the :setup option to a Rack endpoint and you can modify the strategy or anything else about the environment before passing it along to OmniAuth for normal operation.

Skip Info. Some strategies will be able to determine the UID without making additional API calls. You can pass true, false, or a lambda that takes a UID and returns true or false as to whether additional info is required. This gives you the ability to make fewer API calls for cases where you already have a user in your system, for instance.

Custom Forms. If you are utilizing an OmniAuth strategy that displays the standard OmniAuth form, you can now pass in :form => (true || false || lambda) to the strategy to instead render a custom form that conforms better to your application. This replaces the previous poorly conceived method of requiring /auth/:provider to return a 404 in order for OmniAuth to trigger.

Calling All Companies

Now that each strategy for OmniAuth is its own gem, I’m putting a public call out to any and all companies with APIs, but especially companies that are already on a Ruby stack. I would like to get companies on board for maintaining their own “official” OmniAuth strategies. This gives developers using your API the simplest possible means of authenticating to your service and will only help you get more developer traction and experimentation.

I’m also happy to announce that our first “official” strategy maintainers are none other than GitHub! You can say hello to the official GitHub OmniAuth strategy and be sure that any changes to the GitHub API will be safely transitioned into the gem immediately. My hope is that going forward many more companies will join the official strategy ranks. If you’re interested in maintaining an official strategy, you don’t need my permission but I’d love to hear about it so shoot me a message on GitHub.

Where’s That Strategy?

Because of the structural changes to OmniAuth not all existing strategies are available at launch. I fully expect that in the coming weeks the strategy count will regain lost ground and even surpass the count as of the last 0.x release, but if your favorite strategy is missing from the official list here’s what you can do about it:

  1. Find the source code for your strategy in the 0-3-stable branch
  2. Clone omniauth-contrib and add the strategy there
  3. Follow the strategy adaption guide to update the strategy for 1.0
  4. Submit a pull request!

The omniauth-contrib repository is a temporary repository for strategies that have been written but aren’t robust and supported enough to have their own gem yet. This repository is not going to be maintained as an actual RubyGem and the strategies contained inside are meant to eventually be adopted by developers to become their own gems.

One More Thing

One last thing that I wanted to do for 1.0 is create a kind of living example that the community could update to have a simple example of as many strategies as possible. You can now visit omniauth.org and try out a number of authentication strategies that OmniAuth has to offer. The code is all open so you can see how simple it is to add and use OmniAuth in your applications today!

Welcome to 1.0

OmniAuth 1.0 marks an important milestone for the project and I’m looking forward to a new, leaner trajectory that lets us make changes more nimbly (and keeps the outstanding issue count low to zero). While the changes for 1.0 were mostly written by me, OmniAuth has been an outstanding community effort and it couldn’t have gotten to where it is today without the efforts of @sferik and countless other contributors. I hope you enjoy the new release and look forward to hearing your feedback!


Hire a Guard for Your Project

Of all of the new tools that I’ve picked up using for development in the past six months, there is one that has come to stand above the others for its nearly universal utility. That tool is Guard.

Guard is a RubyGem but don’t let that fool you into thinking it’s only useful for Ruby projects. Guard is essentially an autotest for everything. It provides a general purpose set of tools for watching when files are changed in your project and taking action based on it. You can use it to do just about anything, but common uses will include:

  • Re-running automated tests after a file changes.
  • Automatically compiling scripts or assets for a project (e.g. minification).
  • Installing new dependencies that may be added to the project.

With a little creativity and a slight bit of Ruby coding, though, you can make your entire project’s workflow run smoother and faster. It’s like having a telepathic robot buddy who just goes around doing whatever you were about to do next without having to be told (except the first time).

Getting Started With Guard

Guard requires a basic Ruby setup. Once you have Ruby and RubyGems installed, simply run:

gem install guard

This will get you started. If you want to make it easier for others to run your guards as well, you should also install Bundler to encapsulate the different guard gems you’ll be using:

gem install bundler

Once you have these installed, in the root of your project run:

guard init

This will initialize a Guardfile in the project root that will be telling Guard what to do going forward. From here, you will want to install some of the Guard extension gems that let you quickly create automation for your project. Some of my favorites:

  • guard-rspec: Automatically run RSpec tests based on easy-to-customize patterns. I use this on almost every Ruby project these days.
  • guard-coffeescript: Compile Coffeescript into Javascript lickety-split. Even though Coffeescript has its own automatic build command with the -w option, I prefer Guard because it lets you define the configuration once and, in addition, run a single process for all of your project’s automation.
  • guard-process: This is the guard for anything they haven’t made a guard for yet. Using this you can quickly and easily run shell commands as soon as files change, giving you the ability to do almost anything.
  • guard-sass: Never write vanilla CSS again. Using Guard SASS you can automatically compile SASS giving you the full power of mixins, variables, and more for all your styles.

There’s a full list of guards that include all kinds of magic (there’s even guard-livereload that can automatically refresh your browser whenever you make a change to a project), and it’s dead simple to create new Guard libraries if what you want isn’t available (or you can just use guard-process).

Standing Guard

For any of the Guard gems you install, you can add them to your Guardfile by running:

guard init guardname

Where guardname might be rspec or coffeescript, etc. That will fill your Guardfile with a basic implementation of the given guard and is usually enough for you to tweak the settings to your liking without further documentation.

There’s a great example of using Guard for a big Rails project, but I’m not just using it for Ruby. I’ve used Guard on jQuery plugins, Node.js projects, even static websites that I’ve been building (more on that a little later).

To make it easier for others to jump into your project with Guard, it also helps to use Bundler to maintain a Gemfile that points to the various guards you’re using for the specific project. Just run bundle init to get Bundler up and running then edit the file to look something like this:

source 'http://rubygems.org'

gem 'guard'
gem 'guard-coffeescript'
gem 'guard-process'

Then run bundle install. Once your gems are installed and you’ve set up your Guardfile, just run:

bundle exec guard

Guard will start up right away and your project now has some smooth automation action. Guard will even reload itself if you modify the Guardfile, so feel free to tweak as you go!

Guard in the Real World

I’m going to post just a couple examples of Guardfiles I’ve been using in my projects recently to give you an idea of its versatility.

Guarding a jQuery Plugin

Here’s the Guardfile for Sketch.js, a jQuery plugin that I just released:

# Automatically build the source Coffeescript into the lib directory
guard 'coffeescript', :input => 'src', :output => 'lib', :bare => true
# Also automatically build the test Coffeescripts
guard 'coffeescript', :input => 'test', :output => 'test', :bare => true

# Run Docco 
guard 'process', :name => 'Docco', :command => 'docco src/sketch.coffee' do
  watch %r{src/.+\.coffee}
end

# Copy the newly created lib file for minification.
guard 'process', :name => 'Copy to min', :command => 'cp lib/sketch.js lib/sketch.min.js' do
  watch %r{lib/sketch.js}
end

# Use uglify.js to minify the Javascript for maximum smallness
guard 'uglify', :destination_file => "lib/sketch.min.js" do
  watch (%r{lib/sketch.min.js})
end

This enabled my workflow to be instantaneous: I could immediately look at my work whether it was in my examples, my tests, or my documentation. Everything was immediately built and I never had to slow myself down with run and refresh cycles.

Guarding a Node.js Project

I’ve probably only scratched the surface here, but a simple Node.js project that I’m currently working on has this for a Guardfile:

guard 'coffeescript', :input => 'src', :output => '.', :bare => true

guard 'process', :name => 'NPM', :command => 'npm install' do
  watch %r{package.json}
end

Notice that using guard-process I’m automatically installing new dependencies that may arise when the package.json file is altered.

Guarding a Static Website

I’ve come to really appreciate both Coffeescript and SASS as worthwhile abstractions, so even if I’m building something that’s vanilla HTML I might have a Guardfile like this:

guard 'sass', :input => 'sass', :output => 'css'
guard 'coffeescript', :input => 'coffeescripts', :output => 'javascripts'

These are all basic examples, but that (to me) is the point: Guard is so simple to use and basic that you can drop it in every project you build. I’ve yet to run into something that I don’t want to use Guard on.

Tip of the Iceberg

I’ve been expanding my usage of Guard into, well, everything that I’m working on. Thus far it’s included Ruby, Javascript, and static HTML projects, but if I move on to other things Guard will be coming with me. For instance, I’d love to build a Guard to automatically recompile and run an Android application whenever the XML views change. The possibilities are limitless.

If you’re not using Guard, give it a try on one of your current projects. I think you’ll quickly find immense satisfaction in being able to simply cd into the project directory, run guard, and know that you are completely ready to roll. I’d like to see a Guardfile in every open source project I fork, every client project I clone…Guard is so useful that I simply want to be using it all the time. And that is the mark of a great tool.