ChatSnapper - Alpha

Here’s a quick idea I threw together after posting my thoughts on ChatRoulette and ChatRouletiquette. No Sparkle support, no image upload support, and no preferences – yet.

What is ChatSnapper?

ChatSnapper lets you view ChatRoulette in a dedicated window and use the Apple+S command (aka, “Save”) to save a screenshot to your computer. It will save to your ~/Desktop in the most coarse fashion you can imagine.

Next up: image upload (waiting on a YFrog API key), tweeting of links, save preferences, etc. Also, an icon and Sparkle support.

Download

Get the alpha/preview/whatever here: ChatSnapper-alpha.zip

No warranties, people. Troll at your own discretion and sue yourself if something goes wrong. This is the sum total of about 2 hours of work (while watching Olympic snowboarding), so ignore the rough edges.

- February 17, 2010
Read more about:

ChatRoulette, Elevators, and Panopticons

My wife and I – and millions of others, I’m sure – are continually annoyed by folks who walk up to elevators and press buttons already lit.

Though not a new phenomenon, we think we have a solution.

If pressing a lit elevator button were to cancel the call and simply send the machine to the nearest floor in the current direction, there would be a penalty to pressing it more than once.

The interesting thing about this idea is that it need not be universal. Instead, elevator designers could follow the lead of Jeremy Bentham and create a panopticon-style system in which some small portion of elevators operate this way. It only takes the fear of looking like an idiot to regulate behavior (most of the time).

ChatRoulette Weirdos

As ChatRoulette takes off, it’s becoming plagued by pervs flashing their junk or otherwise being slimy. It’s certainly expected, as the anonymity provided by the web brings out that side of people. It’s just a fact of life on the Internet: if there is an opportunity for a guy to flash his weiner anonymously, he will.

And that’s fine. It’s the way of the world. It’s the way of the web.

But so, my friends, is community moderation.

Enter ChatSnapper

Let’s try an experiment.

  1. Follow @ChatSnapper on Twitter.
  2. DM or @reply to @ChatSnapper with a link to a screenshot from ChatRoulette (or other online chats) showing offensive (or just weird) behavior.
  3. Check posted links and help shine a light on the offenders.

Let’s see if the existence of a rogues’ gallery has any effect on the actions of folks.

If this works, I’ll start calling elevator companies.

ADDENDUM

Alex Bisceglie alerted me to a similar effort: ChatRoulette Cock Map. It includes an app that can track the IP of offenders as well.

The very moment that Alex sent that, I was working on a WebKit browser with screencap and yfrog upload. For now, grab a build at: ChatSnapper - Alpha.

- February 17, 2010
Read more about:

Cartilage: A Monk Skeleton for DataMapper

I created a skeleton for MonkRb that leverages DataMapper and, of course, Sinatra. Check it out: Cartilage. Add it to your Monk set up with the monk command.

monk add cartilage git://github.com/tobyjoe/cartilage.git
Once it’s added, create a new project with the monk init command.
monk init --skeleton=cartilage myapp
Once that is done, freeze all the dependencies.
dep vendor --all
Easy as pie, right?

Contributions

I want to add optional memcached support to both Cartilage and Lazybones. If you see anything wonky, fork it and let me know, or just leave a comment or file an issue at the GitHub issue tracker. Cartilage is based on the original skeleton that ships with Monk, by the way.

- August 28, 2009
Read more about:

Lazybones: A Monk Skeleton for CouchDB and Sinatra

I created a skeleton for MonkRb that leverages CouchDB and Sinatra. You can find the project over at GitHub. Check it out: Lazybones. Add it to your Monk set up with the monk command.

monk add lazybones git://github.com/tobyjoe/lazybones.git
Once it’s added, create a new project with the monk init command.
monk init --skeleton=lazybones myapp
Once that is done, freeze all the dependencies.
dep vendor --all
Easy as pie, right?

Contributions

I am working on skeletons for Postgres and MySQL as well, and adding optional memcached support to all of them. If you see anything wonky, fork it and let me know, or just leave a comment or file an issue at the GitHub issue tracker. It’s based on the original skeleton that ships with Monk, by the way.

- August 27, 2009
Read more about:

Don’t Stop Supporting IE6

Planning to drop support for IE 6? Instead, redefine “support” and stay positive.

Yes, creating cross-browser experiences can be painful when support for Internet Explorer 6 (IE6) is required. There are dozens of hacks to get around certain issues, and it is possible to design experiences that are functionally identical on IE6 and more modern browsers. It may mean designers don’t have carte blanche, but that should be fine if their companies or clients mandate full IE6 support. Any good experience designer can work within constraints and still kick ass.

Still, a lot of folks are lobbying their companies, clients, and partners to drop support for IE 6.

