poserver
Version:
Server for JD Bot
781 lines (675 loc) • 33.8 kB
JavaScript
/**
* Created by tomdaley on 9/18/16.
*/
/**
* F A M I L Y V I O L E N C E P R O T E C T I V E O R D E R
*/
var ParsedName = require('./../classes/clsParsedName');
/**
* @namespace
* @property {object} results
* @property {object} results.response
* @property {number} results.response.index
* @property {string} restuls.response.entity
*/
var prompts = require('./../const/prompts');
var Util = require('./../JdBotUtil');
module.exports =
{
createDialogs: function (bot, builder)
{
bot.dialog('/familyViolencePo',
[
function (session)
{
session.userData.selectedService = "/familyViolencePo";
session.userData.violentActs = [];
session.send(prompts.sayOKFamilyViolencePo);
session.userData.identityPrompt = prompts.askVictimFullname;
session.userData.identityRole = "victim";
session.beginDialog('*:/getPersonIdentity');
},
function (session)
{
session.userData.identityPrompt = prompts.askPerpetratorFullname;
session.userData.identityRole = "actor";
session.beginDialog('*:/getPersonIdentity');
},
function (session)
{
session.beginDialog('*:/getActDescription');
},
function (session)
{
Util.queueProtectiveOrder(session);
session.replaceDialog("customerSurvey:/");
}
]
);
/**
* Get information about a person.
*/
bot.dialog('/getPersonIdentity',
[
//Prompt for full name.
function (session)
{
builder.Prompts.text(session, session.userData.identityPrompt);
},
//Process full name
function (session, results, next)
{
var personName = ParsedName.parseName(results.response);
session.userData[session.userData.identityRole] = {};
session.userData[session.userData.identityRole].fullName = results.response;
session.userData[session.userData.identityRole].parsedName = personName;
next();
},
//If able to infer gender from name, then save gender and move to next step.
//Otherwise prompt for gender.
function (session, args, next)
{
/** @param {ParsedName} personName */
var personName = session.userData[session.userData.identityRole].parsedName;
if (personName.inferredGender === -1)
{
var prompt = session.gettext(prompts.askNamedGender, {name: personName.firstName});
builder.Prompts.choice(session, prompt, prompts.gender, session.userData.config.PromptChoiceOptions);
}
else
{
session.userData[session.userData.identityRole].gender = personName.inferredGender;
next();
}
},
//If gender is missing, we must have prompted for it, so process the response.
function (session, results, next)
{
if (!session.userData[session.userData.identityRole].hasOwnProperty("gender"))
{
session.userData[session.userData.identityRole].gender = results.response.index;
}
next();
},
//Prompt for date of birth
function (session)
{
var pp = prompts.possessivePronoun[session.userData[session.userData.identityRole].gender];
var prompt = session.gettext(prompts.askNamedDateOfBirth, {name: pp});
builder.Prompts.time(session, prompt);
},
//Process date of birth
//We get the date in a Javascript Date format, but on the next turn, it is converted to a String
//in JSON format. We might as well deal with that from the beginning so that our code will be
//consistent.
function (session, results, next)
{
session.userData[session.userData.identityRole].birthDate = (builder.EntityRecognizer.resolveTime([results.response])).toJSON();
next();
},
//Ask for current residence address or whereabouts
function (session)
{
var names = Util.getUniqueNames(session.userData.actor.parsedName, session.userData.victim.parsedName);
var aName;
var pronoun;
if (session.userData.identityRole === "victim")
{
aName = names.victimName;
pronoun = prompts.subjectPronoun[session.userData.victim.gender];
}
else
{
aName = names.actorName;
pronoun = prompts.subjectPronoun[session.userData.actor.gender];
}
var prompt = session.gettext(prompts.askCurrentAddress, {"name": aName, "pronoun": pronoun});
builder.Prompts.text(session, prompt);
},
//Get current address or whereabouts
function (session, results, next)
{
session.userData[session.userData.identityRole].currentAddress = results.response;
//See if Google can clean this address up for us AND add a county for the address.
//I hate prompting for county because so many non-lawyers think I'm asking for COUNTRY.
var callback = function (session, parsedAddress)
{
console.log(parsedAddress);
if (parsedAddress.status == "OK")
{
if (parsedAddress.hasCompleteStreet && parsedAddress.hasCompleteCsz)
session.userData[session.userData.identityRole].currentAddress = parsedAddress.fullAddress;
session.userData[session.userData.identityRole].address = parsedAddress;
}
next();
};
Util.geoCodeAddress(results.response, "", session, callback);
},
//Prompt for county, if we need it.
function (session, results, next)
{
var address = session.userData[session.userData.identityRole].address;
if (!address.hasOwnProperty("county"))
{
builder.Prompts.text(session, prompts.askAddressCounty);
}
else
{
next();
}
},
//Process county result
function (session, results, next)
{
if (results.resumed === 0 && results.response != "?")
session.userData[session.userData.identityRole].address.county = results.response;
next();
},
//OK. We're done asking about this person (for now)
function (session)
{
session.endDialog(prompts.movingOn);
}
]
);
/**
* Get information about an alleged act of violence.
*/
bot.dialog('/getActDescription',
[
//Ask for a description of the violent act. Later, we may use a database and tree the user to a
//specific verb so (a) we can use normative language; and (b) we can determine whether we need to
//ask about instrumentalities and body parts.
function (session)
{
var names = Util.getUniqueNames(session.userData.actor.parsedName, session.userData.victim.parsedName);
var elseText = "";
if (session.userData.hasOwnProperty(("violentActs")) &&
session.userData.violentActs.length > 0)
elseText = " else";
var prompt = session.gettext(prompts.askSpecificActDescription, {
else : elseText,
aname: names.actorName,
vname: names.victimName
});
builder.Prompts.text(session, prompt);
},
//Save the violent act description.
function (session, results, next)
{
var violentAct = {};
violentAct.description = results.response;
session.userData.violentActs.push(violentAct);
session.userData.violentActIndex = session.userData.violentActs.length - 1;
next();
},
//Get the act date
function (session)
{
if (session.userData.violentActIndex === 0)
session.beginDialog('/violentAct-GetDateOfFirstAct');
else
session.beginDialog('/violentAct-GetDateOfSubsequentAct');
},
//Get location of the violent act
function (session)
{
if (session.userData.violentActIndex === 0)
session.beginDialog('/violentAct-GetLocationOfFirstAct');
else
session.beginDialog('/violentAct-GetLocationOfSubsequentAct');
},
//Prompt for whether a weapon was used. See introductory notes above.
function (session)
{
var aname = session.userData.actor.fullName;
var prompt = session.gettext(prompts.askWhetherInstrumentality, {"aname": aname});
builder.Prompts.confirm(session, prompt, session.userData.config.PromptChoiceOptions);
},
//If a weapon was involved, ask what kind of weapon it was.
function (session, results, next)
{
var violentAct = session.userData.violentActs[session.userData.violentActIndex];
violentAct.weaponInvolved = results.response;
if (violentAct.weaponInvolved)
{
var aname = prompts.subjectPronoun[session.userData.actor.gender];
var prompt = session.gettext(prompts.askInstrumentality, {"aname": aname});
builder.Prompts.text(session, prompt);
}
else
{
next();
}
},
//Get the weapon type, if applicable.
function (session, results, next)
{
var violentAct = session.userData.violentActs[session.userData.violentActIndex];
if (violentAct.weaponInvolved)
{
violentAct.weapon = results.response;
}
next();
},
//Find out whether there are photographs, videos, or sound recordings
function (session)
{
var prompt = prompts.askWhetherRecordings;
var choices = prompts.recordingChoices;
builder.Prompts.choice(session, prompt, choices, session.userData.config.PromptChoiceOptions);
},
//Save the recordings indicator
function (session, results, next)
{
var violentAct = session.userData.violentActs[session.userData.violentActIndex];
violentAct.actRecordings = prompts.recordingChoices[results.response.index];
next();
},
//Ask whether there were any injuries visible on the date of the act.
function (session)
{
var vname = Util.getUniqueNames(session.userData.actor.parsedName, session.userData.victim.parsedName).name2;
var prompt = session.gettext(prompts.askWhetherVisibleInjuriesDayOfIncident, {"vname": vname});
builder.Prompts.confirm(session, prompt, session.userData.config.PromptChoiceOptions);
},
//Ask to describe visible injuries on date of incident
function (session, results)
{
var violentAct = session.userData.violentActs[session.userData.violentActIndex];
violentAct.injuriesVisibleSameDay = results.response;
var vname = Util.getUniqueNames(session.userData.actor.parsedName, session.userData.victim.parsedName).name2;
var prompt;
if (violentAct.injuriesVisibleSameDay)
{
prompt = session.gettext(prompts.askDescribeInjuries, {"vname": vname});
builder.Prompts.text(session, prompt);
}
else
{
prompt = session.gettext(prompts.askWhetherInjuriesAppearedSubsequently, {"vname": vname});
builder.Prompts.confirm(session, prompt, session.userData.config.PromptChoiceOptions);
}
},
//Either get description of "same day" injuries or prompt for description of subsequent injuries
function (session, results, next)
{
var violentAct = session.userData.violentActs[session.userData.violentActIndex];
if (violentAct.injuriesVisibleSameDay)
{
violentAct.injuriesDescriptionSameDay = results.response;
next();
}
else
{
violentAct.injuriesVisibleLater = results.response;
if (violentAct.injuriesVisibleLater)
{
var vname = Util.getUniqueNames(session.userData.actor.parsedName, session.userData.victim.parsedName).name2;
var prompt = session.gettext(prompts.askDescribeLaterInjuries, {"vname": vname});
builder.Prompts.text(session, prompt);
}
else
{
next();
}
}
},
//Either get description of subsequent injuries & prompt for date visible or skip to next function
function (session, results, next)
{
var violentAct = session.userData.violentActs[session.userData.violentActIndex];
if (violentAct.injuriesVisibleLater)
{
violentAct.injuriesDescriptionLater = results.response;
var vname = Util.getUniqueNames(session.userData.actor.parsedName, session.userData.victim.parsedName).name2;
var prompt = session.gettext(prompts.askSubsequentInjuriesDate, {
"vname" : vname,
"injuries": results.response
});
builder.Prompts.time(session, prompt);
}
else
{
next();
}
},
//Either get date that injuries became visible or skip to next function
function (session, results, next)
{
var violentAct = session.userData.violentActs[session.userData.violentActIndex];
if (violentAct.injuriesVisibleLater)
{
violentAct.injuriesVisibleDate = (builder.EntityRecognizer.resolveTime([results.response])).toJSON();
}
next();
},
//We're done with this description.
function (session, results, next)
{
describePo(session);
next();
},
//See if there are additional acts of violence between these two to report
function (session)
{
var names = Util.getUniqueNames(session.userData.actor.parsedName, session.userData.victim.parsedName);
var people = {"aname": names.actorName, "vname": names.victimName};
var prompt = session.gettext(prompts.askAdditionalActsOfViolence, people);
builder.Prompts.confirm(session, prompt, session.userData.config.PromptChoiceOptions);
},
//If there are additional acts, then start over again. Otherwise, quit this dialog.
function (session, results, next)
{
if (results.response) //Yes
{
session.replaceDialog('/getActDescription');
}
else
{
next();
}
},
function (session)
{
session.endDialog(prompts.thankYou);
}
]
);
bot.dialog('/violentAct-GetLocationOfFirstAct',
[
//Prompt for where the violent act occurred
function (session)
{
builder.Prompts.text(session, prompts.askWhereViolenceOccurred);
},
//Get location of violent act.
function (session, results, next)
{
var violentAct = session.userData.violentActs[session.userData.violentActIndex];
violentAct.location = results.response;
violentAct.address = {};
//See if Google can clean this address up for us AND add a county for the address.
var callback = function (session, parsedAddress)
{
console.log("In callback");
console.log(parsedAddress);
var violentAct = session.userData.violentActs[session.userData.violentActIndex];
if (parsedAddress.status == "OK")
{
if (parsedAddress.hasCompleteStreet && parsedAddress.hasCompleteCsz)
{
violentAct.location = parsedAddress.fullAddress;
}
console.log('Inspect violent act');
console.log(violentAct);
violentAct.address = parsedAddress;
}
console.log("About to go to next()");
console.log(next);
next();
};
Util.geoCodeAddress(results.response, "", session, callback);
},
//Prompt for state, if we need it.
function (session, results, next)
{
var address = session.userData.violentActs[session.userData.violentActIndex].address;
if (!address.hasOwnProperty("state"))
{
builder.Prompts.text(session, prompts.askAddressState);
}
else
{
next();
}
},
//Process state result
function (session, results, next)
{
if (results.resumed === 0 && results.response != "?")
session.userData.violentActs[session.userData.violentActIndex].address.state = results.response;
next()
},
//Prompt for county, if we need it.
function (session, results, next)
{
console.log("After callback");
var address = session.userData.violentActs[session.userData.violentActIndex].address;
console.log(address);
if (!address.hasOwnProperty("county"))
{
builder.Prompts.text(session, prompts.askAddressCounty);
}
else
{
next();
}
},
//Process county result
function (session, results)
{
if (results.resumed === 0 && results.response != "?")
session.userData.violentActs[session.userData.violentActIndex].address.county = results.response;
session.endDialog();
}
]);
bot.dialog('/violentAct-GetLocationOfSubsequentAct',
[
//If this is NOT the first act being reported, ask if the location = previous location.
function (session)
{
var violentAct = session.userData.violentActs[session.userData.violentActIndex];
var previousViolentAct = session.userData.violentActs[session.userData.violentActIndex - 1];
var names = Util.getUniqueNames(session.userData.actor.parsedName, session.userData.victim.parsedName);
var prompt = session.gettext(prompts.askWhetherSameLocationAsPrevious,
{
aname : names.actorName,
anamep : prompts.subjectPronoun[session.userData.actor.gender],
vname : names.victimName,
vnamep : prompts.objectPronoun[session.userData.victim.gender],
thisact : violentAct.description,
prevact : previousViolentAct.description,
plocation: previousViolentAct.location
});
builder.Prompts.confirm(session, prompt, session.userData.config.PromptChoiceOptions);
},
//If this is NOT the first act being reported, get the yes/no about previous location
function (session, results)
{
if (results.response) // this act was at the same location as the prior act
{
var violentAct = session.userData.violentActs[session.userData.violentActIndex];
var previousViolentAct = session.userData.violentActs[session.userData.violentActIndex - 1];
violentAct.location = previousViolentAct.location;
violentAct.address = previousViolentAct.address;
session.endDialog();
}
else
{
//This act was NOT at the same location as the previous one, so prompt for the location.
var prompt;
prompt = session.gettext(prompts.askWhereViolenceOccurred);
builder.Prompts.text(session, prompt);
}
},
//Get the location for this subsequent act
function (session, results, next)
{
var violentAct = session.userData.violentActs[session.userData.violentActIndex];
violentAct.location = results.response;
violentAct.address = {};
//See if Google can clean this address up for us AND add a county for the address.
var callback = function (session, parsedAddress)
{
var violentAct = session.userData.violentActs[session.userData.violentActIndex];
if (parsedAddress.status == "OK")
{
if (parsedAddress.hasCompleteStreet && parsedAddress.hasCompleteCsz)
{
violentAct.location = parsedAddress.fullAddress;
}
violentAct.address = parsedAddress;
}
next();
};
Util.geoCodeAddress(results.response, "", session, callback);
},
//Prompt for state, if we need it.
function (session, results, next)
{
var address = session.userData.violentActs[session.userData.violentActIndex].address;
if (!address.hasOwnProperty("state"))
{
builder.Prompts.text(session, prompts.askAddressState);
}
else
{
next();
}
},
//Process state result
function (session, results, next)
{
if (results.resumed === 0 && results.response != "?")
session.userData.violentActs[session.userData.violentActIndex].address.state = results.response;
next()
},
//Prompt for county, if we need it.
function (session, results, next)
{
var address = session.userData.violentActs[session.userData.violentActIndex].address;
if (!address.hasOwnProperty("county"))
{
builder.Prompts.text(session, prompts.askAddressCounty);
}
else
{
next();
}
},
//Process county result
function (session, results)
{
if (results.resumed === 0 && results.response != "?")
session.userData.violentActs[session.userData.violentActIndex].address.county = results.response;
session.endDialog();
}
]
);
bot.dialog('/violentAct-GetDateOfFirstAct',
[
//If this is the first act being reported, ask for the date of the act.
function (session)
{
var names = Util.getUniqueNames(session.userData.actor.parsedName, session.userData.victim.parsedName);
var prompt;
var violentAct = session.userData.violentActs[session.userData.violentActIndex];
prompt = session.gettext(prompts.askSpecificActDate, {
act : violentAct.description,
aname: names.actorName,
vname: names.victimName
});
builder.Prompts.time(session, prompt);
},
//If this is the first act being reported, we are getting the date, otherwise, move on.
function (session, results)
{
var violentAct = session.userData.violentActs[session.userData.violentActIndex];
violentAct.date = (builder.EntityRecognizer.resolveTime([results.response])).toJSON();
session.endDialog();
}
]
);
bot.dialog('/violentAct-GetDateOfSubsequentAct',
[
//If this is NOT the first act being reported, ask if the date = previous date.
function (session)
{
var violentAct = session.userData.violentActs[session.userData.violentActIndex];
var previousViolentAct = session.userData.violentActs[session.userData.violentActIndex - 1];
var names = Util.getUniqueNames(session.userData.actor.parsedName, session.userData.victim.parsedName);
var prompt = session.gettext(prompts.askWhetherSameDayAsPrevious,
{
aname : names.actorName,
anamep : prompts.subjectPronoun[session.userData.actor.gender],
vname : names.victimName,
vnamep : prompts.objectPronoun[session.userData.victim.gender],
thisact: violentAct.description,
prevact: previousViolentAct.description,
pdate : previousViolentAct.date
});
builder.Prompts.confirm(session, prompt, session.userData.config.PromptChoiceOptions);
},
//If this is NOT the first act being reported, get the yes/no about previous date
function (session, results)
{
if (results.response) // this act was on the same date as the prior act
{
var violentAct = session.userData.violentActs[session.userData.violentActIndex];
var previousViolentAct = session.userData.violentActs[session.userData.violentActIndex - 1];
violentAct.date = previousViolentAct.date;
session.endDialog();
}
else
{
//This act was NOT on the same date as the previous one, so prompt for the date.
var names = Util.getUniqueNames(session.userData.actor.parsedName, session.userData.victim.parsedName);
var prompt;
prompt = session.gettext(prompts.askSpecificActDate, {
act : results.response,
aname: names.actorName,
vname: names.victimName
});
builder.Prompts.time(session, prompt);
}
},
//Get the occurrence date for this subsequent act
function (session, results)
{
var violentAct = session.userData.violentActs[session.userData.violentActIndex];
violentAct.date = (builder.EntityRecognizer.resolveTime([results.response])).toJSON();
session.endDialog();
}
]
);
bot.dialog("/getVerbDetails",
[
function (session)
{
}
]);
}
};
/**
* A temporary function that returns a very rough description of a violent event based on the user's
* input. Something like this will be used on the back end document-generation/attorney-review service.
* For now it shows how far I have to go in parsing broken and battered English into something that will
* cleanly slide into a supporting affidavit.
*
* @param session
*/
function describePo(session)
{
console.log(session.userData);
var violentAct = session.userData.violentActs[session.userData.violentActIndex];
//Convert JSON date to Javascript Date so we have more flexibility in formatting.
var dDate = new Date(violentAct.date);
var aDate = new Date(session.userData.actor.birthDate);
var vDate = new Date(session.userData.victim.birthDate);
var d = "On or about " +
dDate.toDateString() + ", while at " +
violentAct.location + ", " +
session.userData.actor.fullName + ", a " +
prompts.gender[session.userData.actor.gender] + " born " +
aDate.toDateString() + ", did then and there " +
violentAct.description + " " +
session.userData.victim.fullName + ", a " +
prompts.gender[session.userData.victim.gender] + " born " +
vDate.toDateString() + ". ";
d += (violentAct.weaponInvolved) ?
session.userData.actor.fullName + " used a weapon, to wit: " +
violentAct.weapon + "." :
"No weapon was used.";
session.send(d);
}