The Blog

The what's what of the Flowdock atmosphere.

Features That Give Answers To “Who’s Read My Message?” & “Who Is This Guy?”

Mikael Roos May 15th, 2013

We have had a few new features come out this May in Flowdock.

These people have seen your message

First, we have a pretty awesome feature which has been requested a few times. If you @mention someone or use @everyone, you’ll be able to tell when those people have seen the specific message. Simply hover over the message to show the list of users who have seen it. In 1-to-1 chats the feature works regardless if you mention the other person or not.

user-cards-flowdock-screenshot

Second, a couple of convenience features to let you figure out who’s who more easily and find the right person from within Flowdock. You can now click on a user’s nick in Flowdock and see exactly who that person is and when they’ve last been active in Flowdock.

Start 1-to-1 chat

1-to-1 chats can be started in two new ways:

  • From the new user card which is opened when you click on a user’s nick in the chat
  • From the flow dropdown at the top of the page

We’ve also changed the way you control flow access. You can now separately control if you want your flow to be open and visible for other members of your company account, and if you want your flow to be accessible via a join link. Change these settings from the people management screen accesible from the user icon in the top right corner of the app.

new access mode config flowdock

Flowdock API Changes

Mikael Roos May 7th, 2013

At Flowdock, we are changing the way we handle flow IDs in our API. If you are a Flowdock API user, this may affect your integration, and if you are using Hubot with Flowdock, you’ll have to upgrade before the change comes into effect.
The changes will take effect on Monday, May 27th, 2013.

For more information, see our new API Changes page.

Keeping Track Of API Changes

To stay up-to-date with up-and-coming changes and additions to the Flowdock API, frequent the API Changes page or follow the API Changes Atom feed.

Contributing & Discussions

In case you bump into any bugs, problems or inconveniences with the API, feel free to create an issue in our open Flowdock API documentation GitHub repository. If you find anything remiss in the documentation, correcting pull requests will be received with open arms.

Flowdock For iPhone Gets Push Notifications & 1-To-1 Messages

Mikael Roos April 23rd, 2013

Flowdock iPhone Push Notifications

Lately, we’ve been putting plenty of work into the Flowdock iPhone app. It’s now more streamlined and touts a couple of awesome new features: Push notifications & 1-to-1 conversations.

Push Notifications

Push notifications have been highly requested for the iPhone app, and now they’ve been added. Once enabled, you’ll receive a push notification whenever someone mentions your name in a flow or sends you a 1-to-1 message. You’ll never miss a message you want to see. Simply download or upgrade your iOS app and start it up to enable push notifications.

1-To-1 Messaging

Flowdock 1-to-1 discussions / private messages Another clear omission in the iPhone app has been 1-to-1 conversation. Now, you can send and receive private messages with your iPhone while on the go. The feature is fully packed with photo uploads and all. The UI now gives you two sections, one for your flows and another for your 1-to-1 conversations.

Other platforms

Flowdock’s web app works great with most modern mobile browsers. You can simply point your mobile browser to flowdock.com/app to access on the go.

As always, we love to hear your feedback.

Someone Is Typing, Access Mode For Flows And 10 Other Features We Recently Added

Mikael Roos March 20th, 2013

There has been a lot of hustle and bustle at our Helsinki office lately. After being acquired by Rally Software a month ago, we’ve been spending some time getting to know the people and ways of Rally. In the meantime, we never stopped shipping new features to Flowdock. Here’s a few of those features.

Someone Is Typing In Here…

We added a feature which can be found in many chat applications. That is the ability to tell when someone has begun typing something into the chat, but has not yet posted it.

Someone is typing screenshot

We simply show a little “Mikael is typing…” text next to the chat input when this happens. And if you prefer not to show when you’re hesitating, you can turn the feature off from Preferences.

Access Mode For Flows

Previously, you always needed to specifically hand-pick the people you wanted to add to a Flowdock flow. Now you can choose from three different access modes:

  1. Invite-only – everything works as it used to, and you still need to invite or add existing people in your organization to your flow.
  2. Anyone with the link – Anyone with a specific join link can join the flow. You can distribute this single link in any way you like.
  3. Anyone in the company – You have the join link as in (2.), but you also allow anyone in the company account to freely join this flow via the flows drop-down.

The people settings can be accessed via each flow’s user avatar bar.

