In Depth Tutorial on Writing a Slackbot

(This is a repost of an article I wrote on Monsoon’s blog prior to Capital One acquiring us.)

At Monsoon (my employer), we are avid users of Slack. It’s a great collaboration tool in addition to adding a new social dimension to the office. We just crossed 500k messages sent over the platform and we’ve only been on it for a few months!

We recently held a 4-hour slackathon at Monsoon where people were tasked with writing the most useful Slack bot they could think up. The winner was a secret polling script that we use to vote on controversial topics such as what to name our teams or who the coolest person in the office is. We chose to do our event using Hubot, a popular open source bot framework written by Github. Half of the participants were mobile developers, so JavaScript, the hubot scripting language, was foreign to them. We spent a few minutes prior to the event training everybody on how to write scripts to ensure an even playing field.

I’d like to share our Slack tutorial with the rest of the community.

Setting it up takes 5 minutes

To get started with the tutorial, you’ll need to setup your machine by installing Hubot. The most important step is the first two: clone the repo and then run:

$ npm install

Once you’ve done that, you’re ready to write scripts! In the scripts folder you’ll find a file called slackbot-examples.coffee. This example script is a more feature-rich set of examples than the default that comes with Hubot. We’ll go over these examples in greater detail below.

The first thing to notice is that this is a “coffee” file. CoffeeScript is a language that compiles into JavaScript. It is popular with some communities due to its terseness compared to JavaScript. If you don’t like it, you’re welcome to write scripts in JavaScript by naming your file .js instead of .coffee.

Talking to the Bot – robot.respond

In the next step, we start working with a bot.  All bot behaviors start with a listener. The first one we’ll review listens for messages directed at the bot.

When you mention the bot directly in a room via @botname, followed by the command, the bot will execute the above block of code. In this case, it will look for the text “@botname sleep it off.” This behavior will also trigger if you privately message the bot with the text “sleep it off.”

Either of these will trigger the bot to run the command msg.send ‘zzz…’

Making the Bot Say Stuff – msg.send

Now that the bot is listening for messages directed at it, let’s see if we can get it to talk back.  The msg.send command tells the bot to send out a message to the current chat room (that told it to “sleep it off”). In this case, the bot will say, “zzz…” publicly. msg.send always replies in the same channel it detects the original message.

It Sees Everything – robot.hear

We’ve already programmed a bot to respond to messages directed at it, but you can program a bot to listen to conversation anywhere in the office, and respond to a specific word or phrase.  The second type of listener is robot.hear, a blanket listener that reacts to a phrase regardless of who it is directed at.

In this example, we are using the regular expression looking for the word (and not just a phrase containing) “up.” If anybody says “up,” this block will trigger. It will also trigger if you direct “up” at the bot; both of these would trigger the behavior:

Michi: up
Michi: @botname up

It Can Remember – robot.brain

Bots can also store information for retrieval later.  In the “up” example above, the robot initializes and/or increments a value which we save as everything_uppity_count. It does nothing more. In this case, a user can say, “up” all they want and nothing will seemingly happen while the counter increases. This is done through the “brain,” which is a simple key-value store.

Note that the “brain” uses Redis to store its contents. This way, if the bot restarts, the data is preserved. If Redis is not running, the bot will still function, but all data is lost next time the bot restarts.

In the second example of robot.hear, the bot retrieves the current value of everything_uppity_count and displays it via msg.send. As a reminder, this means the robot would just reply in the chat room that it heard the “are we up?” statement.

Calling People Out – msg.reply

Bots can add tailored prefixes to their responses. You can use the command msg.reply for this. msg.reply probably does *not* do what you think it does. Rather, it acts similarly to msg.send except that it prefixes whoever authored the original message it is replying to.

In the above example, the script will simply reply to the original sender as illustrated in the following theoretical exchange:

Michi: What’s up!
Bot: @Michi What’s up!

