       else
         msg.reply "Request failed with status #{status}."
 
+  # Kick off a new timer, stopping the previously running one, if any.
+  robot.respond /start harvest at (.+)\/(.+): (.*)/i, (msg) ->
+    project = msg.match[1]
+    task    = msg.match[2]
+    notes   = msg.match[3]
+    msg.message.user.harvest_account.start msg, project, task, notes, (status, body) ->
+      if 200 <= status <= 299
+        if body.hours_for_previously_running_timer?
+          msg.reply "Previously running timer stopped at #{body.hours_for_previously_running_timer}h."
+        msg.reply "Started tracking. Back to your work, #{msg.message.user.name}!"
+      else
+        msg.reply "Request failed with status #{status}."
+
 # Class managing the Harvest account associated with
 # a user. Keeps track of the user's credentials and can
 # be used to query the Harvest API on behalf of that user.

    this.request(msg).path("daily").get() (err, res, body) ->
      callback res.statusCode, JSON.parse(body)

  # (internal method)
  # Assembles the basic parts of a request to the Harvest
  # API, i.e. the Content-Type/Accept and authorization

      "Accept": "application/json"
    .auth(@email, @password)
    return req

  # (internal method)
  # Searches through all projects available to the sender of
  # `msg` for a project whose name inclues `target_project`.
  # If exactly one is found, query all tasks available for the
  # sender in this projects, and if exactly one is found,
  # execute the callback with the project object as the first
  # and the task object as the second argument. If more or
  # less than one project or task are found to match the query,
  # reply accordingly to the user (the callback never gets
  # executed in this case).
  find_project_and_task: (msg, target_project, target_task, callback) ->
    this.daily msg, (status, body) ->
      # Search through all possible projects for the matching ones
      projects = []
      for project in body.projects
        if project.name.toLowerCase().indexOf(target_project.toLowerCase()) != -1
          projects.push(project)
      # Ask the user if the project name is ambivalent
      if projects.length == 0
        msg.reply "Sorry, no matching projects found."
        return
      else if projects.length > 1
        msg.reply "I found the following #{projects.length} projects for your query, please be more precise:"
        for project in projects
          msg.reply "* #{project.name}"
        return

      # Repeat the same process for the tasks
      tasks = []
      for task in projects[0].tasks
        if task.name.toLowerCase().indexOf(target_task.toLowerCase()) != -1
          tasks.push(task)
      if tasks.length == 0
        msg.reply "Sorry, no matching tasks found."
      else if tasks.length > 1
        msg.reply "I found the following #{tasks.length} tasks for your query, please be more pricese:"
        for task in tasks
          msg.reply "* #{task.name}"
        return

      # Execute the callback with the results
      callback projects[0], tasks[0]