And Some Other Features We Added Lately

  • Added an emoji auto-completer, so you can simply type a colon (:) to start adding an emoji emoticon.
  • Added file uploads to private chat.
  • Worked a lot on the mobile web experience. Now there’s better UI for switching flows. A lot to do there, still. We’re working on it.
  • Improved IE support (IE9 & 10).
  • Added multi-flow support for API & integrations – you can now use a comma separated list of flow tokens in any integration that works using flow tokens (GitHub, JIRA etc).
  • Edit message with up arrow – when you have focus in the chat input and it is empty, pressing the up key will open up your latest chat message for editing.
  • Edit message in private chat – extended the feature to private chats.
  • Made notification volume configurable via Preferences
  • Added actual delete functionality for flows
  • Changed the flow tabs style into a more compact one
  • Added simple keyboard shortcuts to switch flow tab in browser: Press first Esc and then Left, Right, 1, 2, 3 or so on to switch tabs.

Things To Come Are Mobile

We also have a lot of things in the pipeline! Right now we’re cooking up a new version of our iPhone app, which will add some long-awaited features (think push!).

Another thing we’re adding is many users’ pet peeve. We won’t be forcing everyone to use Gravatar anymore but instead you’ll be able to add your avatar directly to Flowdock.

As always, all feedback is extremely welcome!

Flowdock Acquired By Rally Software

Otto Hilska February 13th, 2013

Rally Acquires Flowdock, Expands To Helsinki, Finland

A couple of years ago we left a cozy and predictable consulting business to build a team collaboration product for teams like ours. Riding the startup rollercoaster has been the best learning experience of our lives, and today we’re excited to announce that Flowdock has been acquired by Rally Software.

Flowdock started off as a collection of experiments around real-time web and communication paradigms, but after getting funded by Silicon Valley investors, we had an opportunity to start building the product for our long-term goals. A couple of months ago we released a completely redesigned Flowdock, and shipped more than half of the top 15 most requested features. Based on the thousands of customer feedback emails it looks like that was a leap to the right direction. Supporting our customers and integration partners on desktop, mobile, web and IRC is a lot of work for a team of nine, and with Rally’s resources we can now take the product to the next level.

We’ve been working closely with the Rally Software folks for some time leading up to this announcement. During that time, we’ve got to know a lot of people from Rally and have seen how they work. We’ve found the culture of Rally to be one of openness, active collaboration and deep professionalism.

What’s happening to my Flowdock account?

Business as usual. We will continue to provide the Flowdock service to you as before. Flowdock becomes a part of Rally’s product portfolio, and it will remain as an independent service. The team behind Flowdock continues to work on it, and we’re expecting to ship some of the top-requested features really soon!

We’re continuing to build a strong integration ecosystem, and we’ve already integrated with AgileZen, Rally’s simple card-based project management app.

While we’ve always had plans to make our pricing more flexible, the service will remain affordable for even the smallest teams.

About Rally

Rally Software is a leading global provider of cloud-based solutions for managing Agile software development. The Rally Agile application lifecycle management (ALM) platform transforms the way organizations manage the software development lifecycle by closely aligning software development and strategic business objectives, facilitating collaboration, increasing transparency and automating manual processes. We believe that together Rally and Flowdock can immensely help you work across teams, tools and timezones – from agile software development to sales and marketing. Rally supports 154,000 paid users and more than 1,000 customers, including 36 of the Fortune 100 companies.

A Debt Of Gratitude

We would have never made it very far without the enthusiasm of first customers who boldly took a huge leap and started running their teams on an early version of Flowdock. We’d like to extend our thanks to all the Flowdock customers as well as integration partners. In the future, we’ll be working hard on making Flowdock a must for all kinds of teams. We hope to have your continued support in the process.

Otto, Mikael, Tuomas & the team

Syncing Backbone Models in Real Time Over Socket.io

Otto Vehviläinen January 25th, 2013

The New Flowdock was built from the ground up on top of Backbone.js. Since Flowdock is all about real-time messaging, our web app posts and receives messages via a Socket.io backend. To support saving messages through Socket.io instead of a REST API, we wrote a custom Backbone.sync method.

We also use Bacon.js a lot to manage message streams in the client. If you’re not familiar with Bacon.js, take a look at the primer we posted about Functional Reactive Programming and Bacon.js. The Bacon.js EventStreams are an important part of keeping our data models and collections up to date.

Introduction

About the terminology: Flowdock is a real-time communication tool, which means that the core of our service is delivering different kinds of messages. When I talk about messages in this blog post, you can think of them as chat messages that have a number of properties: content, user who sent it, the flow (chat room) it was posted to and tags, among others. Messages can also be emails, notifications about git commits or anything else we support. The exact format is not important, but rather the idea that messages represent most of the content that is eventually displayed to the user and can be filtered based on a number of factors like the flow it was sent to or the tags it has.

