Add message formatters. Expose message formatters to plugins.
parent
0c25afaec2
commit
8a975d7da4
|
@ -5,6 +5,7 @@ const knex = require('../knex');
|
||||||
const utils = require('../utils');
|
const utils = require('../utils');
|
||||||
const config = require('../config');
|
const config = require('../config');
|
||||||
const attachments = require('./attachments');
|
const attachments = require('./attachments');
|
||||||
|
const { formatters } = require('../formatters');
|
||||||
|
|
||||||
const ThreadMessage = require('./ThreadMessage');
|
const ThreadMessage = require('./ThreadMessage');
|
||||||
|
|
||||||
|
@ -28,133 +29,6 @@ class Thread {
|
||||||
utils.setDataModelProps(this, props);
|
utils.setDataModelProps(this, props);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Eris.Member} moderator
|
|
||||||
* @param {string} text
|
|
||||||
* @param {boolean} isAnonymous
|
|
||||||
* @returns {string}
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
_formatStaffReplyDM(moderator, text, isAnonymous) {
|
|
||||||
const mainRole = utils.getMainRole(moderator);
|
|
||||||
const modName = (config.useNicknames ? moderator.nick || moderator.user.username : moderator.user.username);
|
|
||||||
const modInfo = isAnonymous
|
|
||||||
? (mainRole ? mainRole.name : 'Moderator')
|
|
||||||
: (mainRole ? `(${mainRole.name}) ${modName}` : modName);
|
|
||||||
|
|
||||||
return `**${modInfo}:** ${text}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Eris.Member} moderator
|
|
||||||
* @param {string} text
|
|
||||||
* @param {boolean} isAnonymous
|
|
||||||
* @param {number} messageNumber
|
|
||||||
* @param {number} timestamp
|
|
||||||
* @returns {string}
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
_formatStaffReplyThreadMessage(moderator, text, isAnonymous, messageNumber, timestamp) {
|
|
||||||
const mainRole = utils.getMainRole(moderator);
|
|
||||||
const modName = (config.useNicknames ? moderator.nick || moderator.user.username : moderator.user.username);
|
|
||||||
const modInfo = isAnonymous
|
|
||||||
? `(Anonymous) (${modName}) ${mainRole ? mainRole.name : 'Moderator'}`
|
|
||||||
: (mainRole ? `(${mainRole.name}) ${modName}` : modName);
|
|
||||||
|
|
||||||
// TODO: Add \`[${messageNumber}]\` here once !edit and !delete exist
|
|
||||||
let result = `**${modInfo}:** ${text}`;
|
|
||||||
|
|
||||||
if (config.threadTimestamps) {
|
|
||||||
const formattedTimestamp = timestamp ? utils.getTimestamp(timestamp, 'x') : utils.getTimestamp();
|
|
||||||
result = `[${formattedTimestamp}] ${result}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Eris.Member} moderator
|
|
||||||
* @param {string} text
|
|
||||||
* @param {boolean} isAnonymous
|
|
||||||
* @param {string[]} attachmentLinks
|
|
||||||
* @returns {string}
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
_formatStaffReplyLogMessage(moderator, text, isAnonymous, attachmentLinks = []) {
|
|
||||||
const mainRole = utils.getMainRole(moderator);
|
|
||||||
const modName = moderator.user.username;
|
|
||||||
|
|
||||||
// Mirroring the DM formatting here...
|
|
||||||
const modInfo = isAnonymous
|
|
||||||
? (mainRole ? mainRole.name : 'Moderator')
|
|
||||||
: (mainRole ? `(${mainRole.name}) ${modName}` : modName);
|
|
||||||
|
|
||||||
let result = `**${modInfo}:** ${text}`;
|
|
||||||
|
|
||||||
if (attachmentLinks.length) {
|
|
||||||
result += '\n';
|
|
||||||
for (const link of attachmentLinks) {
|
|
||||||
result += `\n**Attachment:** ${link}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Eris.User} user
|
|
||||||
* @param {string} body
|
|
||||||
* @param {Eris.EmbedBase[]} embeds
|
|
||||||
* @param {string[]} formattedAttachments
|
|
||||||
* @param {number} timestamp
|
|
||||||
* @return string
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
_formatUserReplyThreadMessage(user, body, embeds, formattedAttachments = [], timestamp) {
|
|
||||||
const content = (body.trim() === '' && embeds.length)
|
|
||||||
? '<message contains embeds>'
|
|
||||||
: body;
|
|
||||||
|
|
||||||
let result = `**${user.username}#${user.discriminator}:** ${content}`;
|
|
||||||
|
|
||||||
if (formattedAttachments.length) {
|
|
||||||
for (const formatted of formattedAttachments) {
|
|
||||||
result += `\n\n${formatted}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config.threadTimestamps) {
|
|
||||||
const formattedTimestamp = timestamp ? utils.getTimestamp(timestamp, 'x') : utils.getTimestamp();
|
|
||||||
result = `[${formattedTimestamp}] ${result}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Eris.User} user
|
|
||||||
* @param {string} body
|
|
||||||
* @param {Eris.EmbedBase[]} embeds
|
|
||||||
* @param {string[]} formattedAttachments
|
|
||||||
* @return string
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
_formatUserReplyLogMessage(user, body, embeds, formattedAttachments = []) {
|
|
||||||
const content = (body.trim() === '' && embeds.length)
|
|
||||||
? '<message contains embeds>'
|
|
||||||
: body;
|
|
||||||
|
|
||||||
let result = content;
|
|
||||||
|
|
||||||
if (formattedAttachments.length) {
|
|
||||||
for (const formatted of formattedAttachments) {
|
|
||||||
result += `\n\n${formatted}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} text
|
* @param {string} text
|
||||||
* @param {Eris.MessageFile|Eris.MessageFile[]} file
|
* @param {Eris.MessageFile|Eris.MessageFile[]} file
|
||||||
|
@ -285,7 +159,7 @@ class Thread {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send the reply DM
|
// Send the reply DM
|
||||||
const dmContent = this._formatStaffReplyDM(moderator, text, isAnonymous);
|
const dmContent = formatters.formatStaffReplyDM(moderator, text, { isAnonymous });
|
||||||
let dmMessage;
|
let dmMessage;
|
||||||
try {
|
try {
|
||||||
dmMessage = await this._sendDMToUser(dmContent, files);
|
dmMessage = await this._sendDMToUser(dmContent, files);
|
||||||
|
@ -295,7 +169,7 @@ class Thread {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save the log entry
|
// Save the log entry
|
||||||
const logContent = this._formatStaffReplyLogMessage(moderator, text, isAnonymous, attachmentLinks);
|
const logContent = formatters.formatStaffReplyLogMessage(moderator, text, { isAnonymous, attachmentLinks });
|
||||||
const threadMessage = await this._addThreadMessageToDB({
|
const threadMessage = await this._addThreadMessageToDB({
|
||||||
message_type: THREAD_MESSAGE_TYPE.TO_USER,
|
message_type: THREAD_MESSAGE_TYPE.TO_USER,
|
||||||
user_id: moderator.id,
|
user_id: moderator.id,
|
||||||
|
@ -306,7 +180,7 @@ class Thread {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Show the reply in the inbox thread
|
// Show the reply in the inbox thread
|
||||||
const inboxContent = this._formatStaffReplyThreadMessage(moderator, text, isAnonymous, threadMessage.message_number, null);
|
const inboxContent = formatters.formatStaffReplyThreadMessage(moderator, text, threadMessage.message_number, { isAnonymous });
|
||||||
const inboxMessage = await this._postToThreadChannel(inboxContent, files);
|
const inboxMessage = await this._postToThreadChannel(inboxContent, files);
|
||||||
await this._updateThreadMessage(threadMessage.id, { inbox_message_id: inboxMessage.id });
|
await this._updateThreadMessage(threadMessage.id, { inbox_message_id: inboxMessage.id });
|
||||||
|
|
||||||
|
@ -347,7 +221,7 @@ class Thread {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save log entry
|
// Save log entry
|
||||||
const logContent = this._formatUserReplyLogMessage(msg.author, msg.content, msg.embeds, logFormattedAttachments);
|
const logContent = formatters.formatUserReplyLogMessage(msg.author, msg, { attachmentLinks: logFormattedAttachments });
|
||||||
const threadMessage = await this._addThreadMessageToDB({
|
const threadMessage = await this._addThreadMessageToDB({
|
||||||
message_type: THREAD_MESSAGE_TYPE.FROM_USER,
|
message_type: THREAD_MESSAGE_TYPE.FROM_USER,
|
||||||
user_id: this.user_id,
|
user_id: this.user_id,
|
||||||
|
@ -358,7 +232,7 @@ class Thread {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Show user reply in the inbox thread
|
// Show user reply in the inbox thread
|
||||||
const inboxContent = this._formatUserReplyThreadMessage(msg.author, msg.content, msg.embeds, threadFormattedAttachments, null);
|
const inboxContent = formatters.formatUserReplyThreadMessage(msg.author, msg, { attachmentLinks: threadFormattedAttachments });
|
||||||
const inboxMessage = await this._postToThreadChannel(inboxContent, attachmentFiles);
|
const inboxMessage = await this._postToThreadChannel(inboxContent, attachmentFiles);
|
||||||
if (inboxMessage) await this._updateThreadMessage(threadMessage.id, { inbox_message_id: inboxMessage.id });
|
if (inboxMessage) await this._updateThreadMessage(threadMessage.id, { inbox_message_id: inboxMessage.id });
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,208 @@
|
||||||
|
const Eris = require('eris');
|
||||||
|
const utils = require('./utils');
|
||||||
|
const config = require('./config');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to format the DM that is sent to the user when a staff member replies to them via !reply
|
||||||
|
* @callback FormatStaffReplyDM
|
||||||
|
* @param {Eris.Member} moderator Staff member that is replying
|
||||||
|
* @param {string} text Reply text
|
||||||
|
* @param {{
|
||||||
|
* isAnonymous: boolean,
|
||||||
|
* }} opts={}
|
||||||
|
* @return {string} Message content to send as a DM
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to format a staff reply in a thread channel
|
||||||
|
* @callback FormatStaffReplyThreadMessage
|
||||||
|
* @param {Eris.Member} moderator
|
||||||
|
* @param {string} text
|
||||||
|
* @param {number} messageNumber
|
||||||
|
* @param {{
|
||||||
|
* isAnonymous: boolean,
|
||||||
|
* }} opts={}
|
||||||
|
* @return {string} Message content to post in the thread channel
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to format a staff reply in a log
|
||||||
|
* @callback FormatStaffReplyLogMessage
|
||||||
|
* @param {Eris.Member} moderator
|
||||||
|
* @param {string} text
|
||||||
|
* @param {{
|
||||||
|
* isAnonymous: boolean,
|
||||||
|
* attachmentLinks: string[],
|
||||||
|
* }} opts={}
|
||||||
|
* @returns {string} Text to show in the log
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to format a user reply in a thread channel
|
||||||
|
* @callback FormatUserReplyThreadMessage
|
||||||
|
* @param {Eris.User} user Use that sent the reply
|
||||||
|
* @param {Eris.Message} msg The message object that the user sent
|
||||||
|
* @param {{
|
||||||
|
* attachmentLinks: string[],
|
||||||
|
* }} opts
|
||||||
|
* @return {string} Message content to post in the thread channel
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @callback FormatUserReplyLogMessage
|
||||||
|
* @param {Eris.User} user
|
||||||
|
* @param {Eris.Message} msg
|
||||||
|
* @param {{
|
||||||
|
* attachmentLinks: string[],
|
||||||
|
* }} opts={}
|
||||||
|
* @return {string} Text to show in the log
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef MessageFormatters
|
||||||
|
* @property {FormatStaffReplyDM} formatStaffReplyDM
|
||||||
|
* @property {FormatStaffReplyThreadMessage} formatStaffReplyThreadMessage
|
||||||
|
* @property {FormatStaffReplyLogMessage} formatStaffReplyLogMessage
|
||||||
|
* @property {FormatUserReplyThreadMessage} formatUserReplyThreadMessage
|
||||||
|
* @property {FormatUserReplyLogMessage} formatUserReplyLogMessage
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {MessageFormatters}
|
||||||
|
*/
|
||||||
|
const defaultFormatters = {
|
||||||
|
formatStaffReplyDM(moderator, text, opts = {}) {
|
||||||
|
const mainRole = utils.getMainRole(moderator);
|
||||||
|
const modName = (config.useNicknames ? moderator.nick || moderator.user.username : moderator.user.username);
|
||||||
|
const modInfo = opts.isAnonymous
|
||||||
|
? (mainRole ? mainRole.name : 'Moderator')
|
||||||
|
: (mainRole ? `(${mainRole.name}) ${modName}` : modName);
|
||||||
|
|
||||||
|
return `**${modInfo}:** ${text}`;
|
||||||
|
},
|
||||||
|
|
||||||
|
formatStaffReplyThreadMessage(moderator, text, messageNumber, opts = {}) {
|
||||||
|
const mainRole = utils.getMainRole(moderator);
|
||||||
|
const modName = (config.useNicknames ? moderator.nick || moderator.user.username : moderator.user.username);
|
||||||
|
const modInfo = opts.isAnonymous
|
||||||
|
? `(Anonymous) (${modName}) ${mainRole ? mainRole.name : 'Moderator'}`
|
||||||
|
: (mainRole ? `(${mainRole.name}) ${modName}` : modName);
|
||||||
|
|
||||||
|
// TODO: Add \`[${messageNumber}]\` here once !edit and !delete exist
|
||||||
|
let result = `**${modInfo}:** ${text}`;
|
||||||
|
|
||||||
|
if (config.threadTimestamps) {
|
||||||
|
const formattedTimestamp = utils.getTimestamp();
|
||||||
|
result = `[${formattedTimestamp}] ${result}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
|
formatStaffReplyLogMessage(moderator, text, opts = {}) {
|
||||||
|
const mainRole = utils.getMainRole(moderator);
|
||||||
|
const modName = moderator.user.username;
|
||||||
|
|
||||||
|
// Mirroring the DM formatting here...
|
||||||
|
const modInfo = opts.isAnonymous
|
||||||
|
? (mainRole ? mainRole.name : 'Moderator')
|
||||||
|
: (mainRole ? `(${mainRole.name}) ${modName}` : modName);
|
||||||
|
|
||||||
|
let result = `**${modInfo}:** ${text}`;
|
||||||
|
|
||||||
|
if (opts.attachmentLinks && opts.attachmentLinks.length) {
|
||||||
|
result += '\n';
|
||||||
|
for (const link of opts.attachmentLinks) {
|
||||||
|
result += `\n**Attachment:** ${link}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
|
formatUserReplyThreadMessage(user, msg, opts = {}) {
|
||||||
|
const content = (msg.content.trim() === '' && msg.embeds.length)
|
||||||
|
? '<message contains embeds>'
|
||||||
|
: msg.content;
|
||||||
|
|
||||||
|
let result = `**${user.username}#${user.discriminator}:** ${content}`;
|
||||||
|
|
||||||
|
if (opts.attachmentLinks && opts.attachmentLinks.length) {
|
||||||
|
for (const link of opts.attachmentLinks) {
|
||||||
|
result += `\n\n${link}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.threadTimestamps) {
|
||||||
|
const formattedTimestamp = utils.getTimestamp(msg.timestamp, 'x');
|
||||||
|
result = `[${formattedTimestamp}] ${result}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
|
formatUserReplyLogMessage(user, msg, opts = {}) {
|
||||||
|
const content = (msg.content.trim() === '' && msg.embeds.length)
|
||||||
|
? '<message contains embeds>'
|
||||||
|
: msg.content;
|
||||||
|
|
||||||
|
let result = content;
|
||||||
|
|
||||||
|
if (opts.attachmentLinks && opts.attachmentLinks.length) {
|
||||||
|
for (const link of opts.attachmentLinks) {
|
||||||
|
result += `\n\n${link}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {MessageFormatters}
|
||||||
|
*/
|
||||||
|
const formatters = { ...defaultFormatters };
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
formatters,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {FormatStaffReplyDM} fn
|
||||||
|
* @return {void}
|
||||||
|
*/
|
||||||
|
setStaffReplyDMFormatter(fn) {
|
||||||
|
formatters.formatStaffReplyDM = fn;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {FormatStaffReplyThreadMessage} fn
|
||||||
|
* @return {void}
|
||||||
|
*/
|
||||||
|
setStaffReplyThreadMessageFormatter(fn) {
|
||||||
|
formatters.formatStaffReplyThreadMessage = fn;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {FormatStaffReplyLogMessage} fn
|
||||||
|
* @return {void}
|
||||||
|
*/
|
||||||
|
setStaffReplyLogMessageFormatter(fn) {
|
||||||
|
formatters.formatStaffReplyLogMessage = fn;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {FormatUserReplyThreadMessage} fn
|
||||||
|
* @return {void}
|
||||||
|
*/
|
||||||
|
setUserReplyThreadMessageFormatter(fn) {
|
||||||
|
formatters.formatUserReplyThreadMessage = fn;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {FormatUserReplyLogMessage} fn
|
||||||
|
* @return {void}
|
||||||
|
*/
|
||||||
|
setUserReplyLogMessageFormatter(fn) {
|
||||||
|
formatters.formatUserReplyLogMessage = fn;
|
||||||
|
},
|
||||||
|
};
|
|
@ -1,5 +1,6 @@
|
||||||
const attachments = require('./data/attachments');
|
const attachments = require('./data/attachments');
|
||||||
const { beforeNewThread } = require('./hooks');
|
const { beforeNewThread } = require('./hooks');
|
||||||
|
const formats = require('./formatters');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
getPluginAPI({ bot, knex, config, commands }) {
|
getPluginAPI({ bot, knex, config, commands }) {
|
||||||
|
@ -21,6 +22,7 @@ module.exports = {
|
||||||
hooks: {
|
hooks: {
|
||||||
beforeNewThread,
|
beforeNewThread,
|
||||||
},
|
},
|
||||||
|
formats,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue