lib/botkit/CoreBot.js
function Task(bot, message, botkit) {

    this.convos = [];
    this.botkit = botkit;
    this.bot = bot;

    this.events = {};
    this.source_message = message;
    this.status = 'active';
    this.startTime = new Date();

    this.isActive = function () {
      return this.status == 'active';
    };

    this.createConversation = function (message) {
      var convo = new Conversation(this, message);
      convo.id = botkit.convoCount++;
      this.convos.push(convo);
      return convo;
    };

    this.startConversation = function (message) {

      var convo = this.createConversation(message);
      botkit.logger.debug('>   [Start] ', convo.id, ' Conversation with ', message.user, 'in', message.channel);

      convo.activate();
      return convo;
    };

    this.conversationEnded = function (convo) {
      botkit.logger.debug('>   [End] ', convo.id, ' Conversation with ',
        convo.source_message.user, 'in', convo.source_message.channel);
      this.trigger('conversationEnded', [convo]);
      this.botkit.trigger('conversationEnded', [bot, convo]);
      convo.trigger('end', [convo]);
      var actives = 0;
      for (var c = 0; c < this.convos.length; c++) {
        if (this.convos[c].isActive()) {
          actives++;
        }
      }
      if (actives == 0) {
        this.taskEnded();
      }

    };

    this.endImmediately = function (reason) {

      for (var c = 0; c < this.convos.length; c++) {
        if (this.convos[c].isActive()) {
          this.convos[c].stop(reason || 'stopped');
        }
      }

    };

    this.taskEnded = function () {
      botkit.logger.debug('[End] ', this.id, ' Task for ',
        this.source_message.user, 'in', this.source_message.channel);

      this.status = 'completed';
      this.trigger('end', [this]);

    };

    this.on = function (event, cb) {
      botkit.logger.debug('Setting up a handler for', event);
      var events = event.split(/\,/g);
      for (var e in events) {
        if (!this.events[events[e]]) {
          this.events[events[e]] = [];
        }
        this.events[events[e]].push(cb);
      }
      return this;
    };

    this.trigger = function (event, data) {
      if (this.events[event]) {
        for (var e = 0; e < this.events[event].length; e++) {
          var res = this.events[event][e].apply(this, data);
          if (res === false) {
            return;
          }
        }
      }
    };


    this.getResponsesByUser = function () {

      var users = {};

      // go through all conversations
      // extract normalized answers
      for (var c = 0; c < this.convos.length; c++) {

        var user = this.convos[c].source_message.user;
        users[this.convos[c].source_message.user] = {};
        var convo = this.convos[c];
        users[user] = convo.extractResponses();
      }

      return users;

    };

    this.getResponsesBySubject = function () {
      var answers = {};

      // go through all conversations
      // extract normalized answers
      for (var c = 0; c < this.convos.length; c++) {
        var convo = this.convos[c];

        for (var key in convo.responses) {
          if (!answers[key]) {
            answers[key] = {};
          }
          answers[key][convo.source_message.user] = convo.extractResponse(key);
        }
      }

      return answers;
    };

    this.tick = function () {

      for (var c = 0; c < this.convos.length; c++) {
        if (this.convos[c].isActive()) {
          this.convos[c].tick();
        }
      }
    };
  }
function Task(bot, message, botkit) {

    this.convos = [];
    this.botkit = botkit;
    this.bot = bot;

    this.events = {};
    this.source_message = message;
    this.status = 'active';
    this.startTime = new Date();

    this.isActive = function () {
      return this.status == 'active';
    };

    this.createConversation = function (message) {
      var convo = new Conversation(this, message);
      convo.id = botkit.convoCount++;
      this.convos.push(convo);
      return convo;
    };

    this.startConversation = function (message) {

      var convo = this.createConversation(message);
      botkit.logger.debug('>   [Start] ', convo.id, ' Conversation with ', message.user, 'in', message.channel);

      convo.activate();
      return convo;
    };

    this.conversationEnded = function (convo) {
      botkit.logger.debug('>   [End] ', convo.id, ' Conversation with ',
        convo.source_message.user, 'in', convo.source_message.channel);
      this.trigger('conversationEnded', [convo]);
      this.botkit.trigger('conversationEnded', [bot, convo]);
      convo.trigger('end', [convo]);
      var actives = 0;
      for (var c = 0; c < this.convos.length; c++) {
        if (this.convos[c].isActive()) {
          actives++;
        }
      }
      if (actives == 0) {
        this.taskEnded();
      }

    };

    this.endImmediately = function (reason) {

      for (var c = 0; c < this.convos.length; c++) {
        if (this.convos[c].isActive()) {
          this.convos[c].stop(reason || 'stopped');
        }
      }

    };

    this.taskEnded = function () {
      botkit.logger.debug('[End] ', this.id, ' Task for ',
        this.source_message.user, 'in', this.source_message.channel);

      this.status = 'completed';
      this.trigger('end', [this]);

    };

    this.on = function (event, cb) {
      botkit.logger.debug('Setting up a handler for', event);
      var events = event.split(/\,/g);
      for (var e in events) {
        if (!this.events[events[e]]) {
          this.events[events[e]] = [];
        }
        this.events[events[e]].push(cb);
      }
      return this;
    };

    this.trigger = function (event, data) {
      if (this.events[event]) {
        for (var e = 0; e < this.events[event].length; e++) {
          var res = this.events[event][e].apply(this, data);
          if (res === false) {
            return;
          }
        }
      }
    };


    this.getResponsesByUser = function () {

      var users = {};

      // go through all conversations
      // extract normalized answers
      for (var c = 0; c < this.convos.length; c++) {

        var user = this.convos[c].source_message.user;
        users[this.convos[c].source_message.user] = {};
        var convo = this.convos[c];
        users[user] = convo.extractResponses();
      }

      return users;

    };

    this.getResponsesBySubject = function () {
      var answers = {};

      // go through all conversations
      // extract normalized answers
      for (var c = 0; c < this.convos.length; c++) {
        var convo = this.convos[c];

        for (var key in convo.responses) {
          if (!answers[key]) {
            answers[key] = {};
          }
          answers[key][convo.source_message.user] = convo.extractResponse(key);
        }
      }

      return answers;
    };

    this.tick = function () {

      for (var c = 0; c < this.convos.length; c++) {
        if (this.convos[c].isActive()) {
          this.convos[c].tick();
        }
      }
    };
  }
