pockybot
Version:
Spark bot that handles team recognition
168 lines (167 loc) • 7.39 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const trigger_1 = require("../../models/trigger");
const constants_1 = require("../../constants");
const db_constants_1 = require("../db-constants");
const xmlMessageParser_1 = require("../parsers/xmlMessageParser");
const logger_1 = require("../logger");
class Peg extends trigger_1.default {
constructor(webexService, databaseService, dbUsers, config) {
super();
this.webex = webexService;
this.database = databaseService;
this.dbUsers = dbUsers;
this.config = config;
// match peg, to, at, for with optional spaces between them, and no other words.
// Require at least one keyword match if pegsWithoutKeyword is false
let s = constants_1.default.optionalSpace;
this.pegCommand = `^${s}(?:(?:${s}(?:peg|to|at|for)${s})+)${s}$`;
this.pegComment = '( (?!<spark-mention)(?:(?!<\/p>).)' + (config.getConfig('commentsRequired') ? '+){1}' : '*)?');
}
isToTriggerOn(message) {
let parsedMessage = xmlMessageParser_1.default.parsePegMessage(message);
return this.validateTrigger(parsedMessage);
}
// <spark-mention data-object-type="person" data-object-id="aoeu">BotName</spark-mention>
// peg <spark-mention data-object-type="person" data-object-id="aoei">PersonName</spark-mention>
// for some reasons
async createMessage(message) {
let parsedMessage = xmlMessageParser_1.default.parsePegMessage(message);
if (!this.validateMessage(parsedMessage)) {
return {
markdown: `I'm sorry, I couldn't understand your peg request. Please use the following format:
@` + constants_1.default.botName + ` peg @Person this is the reason for giving you a peg`
};
}
if (this.config.getConfig('requireValues') && !this.validateValues(parsedMessage)) {
return {
markdown: `I'm sorry, you have to include a keyword in your comment. Please include one of the below keywords in your comment:\n`
+ this.config.getStringConfig('keyword').join(', ')
};
}
return await this.givePegWithComment(parsedMessage.comment, parsedMessage.toPersonId, parsedMessage.fromPerson);
}
validateTrigger(message) {
if (message.toPersonId == null || message.botId !== constants_1.default.botId) {
return false;
}
let pattern = new RegExp(this.pegCommand, 'ui');
return pattern.test(message.children[1].text());
}
validateValues(message) {
const keywords = this.config.getStringConfig('keyword');
const penaltyKeywords = this.config.getStringConfig('penaltyKeyword');
// lambda to check if the message contains one of the words in the list on which it is run
const keywordIncluded = keyword => message.comment.toLowerCase().includes(keyword.toLowerCase());
return keywords.some(keywordIncluded) || penaltyKeywords.some(keywordIncluded);
}
validateMessage(message) {
try {
if (message.children.length < 4) {
return false;
}
if (message.children[0].name() !== 'spark-mention' || message.children[2].name() !== 'spark-mention'
|| message.children[0].attr('data-object-type').value() !== 'person'
|| message.children[2].attr('data-object-type').value() !== 'person') {
return false;
}
if (message.children[message.children.length - 1].text().trim() === '') {
return false;
}
return this.validateTrigger(message);
}
catch (e) {
logger_1.Logger.error(`[Peg.validateMessage] Error validating peg message: ${e.message}`);
throw new Error('Error validating peg message');
}
}
async givePegWithComment(comment, toPersonId, fromPerson) {
let result = await this.database.givePegWithComment(comment, toPersonId, fromPerson);
if (result === db_constants_1.default.pegSuccess) {
try {
let pms = await Promise.all([
this.pmReceiver(comment, toPersonId, fromPerson),
this.pmSender(toPersonId, fromPerson)
]);
return pms[1];
}
catch (error) {
logger_1.Logger.error(`[Peg.givePegWithComment] Error in pmReceiver or pmSender: ${error.message}`);
return {
markdown: 'Peg has been given but I was unable to successfully send PMs acknowledging this to both the sender and receiver.'
};
}
}
else if (result === db_constants_1.default.pegAllSpent) {
return {
markdown: 'Sorry, but you have already spent all of your pegs for this fortnight.'
};
}
else {
return {
markdown: 'Error encountered, peg not given'
};
}
}
async pmSender(toPersonId, fromPerson) {
let count;
const keywords = this.config.getStringConfig('keyword');
const penaltyKeywords = this.config.getStringConfig('penaltyKeyword');
try {
count = await this.database.countPegsGiven(fromPerson, keywords, penaltyKeywords);
}
catch (error) {
logger_1.Logger.error(`[Peg.pmSender] Error counting pegsGiven from ${fromPerson}: ${error.message}`);
return {
markdown: 'Giving user\'s count of previously given pegs could not be found. Peg not given.'
};
}
let data;
try {
data = await this.dbUsers.getUser(toPersonId);
}
catch (error) {
logger_1.Logger.error(`[Peg.pmSender] Error in getting receiver in pmSender: ${error.message}`);
return {
markdown: 'User could not be found or created. Peg not given.'
};
}
return {
markdown: 'Peg given to ' + (data.username || 'someone') + '. You have given ' + count + ' ' + (count === 1 ? 'peg' : 'pegs') + ' this fortnight.',
toPersonId: fromPerson,
roomId: null
};
}
async pmReceiver(comment, toPersonId, fromPerson) {
let fromUser;
try {
fromUser = await this.dbUsers.getUser(fromPerson);
}
catch (error) {
logger_1.Logger.error(`[Peg.pmReceiver] Error getting username of user ${fromPerson} to send peg to ${toPersonId}: ${error.message}`);
fromUser = {
userid: '',
username: 'someone'
};
}
let msg;
if (comment.startsWith('for ')) {
msg = `You have received a new peg from ${fromUser.username}: "${comment}"`;
}
else {
msg = `You have received a new peg from ${fromUser.username} for: "${comment}"`;
}
try {
this.webex.messages.create({
markdown: msg,
toPersonId: toPersonId
});
}
catch (error) {
logger_1.Logger.error(`[Peg.pmReceiver] Sending PM to ${toPersonId} with message ${msg} failed`);
throw error;
}
}
}
exports.default = Peg;
;