My issue is how they’re doing it. The more dickish folks are throwing up an insulting roadblock, patronizing IE 6 users.

A more practical approach is to encourage users to upgrade with prominent, consistent notices. This angle isn’t terrible, but still alienates users and disrupts the experience for those users almost as much as a modified or “broken” IE6 experience. It’s just not friendly, or consistent with the brand message that usually mandates an identical UI across target browsers.

Another Option: Boring but Practical

My suggestion is to take this to the contracts. Redefine the word “support” as it applies to user agents (like browsers). Look at the cost/benefit of all types of support for all types of user agents. This should be a part of your business modeling.

Instead of refusing content to IE6 users or breaking brand guidelines by disrupting their experience with a patronizing notice, why not relegate them into a tier of Content-Level Support as opposed to Design Support?

Good sites already do this with a stylesheet for print: we don’t penalize printers for their lack of a good box model. The same is true of screen readers and most RSS readers. Maybe you can think of IE6 as a perfectly viable user agent for consuming content, but cost prohibitive for rendering top-tier experience design. Serve your print styles to IE6 if you don’t want to offer design support. Or serve a basic white-on-black stylesheet. Or no stylesheet. Pretend IE6 is the Googlebot or JAWS or any other non-graphical user agent. Just don’t punish people or talk down to them.

Channel Your Frustration Properly

You don’t have to be a dick to your less-endowed users. Shift them, officially, to a tier you, your clients, your company, and your partners agree upon and move on. Just make sure you’ve built an economic model that includes the IE6 users and estimates the cost of all possible decisions. Look at the realities of IE6 users of Digg to understand the complexities facing the people your cocky designers and lazy developers want to patronize or abandon.

Justify relegating IE6 with real numbers or choose to give it design support and force your designers to work within the constraints. They do get paid to work, after all. If they can’t create great experience design that doesn’t fuck over the people coding those experiences, fire them. Hire designers who understand browsers.

No matter what you do, keep your users’ needs first. They’re the ones you can’t replace.

A Great Resource

A few months back, I started up a GitHub project to create a baseline CSS file for all legacy browsers. Around the time I got contributions from folks at work, I found out about similar (but completed) projects out in the wild. One such project can be found here: http://code.google.com/p/universal-ie6-css/.

- August 06, 2009
Read more about:

Social Media = Advertising Honeypot

Brands are obsessed with “going where the conversation is happening” or “going where users live” these days. Ad rags give advice for using Twitter to clueless marketing types. Every ad campaign has a checklist of touch points on the “social” web. Every RFP demands an itemized list of social networks that will be a part of the campaign. Twitter is the new Flash intro.

Generally, the presence of brands and their representatives on social sites is well-tolerated. Everyone is used to the fact that brands are jumping in. We consumers have large, high-res displays and we’re great at building selective blindness. When brands participate in social media, though, we don’t necessarily need that blindness. They’re automatically invisible unless we want to see them.

The Honeypot

A honeypot is an attractive trap used to embargo a threat. In information security, a dummy server might be placed on the periphery of a network and left somewhat hackable. The dumber crooks break into the honeypot, thinking they’ve silently compromised a network, only to be kept at arm’s length and watched. A thriving, sensitive network might exist right behind the honeypot, but the attacker never knows. He’s satisfied with himself for breaking in and stealing (what he thinks are) the keys to the castle.

On social sites, we only engage with brands if and when we want to. We don’t bother following @zappos if we don’t want to interact with Zappos. The model keeps the power dynamic shifted the way it should be: in the favor of the consumer.

In a way, a brand presence on Twitter is the antithesis of display advertising. Rather than covering every visible surface in a shotgun effort to sneak into the minds of consumers, social media advertising is more passive.

Twitter and Facebook are honeypots for brands, keeping consumers protected from the annoying noise we see everywhere else. We reach in and pull them out when we want, but otherwise keep them at bay.

Twitter is better at this role than Facebook because Twitter lacks display ads. I think that fact alone makes us love Twitter, where we simply tolerate Facebook.

An Olive Branch

So, to brands, I say, welcome. Don’t screw it up, and don’t speak unless you’re spoken to. You’re not “going where the conversation is happening” – you’re going where people are, and letting them talk to you if, when, and how they prefer. Play by the rules and you will, over time, build a community. You’ll earn a voice. Just don’t be insulted if we tune in and out at will. It’s better for all involved.

An Example

Ok, so R/GA is about to bring Taco Bell all up in our grills on Facebook and Twitter. God save us from the chalupa and volcano nachos.

Luckily, I can opt out by not opting in. We all can.

It feels good, doesn’t it?

- August 05, 2009

The Emperor’s New API

Note: this is being cross-posted, with additional content, from the Adobe Experience Design site, Inspire.

