FogBugz, Beeminder, and… pure functions in the cloud?

For a number of years now, I’ve used a free personal instance of FogBugz to track everything I have to do. At any given time I have somewhere between 50-150 open tickets representing things on my to-do list, and over the last four years I have processed around 4300 tickets. This has been immensely successful at reducing my stress and ensuring that I don’t forget about things. However, it’s been somewhat less successful at actually getting me to do stuff. It’s still all too easy to ignore the really important but intimidating tickets, or at times to simply ignore FogBugz altogether.

Just last week, I discovered Beeminder. I’ve only been using it a week, but early indications are that it just might turn out to be as revolutionary for my productivity as FogBugz was. The basic idea is that it turns long-term goals into short-term consequences. You set up arbitrary quantifiable goals, and Beeminder tracks your progress over time and takes your money if you get off track—but you get to set the amount, and in fact it’s completely free until the second time you fail at a particular goal. In fact I haven’t even pledged any money for any of my goals; just the threat of “losing” has been enough to motivate me so far. (In fact, I’m writing this blog post now because I made a goal to write two blog posts a week, and by golly, if I don’t write a new post by tomorrow I’m going to LOSE!)

So, two great tastes that taste great together, right? I could make Beeminder goal(s) to ensure that I close a certain number of tickets per week, or a certain number of high-priority tickets, or a certain number of tickets with a given tag, or whatever seems like it would be helpful. Beeminder has a nice API for entering data, and FogBugz comes with a “URL trigger” plugin which can automatically create GET or POST requests to some URL upon certain events (such as closing a ticket matching certain criteria). The URL trigger plugin lets you construct an arbitrary URL using a list of special variables which get filled in with values from the given ticket. So I can just trigger a POST to the Beeminder URL for entering a data point, and give it arguments indicating the timestamp of the ticket event and a comment with the name of the ticket.

No problem, right?

Well… almost. There’s just one tiny catch. You see, FogBugz outputs timestamps in the format YYYY-MM-DD HH:MM:SS… and Beeminder expects a number of seconds since the epoch. Argggh!

I want to just plug in a little function in the middle to do the conversion. But both the FogBugz and Beeminder APIs are running on remote servers that I have no direct control over. I’d have to somehow send the FogBugz POST to some other server that I do control, munge the data, and forward it on to Beeminder. But setting this up from scratch would be a lot of work, not to mention the expense of maintaining my own server.

Here’s what I really want: a website where I can somehow write my function in a little domain-specific language, and get a URL where I can point FogBugz, which would cause my function to run on the timestamp and the result forwarded appropriately to Beeminder. Of course there are issues to be worked out with security, DOS attacks, and so on, but it seems to me it should be possible in principle.

Does something like this already exist? If not, why not? (And how hard would it be to build one using all the great Haskell tools for web development out there? =) It seems to me that the ability to write “glue” code like this to sit in between various APIs is becoming quite important.

About Brent

Assistant Professor of Computer Science at Hendrix College. Functional programmer, mathematician, teacher, pianist, follower of Jesus.
This entry was posted in meta and tagged , , , , , , , . Bookmark the permalink.

18 Responses to FogBugz, Beeminder, and… pure functions in the cloud?

  1. singpolyma says:

    I used to use Yahoo! pipes et al for this sort of thing, but these days I just write code and put it on a server somewhere. It’s just cleaner and easier and I get more control :)

  2. gwern says:

    I’ve heard Yahoo Pipes and its clones can do things sort of like this.

  3. Wow, this is exactly the kind of awesomeness we were just talking about in our blog post last night —

    This is quite ingenious. Thanks so much for sharing this!

    As for this:

    > both the FogBugz and Beeminder APIs are running on remote servers that I have no direct control over.

    It’s no problem for us to add a special case or throw in an optional param for specifying the time in human-readable form. (Though I think better would be if FogBugz added a special variable for unixtime!)

    Keep us posted (or GET’d — hee hee) on this!

    PS: Ooh, like @gwern says, yahoo pipes may totally work for this. If you use a Date Formatter and give “%s” as the format string, that should output unixtime. Pipe a Date Builder into that and it should parse FogBugz’s format. So it would be FogBugz Trigger URL -> Date Builder -> Date Formatter (with %s) -> Beeminder URL.

    Eager to hear if that works. If not, we’ll definitely do a quick undocumented addition to the Beeminder API.

    • Brent says:

      Thanks! I’ll try yahoo pipes and let you know how it works.

      And thanks for Beeminder. I didn’t take into account that the Beeminder servers ARE perhaps a tiny bit under my control because of super-awesome responsive developers. =)

    • Brent says:

      Looks like Yahoo pipes works great!

  4. I think parametricity could be a handy tool for a “custom cloud filter” service. Let’s say we had a Monad that provided only a Reader-like environment for the request body and a function to make your forwarding POST. Then, anybody could upload some untrusted recipe in that Monad (and a restricted Prelude). You would just type-check it, and then confidently kick it off on a little VM using Snap or Yesod. After that it’s just some routing infrastructure.

    • Brent says:

      Yes, this is exactly the sort of thing I was thinking about. Something that gives you more expressivity than Yahoo Pipes, but is still guaranteed to be safe.

  5. It’s not exactly the general solution you’re looking for, but I imagine you could do something like this pretty well using Heroku.

    A quick Googling suggest that people have successfully deployed Yesod apps to Heroku Cedar. If you created a template app, it would probably be pretty easy to clone the template, and throw in a custom processing function each time you needed to do something like this. Then a simple git push would set the app in motion, and it would run for free as long as a single worker was sufficient.

    • Brent says:

      Cool, thanks for the pointer. I don’t know much about Heroku and didn’t know you could run simple things for free. It turns out that Yahoo Pipes are sufficient in this particular instance, but I’ll keep this in mind in case I need something more complex down the road.

  6. Gabriel says:

    Would you mind to share a little bit more about your FogBugz workflow? Did you customize it a lot (categories, projects, priorities, statuses…) or just fill basic “Bugs” and close them as a basic todo list?

    • Brent says:

      I do create projects (it’s useful to be able to quickly say “show me all the tickets having to do with topic X”) and use priorities and tags and so on to give me further axes along which to sort and filter. Beyond that I don’t use a whole lot of customization: simpler is usually better. The features I do make heavy use of are (1) the ability to create tickets via email (if I get an email and need to respond to it or do something related to it, I just forward it to fogbugz), (2) attaching arbitrary comments and files to tickets (often I don’t complete a ticket all in one go, but make some progress, collect some information, etc., and the add a comment to the ticket explaining what I’ve done so far). I used to use the estimation and timesheet features a lot, but stopped at some point.

  7. Kim-Ee Yeoh says:

    Hey Brent, have you looked at “Punished by Rewards” by Alfie Kohn? Or even better “The Path of Least Resistance” by Fritz?

    By golly, think of what you might LOSE if you don’t figure out the core of self-motivation.

  8. Justin says:

    Check out They wire up various different web services with an event based model.

  9. Pingback: Beeminder API | Beeminder Blog

  10. Pingback: Beeminding for fun and profit | blog :: Brent -> [String]

  11. Malcolm says:

    Interested in hearing more about how this worked for you! Are you still using it? How was the system set up?

    • Brent says:

      Hi Malcolm, I did get it set up with Yahoo Pipes and it worked great for a while. At some point I stopped the goal, not because it stopped working, but just because my priorities/strategies/etc. shifted. I don’t actually remember the specific reasons. I do still have time-based goals to review and work on FogBugz cases.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.