2017-08-12 03:44:35 +03:00
//node imports
const FileSystem = require ( "fs" ) ;
//external lib imports
2017-08-23 01:02:16 +03:00
const JsonFile = require ( "jsonfile" ) ; //for saving to/from JSON
const Url = require ( "url" ) ; //for url parsing
const GetUrls = require ( "get-urls" ) ; //for extracting urls from messages
2017-08-12 03:44:35 +03:00
//my imports
const DiscordUtil = require ( "discordjs-util" ) ;
2017-08-12 03:49:35 +03:00
//app component imports
const GuildData = require ( "./models/guild-data.js" ) ;
const FeedData = require ( "./models/feed-data.js" ) ;
2017-08-12 03:44:35 +03:00
//global vars
const SAVE _FILE = "./guilds.json" ;
module . exports = ( client ) => {
const config = require ( "./config.json" ) ;
const guildsData = FileSystem . existsSync ( SAVE _FILE ) ? fromJSON ( JsonFile . readFileSync ( SAVE _FILE ) ) : { } ;
setInterval ( ( ) => writeFile ( guildsData ) , config . saveIntervalSec * 1000 ) ;
2017-08-23 03:04:56 +03:00
parseLinksInGuilds ( client . guilds , guildsData ) . then ( ( ) => writeFile ( guildsData ) )
. then ( ( ) => checkFeedsInGuilds ( client . guilds , guildsData ) )
. then ( ( ) => setInterval ( ( ) => checkFeedsInGuilds ( client . guilds , guildsData ) , config . feedCheckIntervalSec * 1000 ) ) ; //set up an interval to check all the feeds
2017-08-12 03:55:58 +03:00
//set up an on message handler to detect when links are posted
2017-08-12 03:44:35 +03:00
client . on ( "message" , message => {
if ( message . author . id !== client . user . id ) { //check the bot isn't triggering itself
if ( message . channel . type === "dm" )
2017-08-23 03:47:18 +03:00
HandleMessage . dm ( client , config , message ) ;
2017-08-12 03:44:35 +03:00
else if ( message . channel . type === "text" && message . member )
2017-08-23 03:47:18 +03:00
HandleMessage . text ( client , config , message , guildsData ) ;
2017-08-12 03:44:35 +03:00
}
} ) ;
} ;
const HandleMessage = {
2017-08-23 03:47:18 +03:00
dm : ( client , config , message ) => {
2017-08-12 03:44:35 +03:00
message . reply ( "This bot does not have any handling for direct messages. To learn more or get help please visit http://benji7425.github.io, or join my Discord server here: https://discord.gg/SSkbwSJ" ) ;
} ,
2017-08-23 03:47:18 +03:00
text : ( client , config , message , guildsData ) => {
2017-08-12 03:44:35 +03:00
//handle admins invoking commands
if ( message . content . startsWith ( message . guild . me . toString ( ) ) //user is @mention-ing the bot
&& message . member . permissions . has ( "ADMINISTRATOR" ) ) //user has admin perms
{
const params = message . content . split ( " " ) ; //split the message at the spaces
switch ( params [ 1 ] ) {
//add handling for different commands here
case config . commands . version :
message . reply ( "v" + require ( "../package.json" ) . version ) ;
break ;
2017-08-12 03:49:35 +03:00
case config . commands . addFeed :
2017-08-23 03:27:06 +03:00
addFeed ( client , guildsData , message , config . maxCacheSize ) ;
2017-08-12 03:49:35 +03:00
break ;
2017-08-23 03:47:18 +03:00
case config . commands . viewFeeds :
viewFeeds ( client , guildsData , message ) ;
break ;
2017-08-12 03:44:35 +03:00
}
}
2017-08-23 03:04:56 +03:00
else if ( guildsData [ message . guild . id ] ) {
guildsData [ message . guild . id ] . feeds . forEach ( feedData => {
if ( message . channel . name === feedData . channelName )
feedData . cachedLinks . push ( ... GetUrls ( message . content ) ) ; //spread the urlSet returned by GetUrls into the cache array
} ) ;
}
2017-08-12 03:44:35 +03:00
}
} ;
2017-08-23 03:27:06 +03:00
function addFeed ( client , guildsData , message , maxCacheSize ) {
2017-08-23 01:02:16 +03:00
const feedUrl = [ ... GetUrls ( message . content ) ] [ 0 ] ;
2017-08-13 06:15:06 +03:00
const channel = message . mentions . channels . first ( ) ;
2017-08-13 05:12:20 +03:00
2017-08-23 01:02:16 +03:00
if ( ! feedUrl || ! channel )
return message . reply ( "Please provide both a channel and an RSS feed URL. You can optionally @mention a role also." ) ;
2017-08-13 06:15:06 +03:00
2017-08-23 01:02:16 +03:00
const role = message . mentions . roles . first ( ) ;
2017-08-13 05:12:20 +03:00
2017-08-12 04:05:59 +03:00
const feedData = new FeedData ( {
2017-08-13 05:12:20 +03:00
url : feedUrl ,
2017-08-23 01:02:16 +03:00
channelName : channel . name ,
2017-08-23 03:27:06 +03:00
roleName : role ? role . name : null ,
maxCacheSize : maxCacheSize
2017-08-12 04:05:59 +03:00
} ) ;
2017-08-12 03:49:35 +03:00
//ask the user if they're happy with the details they set up, save if yes, don't if no
2017-08-13 05:12:20 +03:00
DiscordUtil . ask ( client , message . channel , message . member , "Are you happy with this?\n ```JavaScript\n" + JSON . stringify ( feedData , null , "\n" ) + "```" )
2017-08-12 03:49:35 +03:00
. then ( responseMessage => {
//if they responded yes, save the feed and let them know, else tell them to start again
2017-08-13 05:12:20 +03:00
if ( responseMessage . content . toLowerCase ( ) === "yes" ) {
2017-08-12 04:05:59 +03:00
if ( ! guildsData [ message . guild . id ] )
guildsData [ message . guild . id ] = new GuildData ( { id : message . guild . id , feeds : [ ] } ) ;
guildsData [ message . guild . id ] . feeds . push ( feedData ) ;
2017-08-13 05:12:20 +03:00
writeFile ( guildsData ) ;
2017-08-12 03:49:35 +03:00
responseMessage . reply ( "Your new feed has been saved!" ) ;
}
else
responseMessage . reply ( "Your feed has not been saved, please add it again with the correct details" ) ;
} ) ;
}
2017-08-23 03:47:18 +03:00
function viewFeeds ( client , guildsData , message ) {
const guildData = guildsData [ message . guild . id ] ;
message . reply ( guildData . feeds . map ( f => f . toString ( ) ) . join ( "\n" ) ) ;
}
2017-08-13 06:15:06 +03:00
function checkFeedsInGuilds ( guilds , guildsData ) {
Object . keys ( guildsData ) . forEach ( key => guildsData [ key ] . checkFeeds ( guilds ) ) ;
2017-08-12 03:55:58 +03:00
}
function parseLinksInGuilds ( guilds , guildsData ) {
2017-08-12 03:49:35 +03:00
const promises = [ ] ;
2017-08-23 03:04:56 +03:00
for ( let guildId of guilds . keys ( ) ) {
const guildData = guildsData [ guildId ] ;
2017-08-12 03:49:35 +03:00
if ( guildData )
2017-08-23 03:04:56 +03:00
promises . push ( guildData . cachePastPostedLinks ( guilds . get ( guildId ) ) ) ;
2017-08-12 03:49:35 +03:00
}
return Promise . all ( promises ) ;
}
2017-08-12 03:44:35 +03:00
function writeFile ( guildsData ) {
JsonFile . writeFile ( SAVE _FILE , guildsData , err => { if ( err ) DiscordUtil . dateError ( "Error writing file" , err ) ; } ) ;
}
function fromJSON ( json ) {
2017-08-13 05:12:20 +03:00
const guildsData = Object . keys ( json ) ;
guildsData . forEach ( guildID => { json [ guildID ] = new GuildData ( json [ guildID ] ) ; } ) ;
return json ;
2017-08-12 03:44:35 +03:00
}