Note that the reply is in the channel where you sent the original message. If this was a private chat room between you and the bot, the reply would have appeared there.

Replying to Private Messages – Advanced msg.send

Handling private messages is a little more tricky. This is because Hubot doesn’t treat private messages differently from any other types of message. Instead, you have to examine the room that the message is sent in.

In order to reply to a private message, you need to check if the room shares the name with the bot. If the channel names are the same, it is implied that the channel is a private channel. We’ve provided the helper methods to accomplish this:

Starting New Private Conversations – robot.messageRoom

Sending unsolicited private messages is more straightforward. Just remember that private messages are just another room named after a user. To accomplish this, simply tell the bot to message a room:

Notice that an error can be thrown if the channel is invalid. In that case, it’s a good idea to catch the error so that the bot does not crash.

More Examples!

The example script file also includes an example of how to run a web service in the bot to listen for external data sources (such as a github webhook) and how to trigger/watch custom events. Take a look – and when you’ve finished, hopefully you’ll have as much fun designing bots and expanding your office interactions and conversations as we have had here at Monsoon!

The Most Interesting Fact About the Apple Watch

Regarding the pricing… did you notice it too?

The low-end price is $349, but the high-end price starts at…? Not $9,000. Not $9,995. Not $9,999.

$10,000.

They rounded up the price! Even luxury brands like BMW round their prices down.

What is the last mass-market product you can recall that was priced like that? This is a very interesting marketing move since people will now “round up” the value of an Apple Watch.

Avoiding the Mentality of Hiring “Rock Stars”

There’s this sub-culture in startup-land where everything revolves around hiring and retaining “rock star” engineers. And I think it’s mortifying. Not the idea itself, but the implications.

I have heard it over and over from people I respect. But there’s a subtle insinuation that the blame of poor execution rests on whether or not somebody is a “rock star.”

Let’s flip the focus around: what is the difference between a good and bad manager? It’s simple:

  1. Good managers make everybody better. Bad managers don’t help anybody, but hopefully don’t make anybody perform worse.
  2. Blaming somebody for not being a “rock star” is an easy way to shift the blame from yourself.
  3. If managing “rock stars” and firing “non-rock stars” is what management boiled down to, managers wouldn’t be needed.

Hiring a Kobe Bryant for your basketball team is a good idea. But it’s preposterous to blame a losing record on the lack of a 5-man Kobe team.

History is full of leaders pulling off great feats with an unknown team of rookies. Be that leader. Elevate the team. The role of a manager is to help people produce their best work — “rock stars” or not. And, if anything, great leaders forge the rock stars everybody ends up talking about.

PSA: Stop Releasing Hobby Bitcoin (or similar) Projects for Your Own Good

You’re in serious legal jeopardy if you release a virtual currency project into the wild, and not because the currencies themselves are legally murky. Rather, because you are liable for any wrong-doings that might arise from the use of your product or service.

Corporations exist to shield their owners from legal liability. If you pay money to a company and then that company goes bankrupt before giving you your money’s worth, the owners and employees (unless they’re doing criminal activity on purpose) are not personally liable for your loss. On the same principle, if a software developer at Visa makes a mistake and Visa gets hacked, the software developer isn’t personally sued by the shareholders (s/he may be fired, though). The banks, merchants, or consumers impacted might sue Visa, but none of the employees are having their homes repossessed.

Now look at your project. Are you a high school student with a coin-bot that nearly got hacked? Maybe a student developer who made a hobby wallet that was emptied? Or maybe another hobby project stored on a $5/mo shared hosting service? Count your blessings you weren’t sued or prosecuted. If you release something *personally* and your negligence (or bad luck) makes you lose your user’s money, NOTHING is shielding you from them or the law. You are 100% fully legally liable for what happened. It doesn’t matter that it was a bug or that it was “just a hobby.” If somebody put $10k in your online wallet project and you lost it, you’re on the hook.