What’s this Backbone.sync method then? Backbone delegates every save or read operation to its own sync method. By default, it maps the different verbs (create, update, etc.) to CRUD REST API operations á la Rails. Backbone.sync takes three arguments:

  • method, which is any of ‘update’, ‘patch’, ‘create’, ‘read’ and ‘delete’
  • model, which is the model or collection to operate on
  • options.

The default implementation serializes the model or collection (if needed) and then makes an AJAX request to the URL specified by the model’s URL property. The model or collection gets updated after the operation completes.

Creating Messages Over Socket.io

So, our custom sync needs to post new messages to the backend through Socket.io and otherwise work normally.

Flowdock.socketIoSync = (method, model, options) ->

  # Create-operations get routed to Socket.io
  if method == 'create'
    Flowdock.connection.messages.push model.toJSON()

  # All other operations use standard Backbone.sync
  else
    Backbone.sync method, model, options

Flowdock.connection.messages is a Bacon.js Bus that forwards messages without an ID through Socket.io to our backend. The relevant parts of the connection class work as follows:

class Flowdock.Connection

  constructor:
    @messages = new Bacon.Bus()
    @socket = @connect() # Returns a Socket.io socket
    @messages.filter((message) -> !message.id).onValue (message) =>
      @socket.emit "message", message
  ...

We’ve intentionally broken Backbone.sync’ default behaviour of returning a promise and executing success and error callbacks since our implementation handles the state as part of the message stream. Basically, we keep track of the UUIDs of sent messages and check if they come back with an ID (aka “success callback”) and if not, we send an error message to the messages bus (aka “error callback”).

One important thing to note is that the message bus is the same one that receives new messages from Socket.io and which all of our collections listen to. When new messages get pushed to the bus all interested collections — and therefore the UI — can react immediately to the changes, even before the messages perform a roundtrip to our backend.

Only our message models require this kind of sync method, and Backbone enables us to choose the sync method to use per model:

class Models.Message extends Backbone.Model

  sync: Flowdock.socketIoSync
 
  ...

This allows us to simply create a new message, save it, and it’ll automatically go through Socket.io.

# Create a new message
message = new Models.Message(content: 'foo', flow: 'example:main', user: 1)
message.save()
# -> ['message', {
#   event: 'message',
#   content: 'foo',
#   user: 1,
#   flow: 'example:main',
#   uuid: 'abbaacdcABBAACDC'
# }] is emitted to socket

Updating Collections and Models

Part two of the whole synchronizing messages over Socket.io problem is receiving messages: new messages should end up in the correct collections and existing messages should get updated. You might already have wondered how the messages posted through the websocket get IDs and other server generated properties. The simple version of our solution is that we generate UUIDs for new messages in the client before saving them, after which the message collection updates the correct model based on the UUID when the updated message arrives back from the server through Socket.io.

Our collections (and some models) consume message streams and filter messages relevant to them. Usually the consumed stream is a filtered version of the global message bus. This way we can push all of the messages (both new and old) to the single message bus. We don’t need to know who’s listening to it and the message collections always stay up to date.

This is how the consuming a message stream works:

class Collections.Messages extends Backbone.Collection

  ...
 
  consume: (@stream) ->
    @stream.filter(@messageFilter).onValue (message) =>
      # Find message by UUID and update it if found
      existingMessage = @findByUuid(message.uuid)
      if message.id && existingMessage? && !existingMessage.id
        existingMessage.set(message)
        existingMessage.trigger("sync")

      # Add the message if it does not already exist
      else if !message.id || !@get(message.id)
        @add(message)

      return Bacon.more

  ...

This logic is used as new messages and updated data comes in, but we still use the collection.fetch method to load the initial data and history to collections from our REST API.

Conclusions

Backbone.js is not specifically built for real-time applications, so using it in one requires some modification. Backbone is, however, a really solid foundation to build on, and since it has strict conventions, it’s really easy to customize the behaviour.

Using Bacon.js as the interface to the websocket library decouples Backbone collections and models from the Socket.io part and gives us the possibility to swap out Socket.io, and replace it with something else (like Faye, sock.js or EventSource) if needed with minimal effort. None of the collections or models actually know anything about Socket.io, so wrapping another library in a similar Bacon.js interface is easy. The consume pattern also makes unit testing really easy, since we don’t need to mock the Socket.io connection.

Say Goodbye to Typos & Poor Judgment: Flowdock Now Has Message Editing

Mikael Roos January 23rd, 2013

In Flowdock, there are a couple of good use cases for editing your message: the sheer purpose of correcting typos and altering your opinions just after you’ve released them from the confines of the inside of your head. In Flowdock, as of right now, it’s possible to do just that.

Editing my message via the UI in Flowdock

