diff --git a/hydrabot/commands.js b/hydrabot/commands.js index 7a2f7a405..48b4f93cf 100644 --- a/hydrabot/commands.js +++ b/hydrabot/commands.js @@ -11,6 +11,8 @@ Commands[ "info" ] = { var verbose = hasFlag( params, "verbose" ) || hasFlag( params, "v" ); var user = getUser( message, params ); + console.log( "INFO", params ); + bot.reply( message, [ "here's some info on " + user.mention() + ":", "In channel **#" + message.channel.name + "**" + ( verbose ? " - ID *" + message.channel.id + "*" : "" ), ( message.isPM() ? @@ -18,7 +20,85 @@ Commands[ "info" ] = { ), "User ID is *" + user.id + "*", "Authority/OP Level to me is **" + Authority.getLevel( user ) + "**" - ] ); + ], function( err ) { + console.log( err ); + } ); + + } +} + +Commands[ "loading" ] = { + oplevel:0, + fn: function(bot, params, message){ + + var progress = 0; + var currentMessage; + var bars = 20; + + function getM(){ + var before = progress; + var after = bars - progress; + var ret = ""; + for(x=0; x < before; x++){ + ret += "-"; + } + ret += "**#**"; + for(y=0; y < after; y++){ + ret += "-"; + } + return ret; + } + + function doProg(){ + if(progress === (bars + 1)){ + progress = 0; + } + + if(currentMessage){ + bot.updateMessage(currentMessage, getM(), function(err, msg){ + if(!err) + currentMessage = msg; + }); + progress++; + } + + } + + bot.sendMessage(message.channel, getM(), function(err, message){ + currentMessage = message; + setInterval(doProg, 200); + }); + + } +} + +Commands[ "flashy" ] = { + oplevel:0, + fn: function(bot, params, message){ + + var phase = 0; + var msg; + + var textToSay = getKey(params, "m", "FLASH"); + var speed = parseInt( getKey(params, "s", "500") ); + + function change(){ + if(msg){ + + var highlighting = ((phase % 2) === 0 ? "**" : ""); + phase++; + bot.updateMessage(msg, highlighting + textToSay + highlighting, function(err, message){ + if(!err){ + msg = message; + } + }); + } + } + + bot.sendMessage(message.channel, textToSay, function(err, message){ + msg = message; + setInterval(change, speed); + }); } } @@ -99,10 +179,9 @@ Commands[ "clear" ] = { if ( todo === 0 ) { bot.reply( - msg, + message, "Done! " + deletedCount + " message(s) were deleted, with " + failedCount + " error(s).", - false, - true, { + false, { selfDestruct: 5000 } ); @@ -191,6 +270,59 @@ Commands[ "icon" ] = { } } +Commands[ "feedback" ] = { + + oplevel: 0, + fn: function( bot, params, message ) { + + var amount = getKey( params, "amount" ) || getKey( params, "n" ) || 1000; + + bot.getChannelLogs( message.channel, amount, function( err, logs ) { + + console.log(logs); + + if ( err ) { + bot.reply( message, "an error occurred when grabbing the logs.", false, { + selfDestruct: 3000 + } ); + } else { + + var found = []; + for ( msg of logs.contents ) { + + if ( ~msg.content.indexOf( "[request" ) || ~msg.content.indexOf( "[feature" || ~msg.content.indexOf( "[suggestion") ) ) { + if(msg.content.length > 10){ + found.push( msg ); + } + } + + } + + bot.sendMessage( message.author, "Ok, here's a rundown of all feature requests so far:", function( err, ms ) { + + if (!err) + gothroughit(); + + } ); + + bot.reply( message, "I found " + found.length + " result(s) that matched this. I'll send it to you in a PM.", false, { + selfDestruct : 3000 + } ); + + function gothroughit() { + for ( msg of found ) { + + bot.sendMessage( message.author, "**" + msg.author.username + "** said:\n " + msg.content ); + + } + } + } + } ); + + } + +} + Commands[ "remind" ] = { oplevel: 0, fn: function( bot, params, message ) { diff --git a/hydrabot/hydrabot.js b/hydrabot/hydrabot.js index afd8be93c..fa8f5a2a5 100644 --- a/hydrabot/hydrabot.js +++ b/hydrabot/hydrabot.js @@ -33,6 +33,7 @@ var time = Date.now(); // When the bot is ready to go, output to the console hydrabot.on( "ready", function() { console.log( "Ready in "+ (Date.now() - time) +"ms!" ); + console.log(Commands); } ); // When the bot gets disconnected, exit. @@ -43,9 +44,31 @@ hydrabot.on( "disconnected", function( obj ) { process.exit( 0 ); } ); +hydrabot.on("messageDelete", function(message){ + console.log(message); +}) + +hydrabot.on("messageUpdate", function(former, edit){ + + if(former.author.equals(this.user)){ + return; + } + + if(former){ + + var seconds = Math.round((Date.now() - former.time) / 1000); + + var channel = former.channel; + hydrabot.sendMessage(channel, "**"+former.author.username + "** (edit from message "+seconds+" seconds ago):\n " + former.content); + + } + +}) + hydrabot.on( "message", function( message ) { // if the message doesn't begin with a valid command prefix exit + if ( commandPrefixes.indexOf( message.content.charAt( 0 ) ) == -1 ) return; diff --git a/index.js b/index.js index ab0144451..58e490a0b 100644 --- a/index.js +++ b/index.js @@ -8,6 +8,7 @@ var List = require( "./lib/list.js" ).List; var Invite = require( "./lib/invite.js" ).Invite; var PMChannel = require( "./lib/PMChannel.js" ).PMChannel; var WebSocket = require( 'ws' ); +var Internal = require( "./lib/internal.js" ).Internal; exports.Endpoints = Endpoints; exports.Server = Server; @@ -33,6 +34,44 @@ exports.Client = function( options ) { } +exports.Client.prototype.getServers = function() { + return this.serverList; +} + +exports.Client.prototype.getChannels = function() { + return this.serverList.concatSublists( "channels", "id" ); +} + +exports.Client.prototype.getServer = function( id ) { + return this.getServers().filter( "id", id, true ); +} + +exports.Client.prototype.getChannel = function( id ) { + return this.getChannels().filter( "id", id, true ); +} + +exports.Client.prototype.triggerEvent = function( event, args ) { + + if ( !this.ready && event !== "raw" && event !== "disconnected" ) { //if we're not even loaded yet, don't try doing anything because it always ends badly! + return; + } + + if ( this.events[ event ] ) { + this.events[ event ].apply( this, args ); + } else { + return false; + } + +} + +exports.Client.prototype.on = function( name, fn ) { + this.events[ name ] = fn; +} + +exports.Client.prototype.off = function( name ) { + this.events[ name ] = function() {}; +} + exports.Client.prototype.cacheServer = function( id, cb, members ) { var self = this; var serverInput = {}; @@ -44,20 +83,11 @@ exports.Client.prototype.cacheServer = function( id, cb, members ) { return; } - request - .get( Endpoints.SERVERS + "/" + id ) - .set( "authorization", self.token ) - .end( function( err, res ) { - - if ( err ) { - throw err; - } - - var dat = res.body; - - makeServer( dat ); - - } ); + Internal.XHR.getServer( self.token, id, function( err, data ) { + if ( !err ) { + makeServer( data ); + } + } ) } else { // got objects because SPEEEDDDD @@ -72,15 +102,10 @@ exports.Client.prototype.cacheServer = function( id, cb, members ) { } function channelsFromHTTP() { - request - .get( Endpoints.SERVERS + "/" + id + "/channels" ) - .set( "authorization", self.token ) - .end( function( err, res ) { - if ( err ) - throw err; - + Internal.XHR.getChannel( self.token, id, function( err ) { + if ( !err ) cacheChannels( res.body ); - } ); + } ) } var server; @@ -109,59 +134,54 @@ exports.Client.prototype.cacheServer = function( id, cb, members ) { exports.Client.prototype.login = function( email, password ) { - var client = this; + var self = this; - var details = { - email: email, - password: password - }; + Internal.XHR.login( email, password, function( err, token ) { - request - .post( Endpoints.LOGIN ) - .send( details ) - .end( function( err, res ) { - if ( err ) { - client.triggerEvent( "disconnected", [ { - reason: "failed to log in", - error: err - } ] ); - } else { - client.token = res.body.token; - client.loggedIn = true; - client.connectWebsocket(); - } - } ); + if ( err ) { + self.triggerEvent( "disconnected", [ { + reason: "failed to log in", + error: err + } ] ); + } else { + self.token = token; + self.loggedIn = true; + self.connectWebsocket(); + } + } ); } -exports.Client.prototype.reply = function() { +exports.Client.prototype.reply = function( destination, toSend, callback, options ) { - if ( arguments[ 1 ] instanceof Array ) { - arguments[ 1 ] = arguments[ 1 ].join( "\n" ); + if ( toSend instanceof Array ) { + toSend = toSend.join( "\n" ); } - arguments[ 1 ] = arguments[ 0 ].author.mention() + ", " + arguments[ 1 ]; + toSend = destination.author.mention() + ", " + toSend; - this.sendMessage.apply( this, arguments ); + this.sendMessage( destination, toSend, callback, options ); } exports.Client.prototype.connectWebsocket = function( cb ) { - var client = this; + var self = this; this.websocket = new WebSocket( Endpoints.WEBSOCKET_HUB ); this.websocket.onclose = function( e ) { - client.triggerEvent( "disconnected", [ { + self.triggerEvent( "disconnected", [ { reason: "websocket disconnected", error: e } ] ); }; this.websocket.onmessage = function( e ) { - client.triggerEvent( "raw", [ e ] ); + self.triggerEvent( "raw", [ e ] ); var dat = JSON.parse( e.data ); + var webself = this; + switch ( dat.op ) { case 0: @@ -169,12 +189,11 @@ exports.Client.prototype.connectWebsocket = function( cb ) { var data = dat.d; - self = this; setInterval( function() { - self.keepAlive.apply( self ); + webself.keepAlive.apply( webself ); }, data.heartbeat_interval ); - client.user = new User( data.user ); + self.user = new User( data.user ); var _servers = data.guilds, servers = []; @@ -182,68 +201,106 @@ exports.Client.prototype.connectWebsocket = function( cb ) { var cached = 0, toCache = _servers.length; + for ( x in data.private_channels ) { + self.PMList.add( new PMChannel( data.private_channels[ x ].recipient, data.private_channels[ x ].id ) ); + } + for ( x in _servers ) { _server = _servers[ x ]; - client.cacheServer( _server, function( server ) { + self.cacheServer( _server, function( server ) { cached++; if ( cached >= toCache ) { - client.ready = true; - client.triggerEvent( "ready" ); + self.ready = true; + self.triggerEvent( "ready" ); } } ); } - for ( x in data.private_channels ) { - client.PMList.add( new PMChannel( data.private_channels[ x ].recipient, data.private_channels[ x ].id ) ); - } - } else if ( dat.t === "MESSAGE_CREATE" ) { var data = dat.d; - var channel = client.channelFromId( data.channel_id ); - + var channel = self.getChannel( data.channel_id ); var message = new Message( data, channel ); + self.triggerEvent( "message", [ message ] ); + if ( channel.messages ) + channel.messages.add( message ); - client.triggerEvent( "message", [ message ] ); + } else if ( dat.t === "MESSAGE_DELETE" ) { + var data = dat.d; + + var channel = self.getChannel( data.channel_id ); + + if ( !channel.messages ) + return; + + var _msg = channel.messages.filter( "id", data.id, true ); + + if ( _msg ) { + self.triggerEvent( "messageDelete", [ _msg ] ); + channel.messages.removeElement( _msg ); + } + + } else if ( dat.t === "MESSAGE_UPDATE" ) { + + var data = dat.d; + if ( !self.ready ) + return; + + var formerMessage = false; + + var channel = self.getChannel( data.channel_id ); + + if ( channel ) { + + formerMessage = channel.messages.filter( "id", data.id, true ); + newMessage = new Message( data, channel ); + self.triggerEvent( "messageUpdate", [ formerMessage, newMessage ] ); + + if ( formerMessage ) + channel.messages.updateElement( formerMessage, newMessage ); + else + channel.messages.add( newMessage ); + + } } else if ( dat.t === "PRESENCE_UPDATE" ) { var data = dat.d; - client.triggerEvent( "presence", [ new User( data.user ), data.status, client.serverList.filter( "id", data.guild_id, true ) ] ); + self.triggerEvent( "presence", [ new User( data.user ), data.status, self.serverList.filter( "id", data.guild_id, true ) ] ); } else if ( dat.t === "GUILD_DELETE" ) { - var deletedServer = client.serverList.filter( "id", dat.d.id, true ); + var deletedServer = self.serverList.filter( "id", dat.d.id, true ); if ( deletedServer ) { - client.triggerEvent( "serverDelete", [ deletedServer ] ); + self.triggerEvent( "serverDelete", [ deletedServer ] ); } } else if ( dat.t === "CHANNEL_DELETE" ) { - var delServer = client.serverList.filter( "id", dat.d.guild_id, true ); + var delServer = self.serverList.filter( "id", dat.d.guild_id, true ); if ( delServer ) { var channel = delServer.channels.filter( "id", dat.d.id, true ); if ( channel ) { - client.triggerEvent( "channelDelete", [ channel ] ); + self.triggerEvent( "channelDelete", [ channel ] ); } } } else if ( dat.t === "GUILD_CREATE" ) { - if ( !client.serverList.filter( "id", dat.d.id, true ) ) { - client.cacheServer( dat.d, function( server ) { - client.triggerEvent( "serverJoin", [ server ] ); + if ( !self.serverList.filter( "id", dat.d.id, true ) ) { + self.cacheServer( dat.d, function( server ) { + self.triggerEvent( "serverJoin", [ server ] ); } ); } } else if ( dat.t === "CHANNEL_CREATE" ) { - var srv = client.serverList.filter( "id", dat.d.guild_id, true ); + var srv = self.serverList.filter( "id", dat.d.guild_id, true ); if ( srv ) { @@ -252,7 +309,7 @@ exports.Client.prototype.connectWebsocket = function( cb ) { var chann = new Channel( dat.d, srv ); srv.channels.add( new Channel( dat.d, srv ) ); - client.triggerEvent( "channelCreate", [ chann ] ); + self.triggerEvent( "channelCreate", [ chann ] ); } @@ -283,85 +340,76 @@ exports.Client.prototype.connectWebsocket = function( cb ) { var connDat = { op: 2, d: { - token: client.token, + token: self.token, v: 2 } }; - connDat.d.properties = { - "$os": "discord.js", - "$browser": "discord.js", - "$device": "discord.js", - "$referrer": "", - "$referring_domain": "" - }; + connDat.d.properties = Internal.WebSocket.properties; this.sendPacket( connDat ); } } -exports.Client.prototype.logout = function() { +exports.Client.prototype.logout = function( callback ) { - var client = this; + var self = this; - request - .post( Endpoints.LOGOUT ) - .end( function() { - client.loggedIn = false; - } ); + Internal.XHR.logout( self.token, function( err ) { + callback( err ); //if there isn't an error it'll be null anyway so... + self.loggedIn = Boolean( err ); + } ); } -exports.Client.prototype.createServer = function( _name, _region, cb ) { +exports.Client.prototype.createServer = function( name, region, cb ) { - var client = this; + var self = this; - var details = { - name: _name, - region: _region - }; + Internal.XHR.createServer( self.token, name, region, function( err, data ) { - request - .post( Endpoints.SERVERS ) - .set( "authorization", client.token ) - .send( details ) - .end( function( err, res ) { - if ( err ) { - cb( err ); - } else { - client.cacheServer( res.body.id, function( server ) { + if ( err ) { + cb( err ); + } else { - cb( null, server ); + self.cacheServer( data, function( server ) { + cb( null, server ); + } ); - } ); - } - } ); + } + + } ); } -exports.Client.prototype.leaveServer = function( server, cb ) { +exports.Client.prototype.leaveServer = function( server, callback ) { - var client = this; + var self = this; - request - .del( Endpoints.SERVERS + "/" + server.id ) - .set( "authorization", client.token ) - .end( function( err, res ) { - if ( err ) { - cb( err ); - } else { - client.serverList.removeElement( server ); - cb( null ); - } - } ); + // callback is not necessary for this function + callback = callback || function() {}; + + Internal.XHR.leaveServer( self.token, server.id, function( err ) { + + if ( err ) { + callback( err ); + } else { + self.serverList.removeElement( server ); + callback( null ); + } + + } ); } -exports.Client.prototype.createInvite = function( channel, options, cb ) { +exports.Client.prototype.createInvite = function( channel, options, callback ) { - var client = this; + var self = this; var options = options || {}; + // callback is not necessary for this function + callback = callback || function() {}; + if ( channel instanceof Server ) { channel = channel.getDefaultChannel(); } @@ -371,306 +419,247 @@ exports.Client.prototype.createInvite = function( channel, options, cb ) { options.temporary = options.temporary || false; options.xkcdpass = options.xkcd || false; - request - .post( Endpoints.CHANNELS + "/" + channel.id + "/invites" ) - .set( "authorization", client.token ) - .send( options ) - .end( function( err, res ) { - if ( err ) { - cb( err ); - } else { - cb( false, new Invite( res.body ) ); - } - } ) + Internal.XHR.createInvite( self.token, channel.id, options, function( err, data ) { -} - -exports.Client.prototype.startPM = function( user, message, cb, _mentions, options ) { - - var client = this; - - cb = cb || function() {}; - - request - .post( Endpoints.USERS + "/" + client.user.id + "/channels" ) - .set( "authorization", client.token ) - .send( { - recipient_id: user.id - } ) - .end( function( err, res ) { - if ( err ) { - cb( err ); - } else { - client.PMList.add( new PMChannel( res.body.recipient, res.body.id ) ); - client.sendMessage( user, message, cb, _mentions, options ); - } - } ); - -} - -exports.Client.prototype.editMessage = function( originalMessage, newContent, cb, _mentions ){ - - if ( _mentions === false ) { - //mentions is false, explicitly don't want to mention someone - _mentions = []; - } else if ( _mentions === true || _mentions === "auto" || _mentions == null || _mentions == undefined ) { - //want to auto sort mentions - _mentions = []; - var mentionsArray = message.match( /<@[^>]*>/g ) || []; - for ( mention of mentionsArray ) { - _mentions.push( mention.substring( 2, mention.length - 1 ) ); + if ( err ) { + callback( err ); + } else { + callback( null, new Invite( data ) ); } - } else if ( _mentions instanceof Array ) { - //specific mentions - for ( mention in _mentions ) { - _mentions[ mention ] = _mentions[ mention ].id; - } - } else { - - } - - request - .patch( Endpoints.CHANNELS + "/" + originalMessage.channel.id + "/messages/" + originalMessage.id ) - .set( "authorization", client.token ) - .send( {} ) - .end( function( err, res ) { - - if ( err ) { - cb( err ); - return; - } - - var msg = new Message( res.body, client.channelFromId( res.body.channel_id ) ); - if ( options.selfDestruct ) { - setTimeout( function() { - client.deleteMessage( msg ); - }, options.selfDestruct ); - } - cb( null, msg ); - } ); + } ); } -exports.Client.prototype.sendMessage = function( channel, message, cb, _mentions, options ) { +exports.Client.prototype.startPM = function( user, callback ) { + + var self = this; + + callback = callback || function() {}; + + Internal.XHR.startPM( self.token, self.user.id, user.id, function( err, data ) { + + if ( err ) { + callback( err ); + } else { + var channel = new PMChannel( data.recipient, data.id ); + self.PMList.add( channel ); + callback( null, channel ); + } + + } ); + +} + +exports.Client.prototype.sendMessage = function( destination, toSend, callback, options ) { options = options || {}; + callback = callback || function() {}; - if ( message instanceof Array ) { - message = message.join( "\n" ); + var channel_id, message, mentions, self = this; + + channel_id = resolveChannel( destination, self ); + message = resolveMessage( toSend ); + mentions = resolveMentions( message, options.mention ); + + if ( channel_id ) { + send(); + } else { + //a channel is being sorted } - var thisLoopId = Math.floor( Math.random() * 1000 ); + function send() { - if ( channel instanceof User ) { - if ( !this.PMList.deepFilter( [ "user", "id" ], channel.id, true ) ) { - //user does not exist! omgomgomg - this.startPM( channel, message, cb, _mentions, options, true ); - return; + Internal.XHR.sendMessage( self.token, channel_id, { + content: message, + mentions: mentions + }, function( err, data ) { + if ( err ) { + callback( err ); + } else { + var msg = new Message( data, self.getChannel( data.channel_id ) ); + if ( options.selfDestruct ) { + setTimeout( function() { + self.deleteMessage( msg ); + }, options.selfDestruct ); + } + callback( null, msg ); + } + } ); + } + + function setChannId( id ) { + channel_id = id; + } + + function resolveChannel( destination, self ) { + var channel_id = false; + if ( destination instanceof Server ) { + channel_id = destination.getDefaultChannel().id; + } else if ( destination instanceof Channel ) { + channel_id = destination.id; + } else if ( destination instanceof PMChannel ) { + channel_id = destination.id; + } else if ( destination instanceof Message ) { + channel_id = destination.channel.id; + } else if ( destination instanceof User ) { + var destId = self.PMList.deepFilter( [ "user", "id" ], destination.id, true ); + + if ( destId ) { + channel_id = destId.id; + } else { + //start a PM and then get that use that + self.startPM( destination, function( err, channel ) { + if ( err ) { + callback( err ); + } else { + self.PMList.add( new PMChannel( channel.recipient, channel.id ) ); + setChannId( channel.id ); + send(); + } + } ); + return false; + } } else { - channel.id = this.PMList.deepFilter( [ "user", "id" ], channel.id, true ).id; + channel_id = destination; } + return channel_id; } - if ( channel instanceof Message ) { //if the channel is actually a message, get the channel - channel = channel.channel; + function resolveMessage( toSend ) { + var message; + if ( typeof toSend === "string" || toSend instanceof String ) + message = toSend; + else if ( toSend instanceof Array ) + message = toSend.join( "\n" ); + else if ( toSend instanceof Message ) + message = toSend.content; + else + message = toSend; + return message.substring( 0, 2000 ); } - if ( typeof channel === 'string' || channel instanceof String || !isNaN( channel ) ) { - //Channel is an ID - var chanId = channel; - channel = { - id: chanId + function resolveMentions( message, mentionsOpt ) { + var mentions = []; + if ( mentionsOpt === false ) {} else if ( mentionsOpt || mentionsOpt === "auto" || mentionsOpt == null || mentionsOpt == undefined ) { + for ( mention of( message.match( /<@[^>]*>/g ) || [] ) ) { + mentions.push( mention.substring( 2, mention.length - 1 ) ); + } + } else if ( mentionsOpt instanceof Array ) { + for ( mention of mentionsOpt ) { + if ( mention instanceof User ) { + mentions.push( mention.id ); + } else { + mentions.push( mention ); + } + } } + return mentions; } +} - var cb = cb || function() {}; +exports.Client.prototype.deleteMessage = function( message, callback ) { + callback = callback || function() {}; - _mentions = createMentions(_mentions, message); + var self = this; - var client = this; - var details = { - content: message.substring( 0, 2000 ), - mentions: _mentions || [] - }; + Internal.XHR.deleteMessage( self.token, message.channel.id, message.id, callback ); +} - request - .post( Endpoints.CHANNELS + "/" + channel.id + "/messages" ) - .set( "authorization", client.token ) - .send( details ) - .end( function( err, res ) { +exports.Client.prototype.updateMessage = function(oldMessage, newContent, callback, options){ - if ( err ) { - cb( err ); - return; - } + var self = this; + var channel = oldMessage.channel; + options = options || {}; - var msg = new Message( res.body, client.channelFromId( res.body.channel_id ) ); - if ( options.selfDestruct ) { - setTimeout( function() { - client.deleteMessage( msg ); - }, options.selfDestruct ); - } - cb( null, msg ); - } ); + Internal.XHR.updateMessage(self.token, channel.id, oldMessage.id, { + content : newContent, + mentions : [] + }, function(err, data){ + if(err){ + callback(err); + return; + } + var msg = new Message( data, self.getChannel( data.channel_id ) ); + if ( options.selfDestruct ) { + setTimeout( function() { + self.deleteMessage( msg ); + }, options.selfDestruct ); + } + callback( null, msg ); + }); } -exports.Client.prototype.deleteMessage = function( message, cb ) { +exports.Client.prototype.getChannelLogs = function( channel, amount, callback ) { + var self = this; - if ( !message ) - return false; + Internal.XHR.getChannelLogs( self.token, channel.id, ( amount || 50 ), function( err, data ) { - var client = this; + if ( err ) { + callback( err ); + return; + } - request - .del( Endpoints.CHANNELS + "/" + message.channel.id + "/messages/" + message.id ) - .set( "authorization", client.token ) - .end( cb ); + var logs = new List( "id" ); + for ( message of data ) { + logs.add( new Message( message, channel ) ); + } + callback( null, logs ); + + } ); } -exports.Client.prototype.getChannelLogs = function( channel, amount, cb ) { - amount = amount || 0; - var client = this; +exports.Client.prototype.createChannel = function( server, name, type, callback ) { - request - .get( Endpoints.CHANNELS + "/" + channel.id + "/messages?limit=" + amount ) - .set( "authorization", client.token ) - .end( function( err, res ) { + var self = this; - if ( err ) { - cb( err ); - return; - } + Internal.XHR.createChannel( self.token, server.id, name, type, function( err, data ) { - var datList = new List( "id" ); + if ( err ) { + callback( err ); + } else { + var chann = new Channel( data, server ); + server.channels.add( chann ); + callback( null, chann ); + } - for ( item of res.body ) { - datList.add( new Message( item, channel ) ); - } - - cb( null, datList ); - } ); + } ); } -exports.Client.prototype.createChannel = function( server, serverName, serverType, cb ) { +exports.Client.prototype.deleteChannel = function( channel, callback ) { + var self = this; - var client = this; + Internal.XHR.deleteChannel( self.token, channel.id, function( err ) { - request - .post( Endpoints.SERVERS + "/" + server.id + "/channels" ) - .set( "authorization", client.token ) - .send( { - name: serverName, - type: serverType - } ) - .end( function( err, res ) { - if ( err ) { - cb( err ); - } else { - var chann = new Channel( res.body, server ); - client.serverList.filter( "id", server.id, true ).channels.add( chann ); - cb( null, chann ); - } - } ); + channel.server.channels.removeElement( channel ); + self.triggerEvent( "channelDelete", [ channel ] ); + callback( null ); + + } ); } -exports.Client.prototype.deleteChannel = function( channel, cb ) { +exports.Client.prototype.deleteServer = function( server, callback ) { - var client = this; + var self = this; - request - .del( Endpoints.CHANNELS + "/" + channel.id ) - .set( "authorization", client.token ) - .end( function( err, res ) { - if ( err ) { - cb( err ); - } else { + Internal.XHR.deleteServer( self.token, server.id, function( err ) { - client.serverList.filter( "id", channel.server.id, true ).channels.removeElement( channel ); + self.serverList.removeElement( server ); + self.triggerEvent( "serverDelete", [ server ] ); + callback( null ); - client.triggerEvent( "channelDelete", [ channel ] ); - - cb( null ); - } - } ); + } ); } -exports.Client.prototype.deleteServer = function( server, cb ) { - - var client = this; - - request - .del( Endpoints.SERVERS + "/" + server.id ) - .set( "authorization", client.token ) - .end( function( err, res ) { - if ( err ) { - cb( err ); - } else { - - client.serverList.removeElement( server ); - - client.triggerEvent( "serverDelete", [ server ] ); - - cb( null ); - } - } ); - -} - - - - - - - - - - - - - - -/* - ############################################## - UTILS - ############################################## +/** + UTILS + UTILS + UTILS + did I mention UTILS? */ - - - - - - - - - - - - - - - - -exports.isUserID = function( id ) { - return ( ( id + "" ).length === 17 && !isNaN( id ) ); -} - -exports.Client.prototype.channelFromId = function( id ) { - var channelList = this.serverList.concatSublists( "channels", "id" ); - var channel = channelList.filter( "id", id, true ); - - if ( !channel ) { - - channel = this.PMList.filter( "id", id, true ); - - } - - return channel; -} - exports.Client.prototype.getServers = function() { return this.serverList; } @@ -695,50 +684,10 @@ exports.Client.prototype.getUser = function( id ) { return this.getUsers().filter( "id", id, true ); } -exports.Client.prototype.triggerEvent = function( event, args ) { - - if ( !this.ready && event !== "raw" && event !== "disconnected" ) { //if we're not even loaded yet, don't try doing anything because it always ends badly! - return; - } - - if ( this.events[ event ] ) { - this.events[ event ].apply( this, args ); - } else { - return false; - } - +exports.isUserID = function( id ) { + return ( ( id + "" ).length === 17 && !isNaN( id ) ); } -exports.Client.prototype.on = function( name, fn ) { - this.events[ name ] = fn; -} - -exports.Client.prototype.off = function( name ) { - this.events[ name ] = function() {}; -} - -function createMentions(_mentions, message){ - - if ( _mentions === false ) { - //mentions is false, explicitly don't want to mention someone - return []; - } else if ( _mentions === true || _mentions === "auto" || _mentions == null || _mentions == undefined ) { - //want to auto sort mentions - _mentions = []; - var mentionsArray = message.match( /<@[^>]*>/g ) || []; - for ( mention of mentionsArray ) { - _mentions.push( mention.substring( 2, mention.length - 1 ) ); - } - return mentionsArray; - - } else if ( _mentions instanceof Array ) { - //specific mentions - for ( mention in _mentions ) { - _mentions[ mention ] = _mentions[ mention ].id; - } - return _mentions; - } else { - return []; - } - +exports.Client.prototype.addPM = function( pm ) { + this.PMList.add( pm ); } diff --git a/lib/internal.js b/lib/internal.js new file mode 100644 index 000000000..7e1552415 --- /dev/null +++ b/lib/internal.js @@ -0,0 +1,228 @@ +var request = require( "superagent" ); +var Endpoints = require( "./endpoints.js" ); + +var Internal = {}; + +Internal.XHR = {}; +Internal.WebSocket = {}; + +Internal.WebSocket.properties = { + "$os": "discord.js", + "$browser": "discord.js", + "$device": "discord.js", + "$referrer": "", + "$referring_domain": "" +}; + +Internal.XHR.login = function( email, password, callback ) { + + request + .post( Endpoints.LOGIN ) + .send( { + email: email, + password: password + } ) + .end( function( err, res ) { + if ( err ) { + callback( err ); + } else { + callback( null, res.body.token ); + } + } ); + +} + +Internal.XHR.logout = function( token, callback ) { + + request + .post( Endpoints.LOGOUT ) + .end( function( err, res ) { + + err ? callback( err ) : callback( null ); + + } ); + +} + +Internal.XHR.createServer = function( token, name, region, callback ) { + + request + .post( Endpoints.SERVERS ) + .set( "authorization", token ) + .send( { + name: name, + region: region + } ) + .end( function( err, res ) { + if ( err ) { + callback( err ); + } else { + callback( null, res.body ); + } + } ); +} + +Internal.XHR.leaveServer = function( token, serverId, callback ) { + + request + .del( Endpoints.SERVERS + "/" + serverId ) + .set( "authorization", token ) + .end( function( err, res ) { + + err ? callback( err ) : callback( null ); + + } ); + +} + +Internal.XHR.createInvite = function( token, channelId, options, callback ) { + request + .post( Endpoints.CHANNELS + "/" + channelId + "/invites" ) + .set( "authorization", token ) + .send( options ) + .end( function( err, res ) { + if ( err ) { + callback( err ); + } else { + callback( null, res.body ); + } + } ) +} + +Internal.XHR.startPM = function( token, selfID, userID, callback ) { + + request + .post( Endpoints.USERS + "/" + selfID + "/channels" ) + .set( "authorization", token ) + .send( { + recipient_id: userID + } ) + .end( function( err, res ) { + if ( err ) { + callback( err ); + } else { + callback( null, res.body ); + } + } ); + +} + +Internal.XHR.sendMessage = function( token, channelID, messageParameters, callback ) { + request + .post( Endpoints.CHANNELS + "/" + channelID + "/messages" ) + .set( "authorization", token ) + .send( messageParameters ) + .end( function( err, res ) { + + if ( err ) { + callback( err ); + } else { + callback( null, res.body ); + } + + } ); + +} + +Internal.XHR.deleteMessage = function( token, channelID, messageID, callback ) { + request + .del( Endpoints.CHANNELS + "/" + channelID + "/messages/" + messageID ) + .set( "authorization", token ) + .end( function( err ) { + err ? callback( err ) : callback( null ); + } ); +} + +Internal.XHR.updateMessage = function( token, channelID, messageID, messageParameters, callback ){ + + request + .patch(Endpoints.CHANNELS + "/" + channelID + "/messages/" + messageID) + .set( "authorization", token ) + .send( messageParameters ) + .end(function(err, res){ + if ( err ) { + callback( err ); + } else { + callback( null, res.body ); + } + }); +} + +Internal.XHR.getChannelLogs = function( token, channelID, amount, callback ) { + request + .get( Endpoints.CHANNELS + "/" + channelID + "/messages?limit=" + amount ) + .set( "authorization", token ) + .end( function( err, res ) { + + if ( err ) { + callback( err ); + } else { + callback( null, res.body ); + } + + } ); +} + +Internal.XHR.createChannel = function( token, serverID, name, type, callback ) { + request + .post( Endpoints.SERVERS + "/" + serverID + "/channels" ) + .set( "authorization", token ) + .send( { + name: name, + type: type + } ) + .end( function( err, res ) { + if ( err ) { + callback( err ); + } else { + callback( null, res.body ); + } + } ); +} + +Internal.XHR.deleteChannel = function( token, channelID, callback ) { + + request + .del( Endpoints.CHANNELS + "/" + channelID ) + .set( "authorization", token ) + .end( function( err ) { + err ? callback( err ) : callback( null ); + } ); + +} +Internal.XHR.deleteServer = function( token, serverID, callback ) { + request + .del( Endpoints.SERVERS + "/" + serverID ) + .set( "authorization", token ) + .end( function( err ) { + err ? callback( err ) : callback( null ); + } ); +} + +Internal.XHR.getChannels = function( token, serverID, callback ) { + request + .get( Endpoints.SERVERS + "/" + serverID + "/channels" ) + .set( "authorization", token ) + .end( function( err ) { + err ? callback( err ) : callback( null ); + } ); +} + +Internal.XHR.getServer = function( token, serverID, callback ) { + + request + .get( Endpoints.SERVERS + "/" + serverID ) + .set( "authorization", token ) + .end( function( err, res ) { + + if ( err ) { + callback( err ); + } else { + callback( null, res.body ); + } + + } ); + +} + +exports.Internal = Internal; diff --git a/lib/list.js b/lib/list.js index cc403ab6e..5de3d955d 100644 --- a/lib/list.js +++ b/lib/list.js @@ -34,6 +34,22 @@ exports.List.prototype.length = function() { return this.contents.length; } +exports.List.prototype.getIndex = function( object ){ + + var index = false; + + for(elementIndex in this.contents){ + var element = this.contents[elementIndex]; + if( element[this.discriminator] == object[this.discriminator] ){ + return elementIndex; + } + + } + + return index; + +} + exports.List.prototype.removeIndex = function( index ) { this.contents.splice( index, 1 ); } @@ -50,6 +66,20 @@ exports.List.prototype.removeElement = function( child ) { return false; } +exports.List.prototype.updateElement = function( child, newChild ){ + + for ( _element in this.contents ) { + var element = this.contents[_element]; + if ( child[ this.discriminator ] == element[ this.discriminator ] ) { + this.contents[_element] = newChild; + return true; + } + } + + return false; + +} + exports.List.prototype.concatSublists = function( whereList, discriminator ) { //this is meant to look at the contents, and assuming the contents are all lists, concatenate their values.