So far, it looks like cases like these are largely being blamed on the community of users trusting the services. That will eventually change. All it takes is one angry user who lost grandma’s retirement funds to turn a person’s life upside down.

I think it’s great that there is payment innovation happening right now. And I really support developers doing cool side projects. But before publishing projects that move *real money* around on *your personal servers*, think about whether or not it makes sense that you first setup basic legal protections for yourself.

Format Date into yyyy-mm-dd hh:ii:ss Format in JavaScript

This is a recurring thing I have to deal with. Here’s the code:

get_time = function() {
  var date_part, local_time, now, time_part;
  local_time = new Date();
  now = new Date(local_time.getTime() + (local_time.getTimezoneOffset() * 60000));
  date_part = "" + (this.zero_pad(now.getFullYear(), 2)) + "-" + (this.zero_pad(now.getMonth() + 1, 2)) + "-" + (this.zero_pad(now.getDate(), 2));
  time_part = "" + (this.zero_pad(now.getHours(), 2)) + ":" + (this.zero_pad(now.getMinutes(), 2)) + ":" + (this.zero_pad(now.getSeconds(), 2));
  return "" + date_part + " " + time_part;
}
zero_pad = function(number, length) {
  var str;
  str = "" + number;
  while (str.length < length) {
    str = "0" + str;
  }
  return str;
}
alert(get_time())

How Amazing Features Can be a Waste of Time

Differentiation is another way of saying: define your own market. By doing this well, you can avoid the problem of unseating incumbents because they don’t exist or are significantly weaker.

Why Most Features Aren’t About Differentiating

You’ve got 5 seconds. Tell me how you’re better than the incumbent I am currently using. If your pitch to me — as a customer, partner, or investor — is that your site has the most features: you’re screwed. Here’s why, from the perspective of each:

  • Customers & partners: Yes, but, who are you again? I don’t put my eggs in nests that might disappear tomorrow, even if the nest has a built-in heater.
  • Investor: So your company is a feature away from being destroyed?

In the Internet Era, features are cheap. Big or small, a company can bang out a feature in a week or two and start testing it. You disagree because said company would “never” build that feature? Never say never. Innovative companies always surprise people. Hoping your competition doesn’t want free money on the table is tantamount to gambling, and there is a much safer, more logical way of approaching this problem.

So many “feature” companies (i.e., they’d just be a feature in a bigger company’s product) are born every day. The criticism isn’t that these companies are doing something “easy.” The problem is that many startups use a specific superior product experience or feature as a key differentiator, without considering whether or not it helps them corner a new or different market. Being “better” isn’t enough.

Same Thing, Different Optics

Certain feature sets, if marketed right, completely change your target market. This is key. Let me say it again:

Certain features put you in a different market.

Most all companies are chasing a specific market. 18-24 females. College students. People who like coffee. Couples. Widows. Canadians with houses.

Not all features are created equal. Most features just add further convenience or refinement (i.e., “single sign-on,” “AJAX uploading,” “mobile support.”). Focus on competing in a way that assures your competitor’s destruction if they were to follow your lead.

Why Incumbents Ignore Certain Features

Like I said, some features change who a company’s customers are. In worst case scenarios, some features alienate your existing customers entirely (i.e., killing your existing revenue stream).

For example, your feature might be a free, ad-supported version of an existing model. A very famous site called OKCupid did exactly this a few years ago. Even today, this is what they’re known for. Why didn’t the other players in the market copy them? Because going free would mean changing their customers from their users (who pay a monthly fee) to advertisers (who pay for data and exposure). Yes, much like Facebook, OKCupid’s product is its users, and its customers are its advertisers (mmmm sweet, sweet data).

While the main differentiating feature, being free, is an easy feature to build, even to this day, incumbent sites like eHarmony and Match remain paid services. They are ultimately after different markets. You and I can intuitively see that there is likely a well-defined difference between the two markets of people willing and not willing to pay for dating (income, what they are looking for, age, etc.). It’s clear now that there was always two markets in the dating space, and OKCupid successfully cornered it using a simple marketing message.