Strategists everywhere are pushing companies to add APIs to their online properties. Job postings for web developers and architects invariably require experience working with and developing APIs. It comes up in sales meetings, pitches, and casual conversations with industry folks all the time. I’m often left wondering if the term “API” has lost its real meaning and become sort of a stand-in for a handful of fuzzy concepts.

REST APIs are Buzzworthy

In the API chatter, there’s a huge focus on RESTful APIs. Everyone wants a RESTful API. Web developers love REST architectures because the fixed semantics and stateless mapping of resources to URIs lowers the barrier to entry for integration tasks. Devs no longer have to struggle to understand proprietary architectural touches. No WSDL files need to be parsed. No expensive, scale-resistant state-managing caches need to be added. The URI we use in the browser is the same URI our apps use to read JSON or XML, etc. It’s a glorious thing, REST. I absolutely love the style, and preach the benefits to clients whenever possible.

Another thing I peach, when I can, sounds scandalous at first. That message: If you’re adding a REST API to your site, you’re probably doing something wrong. Maybe.

REST APIs are Everywhere. Right?

All the big sites are exposing REST APIs. Twitter has on. Flickr has one. Netflix. Microsoft SharePoint. Everyone, man. Everyone.

But how many are as RESTful as they could be?

If you see the value in a REST API, the last thing you want to do is create something separate from your “main” site or service. Your site is your “API” if you’re being RESTful. If you force a separation or bolt on a separate chunk of URIs meant for API clients you’re probably wasting resources and muddying your domain.

With REST, you should have a distinct, stateless URI for each conceptual resource you provide and should respond to the appropriate HTTP verbs (most commonly, GET, PUT, POST, DELETE, HEAD, TRACE, and OPTIONS).

For example, if you have the concept of a user profile for someone named “TobyJoe” you should have a single URI that represents that profile and that URI should serve any supported format a client application requests. It doesn’t matter what the URI looks like, but there should only be one way of accessing that conceptual resource. You can serve up XML, JSON, HTML, plain text, SVG, or any combination of formats you want. HTTP and the REST style already accommodate for this using certain HTTP request headers. This problem has been solved since the Web existed (basically). And yet, we see a lot of big sites offering two distinct sets of URIs: one for their “site” traffic and one for their “API” traffic.

Really, it shouldn’t matter if someone is requesting the resource at a URI from Safari, Tweetie, cURL, a Flash RIA, or any other HTTP client. The REST style can cover all the content switching and access management you need and you can have a single set of URIs, a single set of semantics, a single engineering team, and a single set of resources to support. The user experience for your third-party development partners will be improved as well.

Twitter: An Easy Example

So why are there two URIs for my Twitter status feed? One for the Twitter-branded HTML (with great microformat support!) at http://twitter.com/tobyjoe and one for XML at http://twitter.com/statuses/user_timeline/tobyjoe.xml?

It’s the same data, in different formats. It’s the same concept: status messages for tobyjoe. Most of the formats Twitter supports are available at the http://twitter.com/statuses/user_timeline/tobyjoe.{EXTENSION} address. Why not the HTML version with the sweet microformats?

Note: I’m sure Twitter has many reasons for this separation. Legacy clients, their ever-changing architecture and unprecedented growth, organizational investment in this style. They have an amazing team over there. I’m only using Twitter as an example because so many developers are familiar with their API.

Still, as both a user and client developer, I’d prefer to see a single URI (or at least one URI template) for each conceptual resource rather than one URI for “people” and one URI template for “machines”.

It’s Not Always That Easy

I know that there are lots of hurdles with development around live products. I don’t discount the operational challenges. I don’t necessarily chastise folks who stray from REST. I would love to see the concept of the RESTful API default to a slightly different meaning that what I see on the web today. Instead of saying, “We are going to add a REST API to our site!” I’d love to see companies say, “We are expanding the choice of representation formats and verbs for some of our URLs!” Not as sexy sounding, but way sexier.

- July 09, 2009
Read more about:

SproutCore Article on O’Reilly InsideRIA Blog

I’m now blogging for InsideRIA. My first article is on SproutCore.

- August 13, 2008
Read more about:

DataMapper/Merb Ambiguous SQLite Error

If you get an error such as:

near ")": syntax error

Check to see if you have any models declaring themselves as DataMapper::Resource but WITHOUT any property declarations.

No meaningful error is reported for this case at the moment (with HEAD as of last night) so it’s a weird one to debug – especially if you generate a bunch of model classes ahead of defining their behavior.

- July 27, 2008
Read more about:

Twitter-Free Fridays

I complied with corporate mandate and wrote a post about Twitter-Free Fridays over on The Barbarian Group blog.

I understand the irony of complaining impotently about an impotent complainer, naturally. Hey, that’s what blogs are for, right?

- July 18, 2008
Read more about: