Exemplo n.º 1
0
  /**
   * Parse any commands and their values from a message.
   *
   * @param {string} message The raw message
   * @return {string[]}
   */
  parseCommands (message) {
    const retVal = {};

    const splits = message.split(/(start:|end:|message:)/);
    let curCommand;

    for (let x in splits) {
      switch (splits[x].toLowerCase()) {
        case 'message:':
        case 'start:':
        case 'end:':
          curCommand = splits[x].toLowerCase().replace(':', '');
          break;
        default:
          if (curCommand) {
            retVal[curCommand] = splits[x].trim();
          }
      }
    }

    // If no start/end dates, try to parse the message
    if (retVal.hasOwnProperty(COMMAND_MESSAGE)) {
      var parsedMessage = chrono.parse(message);
      if (parsedMessage && parsedMessage[0]) {
        if (!retVal.hasOwnProperty(COMMAND_START) &&
            parsedMessage[0].start
        ) {
          retVal[COMMAND_START] = this.setStart(parsedMessage[0].start.date().toString());
        }

        if (!retVal.hasOwnProperty(COMMAND_END)) {
          // check for end of first pass parsing
          if (parsedMessage[0].end) {
            retVal[COMMAND_END] = this.setEnd(parsedMessage[0].end.date().toString());
          } else {
            // remove first match and parse again
            parsedMessage = chrono.parse(message.replace(parsedMessage[0].text, ''));
            if (
              parsedMessage && parsedMessage[0] &&
                parsedMessage[0].start
            ) {
              retVal[COMMAND_END] = this.setEnd(parsedMessage[0].start.date().toString());
            }
          }
        }
      }
    }

    return retVal;
  }
Exemplo n.º 2
0
 EntityRecognizer.recognizeTime = function (utterance, refDate) {
     var response;
     try {
         var results = chrono.parse(utterance, refDate);
         if (results && results.length > 0) {
             var duration = results[0];
             response = {
                 type: 'chrono.duration',
                 entity: duration.text,
                 startIndex: duration.index,
                 endIndex: duration.index + duration.text.length,
                 resolution: {
                     resolution_type: 'chrono.duration',
                     start: duration.start.date()
                 }
             };
             if (duration.end) {
                 response.resolution.end = duration.end.date();
             }
             if (duration.ref) {
                 response.resolution.ref = duration.ref;
             }
             response.score = duration.text.length / utterance.length;
         }
     }
     catch (err) {
         console.error('Error recognizing time: ' + err.toString());
         response = null;
     }
     return response;
 };