The key for you and I is to understand and learn from this lesson: figure out what differentiators you introduce that give you unique access to a new or different market from incumbents.

Don’t Get Distracted

In any given startup, there is probably a backlog of 100 features to choose from. And most of them are from customers. Think about it.

Customers ask for features.

These customers are asking you to pick their market. With each feature you work on, your are moving toward a given audience. If this is a market you don’t want, ignore the feature. A feature that doesn’t help you define, carve out, and keep a specific target market is a waste of time.

In some markets, usability is everything (mobile). In others, aesthetics (marketing). Yet again in others, speed (search engines). Maybe in another, depth of technical end points (APIs). And within these markets, there are niches with even finer requirements.

Identify your core desired audience and build features only they yearn for. Everything else is a distraction.

Feature != (does not equal) Technical

A feature isn’t necessarily a boat load of programming. A “feature” is a marketable unit of software development. The complexity of that development is irrelevant. It can be as simple as a change in design, pricing, copy, or even name. Here are some examples:

  • Pick an XXX domain for your Pinterest clone: bam! PinPorn (NSFW). No difference in technical features from the original, but the site successfully corners its own market via community (the feature).
  • Want to be a Groupon for gay people? Fab. (Another year later, they’ve exited their niche and become a mainstream fashion site.) You know how they did that? They built a sizable mailing list of the gay community from their original ideas to be a gay Facebook and/or Yelp. Fab’s differentiator? Good taste, according to them.
  • Instagram’s killer feature was tight social integration (arguably pretty technical); yet Hipstamatic came first. Instagram brought easy sharing to a paid digital photo filter market that Hipstamatic defined.
  • And, of course, there’s Facebook: a MySpace for college students. The killer “feature” was that you had to have a “.edu” email address. Facebook probably would have perished in its early days without those 5 lines of code (maybe less).

The Real Meaning of Market Differentiation

Recall my example about the free dating market. Rewind 10 years. Online dating was something you paid for. That was it. Maybe this is easy to recognize now, but this market dichotomy (free vs. paid) was not apparent until only recently.

When smart people ask you about your market differentiation, this is what they mean. They are asking you if you’ve found a market angle that existing players will gladly give up because they either don’t value it or can’t compete in it due to conflicting interests.

So next time you’re looking at a list of features to work on, ask yourself: “is this feature putting us in the market that we want to be in?”

Three Analogies for Pitching Your Startup Right

Below are three analogies on how to prepare and pitch your startup better.

TLDR: Don’t focus on being right. Don’t rush the sale. Find believers.

I recently got my startup funded. It was an extremely, extremely challenging exercise. Today’s post is short; I’ll save the funding journey for another time. Today, I wanted to talk about pitching. I’m going to focus on three big, often overlooked issues.

1. Friend-speak: “That’s an awesome idea!” => “Good luck, bro.”

Friends tell you what’s wrong with your idea, but they often say it nicely. Listen to your friends carefully, and recognize that “That’s a cool idea, but what about blah-blah?” is a veiled criticism of your idea. Listen and understand their concerns. A good pitch patches up these holes before they’re even asked.  Often, when an idea is criticized, it’s natural to want to be defensive. It’s important to take criticism as something to solve for, not something to “be right” about. Ok here’s the analogy:

You’re a pirate. You’re practice fighting with your buddy pirates when they accidentally shoot a hole through your hull. But you’re smart so you win the argument with them that there is in fact NOT a hole there (Uhhhh). You decide to go out and challenge some Brits to a battle to the death without first addressing the damage your buddies left on your idea — er, I mean — ship. Oops!

2. You need more time to sell

I haven’t pitched that many people specifically to get money (a lot of pitches were over partnerships), but when I felt rushed there wasn’t a second meeting. When you are trying to convince somebody to give you — a nobody — enough money to buy a few cars (or a house), they need time to digest things. Here’s the analogy:

