From a7c9dafe0621b19b70db5bc23c3cab93f9e3f72b Mon Sep 17 00:00:00 2001 From: hydrabolt Date: Mon, 10 Aug 2015 23:05:38 +0100 Subject: [PATCH] 1.0.1 actual works! --- .gitignore | 1 + index.js | 217 +++++++++++++++++++++++++++++++++++++++++++++++ lib/channel.js | 19 +++++ lib/endpoints.js | 11 +++ lib/message.js | 26 ++++++ lib/server.js | 15 ++++ lib/user.js | 20 +++++ package.json | 6 +- 8 files changed, 314 insertions(+), 1 deletion(-) create mode 100644 .gitignore create mode 100644 index.js create mode 100644 lib/channel.js create mode 100644 lib/endpoints.js create mode 100644 lib/message.js create mode 100644 lib/server.js create mode 100644 lib/user.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..c2658d7d1 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules/ diff --git a/index.js b/index.js new file mode 100644 index 000000000..0ab6580db --- /dev/null +++ b/index.js @@ -0,0 +1,217 @@ +var request = require("superagent"); +var Endpoints = require("./lib/endpoints.js"); +var Server = require("./lib/server.js").Server; +var Message = require("./lib/message.js").Message; +var User = require("./lib/user.js").User; +var Channel = require("./lib/channel.js").Channel; +var WebSocket = require('ws'); + +exports.Client = function(options) { + + this.options = options || {}; + this.token = ""; + this.loggedIn = false; + this.websocket = null; + this.events = {}; + this.user = null; + this.channelCache = {}; + +} + +exports.Client.prototype.triggerEvent = function(event, args) { + + 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.cacheChannel = function(id, cb) { + + if (this.channelCache[id]) { + cb(this.channelCache[id]); + return; + } + + var self = this; + + request + .get(Endpoints.CHANNELS + "/" + id) + .set("authorization", this.token) + .end(function(err, res) { + var dat = res.body; + self.channelCache[id] = new Channel(dat.name, dat.guild_id, dat.type, dat.id, dat.is_private); + cb(self.channelCache[id]); + }); + +} + +exports.Client.prototype.login = function(email, password, cb) { + + var client = this; + + var details = { + email: email, + password: password + }; + + request + .post(Endpoints.LOGIN) + .send(details) + .end(function(err, res) { + if (!res.ok) { + cb(err); + } else { + client.token = res.body.token; + client.loggedIn = true; + cb(); + client.connectWebsocket(); + } + }); + +} + +exports.Client.prototype.connectWebsocket = function(cb) { + + var client = this; + + this.websocket = new WebSocket(Endpoints.WEBSOCKET_HUB); + this.websocket.onclose = function() { + client.triggerEvent("disconnected"); + }; + this.websocket.onmessage = function(e) { + + var dat = JSON.parse(e.data); + + switch (dat.op) { + + case 0: + if (dat.t === "READY") { + + var data = dat.d; + + self = this; + setInterval(function() { + self.keepAlive.apply(self); + }, data.heartbeat_interval); + + var _servers = data.guilds, + servers = []; + for (x in _servers) { + _server = _servers[x]; + servers.push(new Server(_server.region, _server.owner_id, _server.name, _server.roles[0].id, _server.members)); + } + + client.servers = servers; + + client.user = new User(data.user.username, data.user.id, data.user.discriminator, data.user.avatar); + + client.triggerEvent("ready"); + } else if (dat.t === "MESSAGE_CREATE") { + + var data = dat.d; + + client.cacheChannel(data.channel_id, function(channel) { + var message = new Message(data.timestamp, data.author, data.content, channel, data.id, data.mentions); + client.triggerEvent("message", [message]); + }); + + } + break; + + } + + }; + this.websocket.sendPacket = function(p) { + this.send(JSON.stringify(p)); + } + this.websocket.keepAlive = function() { + + this.sendPacket({ + op: 1, + d: Date.now() + }); + + } + this.websocket.onopen = function() { + + var connDat = { + op: 2, + d: { + token: client.token, + v: 2 + } + }; + + connDat.d.properties = { + "$os": "Windows", + "$browser": "Chrome", + "$device": "discord.js", + "$referrer": "", + "$referring_domain": "" + }; + + this.sendPacket(connDat); + } +} + +exports.Client.prototype.logout = function() { + + var client = this; + + request + .post(Endpoints.LOGOUT) + .end(function() { + client.loggedIn = false; + }); + +} + +exports.Client.prototype.createServer = function(details, cb) { + + var client = this; + + request + .post(Endpoints.SERVERS) + .set("authorization", client.token) + .send(details) + .end(function(err, res) { + if (!res.ok) { + cb(err); + } else { + cb(new Server(res.body)); + } + }); + +} + +exports.Client.prototype.sendMessage = function(channelId, message, _mentions){ + + for(mention in _mentions){ + _mentions[mention] = _mentions[mention].id; + } + + var client = this; + var details = { + content : message, + mentions : _mentions || [] + }; + + request + .post(Endpoints.CHANNELS + "/" + channelId.id + "/messages") + .set("authorization", client.token) + .send(details) + .end(function(err, res){ + + }); +} diff --git a/lib/channel.js b/lib/channel.js new file mode 100644 index 000000000..dbd03fbdc --- /dev/null +++ b/lib/channel.js @@ -0,0 +1,19 @@ +exports.Channel = function(name, serverId, type, id, isPrivate){ + + this.name = name; + this.serverId = serverId; + this.type = type; + this.id = id; + this.isPrivate = isPrivate; + +} + +exports.Channel.equals = function(otherChannel){ + + if(otherChannel.id === this.id){ + return true; + } else { + return false; + } + +} diff --git a/lib/endpoints.js b/lib/endpoints.js new file mode 100644 index 000000000..066fcbf31 --- /dev/null +++ b/lib/endpoints.js @@ -0,0 +1,11 @@ +var base = "https://discordapp.com/"; +var apibase = base + "api"; + +exports.WEBSOCKET_HUB = "wss://discordapp.com/hub" + +exports.LOGIN = apibase + "/auth/login"; +exports.LOGOUT = apibase + "/auth/logout"; + +exports.SERVERS = apibase + "/guilds"; + +exports.CHANNELS = apibase + "/channels"; diff --git a/lib/message.js b/lib/message.js new file mode 100644 index 000000000..3417aa7fc --- /dev/null +++ b/lib/message.js @@ -0,0 +1,26 @@ +var User = require("./user.js").User; + +exports.Message = function(time, author, content, channel, id, mentions){ + this.time = Date.parse(time); + this.author = new User(author.username, author.id, author.discriminator, author.avatar); + this.content = content.replace(/<[^>]*>/g, "").replace(/\s+/g, ' ').trim(); + this.channel = channel; + this.id = id; + this.mentions = []; + for(x in mentions){ + var _mention = mentions[x]; + this.mentions.push( new User(_mention.username, _mention.id, _mention.discriminator, _mention.avatar) ); + } +} + +exports.Message.prototype.isMentioned = function(user){ + + for(mention of this.mentions){ + if(user.equals(mention)){ + return true; + } + } + + return false; + +} diff --git a/lib/server.js b/lib/server.js new file mode 100644 index 000000000..dfea014dc --- /dev/null +++ b/lib/server.js @@ -0,0 +1,15 @@ +var User = require("./user.js").User; + +exports.Server = function(region, ownerID, name, id, members){ + + this.region = region; + this.ownerID = ownerID; + this.name = name; + this.id = id; + this.members = []; + for(x in members){ + var _member = members[x].user; + this.members.push( new User(_member.username, _member.id, _member.discriminator, _member.avatar) ); + } + +} diff --git a/lib/user.js b/lib/user.js new file mode 100644 index 000000000..59e4fe6a3 --- /dev/null +++ b/lib/user.js @@ -0,0 +1,20 @@ +exports.User = function(username, id, discriminator, avatar){ + this.username = username; + this.discriminator = discriminator; + this.id = id; + this.avatar = avatar; +} + +exports.User.prototype.mention = function(){ + return "<@"+this.id+">"; +} + +exports.User.prototype.equals = function(otherUser){ + + if(otherUser.id === this.id){ + return true; + } else { + return false; + } + +} diff --git a/package.json b/package.json index 5853ebc22..7ee7138cf 100644 --- a/package.json +++ b/package.json @@ -19,5 +19,9 @@ "bugs": { "url": "https://github.com/hydrabolt/discord.js/issues" }, - "homepage": "https://github.com/hydrabolt/discord.js#readme" + "homepage": "https://github.com/hydrabolt/discord.js#readme", + "dependencies": { + "superagent": "^1.3.0", + "ws": "^0.7.2" + } }