function Task ( bot , message , botkit ) { this . convos = [ ] ; this . botkit = botkit ; this . bot = bot ; this . events = { } ; this . source_message = message ; this . status = 'active' ; this . startTime = new Date ( ) ; this . isActive = function ( ) { return this . status == 'active' ; } ; this . createConversation = function ( message ) { var convo = new Conversation ( this , message ) ; convo . id = botkit . convoCount ++ ; this . convos . push ( convo ) ; return convo ; } ; this . startConversation = function ( message ) { var convo = this . createConversation ( message ) ; botkit . logger . debug ( '>   [Start] ' , convo . id , ' Conversation with ' , message . user , 'in' , message . channel ) ; convo . activate ( ) ; return convo ; } ; this . conversationEnded = function ( convo ) { botkit . logger . debug ( '>   [End] ' , convo . id , ' Conversation with ' , convo . source_message . user , 'in' , convo . source_message . channel ) ; this . trigger ( 'conversationEnded' , [ convo ] ) ; this . botkit . trigger ( 'conversationEnded' , [ bot , convo ] ) ; convo . trigger ( 'end' , [ convo ] ) ; var actives = 0 ; for ( var c = 0 ; c < this . convos . length ; c ++ ) { if ( this . convos [ c ] . isActive ( ) ) { actives ++ ; } } if ( actives == 0 ) { this . taskEnded ( ) ; } } ; this . endImmediately = function ( reason ) { for ( var c = 0 ; c < this . convos . length ; c ++ ) { if ( this . convos [ c ] . isActive ( ) ) { this . convos [ c ] . stop ( reason || 'stopped' ) ; } } } ; this . taskEnded = function ( ) { botkit . logger . debug ( '[End] ' , this . id , ' Task for ' , this . source_message . user , 'in' , this . source_message . channel ) ; this . status = 'completed' ; this . trigger ( 'end' , [ this ] ) ; } ; this . on = function ( event , cb ) { botkit . logger . debug ( 'Setting up a handler for' , event ) ; var events = event . split ( / \, / g ) ; for ( var e in events ) { if ( ! this . events [ events [ e ] ] ) { this . events [ events [ e ] ] = [ ] ; } this . events [ events [ e ] ] . push ( cb ) ; } return this ; } ; this . trigger = function ( event , data ) { if ( this . events [ event ] ) { for ( var e = 0 ; e < this . events [ event ] . length ; e ++ ) { var res = this . events [ event ] [ e ] . apply ( this , data ) ; if ( res === false ) { return ; } } } } ; this . getResponsesByUser = function ( ) { var users = { } ; // go through all conversations // extract normalized answers for ( var c = 0 ; c < this . convos . length ; c ++ ) { var user = this . convos [ c ] . source_message . user ; users [ this . convos [ c ] . source_message . user ] = { } ; var convo = this . convos [ c ] ; users [ user ] = convo . extractResponses ( ) ; } return users ; } ; this . getResponsesBySubject = function ( ) { var answers = { } ; // go through all conversations // extract normalized answers for ( var c = 0 ; c < this . convos . length ; c ++ ) { var convo = this . convos [ c ] ; for ( var key in convo . responses ) { if ( ! answers [ key ] ) { answers [ key ] = { } ; } answers [ key ] [ convo . source_message . user ] = convo . extractResponse ( key ) ; } } return answers ; } ; this . tick = function ( ) { for ( var c = 0 ; c < this . convos . length ; c ++ ) { if ( this . convos [ c ] . isActive ( ) ) { this . convos [ c ] . tick ( ) ; } } } ; }
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~