When you hover your mouse over a chat message, you’ll see a new action next to the tag icon. It’s the edit icon. A quick click on it and you’ll be literally changing history in no time. Don’t worry, we show a little disclaimer in the end of edited messages, so you won’t go crazy thinking that it just said something else there a second ago.

Editing my Flowdock chat message with a regular expression

We’ve also added support for the popular Regex format s/teh/the/ for correcting the latest message you sent.

Bacon.js Makes Functional Reactive Programming Sizzle

Ville Lautanala January 22nd, 2013

Like most other JavaScript developers, we’ve been in a callback hell. Functional Reactive Programming (FRP) is one, and in our opinion rather powerful, tool to improve the structure of your web app. This blog post introduces FRP concepts and benefits with Bacon.js, an FRP library for both browsers and server-side JS. We’ve been using Bacon.js in the new Flowdock.

Reactive programming is different from event-driven programming in the sense that it focuses on data flows and propagation of change instead of handling single events. For example, in an imperative world, there could be a statement that sums up two variables and produces a third variable. If either of the variables change, you wouldn’t expect the value of the result variable to change. If you’re using reactive building blocks, the result variable would always be the sum of the two variables. In this sense, reactive programming is almost like a spreadsheet.

FRP implements reactive programming with functional building blocks. Referential transparency is strictly enforced, which prohibits the use of variables. An alternative way has to be used to handle time-varying values. The main concepts in FRP are properties (not to be confused with JavaScript properties) and event streams. There are different names for these in different implementations. ‘Signal’ and ‘event’ are commonly used, but we’ll stick with Bacon.js nomenclature.

EventStreams are sources of events. These can be mouse clicks, keyboard events or any other input. The power of EventStreams is that they are composable. It is possible to use similar tools that are used to handle arrays for event streams: you can filter events, map event values to other values or reduce events to a property.

Property is used as an abstraction for a time-varying value. Properties are similar to EventStreams, but they also have the notion of current value. Most of the functionality is shared with EventStreams.

Streams and Properties in Bacon

Let’s try out this FRP thing by figuring out if the user is active on a web page. This is something we’ve had to do in Flowdock to determine what kind of notifications we should play. For example, we don’t want to bother users with sound notifications when they are participating actively in the current discussion.

The easiest thing that could work is to use focus and blur events. A pretty standard approach to this, using jQuery would be

var focused = true;
$(window).on('blur', function() { focused = false; });
$(window).on('focus', function() { focused = true; });

Not that bad, but how about the FRP approach then?

var blur = $(window).asEventStream('blur').map(function() {
  return false;
});
var focus =  $(window).asEventStream('focus').map(function() {
  return true;
});
var focused = focus.merge(blur).toProperty(true);

Two Bacon.js EventStreams are defined: blur that emits falses and focus that emits trues. Then the streams are combined using using merge and converted to a Property that captures the value of focus. true is defined as initial value. If you want to inspect the value, a listener to the Property can be bound using onValue

focused.onValue(function(focus) { console.log('focus', focus); });

There’s one gotcha: Bacon.js is lazy. Before the stream or property has any subscribers, it won’t do anything. The current value of the property won’t update and event listeners aren’t bound to the DOM. This can be very useful since it means creating streams causes zero overhead.

Handling state with switching streams

The focus/blur idea to handle activity state is usually not good enough. The focus and blur events aren’t always reliable and we won’t have any idea if the user has left the computer three hours ago.

How about using keyboard and mouse activity then? Let’s say that users are active when they have moved the mouse pointer or pressed some key within the last 30 seconds.

For comparison, this could be implemented in plain old jQuery as follows

var active = true;
var timeout = null;
function setInactive() {
  active = false;
}

$(window).on('keydown mousemove', function() {
  active = true;
  clearTimeout(timeout);
  timeout = setTimeout(setInactive, 30000);
})

A Bacon EventStream of user activities is a good start.

var activity = $(window).asEventStream('mousemove keydown')

The stream only contains events of the positive case. Negative case requires you to detect when there is no activity. Here’s where stream switching becomes useful.

var active = activity.flatMapLatest(function(event) {
  return Bacon.once(true).merge(Bacon.later(30000, false));
}).toProperty(true);

Here stream switching is used to implement state in a functional world. In Bacon, flatMap maps each event in the stream to a new stream of events. flatMapLatest works like flatMap, except that only events from the latest spawned stream are included. So, the value is true for 30 seconds after the last user interaction.

This isn’t the only, or even the simplest, way to implement such an activity property. Bacon throttle could be used to only emit events after a quiet period.

activity.map(function() { return true; }).merge(
  activity.throttle(30000).map(function() { return false; })
).toProperty(true);