Your startup is like a restaurant. First you lure in a customer to try out your food. Once inside, you serve your customer what they are going to eat. It’s a game changing meal, so they’re naturally skeptical. They start to nibble on it. Maybe it’s good. Maybe it’s not. But you’re in a hurry so you jam the food down their throat, ask for money, and remind them to leave a good review on Yelp. They throw up and get major indigestion.

Like with any good meal, make sure you have a full hour to pitch. Your pitch should be 30 minutes max. Leave 30 minutes for questions (which will be sprinkled throughout your presentation).

3. The Crazy Idea Train needs passengers

You’re the conductor of the Crazy Idea Train. You built it, actually. It’s a little rocky, but it’s speeding along! But there’s no passengers. Your friends say they’ll get on the train later. Strangers say you need to pay them money for them to get on board (it looks really ghetto and unstable, after all). And nobody really knows where it’s headed. Maybe it’s going to Billion Dollar Land; maybe its going to Unemployment Mountain. You think it’s the former. But it looks like most people believe it’s the latter.

I’ve thought about this a lot, and I’ve decided that this is actually super duper important not just from an investor’s point of view, but from a founder’s point of view. If you can’t convince one person to join your Crazy Idea Train, then is it really a good idea? Finding a co-founder is social validation that your Crazy Idea has legs. Without this, investors are left to imagine the worst.

I’ve also heard cases of people unsuccessfully looking for co-founders. Again, this to me is a sign of a crappy idea or worse. There’s a lot of reasons why somebody would be unable to find a co-founder, and most of them are bad signs. Are you arrogant and un-friendly? Do you seem untrustworthy? Do others have no confidence in your ability? Are you a terrible leader? Are you all talk? Are you no fun to be around? Do you kill kittens for entertainment? Maybe. Maybe not.

Your number one job as a founder is to sell the company to future investors, acquirers, and employees. If you suck at this, that’s a death sentence. Start with selling to a co-founder.

Summing it up

Don’t focus on being right. Don’t rush the sale. Find believers.

Bonus pro-tip: make sure your lawyer doesn’t put your cell phone number in the SEC filings. Yeah, that happened.

What Agile is NOT

Agile Will NOT Make People Work Faster

People will work just as slow or fast as before. It is not a miracle drug. Agile DOES ensure people are working on the stuff that matters at that particular moment. Which leads to the next point…

Agile Does NOT Mean You Can Change Your Mind All Day Long and Still Ship on Time

If you change your mind that the product should do X instead of Y, you may have to throw away code. This is a fact of life. Agile DOES encourage making key decisions at the last possible moment so that the cost of change is minimized. Agile (a la retrospectives) exposes why or how the deadline was missed and how costly bad decisions were.

Agile is NOT a Better Way to Manage Down

Yes, there are lots of little tasks now. And yes, they are all prioritized and bite-sized so it’s easier to micromanage, right? But you’ve missed the point. Agile let’s the engineers tell the managers what is going on. Agile IS a way to manage expectations (e.g., “managing up”).

Bonus Non-Issue: “We Need to Focus on How It Will Scale”

I’ve heard this a lot. It doesn’t matter (and if you disagree, then you probably aren’t ready for Agile). Agile is about making stuff that works – right now – so you can see if what you’ve made has any value. If it has value, then you worry about scaling. If it’s garbage, nobody will care how it was architected. Get it to work first; scale second. Getting stuff in the customers’ hands and then making decisions based on the feedback is your top priority. If you aren’t focusing on that, you’re probably on your way to creating your very own crappy product that nobody uses.

Today we learned that “agile” is a loaded word.

Browser Wars… Wait, That’s Still Going on Right?

Rewind 5 years (to 2006). Ask any self-proclaimed nerd what the browser market shares were. Market share stats were like the stock market ticker of the Internet Nerds. Everybody knew about it, and everybody cared.

