2018-02-11 14:54:30 -05:00
const threads = require ( '../data/threads' ) ;
const snippets = require ( '../data/snippets' ) ;
const config = require ( '../config' ) ;
const utils = require ( '../utils' ) ;
2019-06-16 15:27:30 -04:00
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/ ;
const quoteChars = [ "'" , '"' ] ;
2019-06-16 15:27:30 -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 ) ;
} )
. replace ( /\\{/g , '{' ) ;
}
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
* /
bot . on ( 'messageCreate' , async msg => {
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
2019-06-16 15:27:30 -04:00
commands . addInboxServerCommand ( 'snippet' , '<trigger> [text$]' , async ( msg , args , thread ) => {
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
} , {
aliases : [ 's' ]
2018-02-11 14:54:30 -05:00
} ) ;
2019-06-16 15:27:30 -04:00
commands . addInboxServerCommand ( 'delete_snippet' , '<trigger>' , async ( msg , args , thread ) => {
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! ` ) ;
} , {
aliases : [ 'ds' ]
2018-02-11 14:54:30 -05:00
} ) ;
2019-06-16 15:27:30 -04:00
commands . addInboxServerCommand ( 'edit_snippet' , '<trigger> [text$]' , async ( msg , args , thread ) => {
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! ` ) ;
} , {
aliases : [ 'es' ]
2018-02-11 14:54:30 -05:00
} ) ;
2019-06-16 15:27:30 -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 ( ) ;
2018-03-11 17:17:14 -04:00
utils . postSystemMessageWithFallback ( msg . channel , thread , ` Available snippets (prefix ${ config . snippetPrefix } ): \n ${ triggers . join ( ', ' ) } ` ) ;
2018-02-11 14:54:30 -05:00
} ) ;
} ;