If this is compared to the event-driven solution, you’ll see that the FRP solution looks more desirable. There are less moving parts and the code is more focused on the logic rather than implementation details.

Composing Properties

The activity based solution might be more resilient than using window blur and focus events, but blur is still useful. Since focus is typically reliable, maybe it could be improved by combining the two solutions: users are actively viewing the page when the window is focused and they have moved their mouse in the past 30 seconds. Luckily, composing properties in Bacon is extremely easy.

focused.combine(active, function(focus, active) {
  return focus && active;
})

Even better, there are methods to combine properties with basic boolean operators.

focused.and(active)

The jQuery implementation is left as an exercise for the reader.

Decoupling apps with Bacon

There are other data sources that we could use for user activity monitoring. The Page Visibility API is a more reliable alternative for focus and blur. If this API is available in the browser, we can use an implementation based on that instead.

Bacon makes it easy to switch out parts of the implementation when constructing EventStreams and Properties. Let’s say that we’ve implemented a Bacon property from Page Visibility state as visibility.

function windowFocus() {
  if (document.hidden === undefined) {
    return visibility;
  else {
    return focused;
  }
}

function activity(focus) {
  var stream = $(window).asEventStream('mousemove keydown');
  return stream.flatMapLatest(function(event) {
    return Bacon.once(true).merge(Bacon.later(30000, false));
  }).toProperty(true).and(focus);
}

activity(windowFocus());

Decoupling the stream and application logic also makes it easier to test components that depend on the activity. You can give the state as argument to other components and don’t need to write complex objects to encapsulate the state.

On the Road to a Bypass Surgery

At Flowdock, we’ve been using Bacon to handle all kinds of things: autocompleting UI components with asynchronous results, synchronising Backbone models over Socket.IO and handling keyboard shortcuts.

This blog post didn’t cover much of the Bacon.js API. The Bacon.js readme is the most comprehensive source of documentation. The Bacon.js wiki has also excellent visualisations of the few important methods and their implications.

Integration Bonanza: Honeybadger, Airbrake, Sprint.ly & DeployHQ

Mikael Roos January 17th, 2013

Since we launched The New Flowdock last month, there’s been a a whole bundle of new integrations implemented on top of the Flowdock API. Here they are with instructions included!

For exception handling and error management we have a couple of newcomers: Honeybadger (howto) and Airbrake (howto), both full-fledged tools for reporting unexpected situations your users bump into.

We also have an integration for a brand new project management app, Sprint.ly (howto).

And last but not least in the slightest, we have an integration to the deployment app DeployHQ (howto). It keeps you updated when your product is deployed.

Have fun and be productive!

The New Flowdock: a Mac App, New Design, Chat + Threading, Emoji…

Mikael Roos December 11th, 2012

You can check it out now or sign up first.

For the past few months, our complete focus has been on creating a beautiful group chat tool which embraces all the other apps your team uses and seamlessly moves between threaded conversation and traditional linear chat.

Flowdock, our web app that combines group chat with a shared inbox, has already proven to be incredibly sticky for teams. Flowdock customers on average spend more than 7 hours using the app on a given workday. Now, the New Flowdock is here and the highlights follow!

Mac Desktop App

We are simultaneously releasing a brand new shiny Mac desktop app complete with desktop notifications, keyboard shortcuts and retina-proof graphics. It even supports the full array of OS X Emojis! Check out the Emoji Cheat Sheet for details.
Download the app here.

Chat & Threads Together

We have added something probably never seen before: a unique combination of chat and thread-based communication. You can choose to reply to a specific chat message (or a message from an external source, like an issue from an issue tracker) or continue the discussion in a normal, linear, chat-like fashion. It’s up to you. Discussions in this style tend to be more efficient and natural.

Responsively Designed For Any Device

The New Flowdock works wonderfully on touch-based devices regardless of their screen size. We seamlessly transcend between single and multi-pane designs dependending on the screen size of your device. This way, you have the same, beautiful experience both on handheld devices and on the desktop.

Complete Redesign

The New Flowdock has been completely redesigned and rewritten. It is beautiful, inside and out. The new slender interface emphasizes the content and adapts to its users’ needs without abandoning a sense of familiarity. All essential controls and content are directly available but never in the way.

On the inside is a Backbone app with delicious Bacon.js sprinkled on top, completely written in CoffeeScript.

Private Messages & Tabbing

Finally here. Private messaging has been added to make Flowdock completely cover all your needs as a full-fledged group chat software. We’ve also added built-in tabbing to make it easier to work in multiple teams and switch contexts when needed.

As always, feedback is very welcome!