But what’s the market shares today? Did you know that IE is below 50% by most measures? Did you know that Chrome ate up Firefox’s market share? And what’s Safari’s market share if all the iPhones and iPads use it?

You probably don’t know.

Because, who cares.

5-10 years ago, it mattered that IE had 70+% of the browser market because it directly influenced what was possible as an application developer. But mobile changed all that.

Mobile browsers ended up being the adoption wedge for HTML5 and alternatives to Flash thanks in large to the fact users — and developers — treated mobile as separate from regular browser apps. What a blessing in disguise: it let everybody start over. And once the mobile stuff got popular and apps broke, people blamed the bad mobile browser (“My ghetto Blackberry won’t load Facebook right!”) instead of the website. It was the perfect storm to force everybody to start adopting HTML5. Add in CSS/JavaScript standardizing tools (Modernizr,  jQuery, GWT, etc.) and developers didn’t even have to do cross-browser testing for simple stuff.

Maybe this is a bad thing to admit, but I haven’t bothered testing in all browsers for a year or two now. Stuff just breaks less often. IE7 is “good enough,” and the other browsers work 99% of the time. Thus, the only time I bother checking browser compatibility is if I’m doing something super complex or a user complains.

Good job, Internet. Ya, the evil Microsoft IE empire is still around, but we won the war and nobody even noticed.

Failure Paralysis – The Thing that Holds You Back

We all have this friend: he talks about all the things he will do soon. He’s going to ask out that cute girl. He’s going to start hitting the gym. He’s going to ask for that big raise. He’s going to be more social. Yet, he never does.

Your friend is a victim of Failure Paralysis.

It’s clear that inaction guarantees a lack of success. No success can be achieved by doing nothing. You can’t even win the lottery unless you buy a ticket. This applies to anything: becoming president, getting a girlfriend, losing weight, seeing a movie, etc. The first step, is to start moving toward the goal.

This is the struggle every entrepreneur eventually has to overcome.

A lot of people talk about the uncertainty around taking that first step. The reality is that as soon as you take that first step, you’ll be hit with 100 new issues you never imagined. You can read all day about poker theory, but it pales in comparison to real playing experience. And yet, so many people get stuck in the theory-crafting stage of an idea. Move past this step.

To succeed, you must do. And not doing assures failure.

What are the odds that the idea in your head will become a million dollar company? Well, if you do nothing, the odds are 0%. If you start now, maybe you increase your odds to 0.1% – a literal infinity-percent better odds. The problem is that some people don’t want 0.1%. They want 99%. Thus, they wait while they do stuff to try to increase their odds. But isn’t actually doing it going to increase your odds too? When does the waiting stop and the doing start? Well, for most people: never.

Everybody has excuses to do something later. But only a few don’t let those excuses stop them. Kevin Rose famously destroyed his relationship to fund Digg. Mark Zuckerberg dropped out of Harvard for Facebook. HARVARD! Actually, so did Bill Gates for Microsoft. Michael Arrington, a now-famous tech journalist, abandoned a career as a lawyer to join the startup world. Even Jack Dorsey bailed (I use this term in jest) on Twitter to go do Square.

Did these guys fear failure? I’m sure. You can’t gamble your future and not be. But that didn’t matter — they ignored all the “sound” advice from their friends and family. I won’t get into each case, but history shows us that if each had waited an extra year or two to make the jump “safer,” they may have missed the boat entirely.

Later is the same as never. Now is the only acceptable time.

Your friends might buy your excuses, but as an Internet-Stranger, I’m going to say the truth: your excuses don’t matter. Results do.

  • Too tired after work? Suck it up or change your sleeping habits.
  • Credit card debt holding you back? Pay it off and quit going out.
  • Not enough time? Manage your time better and quit reading Reddit.
  • Can’t code? It’s OK to suck at it. Learn.

So, take a deep breath, and do something. Anything. Don’t fear failure. Fear not-succeeding.