lib/Aggregate.js

/** @module aggregate */
const utils = require('./utils/Utils.js');

/**
 * Remove key and value pairs with intro* in the key
 * @param {object} responses - value of the responses key in the conversation
 * object
 * @return {object} - responses without intro questions
 */
function removeIntros(responses) {
  const keys = Object.keys(responses);
  const introKeys = keys.map((key) => {
    if (/intro*/gi.test(key)) {
      return key;
    }
  });
  introKeys.map((introKey) => {
    delete responses[introKey];
  });
  return responses;
}

/**
 * @param {object} responses - value of the responses key in the conversation
 * object
 * @return {object} - An object of question and ISO 8601 timestamps with the
 * structure {question+'TimeStamp': {text: <timestamp in ISO 8601>}}
 */
function extractTimeStamps(responses) {
  return Object.keys(responses).reduce((accum, key) => {
    const obj = {};
    const date = new Date(responses[key].timestamp);
    obj[key + 'TimeStamp'] = {text: date};
    return Object.assign(accum, obj);
  }, {});
}

/**
 * Takes a conversation and extracts:
 * - psid (page scoped user id) the messenger user id as per that page
 * - metadata object with startTime, lastActive, bot_identifier & conversation
 * - responses the responses from the conversation
 * @param {object} conversation - A conversation object generated by botkit.
 * @return {object} PSID, responses & submission metadata from the conversation.
 */
function aggregate(conversation) {
  const {startTime, lastActive, responses, context} = conversation;
  const timeStamps = extractTimeStamps(responses);
  const withoutIntros = removeIntros(responses);
  const metadata = {
    startTime,
    lastActive,
    bot_identifier: context,
    conversation,
  };

  return {
    psid: context.user,
    responses: utils.mergeObjects(withoutIntros, timeStamps),
    metadata,
  };
}

/**
 * Generate an Ona submission from an aggregated conversation
 * @param {object} conversation an aggregated conversation
 * @return {object} a valid Ona submission object
 */
function genOnaSubmission({responses}) {
  const submission = {};
  const names = Object.keys(responses);

  const subb = names.map((name) => {
    const kv = {};
    if (name === 'repeat') {
      kv.spoken = responses.repeat.spoken;
      kv.with_whom = responses.repeat.with_whom;
      return kv;
    }
    kv[name] = responses[name].text;
    return kv;
  });

  const sub = subb.reduce((x = {}, kv) => Object.assign(x, kv));
  submission.submission = sub;
  return submission;
}

module.exports = {
  aggregate,
  extractTimeStamps,
  genOnaSubmission,
};