Exemplo n.º 3
0
					async.eachSeries($('.idm_category_row'), function(that, next) {

						var fileinfo = $(that).find('.file_info').html().match(/([\d,]+)\s+downloads\s+\(([\d,]+)\s+views/i);
						var url = $(that).find('h3.ipsType_subtitle a').attr('href').replace(/s=[a-f\d]+&?/gi, '');
						var dateString = $(that).find('.file_info .date').html().trim().replace(/^added|^updated|,/gi, '').trim();
						var dateParsed = chrono.parse(dateString, today);
						if (dateParsed.length == 0) {
							logger.log('warn', '[vpf] Could not parse date "%s".', dateString);
						}

						var u = url.match(/showfile=(\d+)/i);
						// author dom is different when logged in (names are linked)
						var author = $(that).find('.basic_info .desc').html().match(/by\s+([^\s]+)/i);
						var descr = $(that).find('span[class="desc"]').html();
						if (u) {
							currentResult.push({
								fileId: parseInt(u[1]),
								title: $(that).find('h3.ipsType_subtitle a').attr('title').replace(/^view file named\s+/ig, ''),
								description: descr ? ent.decode(descr).trim() : '',
								downloads: parseInt(fileinfo[1].replace(/,/, '')),
								views: parseInt(fileinfo[2].replace(/,/, '')),
								updated: dateParsed.length > 0 ? dateParsed[0].startDate : null,
								author: author ? author[1] : $(that).find('.___hover___member span').html()
							});
							next();
						} else {
							logger.log('error', 'ERROR: Could not parse file ID from %s.', url);
							next('Could not parse file ID from ' + url);
						}

					}, function() {
Exemplo n.º 4
0
app.get('*', (req, res) => {
    let input = req.path.substring(1)
    let natural = null
    let unixTime = null

    //is natural date?
    if (!Number(input)) {
        try {
            natural = chrono.parse(input)[0].start.date()
            unixTime = Math.round(natural.getTime() / 1000)
        } catch (e) {
            natural = null
            unixTime = null
        }
    } else {
        unixTime = Number(input)
    }

    if (unixTime) {
        natural = strftime('%B %d, %Y', new Date(unixTime * 1000))
    }

    res.json({
        "unix": unixTime,
        "natural": natural
    })
})
Exemplo n.º 5
0
export default function(str, timezoneOffset) {
  const patternHour   = /(\d*\.{0,1}\d+)\s*(hours|hour|hrs|hr|h)\b/i;
  const patternMin    = /(\d*\.{0,1}\d+)\s*(minutes|minute|mins|min|m)\b/i;
  const patternChrono = /(\d*):(\d+)\s*(hours|hour|hrs|hr|h)\b/i

  const hoursMatch   = str.match(patternHour)
  const minutesMatch = str.match(patternMin)
  const chronoMatch  = str.match(patternChrono)

  const duration = moment.duration()

  if (hoursMatch && !chronoMatch)
    duration.add(parseFloat(hoursMatch[1]), 'hours')
  if (minutesMatch && !chronoMatch)
    duration.add(parseFloat(minutesMatch[1]), 'minutes')
  if (chronoMatch)
    duration
    .add(parseInt(chronoMatch[1]), 'hours')
    .add(parseInt(chronoMatch[2]), 'minutes')

  let momentDate = moment()

  //  Make sure momentDate is in user's timezone
  if (timezoneOffset)
    momentDate.utcOffset(timezoneOffset)

  // Strip out time string from message
  let message = str
  .replace(patternChrono, '')
  .replace(patternHour, '')
  .replace(patternMin, '')

  const parsedDate = chrono.parse(message)[0]

  // Strip out date string from message
  const dateStr = parsedDate ? parsedDate.text : ''
  message = message.replace(dateStr, '').trim()

  if (parsedDate) {
    parsedDate.start.assign('timezoneOffset', timezoneOffset)
    momentDate = parsedDate
    .start
    .moment()
  }

  //  Make sure date is noon in UTC
  const originalDayOfMonth = momentDate.date()
  const date = momentDate
  .utc()
  .date(originalDayOfMonth)
  .hour(12)
  .minute(0)
  .second(0)
  .millisecond(0)
  .toDate()

  return { date, duration: duration.asSeconds(), message }
}
Exemplo n.º 6
0
  robot.respond(/envoy guests\s*(.*)$/, { suggestions: ["envoy guests [time period]"] }, function(msg, done) {
    var timeQuery = msg.match[1];
    var startTime = "", endTime = "";

    if(timeQuery && timeQuery.trim() != "") {
      timeQuery = timeQuery.trim();
      results = chrono.parse(timeQuery);
      if(results.length > 0) {
        var result = results[0];
        var start = result.start.date();
        startTime = strftime("%Y-%m-%d", start);

        if(result.end) {
          endTime = strftime("%Y-%m-%d", result.end.date());
        } else {
          var end = new moment(start).add(24, 'h').toDate();
          endTime = strftime("%Y-%m-%d", end);
        }
      }
    }

    var url = "https://app.envoy.com/api/entries.json?api_key=" + process.env.NESTOR_ENVOY_API_KEY;
    var message = "Fetching guests...";

    if(startTime != "" && endTime != "") {
      url = url + "&from_date=" + startTime + "&to_date=" + endTime;
      message = "Fetching entries from " + startTime + " to " + endTime;
    }

    msg.reply(message).then(function() {
      robot.http(url).get()(function(err, resp, body) {
        if(resp.statusCode != 200) {
          msg.reply("Oops, there was an error getting guests list from Envoy", done);
        } else {
          var guestList = [];
          var entries = JSON.parse(body);

          for(var i in entries) {
            var entry = entries[i];
            guestList.push(msg.newRichResponse({
              title: entry.your_full_name,
              fields: [
                { 'title': 'Email', 'value': entry.your_email_address, 'short': true },
                { 'title': 'Company', 'value': entry.your_company, 'short': true },
                { 'title': 'Signed In', 'value': moment(entry.signed_in_time_utc).fromNow(), 'short': true }
              ]
            }));
          }

          if(guestList.length == 0) {
            msg.send("Oops you don't have any guests", done);
          } else {
            msg.send(guestList, done);
          }
        }
      });
    });
  });
Exemplo n.º 7
0
let fromVerbalDescription = (desc) => {
  let parsed = chrono.parse(desc);
  let newEvent = build();
  if (parsed.length > 0) {
    let data = parsed[0];
    if (data.start) newEvent.startsAt = data.start.date();
    if (data.end) newEvent.endsAt = data.end.date();
    newEvent.name = desc.split(data.text)[0].trim();
  }
  return newEvent;
}
Exemplo n.º 8
0
/**
 * helper function to parse a string date range into start and end dates
 * uses chrono to compute the range defaults to
 * { 
 *   start: 6daysago,
 *   end: today
 * }
 */
function parseDateRange (range) {
  let days = parseInt(range)
  days = days >= 0 ? days : 6 // default 6 days
  let dates = chrono.parse(range)[0] || [{}]
  // by default, set the date range then check if chrono parsed anything good
  let start = moment().subtract(days, 'days').startOf('day').toDate()
  let end   = moment().endOf('day').toDate()
  if (dates.start && dates.end) {
    start = moment(dates.start.date()).startOf('day').toDate()
    end   = moment(dates.end.date()).endOf('day').toDate()
  }

  return { start, end }
}
Exemplo n.º 9
0
app.post("/", function(req, res, next) {
  // TODO validate token (as a filter)

  if (req.body.text === "") {
    return res.send("To have me tell someone something for you, /tell <who> <what> <when>");
  }

  var parts = req.body.text.split(" "),
      who = parts.shift(),
      what = parts.join(" "),
      when = chrono.parse(what)[0],
      by = req.body.user_name,
      verbs = VERBS[req.body.command];

  if (who === "me") {
    who = by;
  }

  if (who.charAt(0) !== "@") {
    who = "@" + who;
  }

  if (by.charAt(0) !== "@") {
    by = "@" + by;
  }

  if (!when) {
    return res.send("Um, I couldn't figure out when you meant.");
  }

  var body = what.slice(0, when.index - 1) + what.slice(when.index + when.text.length),
      msg = util.format("%s %s me to %s you %s",
                        by,
                        verbs[0],
                        verbs[1],
                        body),
      score = when.startDate.getTime() + TZ_OFFSET * 60 * 1000;

  var reminder = {
    who: who,
    what: msg,
    when: when.startDate,
    by: by
  };

  return client.zadd(REDIS_KEY,
                     score,
                     JSON.stringify(reminder),
                     function(err) {
    if (err) {
      return next(err);
    }

    return res.send(201, util.format("Ok, I'll %s %s %s %s.",
                                     verbs[1],
                                     who,
                                     body,
                                     moment(score).zone(TZ_OFFSET).calendar()));

  });
});
Exemplo n.º 10
0
   })
   if (!resolvedDate && (date || time)) {
     if (!date) {
       date = utils.toDate8601(now)
     }
     if (time) {
       date += time
     }
     resolvedDate = new Date(date)
   }
   return resolvedDate
 },
 recognizeTime (utterance, refDate) {
   let response = null
   try {
     const results = chrono.parse(utterance, refDate)
     if (results && results.length > 0) {
       let duration = results[0]
       response = {
         type: 'chrono.duration',
         entity: duration.text,
         startIndex: duration.index,
         endIndex: duration.index + duration.text.length,
         resolution: {
           resolution_type: 'chrono.duration',
           start: duration.start.date()
         }
       }
       if (duration.end) {
         response.resolution.end = duration.end.date()
       }
Exemplo n.º 11
0
const handler = (payload, res) => {
  const msg = _.defaults({
    channel: payload.channel_name
  }, msgDefaults);

  const eventString = payload.text;
  const eventData = chrono.parse(eventString);

  let endDate,
    entries = [],
    startDate,
    updatedString;

  if (eventData.length) {
    updatedString = eventString.replace(eventData[0].text, '').trim();

    if (eventData[0].end === undefined) {
        // same start and end day
        msg.text = 'I\'ve recorded that on ' +
        moment(eventData[0].start.date()).format('MMMM Do') +
        ' you\'ll be "' + updatedString + '"';

        entries.push({
            action_date: eventData[0].start.date(),
            action: updatedString,
            user_name: payload.user
        });


    } else {
        // multiple dates in range
        msg.text = 'I\'ve recorded that between ' +
        moment(eventData[0].start.date()).format('MMMM Do') +
        ' and ' +
        moment(eventData[0].end.date()).format('MMMM Do') +
        ' you\'ll be "' + updatedString + '"';

        let startDate = eventData[0].start.date();
        let endDate = eventData[0].end.date();

        endDate = endDate.setDate(endDate.getDate() + 1);

        while(startDate < endDate){
            entries.push({
                action_date: startDate,
                action: updatedString,
                user_name: payload.user
            });

            let newDate = startDate.setDate(startDate.getDate() + 1);
            startDate = new Date(newDate);
        }
    }

    entries.forEach( function(entry) {
        let insert = knex('entries').insert(entry);
        let update = knex('entries').update(entry);

        let query = util.format(
            '%s ON CONFLICT ("user_name", "action_date") DO UPDATE SET %s',
            insert.toString(),
            update.toString().replace(/^update ([`"])[^\1]+\1 set/i, '')
        );

        knex.raw(query).then();
    });

  } else {
    if (eventString.length) {
        msg.text = 'Sorry - I couldn\'t figure out what you meant by "' + eventString + '"';
    } else {
        msg.text = 'Use `@uptae help` for instructions on use.';
    }
  }

  res.set('content-type', 'application/json');
  res.status(200).json(msg);
  return;
};
Exemplo n.º 12
0
exports.run = function (api, event) {
    if (event.arguments.length === 1) {
        return print(api, event);
    }
    else if (event.arguments.length === 2) {
        if (isNumeric(event.arguments[1])) {
            return castVote(api, event, parseInt(event.arguments[1]));
        }
        else if (event.arguments[1] === 'cancel') {
            return end(api, event, 'cancel', false);
        }
        else if (event.arguments[1] === 'end') {
            return end(api, event, 'end', true);
        }
    }

    event.arguments.splice(0, 1);
    let timeout = 0,
        question = defaultQuestion;

    for (let i = 0 ; i < event.arguments.length - 1; i++) {
        if (event.arguments[i] === '-q') {
            if (question !== defaultQuestion) {
                api.sendMessage('Do you really think that having more than one question is good idea? Even I\'m confused by this prospect', event.thread_id);
                return;
            }
            question = event.arguments[i + 1];
            event.arguments.splice(i, 2);
            i--;
        }
        else if (event.arguments[i] === '-t') {
            if (timeout !== 0) {
                api.sendMessage('Do you really think that having more than one timeout is good idea? Even I\'m confused by this prospect', event.thread_id);
                return;
            }
            if (isNumeric(event.arguments[i + 1])) {
                timeout = new Date(parseInt(event.arguments[i + 1]) * 1000 + Date.now());
            }
            else {
                let chronoDate = chrono.parse(event.arguments[i + 1]);
                if (chronoDate[0]) {
                    let date = chronoDate[0].start.date();
                    timeout = date;
                }
                else {
                    api.sendMessage('Sorry I couldn\'t work out what date or time you ment.', event.thread_id);
                    return;
                }
            }
            if (timeout < Date.now()) {
                api.sendMessage('Do you really think that a time in the past is a good idea? I\'m  going to ignore you now.', event.thread_id);
                return;
            }
            event.arguments.splice(i, 2);
            i--;
        }
    }


    if (event.arguments.length < 2)  {
        return api.sendMessage('WTF are you doing????!', event.thread_id);
    }

    event.arguments.unshift(question);

    createVote(api, event, event.arguments, timeout);
};
Exemplo n.º 13
0
	function testNLCDateParser(){
		printResults(chrono.parse('Please do the installation next Friday at 3pm'));
	};
Exemplo n.º 14
0
PlannerBot.prototype._analyzeMessage = function (event, newMessage, cb) {

  var self = this;

  // Date Extractions
  var results = chrono.parse(newMessage.text);
  results.forEach(function(item, i) {

    //console.log("________ITEM ______");
        //console.log(item);
    if(self._isEventValid(event) === "missing startDate") {
      if(typeof item.start !== "undefined") {
        if (!item.start.isCertain('hour')) {
            item.start.assign('hour', 0);
        }
        event.startDate = item.start.date();
      }
    } else if(self._isEventValid(event) === "missing startTime") {
      // If the startDate has been already found, I need the time
      if (item.start.isCertain('hour') === true) {
        if(typeof item.start.knownValues.hour !== "undefined") {
          event.startDate = moment(event.startDate).set('hour', item.start.knownValues.hour).format();
        }
        if(typeof item.start.knownValues.minute !== "undefined") {
          event.startDate = moment(event.startDate).set('minute', item.start.knownValues.minute).format();
        }
      }
    }

    if(typeof item.end !== "undefined") {
      if (!item.end.isCertain('hour')) {
          item.end.assign('hour', 0);
      }
      event.endDate = item.end.date();
    } else if(typeof item.end === "undefined" &&
              typeof event.startDate !== "undefined" &&
              typeof item.start !== "undefined" &&
              i > 0) {
                // I have found the endDate using the item.start object (basically I've found 2 start dates
                if (!item.start.isCertain('hour')) {
                    item.start.assign('hour', 0);
                }
                event.endDate = item.start.date();
    }

//      console.log("DIFF = " + moment(event.endDate).diff(moment(event.startDate), 'days'));
//        console.log("__________________");
  });

  if(moment(event.endDate).diff(moment(event.startDate), 'days') > 0) {
      event.allday = true;
  }

  // If the event is not allday and the endDate is null or before startDate, I will force endDate to be startDate + 1h
  if(event.allday === false && event.startDate !== "" && (event.endDate === "" || moment(event.endDate).isBefore(event.startDate))) {
    event.endDate = moment(event.startDate).add(1, 'hour');
  } else if(event.allday === true && event.endDate === "") {
    // If the event is allday (true) it means that a time hasn't been specified
    // and the bot has asked the user to confirm that there's no time for this event
    // The endDate will be the same as startDate in case no endDate has been defined by the user
    event.endDate = moment(event.startDate);
  }

  // AlchemyAPI invoked here
  alchemy.combined(newMessage.text, ['TextGetRelations'], {}, function(err, response) {
    if (err) throw err;

    // See http://www.alchemyapi.com/api/combined-call/ for format of returned object.
    var relations = response.relations;

    relations.forEach(function(relation, index, array) {
      if(typeof relation.subject !== "undefined" && typeof relation.subject.text !== "undefined") {
        event.subject = relation.subject;
      }
      if(typeof relation.action !== "undefined" && typeof relation.action.text !== "undefined") {
        event.action = relation.action;
      }
      if(typeof relation.object !== "undefined" && typeof relation.object.text !== "undefined") {
        event.object = relation.object;
      }
    });

    var regex_im = /I(’|')m/gmi;
    var regex_ill = /I(’|')ll/gmi;

    // If the event is valid (ready) means that all required fields are filled and I can proceed
    // otherwise I need to ask the missing informations to the user
    if(self._isEventValid(event) === true) {
//    console.log("************ RELATIONS ************");
//    console.log(event.summary);
//    console.log(relations);
//    console.log(relations[0].action.verb);
//    console.log(event.subject);
//    console.log(event.action);
//    console.log(event.object);
    if(typeof event.action !== "undefined" &&
    typeof event.action.verb !== "undefined" &&
    typeof event.action.verb.text !== "undefined" &&
    typeof event.action.verb.tense !== "undefined" &&
    typeof event.subject !== "undefined" &&
    typeof event.subject.text !== "undefined" &&
    event.subject.text !== "") {

          // Present
          if(event.action.verb.tense === "present") {
            if(event.subject.text === "I" && event.action.verb.text === "have") {
              // I replace "I" with "Andrea"
              event.summary = event.summary.replace(event.subject.text, self.slack.members[event.message.user].first_name);
              // I replace "have" with "has"
              event.summary = event.summary.replace(event.action.verb.text, "has");
              console.log("------------------ P1 --------------");
            } else if(event.subject.text === "I" && event.summary.search(regex_im) >= 0) {
              // I replace "I'm" or "I’m" with "Andrea is"
              event.summary = event.summary.replace(regex_im, self.slack.members[event.message.user].first_name + " is");
              console.log("------------------ P2 --------------");
            } else if(event.subject.text === "I" && event.action.text === "am") {
              // I replace "I am" with "Andrea is"
              event.summary = event.summary.replace(event.subject.text, self.slack.members[event.message.user].first_name);
              // I replace "m" with "is"
              event.summary = event.summary.replace(event.action.text, "is");
              console.log("------------------ P3 --------------");
            } else if(event.subject.text === "I" && (event.action.text === "ll be" || event.action.text === "will" || event.summary.search(regex_ill) >= 0)) {
              // Alchemy doesn't contracted verbs like "I'll" and it returns action.verb.tense = "present" for those
              // so here I try to see if there's "'ll" in the message
              // I replace "I'll" with "Andrea will" when Alchemy returns tense: present
              event.summary = event.summary.replace(regex_ill, self.slack.members[event.message.user].first_name+" will");
              console.log("------------------ P4 --------------");
            } else if(event.subject.text === "I" || event.subject.text.indexOf("and I") >= 0 || event.summary.indexOf("and I") >= 0) {
              // I replace "and I " with "and Andrea"
              event.summary = event.summary.replace("and I ", "and " + self.slack.members[event.message.user].first_name+" ");
              console.log("------------------ P5 --------------");
            } else {
              // The subject is not "I"
              // I append "Andrea" before the summary
              event.summary = self.slack.members[event.message.user].first_name + ": " + event.summary;
              console.log("------------------ P-ELSE --------------");
            }
          } else if(event.action.verb.tense === "future") {
            if(event.subject.text === "I" && event.summary.search(regex_im) >= 0) {
              // I replace "I'm" with "Andrea is"
              event.summary = event.summary.replace(regex_im, self.slack.members[event.message.user].first_name+" is");
              console.log("------------------ F1 --------------");
            } else if(event.subject.text === "I" && event.summary.search(regex_ill) >= 0) {
              // I replace "I'll" with "Andrea will" when Alchemy returns tense: future
              event.summary = event.summary.replace(regex_ill, self.slack.members[event.message.user].first_name+" will");
              console.log("------------------ F2 --------------");
            } else if(event.subject.text === "I" || event.subject.text.indexOf("and I") >=0 || event.summary.indexOf("and I ") >= 0) {
              // I replace "and I " with "and Andrea"
              event.summary = event.summary.replace("and I ", "and " + self.slack.members[event.message.user].first_name+" ");
              console.log("------------------ F3 --------------");
            } else if(event.subject.text === "I") {
              // I replace "I" with "Andrea"
              event.summary = event.summary.replace(event.subject.text, self.slack.members[event.message.user].first_name);
              console.log("------------------ F4 --------------");
            } else {
              // The subject is not "I"
              // I append "Andrea" before the summary
              event.summary = self.slack.members[event.message.user].first_name + ": " + event.summary;
              console.log("------------------ F-ELSE --------------");
            }
          } else {
              // Past tense maybe?
              // I append the name
              event.summary = self.slack.members[event.message.user].first_name + ": " + event.summary;
              console.log("------------------ PAST-or-UNKNOWN --------------");
          }

/*
I'm going to the gym today at 16:00
I'll be at the gym today at 16:00
Bhav and I meeting Cannon on 13th of April at 2:30 pm
*/
      } else if(event.subject === "" ||
                typeof event.subject === "undefined" ||
                event.subject.text === "") {
                // For sentences like "I’m going to an event on the 29/03 from 16:00 to 19:00" AlchemyAPI doesn't reutrn
                // any relation, so before I apply the "default solution" I want to try a bit harder...
                if(event.summary.search(regex_im) >= 0) {
                   // I replace "I'm" with "Andrea is"
                   event.summary = event.summary.replace(regex_im, self.slack.members[event.message.user].first_name+" is");
                } else if(event.summary.search(regex_ill) >= 0) {
                   // I replace "I'll" with "Andrea will"
                   event.summary = event.summary.replace(regex_ill, self.slack.members[event.message.user].first_name+" will");
                } else {
                   // I append "Andrea" before the summary
                   event.summary = self.slack.members[event.message.user].first_name + ": " + event.summary;
                }
          console.log("------------------ ALMOST-LAST-HOPE --------------");
      } else {
          // This case is not handled correctly yet, if I end up here it means I have no a clue of who is the subject of the action
          // so I will append the sender name, just in case.
          event.summary = self.slack.members[event.message.user].first_name + ": " + event.summary;
          console.log("------------------ LAST-HOPE --------------");
      }


      // remove "@plannerbot:" from the string
      var originalMessage = event.summary.replace("<@" + self.botID + ">: ", "");

      // I will ask a confirmation to the user
      // Initialising the message
      var _msg = "Do you want me to schedule `" + originalMessage + "`";

      // If the event has a endDate, then I need to display a "period" not a specific date
      var readableDateFormat = "dddd, Do of MMMM, YYYY";

      // If the event has start & end dates I will display a period (From .. To ..)
      if(event.endDate !== "" && moment(event.startDate).isSame(event.endDate) === false) {
        if(moment(event.startDate).hour() > 0 && moment(event.endDate).hour() > 0) {
          readableDateFormat = "HH:mm dddd, Do of MMMM, YYYY"
        }
        _msg += " from `" + moment(event.startDate).format(readableDateFormat) + "` to `" + moment(event.endDate).format(readableDateFormat) + "`?";
      } else {
          // There is no endDate so must be a all-day event
          _msg += " on `" + moment(event.startDate).format(readableDateFormat) + "`?";
      }

      self._replyToUser(event.message.user, _msg);
    } else {

      // The event is not valid, means some of required params (such as startDate) are missing
      if(self._isEventValid(event) === "missing startDate") {
        // I need to ask the startDate to the user
        var _msg = "When is this happening?";
        self._replyToUser(event.message.user, _msg);
      } else if(self._isEventValid(event) === "missing startTime") {
        // I need to ask the startTime to the user
        var _msg = "Do you have a time for this event, if yes, what time?";
        self._replyToUser(event.message.user, _msg);
      } else {
        var _msg = "Sorry but I have no idea of what is happening";
        self._replyToUser(event.message.user, _msg);
      }
    }
    if(typeof cb === "function") {
      cb(true);
    }

  });
}