2020-08-12 17:08:37 -04:00
const threads = require ( "../data/threads" ) ;
const snippets = require ( "../data/snippets" ) ;
const config = require ( "../cfg" ) ;
const utils = require ( "../utils" ) ;
const { parseArguments } = require ( "knub-command-manager" ) ;
2018-02-11 14:54:30 -05:00
2019-06-09 12:17:32 -04:00
const whitespaceRegex = /\s/ ;
2020-08-12 17:08:37 -04:00
const quoteChars = [ "'" , "\"" ] ;
2019-06-09 12:17:32 -04:00
2019-08-13 13:34:46 -04:00
module . exports = ( { bot , knex , config , commands } ) => {
2019-06-09 12:17:32 -04:00
/ * *
* "Renders" a snippet by replacing all argument placeholders e . g . { 1 } { 2 } with their corresponding arguments .
* The number in the placeholder is the argument ' s order in the argument list , i . e . { 1 } is the first argument ( = index 0 )
* @ param { String } body
* @ param { String [ ] } args
* @ returns { String }
* /
function renderSnippet ( body , args ) {
return body
. replace ( /(?<!\\){\d+}/g , match => {
const index = parseInt ( match . slice ( 1 , - 1 ) , 10 ) - 1 ;
return ( args [ index ] != null ? args [ index ] : match ) ;
} )
2020-08-12 17:08:37 -04:00
. replace ( /\\{/g , "{" ) ;
2019-06-09 12:17:32 -04:00
}
2018-02-11 14:54:30 -05:00
/ * *
* When a staff member uses a snippet ( snippet prefix + trigger word ) , find the snippet and post it as a reply in the thread
* /
2020-08-12 17:08:37 -04:00
bot . on ( "messageCreate" , async msg => {
2018-02-11 14:54:30 -05:00
if ( ! utils . messageIsOnInboxServer ( msg ) ) return ;
if ( ! utils . isStaff ( msg . member ) ) return ;
if ( msg . author . bot ) return ;
if ( ! msg . content ) return ;
2018-09-20 15:54:47 -04:00
if ( ! msg . content . startsWith ( config . snippetPrefix ) && ! msg . content . startsWith ( config . snippetPrefixAnon ) ) return ;
let snippetPrefix , isAnonymous ;
if ( config . snippetPrefixAnon . length > config . snippetPrefix . length ) {
// Anonymous prefix is longer -> check it first
if ( msg . content . startsWith ( config . snippetPrefixAnon ) ) {
snippetPrefix = config . snippetPrefixAnon ;
isAnonymous = true ;
} else {
snippetPrefix = config . snippetPrefix ;
isAnonymous = false ;
}
} else {
// Regular prefix is longer -> check it first
if ( msg . content . startsWith ( config . snippetPrefix ) ) {
snippetPrefix = config . snippetPrefix ;
isAnonymous = false ;
} else {
snippetPrefix = config . snippetPrefixAnon ;
isAnonymous = true ;
}
}
2018-02-11 14:54:30 -05:00
const thread = await threads . findByChannelId ( msg . channel . id ) ;
if ( ! thread ) return ;
2019-06-09 12:17:32 -04:00
let [ , trigger , rawArgs ] = msg . content . slice ( snippetPrefix . length ) . match ( / ( \ S + ) ( ? : \ s + ( . * ) ) ? / s ) ;
trigger = trigger . toLowerCase ( ) ;
2018-02-11 14:54:30 -05:00
const snippet = await snippets . get ( trigger ) ;
if ( ! snippet ) return ;
2019-06-16 15:27:30 -04:00
let args = rawArgs ? parseArguments ( rawArgs ) : [ ] ;
args = args . map ( arg => arg . value ) ;
2019-06-09 12:17:32 -04:00
const rendered = renderSnippet ( snippet . body , args ) ;
const replied = await thread . replyToUser ( msg . member , rendered , [ ] , isAnonymous ) ;
2019-02-23 15:55:26 -05:00
if ( replied ) msg . delete ( ) ;
2018-02-11 14:54:30 -05:00
} ) ;
// Show or add a snippet
2020-08-12 17:08:37 -04:00
commands . addInboxServerCommand ( "snippet" , "<trigger> [text$]" , async ( msg , args , thread ) => {
2019-06-16 15:27:30 -04:00
const snippet = await snippets . get ( args . trigger ) ;
2018-02-11 14:54:30 -05:00
if ( snippet ) {
2019-06-16 15:27:30 -04:00
if ( args . text ) {
2018-02-11 14:54:30 -05:00
// If the snippet exists and we're trying to create a new one, inform the user the snippet already exists
2019-06-16 15:27:30 -04:00
utils . postSystemMessageWithFallback ( msg . channel , thread , ` Snippet " ${ args . trigger } " already exists! You can edit or delete it with ${ config . prefix } edit_snippet and ${ config . prefix } delete_snippet respectively. ` ) ;
2018-02-11 14:54:30 -05:00
} else {
// If the snippet exists and we're NOT trying to create a new one, show info about the existing snippet
2019-06-16 15:27:30 -04:00
utils . postSystemMessageWithFallback ( msg . channel , thread , ` \` ${ config . snippetPrefix } ${ args . trigger } \` replies with: \` \` \` ${ utils . disableCodeBlocks ( snippet . body ) } \` \` \` ` ) ;
2018-02-11 14:54:30 -05:00
}
} else {
2019-06-16 15:27:30 -04:00
if ( args . text ) {
2018-02-11 14:54:30 -05:00
// If the snippet doesn't exist and the user wants to create it, create it
2019-06-16 15:27:30 -04:00
await snippets . add ( args . trigger , args . text , msg . author . id ) ;
utils . postSystemMessageWithFallback ( msg . channel , thread , ` Snippet " ${ args . trigger } " created! ` ) ;
2018-02-11 14:54:30 -05:00
} else {
// If the snippet doesn't exist and the user isn't trying to create it, inform them how to create it
2019-06-16 15:27:30 -04:00
utils . postSystemMessageWithFallback ( msg . channel , thread , ` Snippet " ${ args . trigger } " doesn't exist! You can create it with \` ${ config . prefix } snippet ${ args . trigger } text \` ` ) ;
2018-02-11 14:54:30 -05:00
}
}
2019-06-16 15:27:30 -04:00
} , {
2020-08-12 17:08:37 -04:00
aliases : [ "s" ]
2018-02-11 14:54:30 -05:00
} ) ;
2020-08-12 17:08:37 -04:00
commands . addInboxServerCommand ( "delete_snippet" , "<trigger>" , async ( msg , args , thread ) => {
2019-06-16 15:27:30 -04:00
const snippet = await snippets . get ( args . trigger ) ;
2018-02-11 14:54:30 -05:00
if ( ! snippet ) {
2019-06-16 15:27:30 -04:00
utils . postSystemMessageWithFallback ( msg . channel , thread , ` Snippet " ${ args . trigger } " doesn't exist! ` ) ;
2018-02-11 14:54:30 -05:00
return ;
}
2019-06-16 15:27:30 -04:00
await snippets . del ( args . trigger ) ;
utils . postSystemMessageWithFallback ( msg . channel , thread , ` Snippet " ${ args . trigger } " deleted! ` ) ;
} , {
2020-08-12 17:08:37 -04:00
aliases : [ "ds" ]
2018-02-11 14:54:30 -05:00
} ) ;
2020-08-12 17:08:37 -04:00
commands . addInboxServerCommand ( "edit_snippet" , "<trigger> [text$]" , async ( msg , args , thread ) => {
2019-06-16 15:27:30 -04:00
const snippet = await snippets . get ( args . trigger ) ;
2018-02-11 14:54:30 -05:00
if ( ! snippet ) {
2019-06-16 15:27:30 -04:00
utils . postSystemMessageWithFallback ( msg . channel , thread , ` Snippet " ${ args . trigger } " doesn't exist! ` ) ;
2018-02-11 14:54:30 -05:00
return ;
}
2019-06-16 15:27:30 -04:00
await snippets . del ( args . trigger ) ;
await snippets . add ( args . trigger , args . text , msg . author . id ) ;
2018-02-11 14:54:30 -05:00
2019-06-16 15:27:30 -04:00
utils . postSystemMessageWithFallback ( msg . channel , thread , ` Snippet " ${ args . trigger } " edited! ` ) ;
} , {
2020-08-12 17:08:37 -04:00
aliases : [ "es" ]
2018-02-11 14:54:30 -05:00
} ) ;
2020-08-12 17:08:37 -04:00
commands . addInboxServerCommand ( "snippets" , [ ] , async ( msg , args , thread ) => {
2018-02-11 14:54:30 -05:00
const allSnippets = await snippets . all ( ) ;
const triggers = allSnippets . map ( s => s . trigger ) ;
triggers . sort ( ) ;
2020-08-12 17:08:37 -04:00
utils . postSystemMessageWithFallback ( msg . channel , thread , ` Available snippets (prefix ${ config . snippetPrefix } ): \n ${ triggers . join ( ", " ) } ` ) ;
2018-02-11 14:54:30 -05:00
} ) ;
} ;