function DiscordClient(options) {
if (!isNode) Emitter.call(this);
if (!options || options.constructor.name !== 'Object') return console.error("An Object is required to create the discord.io client
.");
applyProperties(this, [
["_ws", null],
["_uIDToDM", {}],
["_ready", false],
["_vChannels", {}],
["_messageCache", {}],
["_connecting", false],
["_mainKeepAlive", null],
["_req", APIRequest.bind(this)],
["_shard", validateShard(options.shard)],
["_messageCacheLimit", typeof(options.messageCacheLimit) === 'number' ? options.messageCacheLimit : 50],
]);
this.presenceStatus = "offline";
this.connected = false;
this.inviteURL = null;
this.connect = this.connect.bind(this, options);
if (options.autorun === true) this.connect();
}...
/*Variable area*/
var Discord = require('discord.io');
var bot = new Discord.Client({
token: "",
autorun: true
});
/*Event area*/
bot.on("ready", function(event) {
...function Emitter() {
var emt = this;
if (isNode) {
EE.call(this);
if (this.prototype) return Util.inherits(this, EE);
return new EE();
}
//Thank you, http://stackoverflow.com/a/24216547
function _Emitter() {
var eventTarget = document.createDocumentFragment();
["addEventListener", "dispatchEvent", "removeEventListener"].forEach(function(method) {
if (!this[method]) this[method] = eventTarget[method].bind(eventTarget);
}, this);
}
//But I did the rest myself! D:<
_Emitter.call(this);
this._evts = {};
this.on = function(eName, eFunc) {
if (!emt._evts[eName]) emt._evts[eName] = [];
emt._evts[eName].push(eOn);
return this.addEventListener(eName, eOn);
function eOn(e) {
return eFunc.apply(null, resolveEvent(e));
}
};
this.once = function(eName, eFunc) {
if (!emt._evts[eName]) emt._evts[eName] = [];
emt._evts[eName].push(eOnce);
return this.addEventListener(eName, eOnce);
function eOnce(e) {
eFunc.apply(null, resolveEvent(e));
return emt.removeListener(eName, eOnce);
}
};
this.removeListener = function(eName, eFunc) {
if (emt._evts[eName]) emt._evts[eName].splice(emt._evts[eName].lastIndexOf(eFunc), 1);
return this.removeEventListener(eName, eFunc);
};
this.emit = function(eName) {
return this.dispatchEvent( new CustomEvent(eName, {'detail': Array.prototype.slice.call(arguments, 1) }) );
};
return this;
}n/a
function DiscordClient(options) {
if (!isNode) Emitter.call(this);
if (!options || options.constructor.name !== 'Object') return console.error("An Object is required to create the discord.io client
.");
applyProperties(this, [
["_ws", null],
["_uIDToDM", {}],
["_ready", false],
["_vChannels", {}],
["_messageCache", {}],
["_connecting", false],
["_mainKeepAlive", null],
["_req", APIRequest.bind(this)],
["_shard", validateShard(options.shard)],
["_messageCacheLimit", typeof(options.messageCacheLimit) === 'number' ? options.messageCacheLimit : 50],
]);
this.presenceStatus = "offline";
this.connected = false;
this.inviteURL = null;
this.connect = this.connect.bind(this, options);
if (options.autorun === true) this.connect();
}n/a
function DiscordClient(options) {
if (!isNode) Emitter.call(this);
if (!options || options.constructor.name !== 'Object') return console.error("An Object is required to create the discord.io client
.");
applyProperties(this, [
["_ws", null],
["_uIDToDM", {}],
["_ready", false],
["_vChannels", {}],
["_messageCache", {}],
["_connecting", false],
["_mainKeepAlive", null],
["_req", APIRequest.bind(this)],
["_shard", validateShard(options.shard)],
["_messageCacheLimit", typeof(options.messageCacheLimit) === 'number' ? options.messageCacheLimit : 50],
]);
this.presenceStatus = "offline";
this.connected = false;
this.inviteURL = null;
this.connect = this.connect.bind(this, options);
if (options.autorun === true) this.connect();
}...
/*Variable area*/
var Discord = require('discord.io');
var bot = new Discord.Client({
token: "",
autorun: true
});
/*Event area*/
bot.on("ready", function(event) {
...function EventEmitter() {
EventEmitter.init.call(this);
}n/a
acceptInvite = function (inviteCode, callback) {
if (this.bot) return handleErrCB("[acceptInvite] This account is a 'bot' type account, and cannot use 'acceptInvite'. Please use
the client's inviteURL property instead.", callback);
var client = this, joinedServers = Object.keys(client.servers);
this._req('post', Endpoints.INVITES(inviteCode), function(err, res) {
try {
//Try to create the server with the small amount of data
//that Discord provides directly from the HTTP response
//since the websocket event may take a second to show.
if (!client.servers[res.body.guild.id]) {
client.servers[res.body.guild.id] = res.body.guild;
client.servers[res.body.guild.id].channels = {};
client.servers[res.body.guild.id].channels[res.body.channel.id] = res.body.channel;
} else {
if (joinedServers.indexOf(res.body.guild.id) > -1) {
return handleErrCB(("Already joined server: " + res.body.guild.id), callback);
}
}
} catch(e) {}
handleResCB(("The invite code provided " + inviteCode + " is incorrect."), err, res, callback);
});
}n/a
addReaction = function (input, callback) {
this._req('put', Endpoints.USER_REACTIONS(input.channelID, input.messageID, stringifyEmoji(input.reaction)), function(err, res) {
handleResCB("Unable to add reaction", err, res, callback);
});
}n/a
addServerEmoji = function (input, callback) {
var payload = {
name: input.name,
image: "data:image/png;base64," + input.image
};
this._req('post', Endpoints.SERVER_EMOJIS(input.serverID), payload, function(err, res) {
handleResCB("Unable to add emoji to the server", err, res, callback);
});
}n/a
addToRole = function (input, callback) {
this._req('put', Endpoints.MEMBER_ROLES(input.serverID, input.userID, input.roleID), function(err, res) {
handleResCB("Could not add role", err, res, callback);
});
}n/a
ban = function (input, callback) {
if (input.lastDays) {
input.lastDays = Number(input.lastDays);
input.lastDays = Math.min(input.lastDays, 7);
input.lastDays = Math.max(input.lastDays, 1);
}
this._req('put', Endpoints.BANS(input.serverID, input.userID) + (input.lastDays ? "?delete-message-days=" + input.lastDays : ""),
function(err, res) {
handleResCB("Could not ban user", err, res, callback);
});
}n/a
connect = function () {
if (!this.connected && !this._connecting) return setTimeout(
init,
Math.max(0, CONNECT_WHEN - Date.now()),
this,
arguments[0],
void( CONNECT_WHEN = Math.max(CONNECT_WHEN, Date.now()) + 6000 )
);
}...
bot.on("any", function(event) {
/*console.log(rawEvent)*/ //Logs every event
});
bot.on("disconnect", function() {
console.log("Bot disconnected");
/*bot.connect()*/ //Auto reconnect
});
/*Function declaration area*/
function sendMessages(ID, messageArr, interval) {
var resArr = [], len = messageArr.length;
var callback = typeof(arguments[2]) === 'function' ? arguments[2] : arguments[3];
if (typeof(interval) !== 'number') interval = 1000;
...createChannel = function (input, callback) {
var client = this, payload = {
name: input.name,
type: (['text', 'voice'].indexOf(input.type) < 0) ? 'text' : input.type
};
this._req('post', Endpoints.SERVERS(input.serverID) + "/channels", payload, function(err, res) {
try {
var serverID = res.body.guild_id;
var channelID = res.body.id;
client.channels[channelID] = new Channel( client, client.servers[serverID], res.body );
} catch(e) {}
handleResCB('Unable to create channel', err, res, callback);
});
}n/a
createDMChannel = function (userID, callback) {
var client = this;
this._req('post', Endpoints.USER(client.id) + "/channels", {recipient_id: userID}, function(err, res) {
if (!err && goodResponse(res)) client._uIDToDM[res.body.recipient.id] = res.body.id;
handleResCB("Unable to create DM Channel", err, res, callback);
});
}...
Only really used for sendMessage and uploadFile.*/
//Callback used instead of return because requesting seems necessary.
if (client._uIDToDM[ID]) return callback(client._uIDToDM[ID]);
//If it's a UserID, and it's in the UserID : ChannelID cache, use the found ChannelID
//If the ID isn't in the UserID : ChannelID cache, let's try seeing if it belongs to a user.
if (client.users[ID]) return client.createDMChannel(ID, function(err, res) {
if (err) return console.log("Internal ID resolver error: " + err);
callback(res.id);
});
return callback(ID); //Finally, the ID must not belong to a User, so send the message directly to it, as it must be a Channel
x27;s.
}
function resolveEvent(e) {
...createInvite = function (input, callback) {
var payload, client = this;
payload = {
max_age: 0,
max_users: 0,
temporary: false
};
if ( Object.keys(input).length === 1 && input.channelID ) {
payload = {
validate: client.internals.lastInviteCode || null
};
}
for (var key in input) {
if (Object.keys(payload).indexOf(key) < 0) continue;
payload[key] = input[key];
}
this._req('post', Endpoints.CHANNEL(input.channelID) + "/invites", payload, function(err, res) {
try {client.internals.lastInviteCode = res.body.code;} catch(e) {}
handleResCB('Unable to create invite', err, res, callback);
});
}n/a
createRole = function (serverID, callback) {
var client = this;
this._req('post', Endpoints.ROLES(serverID), function(err, res) {
try {
client.servers[serverID].roles[res.body.id] = new Role(res.body);
} catch(e) {}
handleResCB("Unable to create role", err, res, callback);
});
}n/a
createServer = function (input, callback) {
var payload, client = this;
payload = {icon: null, name: null, region: null};
for (var key in input) {
if (Object.keys(payload).indexOf(key) < 0) continue;
payload[key] = input[key];
}
if (input.icon) payload.icon = "data:image/jpg;base64," + input.icon;
client._req('post', Endpoints.SERVERS(), payload, function(err, res) {
try {
client.servers[res.body.id] = {};
copyKeys(res.body, client.servers[res.body.id]);
} catch(e) {}
handleResCB("Could not create server", err, res, callback);
});
}n/a
createWebhook = function (serverID, callback) {
this._req('post', Endpoints.SERVER_WEBHOOKS(serverID), function(err, res) {
handleResCB("Could not create a Webhook", err, res, callback);
});
}n/a
deafen = function (input, callback) {
this._req('patch', Endpoints.MEMBERS(input.serverID, input.userID), {deaf: true}, function(err, res) {
handleResCB("Could not deafen user", err, res, callback);
});
}n/a
deleteChannel = function (channelID, callback) {
this._req('delete', Endpoints.CHANNEL(channelID), function(err, res) {
handleResCB("Unable to delete channel", err, res, callback);
});
}n/a
deleteChannelPermission = function (input, callback) {
var payload, pType, ID;
if (!input.userID && !input.roleID) return handleErrCB("[deleteChannelPermission] No userID or roleID provided", callback);
if (!this.channels[input.channelID]) return handleErrCB(("[deleteChannelPermission] No channel found for ID: " + input.channelID
), callback);
pType = input.userID ? 'user' : 'role';
ID = input[pType + "ID"];
payload = {
type: (pType === 'user' ? 'member' : 'role'),
id: ID
};
this._req('delete', Endpoints.CHANNEL(input.channelID) + "/permissions/" + ID, payload, function(err, res) {
handleResCB('Unable to delete permission', err, res, callback);
});
}n/a
deleteInvite = function (inviteCode, callback) {
this._req('delete', Endpoints.INVITES(inviteCode), function(err, res) {
handleResCB('Unable to delete invite', err, res, callback);
});
}n/a
deleteMessage = function (input, callback) {
this._req('delete', Endpoints.MESSAGES(input.channelID, input.messageID), function(err, res) {
handleResCB("Unable to delete message", err, res, callback);
});
}n/a
deleteMessages = function (input, callback) {
this._req('post', Endpoints.BULK_DELETE(input.channelID), {messages: input.messageIDs.slice(0, 100)}, function(err, res) {
handleResCB("Unable to delete messages", err, res, callback);
});
}n/a
deletePinnedMessage = function (input, callback) {
this._req('delete', Endpoints.PINNED_MESSAGES(input.channelID, input.messageID), function(err, res) {
handleResCB("Unable to delete pinned message", err, res, callback);
});
}n/a
deleteRole = function (input, callback) {
this._req('delete', Endpoints.ROLES(input.serverID, input.roleID), function(err, res) {
handleResCB("Could not remove role", err, res, callback);
});
}n/a
deleteServer = function (serverID, callback) {
this._req('delete', Endpoints.SERVERS(serverID), function(err, res) {
handleResCB("Could not delete server", err, res, callback);
});
}n/a
deleteServerEmoji = function (input, callback) {
this._req('delete', Endpoints.SERVER_EMOJIS(input.serverID, input.emojiID), function(err, res) {
handleResCB("[deleteServerEmoji] Could not delete server emoji", err, res, callback);
});
}n/a
disconnect = function () {
if (this._ws) this._ws.close();
}n/a
editChannelInfo = function (input, callback) {
var channel, payload;
try {
channel = this.channels[input.channelID];
payload = {
name: channel.name,
topic: channel.topic,
bitrate: channel.bitrate,
position: channel.position,
user_limit: channel.user_limit
};
for (var key in input) {
if (Object.keys(payload).indexOf(key) < 0) continue;
if (+input[key]) {
if (key === 'bitrate') {
payload.bitrate = Math.min( Math.max( input.bitrate, 8000), 96000);
continue;
}
if (key === 'user_limit') {
payload.user_limit = Math.min( Math.max( input.user_limit, 0), 99);
continue;
}
}
payload[key] = input[key];
}
this._req('patch', Endpoints.CHANNEL(input.channelID), payload, function(err, res) {
handleResCB("Unable to edit channel", err, res, callback);
});
} catch(e) {return handleErrCB(e, callback);}
}n/a
editChannelPermissions = function (input, callback) { //Will shrink this up later
var payload, pType, ID, channel, permissions, allowed_values;
if (!input.userID && !input.roleID) return handleErrCB("[editChannelPermissions] No userID or roleID provided", callback);
if (!this.channels[input.channelID]) return handleErrCB(("[editChannelPermissions] No channel found for ID: " + input.channelID
), callback);
if (!input.allow && !input.deny && !input.default) return handleErrCB("[editChannelPermissions] No allow, deny or default array
provided.", callback);
pType = input.userID ? 'user' : 'role';
ID = input[pType + "ID"];
channel = this.channels[ input.channelID ];
permissions = channel.permissions[pType][ID] || { allow: 0, deny: 0 };
allowed_values = [0, 4, 28].concat((channel.type === 'text' ?
[10, 11, 12, 13, 14, 15, 16, 17, 18] :
[20, 21, 22, 23, 24, 25] ));
//Take care of allow first
if (type(input.allow) === 'array') {
input.allow.forEach(function(perm) {
if (allowed_values.indexOf(perm) < 0) return;
if (hasPermission(perm, permissions.deny)) {
permissions.deny = removePermission(perm, permissions.deny);
}
permissions.allow = givePermission(perm, permissions.allow);
});
}
//Take care of deny second
if (type(input.deny) === 'array') {
input.deny.forEach(function(perm) {
if (allowed_values.indexOf(perm) < 0) return;
if (hasPermission(perm, permissions.allow)) {
permissions.allow = removePermission(perm, permissions.allow);
}
permissions.deny = givePermission(perm, permissions.deny);
});
}
//Take care of defaulting last
if (type(input.default) === 'array') {
input.default.forEach(function(perm) {
if (allowed_values.indexOf(perm) < 0) return;
permissions.allow = removePermission(perm, permissions.allow);
permissions.deny = removePermission(perm, permissions.deny);
});
}
payload = {
type: (pType === 'user' ? 'member' : 'role'),
id: ID,
deny: permissions.deny,
allow: permissions.allow
};
this._req('put', Endpoints.CHANNEL(input.channelID) + "/permissions/" + ID, payload, function(err, res) {
handleResCB('Unable to edit permission', err, res, callback);
});
}n/a
editMessage = function (input, callback) {
this._req('patch', Endpoints.MESSAGES(input.channelID, input.messageID), generateMessage(input.message || '', input.embed), function
(err, res) {
handleResCB("Unable to edit message", err, res, callback);
});
}n/a
editNickname = function (input, callback) {
var payload = {nick: String( input.nick ? input.nick : "" )};
var url = input.userID === this.id ?
Endpoints.MEMBERS(input.serverID) + "/@me/nick" :
Endpoints.MEMBERS(input.serverID, input.userID);
this._req('patch', url, payload, function(err, res) {
handleResCB("Could not change nickname", err, res, callback);
});
}n/a
editNote = function (input, callback) {
this._req('put', Endpoints.NOTE(input.userID), {note: input.note}, function(err, res) {
handleResCB("Could not edit note", err, res, callback);
});
}n/a
editRole = function (input, callback) {
var role, payload;
try {
role = new Role(this.servers[input.serverID].roles[input.roleID]);
payload = {
name: role.name,
color: role.color,
hoist: role.hoist,
permissions: role._permissions,
mentionable: role.mentionable,
position: role.position
};
for (var key in input) {
if (Object.keys(payload).indexOf(key) < 0) continue;
if (key === 'permissions') {
for (var perm in input[key]) {
role[perm] = input[key][perm];
payload.permissions = role._permissions;
}
continue;
}
if (key === 'color') {
if (String(input[key])[0] === '#') payload.color = parseInt(String(input[key]).replace('#', '0x'), 16);
if (Discord.Colors[input[key]]) payload.color = Discord.Colors[input[key]];
if (type(input[key]) === 'number') payload.color = input[key];
continue;
}
payload[key] = input[key];
}
this._req('patch', Endpoints.ROLES(input.serverID, input.roleID), payload, function(err, res) {
handleResCB("Unable to edit role", err, res, callback);
});
} catch(e) {return handleErrCB(('[editRole] ' + e), callback);}
}...
There are two ways to set role colors with this lib.
The first method allows you to provide any color you want, as a Number. I recommend using Hex numbers as this maps easily to HTML
color codes. Assuming you want to use the color `#F35353`, you can just use `0xF35353`
```js
bot.editRole({
color: 0xF35353
});
```
The second method is providing the name of one of the official colors Discord has on its picker. The name you type will map to one
of the colors below.
```javascript
bot.editRole({
...editServer = function (input, callback) {
var payload, serverID = input.serverID, server, client = this;
if (!client.servers[serverID]) return handleErrCB(("[editServer] Server " + serverID + " not found."), callback);
server = client.servers[serverID];
payload = {
name: server.name,
icon: server.icon,
region: server.region,
afk_channel_id: server.afk_channel_id,
afk_timeout: server.afk_timeout
};
for (var key in input) {
if (Object.keys(payload).indexOf(key) < 0) continue;
if (key === 'afk_channel_id') {
if (server.channels[input[key]] && server.channels[input[key]].type === 'voice') payload[key] = input[key];
continue;
}
if (key === 'afk_timeout') {
if ([60, 300, 900, 1800, 3600].indexOf(Number(input[key])) > -1) payload[key] = input[key];
continue;
}
payload[key] = input[key];
}
if (input.icon) payload.icon = "data:image/jpg;base64," + input.icon;
client._req('patch', Endpoints.SERVERS(input.serverID), payload, function(err, res) {
handleResCB("Unable to edit server", err, res, callback);
});
}n/a
editServerEmoji = function (input, callback) {
var emoji, payload = {};
if ( !this.servers[input.serverID] ) return handleErrCB(("[editServerEmoji] Server not available: " + input.serverID), callback
);
if ( !this.servers[input.serverID].emojis[input.emojiID]) return handleErrCB(("[editServerEmoji] Emoji not available: " + input
.emojiID), callback);
emoji = this.servers[input.serverID].emojis[input.emojiID];
payload.name = input.name || emoji.name;
payload.roles = input.roles || emoji.roles;
this._req('patch', Endpoints.SERVER_EMOJIS(input.serverID, input.emojiID), payload, function(err, res) {
handleResCB("[editServerEmoji] Could not edit server emoji", err, res, callback);
});
}n/a
editServerWidget = function (input, callback) {
var client = this, payload, url = Endpoints.SERVERS(input.serverID) + "/embed";
client._req('get', url, function(err, res) {
if (err) return handleResCB("Unable to GET server widget settings. Can not edit without retrieving first.", err, res, callback
);
payload = {
enabled: ('enabled' in input ? input.enabled : res.body.enabled),
channel_id: ('channelID' in input ? input.channelID : res.body.channel_id)
};
client._req('patch', url, payload, function(err, res) {
handleResCB("Unable to edit server widget", err, res, callback);
});
});
}n/a
editUserInfo = function (input, callback) {
var payload = {
avatar: this.avatar,
email: this.email,
new_password: null,
password: null,
username: this.username
},
plArr = Object.keys(payload);
for (var key in input) {
if (plArr.indexOf(key) < 0) return handleErrCB(("[editUserInfo] '" + key + "' is not a valid key. Valid keys are: " + plArr.join
(", ")), callback);
payload[key] = input[key];
}
if (input.avatar) payload.avatar = "data:image/jpg;base64," + input.avatar;
this._req('patch', Endpoints.ME, payload, function(err, res) {
handleResCB("Unable to edit user information", err, res, callback);
});
}n/a
editWebhook = function (input, callback) {
var client = this, payload = {}, allowed = ['avatar', 'name'];
this._req('get', Endpoints.WEBHOOKS(input.webhookID), function(err, res) {
if (err || !goodResponse(res)) return handleResCB("Couldn't get webhook, do you have permissions to access it?", err, res, callback
);
allowed.forEach(function(key) {
payload[key] = (key in input ? input[key] : res.body[key]);
});
payload.channel_id = input.channelID || res.body.channel_id;
client._req('patch', Endpoints.WEBHOOKS(input.webhookID), payload, function(err, res) {
return handleResCB("Couldn't update webhook", err, res, callback);
});
});
}n/a
fixMessage = function (message) {
var client = this;
return message.replace(/<@&(\d*)>|<@!(\d*)>|<@(\d*)>|<#(\d*)>/g, function(match, RID, NID, UID, CID) {
var k, i;
if (UID || CID) {
if (client.users[UID]) return "@" + client.users[UID].username;
if (client.channels[CID]) return "#" + client.channels[CID].name;
}
if (RID || NID) {
k = Object.keys(client.servers);
for (i=0; i<k.length; i++) {
if (client.servers[k[i]].roles[RID]) return "@" + client.servers[k[i]].roles[RID].name;
if (client.servers[k[i]].members[NID]) return "@" + client.servers[k[i]].members[NID].nick;
}
}
});
}n/a
getAccountSettings = function (callback) {
this._req('get', Endpoints.SETTINGS, function(err, res) {
handleResCB("Error GETing client settings", err, res, callback);
});
}...
getDirectMessages(client, _data.private_channels);
if (client.bot) client.getOauthInfo(function(err, res) {
if (err) return console.log(err);
client.internals.oauth = res;
client.inviteURL = "https://discordapp.com/oauth2/authorize?client_id=" + res.id + "&scope=bot";
});
if (!client.bot) client.getAccountSettings(function(err, res) {
if (err) return console.log(err);
client.internals.settings = res;
});
return (function() {
if (client._ready) return;
var ready = [false];
...getAllUsers = function (callback) {
var servers = Object.keys(this.servers).filter(function(s) {
s = this.servers[s];
if (s.members) return s.member_count !== Object.keys(s.members).length && (this.bot ? s.large : true);
}, this);
if (!servers[0]) {
this.emit('allUsers');
return handleErrCB("There are no users to be collected", callback);
}
if (!this.bot) send(this._ws, Payloads.ALL_USERS(this));
return getOfflineUsers(this, servers, callback);
}n/a
getAudioContext = function (channelObj, callback) {
// #q/qeled gave a proper timing solution. Credit where it's due.
if (!isNode) return handleErrCB("Using audio in the browser is currently not supported.", callback);
var channelID = channelObj.channelID || channelObj, voiceSession = this._vChannels[channelID], encoder = chooseAudioEncoder(['ffmpeg
', 'avconv']);
if (!voiceSession) return handleErrCB(("You have not joined the voice channel: " + channelID), callback);
if (voiceSession.ready !== true) return handleErrCB(("The connection to the voice channel " + channelID + " has not been initialized
yet."), callback);
if (!encoder) return handleErrCB("You need either 'ffmpeg' or 'avconv' and they need to be added to PATH", callback);
voiceSession.audio = voiceSession.audio || new AudioCB(
voiceSession,
channelObj.stereo === false ? 1 : 2,
encoder,
Math.abs(Number(channelObj.maxStreamSize)));
return call(callback, [null, voiceSession.audio]);
}...
client.joinVoiceChannel(VCID, function(err, events) {
if (err) return console.error(err);
events.on('speaking', function(userID, SSRC, speakingBool) {
console.log("%s is " + (speakingBool ? "now speaking" : "done speaking"), userID );
});
client.getAudioContext(VCID, function(err, stream) {
if (err) return console.error(err);
fs.createReadStream(song).pipe(stream, {end: false});
stream.on('done', function() {
fs.createReadStream(song).pipe(stream, {end: false});
});
});
});
...getBans = function (serverID, callback) {
this._req('get', Endpoints.BANS(serverID), function(err, res) {
handleResCB("Could not get ban list", err, res, callback);
});
}n/a
getChannelInvites = function (channelID, callback) {
this._req('get', Endpoints.CHANNEL(channelID) + "/invites", function(err, res) {
handleResCB('Unable to get invite list for channel' + channelID, err, res, callback);
});
}n/a
getChannelWebhooks = function (channelID, callback) {
this._req('get', Endpoints.CHANNEL_WEBHOOKS(channelID), function(err, res) {
handleResCB("Could not get channel Webhooks", err, res, callback);
});
}n/a
getMember = function (input, callback) {
this._req('get', Endpoints.MEMBERS(input.serverID, input.userID), function(err, res) {
handleResCB("Could not get member", err, res, callback);
});
}n/a
getMembers = function (input, callback) {
var qs = {};
qs.limit = (typeof(input.limit) !== 'number' ? 50 : input.limit);
if (input.after) qs.after = input.after;
this._req('get', Endpoints.MEMBERS(input.serverID) + qstringify(qs), function(err, res) {
handleResCB("Could not get members", err, res, callback);
});
}n/a
getMessage = function (input, callback) {
this._req('get', Endpoints.MESSAGES(input.channelID, input.messageID), function(err, res) {
handleResCB("Unable to get message", err, res, callback);
});
}n/a
getMessages = function (input, callback) {
var client = this, qs = {}, messages = [], lastMessageID = "";
var total = typeof(input.limit) !== 'number' ? 50 : input.limit;
if (input.before) qs.before = input.before;
if (input.after) qs.after = input.after;
(function getMessages() {
if (total > 100) {
qs.limit = 100;
total = total - 100;
} else {
qs.limit = total;
}
if (messages.length >= input.limit) return call(callback, [null, messages]);
client._req('get', Endpoints.MESSAGES(input.channelID) + qstringify(qs), function(err, res) {
if (err) return handleErrCB("Unable to get messages", callback);
messages = messages.concat(res.body);
lastMessageID = messages[messages.length - 1] && messages[messages.length - 1].id;
if (lastMessageID) qs.before = lastMessageID;
if (!res.body.length < qs.limit) return call(callback, [null, messages]);
return setTimeout(getMessages, 1000);
});
})();
}n/a
getOauthInfo = function (callback) {
this._req('get', Endpoints.OAUTH, function(err, res) {
handleResCB("Error GETing OAuth information", err, res, callback);
});
}...
case "READY":
copyKeys(_data.user, client);
client.internals.sessionID = _data.session_id;
getServerInfo(client, _data.guilds);
getDirectMessages(client, _data.private_channels);
if (client.bot) client.getOauthInfo(function(err, res) {
if (err) return console.log(err);
client.internals.oauth = res;
client.inviteURL = "https://discordapp.com/oauth2/authorize?client_id=" + res.id + "&scope=bot";
});
if (!client.bot) client.getAccountSettings(function(err, res) {
if (err) return console.log(err);
client.internals.settings = res;
...getPinnedMessages = function (input, callback) {
this._req('get', Endpoints.PINNED_MESSAGES(input.channelID), function(err, res) {
handleResCB("Unable to get pinned messages", err, res, callback);
});
}n/a
getReaction = function (input, callback) {
var qs = { limit: (typeof(input.limit) !== 'number' ? 100 : input.limit) };
this._req('get', Endpoints.MESSAGE_REACTIONS(input.channelID, input.messageID, stringifyEmoji(input.reaction)) + qstringify(qs),
function(err, res) {
handleResCB("Unable to get reaction", err, res, callback);
});
}n/a
getServerInvites = function (serverID, callback) {
this._req('get', Endpoints.SERVERS(serverID) + "/invites", function(err, res) {
handleResCB('Unable to get invite list for server' + serverID, err, res, callback);
});
}n/a
getServerWebhooks = function (serverID, callback) {
this._req('get', Endpoints.SERVER_WEBHOOKS(serverID), function(err, res) {
handleResCB("Could not get server Webhooks", err, res, callback);
});
}n/a
getUser = function (input, callback) {
if (!this.bot) return handleErrCB("[getUser] This account is a 'user' type account, and cannot use 'getUser'. Only bots can use
this endpoint.", callback);
this._req('get', Endpoints.USER(input.userID), function(err, res) {
handleResCB("Could not get user", err, res, callback);
});
}n/a
joinVoiceChannel = function (channelID, callback) {
var serverID, server, channel, voiceSession;
try {
serverID = this.channels[channelID].guild_id;
server = this.servers[serverID];
channel = server.channels[channelID];
} catch(e) {}
if (!serverID) return handleErrCB(("Cannot find the server related to the channel provided: " + channelID), callback);
if (channel.type !== 'voice') return handleErrCB(("Selected channel is not a voice channel: " + channelID), callback);
if (this._vChannels[channelID]) return handleErrCB(("Voice channel already active: " + channelID), callback);
voiceSession = getVoiceSession(this, channelID, server);
checkVoiceReady(voiceSession, callback);
return send(this._ws, Payloads.UPDATE_VOICE(serverID, channelID));
}...
var VCID = "";
var song = "file.mp3";
client.on('ready', function() {
console.log("%s (%s)", client.username, client.id);
client.joinVoiceChannel(VCID, function(err, events) {
if (err) return console.error(err);
events.on('speaking', function(userID, SSRC, speakingBool) {
console.log("%s is " + (speakingBool ? "now speaking" : "done speaking"), userID );
});
client.getAudioContext(VCID, function(err, stream) {
if (err) return console.error(err);
...kick = function (input, callback) {
this._req('delete', Endpoints.MEMBERS(input.serverID, input.userID), function(err, res) {
handleResCB("Could not kick user", err, res, callback);
});
}n/a
leaveServer = function (serverID, callback) {
this._req('delete', Endpoints.SERVERS_PERSONAL(serverID), function(err, res) {
handleResCB("Could not leave server", err, res, callback);
});
}n/a
leaveVoiceChannel = function (channelID, callback) {
if (!this._vChannels[channelID]) return handleErrCB(("Not in the voice channel: " + channelID), callback);
return leaveVoiceChannel(this, channelID, callback);
}n/a
moveUserTo = function (input, callback) {
this._req('patch', Endpoints.MEMBERS(input.serverID, input.userID), {channel_id: input.channelID}, function(err, res) {
handleResCB("Could not move the user", err, res, callback);
});
}n/a
mute = function (input, callback) {
this._req('patch', Endpoints.MEMBERS(input.serverID, input.userID), {mute: true}, function(err, res) {
handleResCB("Could not mute user", err, res, callback);
});
}n/a
pinMessage = function (input, callback) {
this._req('put', Endpoints.PINNED_MESSAGES(input.channelID, input.messageID), function(err, res) {
handleResCB("Unable to pin message", err, res, callback);
});
}n/a
queryInvite = function (inviteCode, callback) {
this._req('get', Endpoints.INVITES(inviteCode), function(err, res) {
handleResCB('Unable to get information about invite', err, res, callback);
});
}n/a
removeAllReactions = function (input, callback) {
this._req('delete', Endpoints.MESSAGE_REACTIONS(input.channelID, input.messageID), function(err, res) {
handleResCB("Unable to remove reactions", err, res, callback);
});
}n/a
removeFromRole = function (input, callback) {
this._req('delete', Endpoints.MEMBER_ROLES(input.serverID, input.userID, input.roleID), function(err, res) {
handleResCB("Could not remove role", err, res, callback);
});
}n/a
removeReaction = function (input, callback) {
this._req('delete', Endpoints.USER_REACTIONS(input.channelID, input.messageID, stringifyEmoji(input.reaction), input.userID), function
(err, res) {
handleResCB("Unable to remove reaction", err, res, callback);
});
}n/a
sendMessage = function (input, callback) {
var message = generateMessage(input.message || '', input.embed);
message.tts = (input.tts === true);
message.nonce = input.nonce || message.nonce;
if (input.typing === true) {
return simulateTyping(
this,
input.to,
message,
( (message.content.length * 0.12) * 1000 ),
callback
);
}
sendMessage(this, input.to, message, callback);
}...
var resArr = [], len = messageArr.length;
var callback = typeof(arguments[2]) === 'function' ? arguments[2] : arguments[3];
if (typeof(interval) !== 'number') interval = 1000;
function _sendMessages() {
setTimeout(function() {
if (messageArr[0]) {
bot.sendMessage({
to: ID,
message: messageArr.shift()
}, function(err, res) {
resArr.push(err || res);
if (resArr.length === len) if (typeof(callback) === 'function') callback(resArr);
});
_sendMessages();
...setPresence = function (input) {
var payload = Payloads.STATUS(input);
send(this._ws, payload);
if (payload.d.idle_since === null) return void(this.presenceStatus = 'online');
this.presenceStatus = 'idle';
}n/a
simulateTyping = function (channelID, callback) {
this._req('post', Endpoints.TYPING(channelID), function(err, res) {
handleResCB("Unable to simulate typing", err, res, callback);
});
}...
r.authorization = (client.bot ? "Bot " : "") + client.internals.token;
} catch(e) {}
return r;
}
function simulateTyping(client, to, message, time, callback) {
if (time <= 0) return sendMessage(client, to, message, callback);
client.simulateTyping(to, function() {
setTimeout(simulateTyping, Math.min(time, 5000), client, to, message, time - 5000, callback);
});
}
function stringifyEmoji(emoji) {
if (typeof emoji === 'object') // if (emoji.name && emoji.id)
return emoji.name + ':' + emoji.id;
if (emoji.indexOf(':') > -1)
...transferOwnership = function (input, callback) {
this._req('patch', Endpoints.SERVERS(input.serverID), {owner_id: input.userID}, function(err, res) {
handleResCB("Could not transfer server ownership", err, res, callback);
});
}n/a
unban = function (input, callback) {
this._req('delete', Endpoints.BANS(input.serverID, input.userID), function(err, res) {
handleResCB("Could not unban user", err, res, callback);
});
}n/a
undeafen = function (input, callback) {
this._req('patch', Endpoints.MEMBERS(input.serverID, input.userID), {deaf: false}, function(err, res) {
handleResCB("Could not undeafen user", err, res, callback);
});
}n/a
unmute = function (input, callback) {
this._req('patch', Endpoints.MEMBERS(input.serverID, input.userID), {mute: false}, function(err, res) {
handleResCB("Could not unmute user", err, res, callback);
});
}n/a
uploadFile = function (input, callback) {
/* After like 15 minutes of fighting with Request, turns out Discord doesn't allow multiple files in one message...
despite having an attachments array.*/
var file,
client = this, multi = new Multipart(), message = generateMessage(input.message || ""),
isBuffer = (input.file instanceof Buffer), isString = (type(input.file) === 'string');
if (!isBuffer && !isString) return handleErrCB("[uploadFile] uploadFile requires a String or Buffer as the 'file' value", callback
);
if (isBuffer) if (input.filename) file = input.file; else return handleErrCB("[uploadFile] uploadFile requires a 'filename' value
to be set if using a Buffer", callback);
if (isString) try { file = FS.readFileSync(input.file); } catch(e) { return handleErrCB("[uploadFile] File does not exist: " +
input.file, callback); }
[
["content", message.content],
["mentions", ""],
["tts", false],
["nonce", message.nonce],
["file", file, input.filename || BN(input.file)]
].forEach(multi.append, multi);
multi.finalize();
resolveID(client, input.to, function(channelID) {
client._req('post', Endpoints.MESSAGES(channelID), multi, function(err, res) {
handleResCB("Unable to upload file", err, res, callback);
});
});
}...
var resArr = [], len = fileArr.length;
var callback = typeof(arguments[2]) === 'function' ? arguments[2] : arguments[3];
if (typeof(interval) !== 'number') interval = 1000;
function _sendFiles() {
setTimeout(function() {
if (fileArr[0]) {
bot.uploadFile({
to: channelID,
file: fileArr.shift()
}, function(err, res) {
resArr.push(err || res);
if (resArr.length === len) if (typeof(callback) === 'function') callback(resArr);
});
_sendFiles();
...BANS = function (serverID, userID) {
return this.SERVERS(serverID) + "/bans" + (userID ? "/" + userID : "");
}...
DCP.ban = function(input, callback) {
if (input.lastDays) {
input.lastDays = Number(input.lastDays);
input.lastDays = Math.min(input.lastDays, 7);
input.lastDays = Math.max(input.lastDays, 1);
}
this._req('put', Endpoints.BANS(input.serverID, input.userID) + (input.lastDays
? "?delete-message-days=" + input.lastDays : ""), function(err, res) {
handleResCB("Could not ban user", err, res, callback);
});
};
/**
* Unban a user from a server.
* @arg {Object} input
...BULK_DELETE = function (channelID) {
return this.CHANNEL(channelID) + "/messages/bulk-delete";
}...
/**
* Delete a batch of messages.
* @arg {Object} input
* @arg {Snowflake} input.channelID
* @arg {Array<Snowflake>} input.messageIDs - An Array of message IDs, with a maximum of 100 indexes.
*/
DCP.deleteMessages = function(input, callback) {
this._req('post', Endpoints.BULK_DELETE(input.channelID), {messages: input
.messageIDs.slice(0, 100)}, function(err, res) {
handleResCB("Unable to delete messages", err, res, callback);
});
};
/**
* Pin a message to the channel.
* @arg {Object} input
...CHANNEL = function (channelID) {
return API + "/channels/" + channelID;
}...
}
for (var key in input) {
if (Object.keys(payload).indexOf(key) < 0) continue;
payload[key] = input[key];
}
this._req('post', Endpoints.CHANNEL(input.channelID) + "/invites"
;, payload, function(err, res) {
try {client.internals.lastInviteCode = res.body.code;} catch(e) {}
handleResCB('Unable to create invite', err, res, callback);
});
};
/**
* Delete an invite code.
...CHANNEL_WEBHOOKS = function (channelID) {
return this.CHANNEL(channelID) +"/webhooks";
}...
};
/**
* Get webhooks from a channel
* @arg {Snowflake} channelID
*/
DCP.getChannelWebhooks = function(channelID, callback) {
this._req('get', Endpoints.CHANNEL_WEBHOOKS(channelID), function(err, res) {
handleResCB("Could not get channel Webhooks", err, res, callback);
});
};
/**
* Create a webhook for a server
* @arg {Snowflake} serverID
...INVITES = function (inviteCode) {
return API + "/invite/" + inviteCode;
}...
/**
* Accept an invite to a server [User Only]
* @arg {String} inviteCode - The code part of an invite URL (e.g. 0MvHMfHcTKVVmIGP)
*/
DCP.acceptInvite = function(inviteCode, callback) {
if (this.bot) return handleErrCB("[acceptInvite] This account is a 'bot' type account, and cannot use 'acceptInvite
'. Please use the client's inviteURL property instead.", callback);
var client = this, joinedServers = Object.keys(client.servers);
this._req('post', Endpoints.INVITES(inviteCode), function(err, res) {
try {
//Try to create the server with the small amount of data
//that Discord provides directly from the HTTP response
//since the websocket event may take a second to show.
if (!client.servers[res.body.guild.id]) {
client.servers[res.body.guild.id] = res.body.guild;
client.servers[res.body.guild.id].channels = {};
...MEMBERS = function (serverID, userID) {
return this.SERVERS(serverID) + "/members" + (userID ? "/" + userID : "");
}...
/**
* Remove a user from a server.
* @arg {Object} input
* @arg {Snowflake} input.serverID
* @arg {Snowflake} input.userID
*/
DCP.kick = function(input, callback) {
this._req('delete', Endpoints.MEMBERS(input.serverID, input.userID), function
(err, res) {
handleResCB("Could not kick user", err, res, callback);
});
};
/**
* Remove and ban a user from a server.
* @arg {Object} input
...MEMBER_ROLES = function (serverID, userID, roleID) {
return this.MEMBERS(serverID, userID) + "/roles" + (roleID ? "/" + roleID : "");
}...
* Add a user to a role.
* @arg {Object} input
* @arg {Snowflake} input.serverID
* @arg {Snowflake} input.roleID
* @arg {Snowflake} input.userID
*/
DCP.addToRole = function(input, callback) {
this._req('put', Endpoints.MEMBER_ROLES(input.serverID, input.userID, input
.roleID), function(err, res) {
handleResCB("Could not add role", err, res, callback);
});
};
/**
* Remove a user from a role.
* @arg {Object} input
...MESSAGES = function (channelID, messageID) {
return this.CHANNEL(channelID) + "/messages" + (messageID ? "/" + messageID : "");
}...
["tts", false],
["nonce", message.nonce],
["file", file, input.filename || BN(input.file)]
].forEach(multi.append, multi);
multi.finalize();
resolveID(client, input.to, function(channelID) {
client._req('post', Endpoints.MESSAGES(channelID), multi, function(err, res
) {
handleResCB("Unable to upload file", err, res, callback);
});
});
};
/**
* Send a message to a channel.
...MESSAGE_REACTIONS = function (channelID, messageID, reaction) {
return this.MESSAGES(channelID, messageID) + "/reactions" + ( reaction ? ("/" + reaction) : "" );
}...
* @arg {Snowflake} input.channelID
* @arg {Snowflake} input.messageID
* @arg {String} input.reaction - Either the emoji unicode or the emoji name:id/object.
* @arg {String} [input.limit]
*/
DCP.getReaction = function(input, callback) {
var qs = { limit: (typeof(input.limit) !== 'number' ? 100 : input.limit) };
this._req('get', Endpoints.MESSAGE_REACTIONS(input.channelID, input.messageID
, stringifyEmoji(input.reaction)) + qstringify(qs), function(err, res) {
handleResCB("Unable to get reaction", err, res, callback);
});
};
/**
* Remove an emoji reaction from a message.
* @arg {Object} input
...NOTE = function (userID) {
return ME + "/notes/" + userID;
}...
/**
* Edit a user's note.
* @arg {Object} input
* @arg {Snowflake} input.userID
* @arg {String} input.note - The note content that you want to use.
*/
DCP.editNote = function(input, callback) {
this._req('put', Endpoints.NOTE(input.userID), {note: input.note}, function
(err, res) {
handleResCB("Could not edit note", err, res, callback);
});
};
/**
* Retrieve a user object from Discord, the library already caches users, however.
* @arg {Object} input
...PINNED_MESSAGES = function (channelID, messageID) {
return this.CHANNEL(channelID) + "/pins" + (messageID ? "/" + messageID : "");
}...
/**
* Pin a message to the channel.
* @arg {Object} input
* @arg {Snowflake} input.channelID
* @arg {Snowflake} input.messageID
*/
DCP.pinMessage = function(input, callback) {
this._req('put', Endpoints.PINNED_MESSAGES(input.channelID, input.messageID
), function(err, res) {
handleResCB("Unable to pin message", err, res, callback);
});
};
/**
* Get an array of pinned messages from a channel.
* @arg {Object} input
...ROLES = function (serverID, roleID) {
return this.SERVERS(serverID) + "/roles" + (roleID ? "/" + roleID : "");
}...
/**
* Create a role for a server.
* @arg {Snowflake} serverID
*/
DCP.createRole = function(serverID, callback) {
var client = this;
this._req('post', Endpoints.ROLES(serverID), function(err, res) {
try {
client.servers[serverID].roles[res.body.id] = new Role(res.body);
} catch(e) {}
handleResCB("Unable to create role", err, res, callback);
});
};
...SERVERS = function (serverID) {
return API + "/guilds" + (serverID ? "/" + serverID : "");
}...
payload = {icon: null, name: null, region: null};
for (var key in input) {
if (Object.keys(payload).indexOf(key) < 0) continue;
payload[key] = input[key];
}
if (input.icon) payload.icon = "data:image/jpg;base64," + input.icon;
client._req('post', Endpoints.SERVERS(), payload, function(err, res) {
try {
client.servers[res.body.id] = {};
copyKeys(res.body, client.servers[res.body.id]);
} catch(e) {}
handleResCB("Could not create server", err, res, callback);
});
};
...SERVERS_PERSONAL = function (serverID) {
return this.ME + "/guilds" + (serverID ? "/" + serverID : ""); //Method to list personal servers?
}...
};
/**
* Leave a server.
* @arg {Snowflake} serverID
*/
DCP.leaveServer = function(serverID, callback) {
this._req('delete', Endpoints.SERVERS_PERSONAL(serverID), function(err, res
) {
handleResCB("Could not leave server", err, res, callback);
});
};
/**
* Delete a server owned by the client.
* @arg {Snowflake} serverID
...SERVER_EMOJIS = function (serverID, emojiID) {
return this.SERVERS(serverID) + "/emojis" + (emojiID ? "/" + emojiID : "");
}...
* @arg {String<Base64>} input.image - The emoji's image data in Base64
*/
DCP.addServerEmoji = function(input, callback) {
var payload = {
name: input.name,
image: "data:image/png;base64," + input.image
};
this._req('post', Endpoints.SERVER_EMOJIS(input.serverID), payload, function
(err, res) {
handleResCB("Unable to add emoji to the server", err, res, callback);
});
}
/**
* [User Account] Edit a server emoji data (name only, currently)
* @arg {Object} input
...SERVER_WEBHOOKS = function (serverID) {
return this.SERVERS(serverID) + "/webhooks";
}...
};
/**
* Get all webhooks for a server
* @arg {Snowflake} serverID
*/
DCP.getServerWebhooks = function(serverID, callback) {
this._req('get', Endpoints.SERVER_WEBHOOKS(serverID), function(err, res) {
handleResCB("Could not get server Webhooks", err, res, callback);
});
};
/**
* Get webhooks from a channel
* @arg {Snowflake} channelID
...TYPING = function (channelID) {
return this.CHANNEL(channelID) + "/typing";
}...
};
/**
* Send 'typing...' status to a channel
* @arg {Snowflake} channelID
*/
DCP.simulateTyping = function(channelID, callback) {
this._req('post', Endpoints.TYPING(channelID), function(err, res) {
handleResCB("Unable to simulate typing", err, res, callback);
});
};
/**
* Replace Snowflakes with the names if applicable.
* @arg {String} message - The message to fix.
...USER = function (userID) {
return API + "/users/" + userID;
}...
/**
* Retrieve a user object from Discord, Bot only endpoint. You don't have to share a server with this user.
* @arg {Object} input
* @arg {Snowflake} input.userID
*/
DCP.getUser = function(input, callback) {
if (!this.bot) return handleErrCB("[getUser] This account is a 'user' type account, and cannot use 'getUser
'. Only bots can use this endpoint.", callback);
this._req('get', Endpoints.USER(input.userID), function(err, res) {
handleResCB("Could not get user", err, res, callback);
});
};
/**
* Edit the client's user information.
* @arg {Object} input
...USER_REACTIONS = function (channelID, messageID, reaction, userID) {
return this.MESSAGE_REACTIONS(channelID, messageID, reaction) + '/' + ( (!userID || userID === this.id) ? '@me' : userID );
}...
* Add an emoji reaction to a message.
* @arg {Object} input
* @arg {Snowflake} input.channelID
* @arg {Snowflake} input.messageID
* @arg {String} input.reaction - Either the emoji unicode or the emoji name:id/object.
*/
DCP.addReaction = function(input, callback) {
this._req('put', Endpoints.USER_REACTIONS(input.channelID, input.messageID
, stringifyEmoji(input.reaction)), function(err, res) {
handleResCB("Unable to add reaction", err, res, callback);
});
};
/**
* Get an emoji reaction of a message.
* @arg {Object} input
...WEBHOOKS = function (webhookID) {
return API + "/webhooks/" + webhookID;
}...
* @arg {Snowflake} input.webhookID - The Webhook's ID
* @arg {String} [input.name]
* @arg {String<Base64>} [input.avatar]
* @arg {String} [input.channelID]
*/
DCP.editWebhook = function(input, callback) {
var client = this, payload = {}, allowed = ['avatar', 'name'];
this._req('get', Endpoints.WEBHOOKS(input.webhookID), function(err, res) {
if (err || !goodResponse(res)) return handleResCB("Couldn't get webhook, do you have permissions to access it?",
err, res, callback);
allowed.forEach(function(key) {
payload[key] = (key in input ? input[key] : res.body[key]);
});
payload.channel_id = input.channelID || res.body.channel_id;
client._req('patch', Endpoints.WEBHOOKS(input.webhookID), payload, function(err, res) {
...