Pushing changes
This commit is contained in:
327
node_modules/discordie/lib/interfaces/IAuthenticatedUser.js
generated
vendored
Normal file
327
node_modules/discordie/lib/interfaces/IAuthenticatedUser.js
generated
vendored
Normal file
@ -0,0 +1,327 @@
|
||||
"use strict";
|
||||
|
||||
const IBase = require("./IBase");
|
||||
const IUser = require("./IUser");
|
||||
const Utils = require("../core/Utils");
|
||||
const AuthenticatedUser = require("../models/AuthenticatedUser");
|
||||
const Constants = require("../Constants");
|
||||
const StatusTypes = Constants.StatusTypes;
|
||||
|
||||
const rest = require("../networking/rest");
|
||||
|
||||
/**
|
||||
* @interface
|
||||
* @model AuthenticatedUser
|
||||
* @extends IBase
|
||||
*/
|
||||
class IAuthenticatedUser extends IBase {
|
||||
constructor(discordie) {
|
||||
super();
|
||||
Utils.definePrivate(this, {_discordie: discordie});
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets date and time the account was registered (created) at.
|
||||
* @returns {Date}
|
||||
* @readonly
|
||||
*/
|
||||
get registeredAt() {
|
||||
return new Date(Utils.timestampFromSnowflake(this.id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets current JPG or GIF avatar URL.
|
||||
* @returns {String|null}
|
||||
* @readonly
|
||||
*/
|
||||
get avatarURL() {
|
||||
return Object.getOwnPropertyDescriptor(IUser.prototype, "avatarURL")
|
||||
.get.apply(this, arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets current JPG avatar URL.
|
||||
* @returns {String|null}
|
||||
* @readonly
|
||||
*/
|
||||
get staticAvatarURL() {
|
||||
return Object.getOwnPropertyDescriptor(IUser.prototype, "staticAvatarURL")
|
||||
.get.apply(this, arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a value indicating whether the account is claimed.
|
||||
* @returns {boolean}
|
||||
* @readonly
|
||||
*/
|
||||
get isClaimedAccount() {
|
||||
return this.email != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the user is mentioned in a `message`.
|
||||
* @param {IMessage} message
|
||||
* @param {boolean} ignoreImplicitMentions
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isMentioned(message, ignoreImplicitMentions) {
|
||||
return IUser.prototype.isMentioned.apply(this, arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to get the bot's OAuth2 application info.
|
||||
*
|
||||
* Works only with bot accounts.
|
||||
*
|
||||
* Example response object:
|
||||
* ```js
|
||||
* {
|
||||
* "description": "Test",
|
||||
* "icon": null,
|
||||
* "id": "179527948411052118",
|
||||
* "name": "app name or something",
|
||||
* "rpc_origins": [],
|
||||
* "flags": 0,
|
||||
* "owner": {
|
||||
* "username": "bot owner",
|
||||
* "discriminator": "4937",
|
||||
* "id": "169454786183781631",
|
||||
* "avatar": null
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
* @returns {Promise<Object, Error>}
|
||||
*/
|
||||
getApplication() {
|
||||
return rest(this._discordie).oauth2.getApplication(Constants.ME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to edit user profile,
|
||||
* substituting `undefined` or `null` properties with current values.
|
||||
*
|
||||
* Passing `null` in `avatar` will remove current avatar. Use `undefined`
|
||||
* instead of `null` in this case.
|
||||
* @param {String} currentPassword - Use null as password on bot accounts
|
||||
* @param {String} [username]
|
||||
* @param {String|Buffer|null} [avatar] - Buffer or base64 data URL
|
||||
* @param {String} [email]
|
||||
* @param {String} [newPassword]
|
||||
* @returns {Promise<IUser, Error>}
|
||||
* @example
|
||||
* // avatar from file
|
||||
* client.User.edit(currentPassword, null, fs.readFileSync("test.png"));
|
||||
* client.User.edit(currentPassword, null, fs.readFileSync("test.jpg"));
|
||||
* // avatar unchanged
|
||||
* client.User.edit(currentPassword, "test", undefined, "new@example.com");
|
||||
* client.User.edit(currentPassword, "test", client.User.avatar);
|
||||
* // no avatar / default avatar
|
||||
* client.User.edit(currentPassword, "test", null);
|
||||
*/
|
||||
edit(currentPassword, username, avatar, email, newPassword) {
|
||||
const user = this._discordie._user;
|
||||
username = username || user.username;
|
||||
email = email || user.email;
|
||||
newPassword = newPassword || null;
|
||||
|
||||
if (avatar instanceof Buffer) {
|
||||
avatar = Utils.imageToDataURL(avatar);
|
||||
} else if (avatar === undefined) {
|
||||
avatar = user.avatar;
|
||||
}
|
||||
|
||||
return new Promise((rs, rj) => {
|
||||
rest(this._discordie)
|
||||
.users.me(currentPassword, username, avatar, email, newPassword)
|
||||
.then(() => rs(this._discordie.User))
|
||||
.catch(rj);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to edit avatar.
|
||||
*
|
||||
* Setting avatar to `null` will remove current avatar.
|
||||
* @param {String|Buffer|null} avatar - Buffer or base64 data URL
|
||||
* @param {String} [currentPassword] - Not applicable for bot accounts
|
||||
* @returns {Promise<IUser, Error>}
|
||||
* @example
|
||||
* // avatar from file
|
||||
* client.User.setAvatar(fs.readFileSync("test.png"));
|
||||
* // remove avatar
|
||||
* client.User.setAvatar(null);
|
||||
*/
|
||||
setAvatar(avatar, currentPassword) {
|
||||
return this.edit(currentPassword, null, avatar);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to edit username.
|
||||
* @param {String} username
|
||||
* @param {String} [currentPassword] - Not applicable for bot accounts
|
||||
* @returns {Promise<IUser, Error>}
|
||||
*/
|
||||
setUsername(username, currentPassword) {
|
||||
return this.edit(currentPassword, username);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets current user status via websocket.
|
||||
*
|
||||
* With multiple sessions status from last connected will override statuses
|
||||
* from previous sessions.
|
||||
*
|
||||
* > Note: By default Discord client does not display game/status updates for
|
||||
* > the user it's logged in into. It will be visible for other users.
|
||||
* @param {Object|String} status
|
||||
* Object `{status: String, afk: boolean}` or string.
|
||||
* Field `afk` changes how Discord handles push notifications.
|
||||
* @param {Object|String|null} [game] - Object `{name: String}` or string
|
||||
* @example
|
||||
* var game = {name: "with code"}; // sets status as "Playing with code"
|
||||
* var streamingGame = {type: 1, name: "something", url: ""}; // "Streaming"
|
||||
* // note: streaming status requires a valid twitch url:
|
||||
* // ex. "http://twitch.tv/channel"
|
||||
* client.User.setStatus("idle", game); // idle, playing
|
||||
* client.User.setStatus(null, game); // no status change, playing
|
||||
* client.User.setStatus(null, "with code"); // no status change, playing
|
||||
* client.User.setStatus(null, streamingGame); // no status change, streaming
|
||||
* client.User.setStatus("online", game); // online, playing
|
||||
* client.User.setStatus("idle", null); // idle, not playing
|
||||
* client.User.setStatus("dnd"); // "do not disturb"
|
||||
* client.User.setStatus("invisible");
|
||||
* client.User.setStatus({status: "idle", afk: true});
|
||||
*/
|
||||
setStatus(status, game) {
|
||||
if (arguments.length == 0) return;
|
||||
|
||||
var afk = this.afk;
|
||||
if (!status) status = this.status;
|
||||
if (typeof status === "object") {
|
||||
afk = status.afk != null ? !!status.afk : this.afk;
|
||||
status = status.status != null ? status.status : this.status;
|
||||
}
|
||||
|
||||
if (game === undefined) game = this.game;
|
||||
if (typeof game === "string") game = {name: game};
|
||||
|
||||
status = Object.keys(StatusTypes).map(v => StatusTypes[v])
|
||||
.find(v => v === status.toLowerCase());
|
||||
status = status || StatusTypes.ONLINE;
|
||||
|
||||
if (this._discordie._user) {
|
||||
this._discordie._user = this._discordie._user.merge({status, game, afk});
|
||||
}
|
||||
|
||||
if (!this._discordie.gatewaySocket) return;
|
||||
|
||||
this._discordie.gatewaySocket.statusUpdate(
|
||||
status,
|
||||
status === StatusTypes.IDLE ? Date.now() : null,
|
||||
game,
|
||||
afk
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets playing game for current user via websocket.
|
||||
*
|
||||
* With multiple sessions status from last connected will override statuses
|
||||
* from previous sessions.
|
||||
*
|
||||
* > Note: By default Discord client does not display game/status updates for
|
||||
* > the user it's logged in into. It will be visible for other users.
|
||||
* @param {Object|String|null} game - Object `{name: String}` or string
|
||||
* @example
|
||||
* var game = {name: "with code"}; // sets game as "Playing with code"
|
||||
* var streamingGame = {type: 1, name: "something", url: ""}; // "Streaming"
|
||||
* // note: streaming status requires a valid twitch url:
|
||||
* // ex. "http://twitch.tv/channel"
|
||||
* client.User.setGame(game); // playing
|
||||
* client.User.setGame("with code"); // playing
|
||||
* client.User.setGame(streamingGame); // streaming
|
||||
* client.User.setGame(null); // not playing
|
||||
*/
|
||||
setGame(game) {
|
||||
if (arguments.length == 0) return;
|
||||
this.setStatus(null, game);
|
||||
}
|
||||
|
||||
/**
|
||||
* Name of the game current user is playing.
|
||||
* @returns {String|null}
|
||||
* @readonly
|
||||
*/
|
||||
get gameName() {
|
||||
return this.game ? this.game.name : null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Attempts to get a guild member interface, returns null if this user is not
|
||||
* a member of the `guild` or `guild` is not in cache.
|
||||
* @param {IGuild|String} guild
|
||||
* @returns {IGuildMember|null}
|
||||
*/
|
||||
memberOf(guild) {
|
||||
return this._discordie.Users.getMember(guild.valueOf(), this.id) || null;
|
||||
}
|
||||
|
||||
/**
|
||||
* See `IUser.permissionsFor`.
|
||||
* @see IUser.permissionsFor
|
||||
* @param {IChannel|IGuild} context
|
||||
* @returns {IPermissions}
|
||||
*/
|
||||
permissionsFor(context) {
|
||||
return IUser.prototype.permissionsFor.apply(this, arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* See `IUser.can`.
|
||||
* @see IUser.can
|
||||
* @param {Number} permission - One or multiple permission bits
|
||||
* @param {IChannel|IGuild} context
|
||||
* @returns {boolean}
|
||||
*/
|
||||
can(permission, context) {
|
||||
return IUser.prototype.can.apply(this, arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* See `IUser.getVoiceChannel`.
|
||||
* @see IUser.getVoiceChannel
|
||||
* @param {IGuild|String} guild - Guild or an id string
|
||||
* @returns {IVoiceChannel|null}
|
||||
*/
|
||||
getVoiceChannel(guild) {
|
||||
return IUser.prototype.getVoiceChannel.apply(this, arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a mention from this user's id.
|
||||
* @returns {String}
|
||||
* @readonly
|
||||
* @example
|
||||
* channel.sendMessage(user.mention + ", example mention");
|
||||
*/
|
||||
get mention() {
|
||||
return `<@${this.id}>`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a nickname mention from this user's id.
|
||||
* @returns {String}
|
||||
* @readonly
|
||||
*/
|
||||
get nickMention() {
|
||||
return `<@!${this.id}>`;
|
||||
}
|
||||
}
|
||||
|
||||
IAuthenticatedUser._inherit(AuthenticatedUser, function(key) {
|
||||
return this._discordie._user[key];
|
||||
});
|
||||
|
||||
module.exports = IAuthenticatedUser;
|
157
node_modules/discordie/lib/interfaces/IBase.js
generated
vendored
Normal file
157
node_modules/discordie/lib/interfaces/IBase.js
generated
vendored
Normal file
@ -0,0 +1,157 @@
|
||||
"use strict";
|
||||
|
||||
const Utils = require("../core/Utils");
|
||||
|
||||
class IBase {
|
||||
static _inherit(proto, get) {
|
||||
var thisProto = this.prototype;
|
||||
thisProto._valueOverrides = thisProto._valueOverrides || {};
|
||||
thisProto._gettersByProperty = thisProto._gettersByProperty || {};
|
||||
thisProto._suppressErrors = false;
|
||||
Object.defineProperties(thisProto, {
|
||||
_valueOverrides: {enumerable: false},
|
||||
_gettersByProperty: {enumerable: false},
|
||||
_suppressErrors: {enumerable: false}
|
||||
});
|
||||
|
||||
thisProto._gettersByProperty[this.name] =
|
||||
thisProto._gettersByProperty[this.name] || {};
|
||||
|
||||
const interfacingProperties = new proto();
|
||||
for (let key in interfacingProperties) {
|
||||
thisProto._gettersByProperty[this.name][key] = get;
|
||||
|
||||
Object.defineProperty(thisProto, key, {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
get: function() {
|
||||
const __thisproto__ = Object.getPrototypeOf(this);
|
||||
try {
|
||||
const value = get.call(this, key);
|
||||
if (__thisproto__._valueOverrides[key]) {
|
||||
return __thisproto__._valueOverrides[key].call(this, value);
|
||||
}
|
||||
return value;
|
||||
} catch (e) {
|
||||
const __ctrproto__ = Object.getPrototypeOf(this.constructor);
|
||||
if (!__ctrproto__._suppressErrors) console.error(e.stack);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
static _setValueOverride(k, fn) {
|
||||
if (!this.prototype.hasOwnProperty(k)) {
|
||||
throw new Error(
|
||||
`Property '${k}' is not defined for ${this.constructor.name}`
|
||||
);
|
||||
}
|
||||
|
||||
if (typeof fn !== "function") {
|
||||
return delete this._valueOverrides[k];
|
||||
}
|
||||
this.prototype._valueOverrides[k] = fn;
|
||||
}
|
||||
static _setSuppressErrors(value) {
|
||||
Object.getPrototypeOf(this)._suppressErrors = value;
|
||||
}
|
||||
|
||||
// Get a copy of raw model data or property
|
||||
getRaw(property) {
|
||||
var allGetters = Object.getPrototypeOf(this)._gettersByProperty;
|
||||
var getters = allGetters[this.constructor.name];
|
||||
if (!getters) {
|
||||
// no own properties, lookup last inherited class
|
||||
var lastClass = Object.keys(allGetters).pop();
|
||||
getters = allGetters[lastClass];
|
||||
}
|
||||
|
||||
getters = getters || {};
|
||||
|
||||
if (property) {
|
||||
if (!getters.hasOwnProperty(property)) return;
|
||||
return getters[property].call(this, property);
|
||||
}
|
||||
|
||||
var copy = {};
|
||||
for (var key in this) {
|
||||
try {
|
||||
if (getters.hasOwnProperty(key))
|
||||
copy[key] = getters[key].call(this, key);
|
||||
} catch (e) {
|
||||
copy[key] = null;
|
||||
console.error("Could not get key", key);
|
||||
console.error(e.stack);
|
||||
}
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
||||
// Get a copy of internal model data, including inherited properties
|
||||
toJSON() {
|
||||
var copy = {};
|
||||
const __thisproto__ = Object.getPrototypeOf(this);
|
||||
for (var classname in __thisproto__._gettersByProperty) {
|
||||
var getters = __thisproto__._gettersByProperty[classname];
|
||||
for (var key in this) {
|
||||
try {
|
||||
if (getters.hasOwnProperty(key)) {
|
||||
copy[key] = getters[key].call(this, key);
|
||||
const v = copy[key];
|
||||
const type = v && v.constructor && v.constructor.name;
|
||||
if (type === "Set") copy[key] = Array.from(v);
|
||||
if (type === "Map") copy[key] = Array.from(v.values());
|
||||
}
|
||||
} catch (e) {
|
||||
copy[key] = null;
|
||||
console.error("Could not get key ", key);
|
||||
console.error(e.stack);
|
||||
}
|
||||
}
|
||||
if (classname === this.constructor.name) break;
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
||||
// Custom inspect output (console.log, util.format, util.inspect)
|
||||
inspect() {
|
||||
var copy = new (
|
||||
// create fake object to preserve class name
|
||||
new Function("return function " + this.constructor.name + "(){}")()
|
||||
);
|
||||
for (var key in this) { copy[key] = this[key]; }
|
||||
return copy;
|
||||
}
|
||||
|
||||
get _valid() {
|
||||
try {
|
||||
var allGetters = Object.getPrototypeOf(this)._gettersByProperty;
|
||||
for (var classname in allGetters) {
|
||||
if (allGetters[classname].hasOwnProperty("id"))
|
||||
return allGetters[classname]["id"].call(this, "id");
|
||||
}
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
valueOf() {
|
||||
if (!this.id) return null;
|
||||
return this.id;
|
||||
}
|
||||
equals(b) {
|
||||
return this.valueOf() === b.valueOf();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets date and time this object was created at.
|
||||
* @returns {Date}
|
||||
* @readonly
|
||||
*/
|
||||
get createdAt() {
|
||||
return new Date(Utils.timestampFromSnowflake(this.id));
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = IBase;
|
75
node_modules/discordie/lib/interfaces/ICall.js
generated
vendored
Normal file
75
node_modules/discordie/lib/interfaces/ICall.js
generated
vendored
Normal file
@ -0,0 +1,75 @@
|
||||
"use strict";
|
||||
|
||||
const Constants = require("../Constants");
|
||||
|
||||
const IBase = require("./IBase");
|
||||
const Utils = require("../core/Utils");
|
||||
|
||||
const Call = require("../models/Call");
|
||||
|
||||
/**
|
||||
* @interface
|
||||
* @model Call
|
||||
* @extends IBase
|
||||
*/
|
||||
class ICall extends IBase {
|
||||
constructor(discordie, directMessageChannelId) {
|
||||
super();
|
||||
Utils.definePrivate(this, {
|
||||
_discordie: discordie,
|
||||
_directMessageChannelId: directMessageChannelId
|
||||
});
|
||||
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets date and time this call was created at.
|
||||
* @returns {Date}
|
||||
* @readonly
|
||||
*/
|
||||
get createdAt() {
|
||||
const call = this._discordie._calls.get(this._directMessageChannelId);
|
||||
if (!call) return new Date(null);
|
||||
|
||||
return new Date(Utils.timestampFromSnowflake(call.message_id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the call is ringing for current user.
|
||||
* @return {boolean}
|
||||
* @readonly
|
||||
*/
|
||||
get isRinging() {
|
||||
const call = this._discordie._calls.get(this._directMessageChannelId);
|
||||
if (!call) return false;
|
||||
|
||||
const userId = this._discordie._user && this._discordie._user.id;
|
||||
if (!userId) return false;
|
||||
|
||||
return call.ringing ? call.ringing.indexOf(userId) >= 0 : false;
|
||||
}
|
||||
}
|
||||
|
||||
ICall._inherit(Call, function modelPropertyGetter(key) {
|
||||
return this._discordie._calls.get(this._directMessageChannelId)[key];
|
||||
});
|
||||
|
||||
/**
|
||||
* @readonly
|
||||
* @instance
|
||||
* @memberOf ICall
|
||||
* @name ringing
|
||||
* @returns {Array<IUser>|null}
|
||||
*/
|
||||
ICall._setValueOverride("ringing", function(ringing) {
|
||||
const users = [];
|
||||
if (!ringing) return users;
|
||||
for (let id of ringing) {
|
||||
const user = this._discordie.Users.get(id);
|
||||
if (user) users.push(user);
|
||||
}
|
||||
return users;
|
||||
});
|
||||
|
||||
module.exports = ICall;
|
307
node_modules/discordie/lib/interfaces/IChannel.js
generated
vendored
Normal file
307
node_modules/discordie/lib/interfaces/IChannel.js
generated
vendored
Normal file
@ -0,0 +1,307 @@
|
||||
"use strict";
|
||||
|
||||
const Constants = require("../Constants");
|
||||
const ChannelTypes = Constants.ChannelTypes;
|
||||
|
||||
const IBase = require("./IBase");
|
||||
const Utils = require("../core/Utils");
|
||||
const Channel = require("../models/Channel");
|
||||
const IUser = require("./IUser");
|
||||
const IRole = require("./IRole");
|
||||
const IGuildMember = require("./IGuildMember");
|
||||
const IAuthenticatedUser = require("./IAuthenticatedUser");
|
||||
const IPermissions = require("./IPermissions");
|
||||
const IPermissionOverwrite = require("./IPermissionOverwrite");
|
||||
|
||||
const rest = require("../networking/rest");
|
||||
|
||||
/**
|
||||
* @interface
|
||||
* @model Channel
|
||||
* @extends IBase
|
||||
* @description
|
||||
* Base channel class.
|
||||
*
|
||||
* Use the `type` property to determine whether it is a
|
||||
* `ITextChannel`, `IDirectMessageChannel` or `IVoiceChannel`:
|
||||
*
|
||||
* ```js
|
||||
* Discordie.ChannelTypes: {
|
||||
* GUILD_TEXT: 0, // ITextChannel
|
||||
* DM: 1, // IDirectMessageChannel
|
||||
* GUILD_VOICE: 2, // IVoiceChannel
|
||||
* GROUP_DM: 3 // IDirectMessageChannel
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
class IChannel extends IBase {
|
||||
constructor(discordie, channelId) {
|
||||
super();
|
||||
Utils.definePrivate(this, {
|
||||
_discordie: discordie,
|
||||
_channelId: channelId
|
||||
});
|
||||
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* **Deprecated**: Removed in API v6. Use `isPrivate` instead.
|
||||
* @return {boolean|null}
|
||||
* @readonly
|
||||
*/
|
||||
get is_private() {
|
||||
return this.isPrivate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether this channel is a direct message channel or a group.
|
||||
* @return {boolean|null}
|
||||
* @readonly
|
||||
*/
|
||||
get isPrivate() {
|
||||
if (!this._valid) return null;
|
||||
return this._discordie._channels._isPrivate(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether this channel is a voice channel in a guild.
|
||||
* @return {boolean}
|
||||
* @readonly
|
||||
*/
|
||||
get isGuildVoice() {
|
||||
return this.type === ChannelTypes.GUILD_VOICE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether this channel is a text channel in a guild.
|
||||
* @return {boolean}
|
||||
* @readonly
|
||||
*/
|
||||
get isGuildText() {
|
||||
return this.type === ChannelTypes.GUILD_TEXT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether this channel is a direct message channel (non-group).
|
||||
* @return {boolean}
|
||||
* @readonly
|
||||
*/
|
||||
get isDM() {
|
||||
return this.type === ChannelTypes.DM;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether this channel is a group direct message channel.
|
||||
* @return {boolean}
|
||||
* @readonly
|
||||
*/
|
||||
get isGroupDM() {
|
||||
return this.type === ChannelTypes.GROUP_DM;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets guild of this channel.
|
||||
* @returns {IGuild|null}
|
||||
* @readonly
|
||||
*/
|
||||
get guild() {
|
||||
return this._discordie.Guilds.get(this.guild_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to create an invite for this channel.
|
||||
* @param {Object} options
|
||||
* @returns {Promise<Object, Error>}
|
||||
* @example
|
||||
* channel.createInvite({
|
||||
* max_age: 60 * 60 * 24, // value in seconds
|
||||
* max_uses: 0, // pretty obvious
|
||||
* temporary: false
|
||||
* // temporary membership, kicks members without roles on disconnect
|
||||
* });
|
||||
* // Example response:
|
||||
* {
|
||||
* "max_age": 86400,
|
||||
* "code": "AAAAAAAAAAAAAAAA",
|
||||
* "guild": {
|
||||
* "splash_hash": null,
|
||||
* "id": "00000000000000000",
|
||||
* "name": "test"
|
||||
* },
|
||||
* "revoked": false,
|
||||
* "created_at": "2015-10-16T10:45:38.566978+00:00",
|
||||
* "temporary": false,
|
||||
* "uses": 0,
|
||||
* "max_uses": 0,
|
||||
* "inviter": {
|
||||
* "username": "testuser",
|
||||
* "discriminator": "3273",
|
||||
* "bot": true,
|
||||
* "id": "00000000000000000",
|
||||
* "avatar": null
|
||||
* },
|
||||
* "channel": {
|
||||
* "type": "text",
|
||||
* "id": "000000000000000000",
|
||||
* "name": "testchannel"
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
createInvite(options) {
|
||||
return this._discordie.Invites.create(this, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to create a permission overwrite for this channel.
|
||||
* @param {IAuthenticatedUser|IRole|IGuildMember} roleOrMember
|
||||
* @param {IPermissions|Number} [allow]
|
||||
* @param {IPermissions|Number} [deny]
|
||||
* @returns {Promise<IPermissionOverwrite, Error>}
|
||||
* @example
|
||||
* channel.createPermissionOverwrite(this.User);
|
||||
* channel.createPermissionOverwrite(
|
||||
* channel.guild.members.find(m => m.username == "testuser")
|
||||
* );
|
||||
* channel.createPermissionOverwrite(
|
||||
* channel.guild.roles.find(r => r.name == "new role")
|
||||
* )
|
||||
* .then(overwrite => console.log(overwrite))
|
||||
* .catch(error => console.log(error));
|
||||
*/
|
||||
createPermissionOverwrite(roleOrMember, allow, deny) {
|
||||
if (![IAuthenticatedUser, IRole, IGuildMember]
|
||||
.some(t => roleOrMember instanceof t))
|
||||
throw new TypeError(
|
||||
"roleOrMember must be an instance of IRole or IGuildMember"
|
||||
);
|
||||
|
||||
if (allow === undefined) allow = 0;
|
||||
if (deny === undefined) deny = 0;
|
||||
if (allow instanceof IPermissions) allow = allow.raw;
|
||||
if (deny instanceof IPermissions) deny = deny.raw;
|
||||
const types = [
|
||||
{t: IRole, s: "role"},
|
||||
{t: IGuildMember, s: "member"},
|
||||
{t: IAuthenticatedUser, s: "member"}
|
||||
];
|
||||
const type = types.find(spec => roleOrMember instanceof spec.t).s;
|
||||
|
||||
return new Promise((rs, rj) => {
|
||||
const raw = {
|
||||
id: roleOrMember.valueOf(),
|
||||
type: type,
|
||||
allow: allow,
|
||||
deny: deny
|
||||
};
|
||||
rest(this._discordie)
|
||||
.channels.putPermissionOverwrite(this._channelId, raw)
|
||||
.then(o =>
|
||||
rs(new IPermissionOverwrite(this._discordie, o.id, this._channelId))
|
||||
)
|
||||
.catch(rj);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to update this channel.
|
||||
* @param {String} [name]
|
||||
* @param {String} [topic]
|
||||
* @param {Number} [bitrate] - Only for voice channels
|
||||
* @param {Number} [userLimit] - Only for voice channels
|
||||
* @returns {Promise<IChannel, Error>}
|
||||
*/
|
||||
update(name, topic, bitrate, userLimit) {
|
||||
if (typeof name !== "string") name = this.name;
|
||||
if (typeof topic !== "string") topic = this.topic;
|
||||
if (typeof bitrate !== "number") bitrate = this.bitrate;
|
||||
if (typeof userLimit !== "number") userLimit = this.user_limit;
|
||||
return new Promise((rs, rj) => {
|
||||
rest(this._discordie)
|
||||
.channels.patchChannel(this.id,
|
||||
name, topic, bitrate, userLimit, this.position
|
||||
)
|
||||
.then((channel) => rs(this._discordie.Channels.get(channel.id)))
|
||||
.catch(rj);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to create a new channel with permission overwrites of
|
||||
* this channel.
|
||||
* @param {String} name
|
||||
* @param {Number} [type] - See IChannel / Discordie.ChannelTypes
|
||||
* @param {Number} [bitrate] - Only for voice channels
|
||||
* @param {Number} [userLimit] - Only for voice channels
|
||||
*/
|
||||
clone(name, type, bitrate, userLimit) {
|
||||
if (!this._valid) return Promise.reject(new Error("Invalid channel"));
|
||||
if (!this.guild) return Promise.reject(new Error("Invalid guild"));
|
||||
name = name != null ? name : this.name;
|
||||
type = type != null ? type : this.type;
|
||||
if (type === ChannelTypes.GUILD_VOICE || type === "voice") {
|
||||
if (bitrate == null) bitrate = this.bitrate;
|
||||
if (userLimit == null) userLimit = this.user_limit;
|
||||
}
|
||||
const permissionOverwrites = this.permission_overwrites;
|
||||
return this.guild
|
||||
.createChannel(type, name, permissionOverwrites, bitrate, userLimit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves this channel to `position` and makes a batch channel update request.
|
||||
* @param {Number} position
|
||||
* @returns {Promise}
|
||||
*/
|
||||
setPosition(position) {
|
||||
const channels = (this.type == ChannelTypes.GUILD_VOICE) ?
|
||||
this.guild.voiceChannels :
|
||||
this.guild.textChannels;
|
||||
|
||||
const changes = Utils.reorderObjects(channels, this, position);
|
||||
if (!changes) return Promise.resolve();
|
||||
|
||||
return rest(this._discordie)
|
||||
.channels.batchPatchChannels(this.guild_id, changes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to delete this channel.
|
||||
* @returns {Promise}
|
||||
*/
|
||||
delete() {
|
||||
return rest(this._discordie).channels.deleteChannel(this.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to get a list of invites for this channel.
|
||||
* @returns {Promise<Array<Object>, Error>}
|
||||
*/
|
||||
getInvites() {
|
||||
return rest(this._discordie).channels.getInvites(this.id);
|
||||
}
|
||||
}
|
||||
|
||||
IChannel._inherit(Channel, function modelPropertyGetter(key) {
|
||||
return this._discordie._channels.get(this._channelId)[key];
|
||||
});
|
||||
|
||||
/**
|
||||
* @readonly
|
||||
* @instance
|
||||
* @memberOf IChannel
|
||||
* @name permission_overwrites
|
||||
* @returns {Array<IPermissionOverwrite>}
|
||||
*/
|
||||
IChannel._setValueOverride("permission_overwrites", function(overwritesRaw) {
|
||||
const overwrites = [];
|
||||
if (!overwritesRaw) return overwrites;
|
||||
for (let overwrite of overwritesRaw) {
|
||||
overwrites.push(new IPermissionOverwrite(
|
||||
this._discordie, overwrite.id, this._channelId
|
||||
));
|
||||
}
|
||||
return overwrites;
|
||||
});
|
||||
|
||||
module.exports = IChannel;
|
65
node_modules/discordie/lib/interfaces/IChannelCollection.js
generated
vendored
Normal file
65
node_modules/discordie/lib/interfaces/IChannelCollection.js
generated
vendored
Normal file
@ -0,0 +1,65 @@
|
||||
"use strict";
|
||||
|
||||
const ICollectionBase = require("./ICollectionBase");
|
||||
const IChannel = require("./IChannel");
|
||||
const ITextChannel = require("./ITextChannel");
|
||||
const IVoiceChannel = require("./IVoiceChannel");
|
||||
const IGuild = require("./IGuild");
|
||||
const Utils = require("../core/Utils");
|
||||
const Constants = require("../Constants");
|
||||
const ChannelTypes = Constants.ChannelTypes;
|
||||
|
||||
/**
|
||||
* @interface
|
||||
* @extends ICollectionBase
|
||||
*/
|
||||
class IChannelCollection extends ICollectionBase {
|
||||
constructor(discordie, valuesGetter, valueGetter) {
|
||||
super({
|
||||
valuesGetter: valuesGetter,
|
||||
valueGetter: valueGetter,
|
||||
itemFactory: (id) => {
|
||||
const type = this._discordie._channels.getChannelType(id);
|
||||
if (type && type === ChannelTypes.GUILD_VOICE) {
|
||||
return new IVoiceChannel(this._discordie, id);
|
||||
}
|
||||
return new ITextChannel(this._discordie, id);
|
||||
}
|
||||
});
|
||||
Utils.definePrivate(this, {_discordie: discordie});
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an array of `IChannel` (`ITextChannel` and `IVoiceChannel`)
|
||||
* for `guild`.
|
||||
* @param {IGuild|String} guild
|
||||
* @returns {Array<IChannel>}
|
||||
*/
|
||||
forGuild(guild) {
|
||||
return this.filter(channel => channel.guild_id == guild.valueOf());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an array of `ITextChannel` for `guild`.
|
||||
* @param {IGuild|String} guild
|
||||
* @returns {Array<ITextChannel>}
|
||||
*/
|
||||
textForGuild(guild) {
|
||||
return this.filter(channel =>
|
||||
channel.guild_id == guild && channel.type == ChannelTypes.GUILD_TEXT
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an array of `IVoiceChannel` for `guild`.
|
||||
* @param {IGuild|String} guild
|
||||
* @returns {Array<IVoiceChannel>}
|
||||
*/
|
||||
voiceForGuild(guild) {
|
||||
return this.filter(channel =>
|
||||
channel.guild_id == guild && channel.type == ChannelTypes.GUILD_VOICE
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = IChannelCollection;
|
192
node_modules/discordie/lib/interfaces/ICollectionBase.js
generated
vendored
Normal file
192
node_modules/discordie/lib/interfaces/ICollectionBase.js
generated
vendored
Normal file
@ -0,0 +1,192 @@
|
||||
"use strict";
|
||||
|
||||
const Utils = require("../core/Utils");
|
||||
|
||||
class ICollectionBase {
|
||||
constructor(descriptor) {
|
||||
if (!descriptor.valuesGetter)
|
||||
throw new Error("valuesGetter is not defined");
|
||||
if (!descriptor.itemFactory)
|
||||
throw new Error("itemFactory is not defined");
|
||||
|
||||
this._valuesGetter = descriptor.valuesGetter;
|
||||
this._valueGetter = descriptor.valueGetter;
|
||||
this._itemFactory = descriptor.itemFactory;
|
||||
this._cache = new WeakMap();
|
||||
Utils.privatify(this);
|
||||
}
|
||||
_getOrCreateInterface(item, customItemFactory) {
|
||||
var factory = customItemFactory || this._itemFactory;
|
||||
var cache = this._cache;
|
||||
if (!cache.get(item))
|
||||
cache.set(item, factory(item.id));
|
||||
return cache.get(item);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an an element, if `key` of an element in the collection
|
||||
* with exact `value` can be found.
|
||||
* Otherwise null is returned.
|
||||
* @param key
|
||||
* @param value
|
||||
* @returns {*}
|
||||
*/
|
||||
getBy(key, value) {
|
||||
if (key === "id" && this._valueGetter) {
|
||||
var item = this._valueGetter(value);
|
||||
if (!item) return null;
|
||||
return this._getOrCreateInterface(item);
|
||||
}
|
||||
|
||||
for (var item of this._valuesGetter()) {
|
||||
if (item[key] != value) continue;
|
||||
return this._getOrCreateInterface(item);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an element with requested `id`, if exists in the collection.
|
||||
* Otherwise null is returned.
|
||||
* @param {String} id
|
||||
* @returns {*}
|
||||
*/
|
||||
get(id) { return this.getBy("id", id); }
|
||||
|
||||
*[Symbol.iterator]() {
|
||||
for (var item of this._valuesGetter()) {
|
||||
yield this._getOrCreateInterface(item);
|
||||
}
|
||||
}
|
||||
|
||||
_getRawItemBy(key, value) {
|
||||
for (var item of this._valuesGetter()) {
|
||||
if (item[key] != value) continue;
|
||||
return item;
|
||||
}
|
||||
}
|
||||
*_getRawIterator() {
|
||||
for (var item of this._valuesGetter()) {
|
||||
yield item;
|
||||
}
|
||||
}
|
||||
_getRaw(id) { return this._getRawItemBy("id", id); }
|
||||
|
||||
/**
|
||||
* Creates a new array with all elements that pass the test implemented
|
||||
* by the provided function.
|
||||
* @param {Function} fn - Function with signature fn(item)
|
||||
* @returns {Array}
|
||||
*/
|
||||
filter(condition) {
|
||||
if (typeof condition !== "function") {
|
||||
throw new TypeError("condition is not a function");
|
||||
}
|
||||
const items = [];
|
||||
for (var item of this) {
|
||||
if (condition(item))
|
||||
items.push(item);
|
||||
}
|
||||
return items;
|
||||
}
|
||||
concat(collection) {
|
||||
if (collection == null) {
|
||||
throw new TypeError("collection is null or not defined");
|
||||
}
|
||||
if (typeof collection.filter !== "function") {
|
||||
throw new TypeError();
|
||||
}
|
||||
collection = collection.filter(() => true);
|
||||
return this.filter(() => true).concat(collection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a value in the collection, if an element in the collection
|
||||
* satisfies the provided testing function. Otherwise null is returned.
|
||||
* @param {Function} fn - Function with signature fn(item)
|
||||
* @returns {Object|null}
|
||||
*/
|
||||
find(condition) {
|
||||
if (typeof condition !== "function") {
|
||||
throw new TypeError("condition is not a function");
|
||||
}
|
||||
for (var item of this) {
|
||||
if (condition(item))
|
||||
return item;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes a provided function once per element.
|
||||
* @param {Function} fn - Function with signature fn(item)
|
||||
*/
|
||||
forEach(fn) {
|
||||
if (typeof fn !== "function") {
|
||||
throw new TypeError("fn is not a function");
|
||||
}
|
||||
for (var item of this) {
|
||||
fn(item);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new array with the results of calling a provided function on
|
||||
* every element in this collection.
|
||||
* @param {Function} fn - Function with signature fn(item)
|
||||
* @returns {Array}
|
||||
*/
|
||||
map(fn) {
|
||||
if (typeof fn !== "function") {
|
||||
throw new TypeError("fn is not a function");
|
||||
}
|
||||
const items = [];
|
||||
for (var item of this) {
|
||||
items.push(fn(item));
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
inspect() {
|
||||
var copy = new (
|
||||
// create fake object to preserve class name
|
||||
new Function("return function " + this.constructor.name + "(){}")()
|
||||
);
|
||||
copy.length = this.length;
|
||||
return copy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new array with elements of this collection.
|
||||
* @returns {Array}
|
||||
*/
|
||||
toArray() {
|
||||
const array = [];
|
||||
for (var item of this) {
|
||||
array.push(item);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
toJSON() { return this.toArray(); }
|
||||
|
||||
/**
|
||||
* Number of elements in this collection.
|
||||
* @returns {Number}
|
||||
* @readonly
|
||||
*/
|
||||
get length() {
|
||||
var i = 0;
|
||||
for (var item of this._valuesGetter()) i++;
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
* Number of elements in this collection. Alias for `.length`.
|
||||
* @returns {Number}
|
||||
* @readonly
|
||||
*/
|
||||
get size() { return this.length; }
|
||||
}
|
||||
|
||||
module.exports = ICollectionBase;
|
589
node_modules/discordie/lib/interfaces/IDirectMessageChannel.js
generated
vendored
Normal file
589
node_modules/discordie/lib/interfaces/IDirectMessageChannel.js
generated
vendored
Normal file
@ -0,0 +1,589 @@
|
||||
"use strict";
|
||||
|
||||
const Constants = require("../Constants");
|
||||
const Endpoints = Constants.Endpoints;
|
||||
const ChannelTypes = Constants.ChannelTypes;
|
||||
|
||||
const IBase = require("./IBase");
|
||||
const ITextChannel = require("./ITextChannel");
|
||||
const ICall = require("./ICall");
|
||||
const Utils = require("../core/Utils");
|
||||
const Channel = require("../models/Channel");
|
||||
|
||||
const rest = require("../networking/rest");
|
||||
|
||||
/**
|
||||
* @interface
|
||||
* @model Channel
|
||||
* @extends IBase
|
||||
*/
|
||||
class IDirectMessageChannel extends IBase {
|
||||
constructor(discordie, directMessageChannelId) {
|
||||
super();
|
||||
Utils.definePrivate(this, {
|
||||
_discordie: discordie,
|
||||
_directMessageChannelId: directMessageChannelId,
|
||||
_call: new ICall(discordie, directMessageChannelId)
|
||||
});
|
||||
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* **Deprecated**: Removed in API v6. Use `isPrivate` instead.
|
||||
* @return {boolean|null}
|
||||
* @readonly
|
||||
*/
|
||||
get is_private() {
|
||||
return this.isPrivate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether this channel is a direct message channel or a group.
|
||||
* @return {boolean|null}
|
||||
* @readonly
|
||||
*/
|
||||
get isPrivate() {
|
||||
if (!this._valid) return null;
|
||||
return this._discordie._channels._isPrivate(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether this channel is a voice channel in a guild.
|
||||
* @return {boolean}
|
||||
* @readonly
|
||||
*/
|
||||
get isGuildVoice() {
|
||||
return this.type === ChannelTypes.GUILD_VOICE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether this channel is a text channel in a guild.
|
||||
* @return {boolean}
|
||||
* @readonly
|
||||
*/
|
||||
get isGuildText() {
|
||||
return this.type === ChannelTypes.GUILD_TEXT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether this channel is a direct message channel (non-group).
|
||||
* @return {boolean}
|
||||
* @readonly
|
||||
*/
|
||||
get isDM() {
|
||||
return this.type === ChannelTypes.DM;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether this channel is a group direct message channel.
|
||||
* @return {boolean}
|
||||
* @readonly
|
||||
*/
|
||||
get isGroupDM() {
|
||||
return this.type === ChannelTypes.GROUP_DM;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the owner of the private channel.
|
||||
*
|
||||
* Returns null if the owner user is not in cache or there is no owner.
|
||||
* @returns {IAuthenticatedUser|IUser|null}
|
||||
* @readonly
|
||||
*/
|
||||
get owner() {
|
||||
if (!this.owner_id) return null;
|
||||
const owner = this._discordie.Users.get(this.owner_id);
|
||||
if (!owner) return null;
|
||||
if (this._discordie.User.equals(owner))
|
||||
return this._discordie.User;
|
||||
return owner;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the `user` is the owner of the private channel.
|
||||
* @param {IGuildMember|IUser|IAuthenticatedUser|String} user
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isOwner(user) {
|
||||
if (!user) return false;
|
||||
if (!this.owner_id) return false;
|
||||
return this.owner_id === user.valueOf();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a string URL of image icon of this channel.
|
||||
* @returns {String|null}
|
||||
* @readonly
|
||||
*/
|
||||
get iconURL() {
|
||||
if (!this.icon) return null;
|
||||
return Constants.CDN_ENDPOINT + Endpoints.CDN_DM_ICON(this.id, this.icon);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets first recipient of this channel.
|
||||
*
|
||||
* Returns null if this channel is invalid or has no recipients.
|
||||
*
|
||||
* **Deprecated**: Use `recipients` instead.
|
||||
* @returns {IUser|null}
|
||||
* @readonly
|
||||
*/
|
||||
get recipient() {
|
||||
if (!this._valid) return null;
|
||||
return this.recipients[0] || null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a value indicating whether all messages were loaded.
|
||||
* @returns {boolean}
|
||||
* @readonly
|
||||
*/
|
||||
get allMessagesLoaded() {
|
||||
return !this._discordie._messages.channelHasMore(this.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an array of cached messages in this channel, sorted in order of
|
||||
* arrival (message cache is sorted on message insertion, not when this
|
||||
* getter is invoked).
|
||||
*
|
||||
* Returns an empty array if channel no longer exists.
|
||||
* @returns {Array<IMessage>}
|
||||
* @readonly
|
||||
*/
|
||||
get messages() {
|
||||
return this._discordie.Messages.forChannel(this.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to fetch messages for this channel.
|
||||
*
|
||||
* Discord API does not allow fetching more than 100 messages at once.
|
||||
*
|
||||
* Promise resolves with an Object with following structure:
|
||||
* ```js
|
||||
* {
|
||||
* messages: Array<IMessage>,
|
||||
* limit: Number, // same as parameter passed or default value
|
||||
* before: String | null, // message id
|
||||
* after: String | null // message id
|
||||
* }
|
||||
* ```
|
||||
* @param {Number|null} [limit] - Default is 100
|
||||
* @param {IMessage|String|null} [before] - Message or message id
|
||||
* @param {IMessage|String|null} [after] - Message or message id
|
||||
* @returns {Promise<Object, Error>}
|
||||
* @example
|
||||
* var guild = client.Guilds.find(g => g.name == "test");
|
||||
* var channel = guild.generalChannel;
|
||||
*
|
||||
* // simple fetch:
|
||||
* channel.fetchMessages().then(() => {
|
||||
* console.log("[simple] messages in cache: " + channel.messages.length);
|
||||
* });
|
||||
*
|
||||
* // fetching more than 100 messages into cache sequentially:
|
||||
* fetchMessagesEx(channel, 420).then(() => {
|
||||
* console.log("[extended] messages in cache: " + channel.messages.length);
|
||||
* });
|
||||
*
|
||||
* // fetch more messages just like Discord client does
|
||||
* function fetchMessagesEx(channel, left) {
|
||||
* // message cache is sorted on insertion
|
||||
* // channel.messages[0] will get oldest message
|
||||
* var before = channel.messages[0];
|
||||
* return channel.fetchMessages(Math.min(left, 100), before)
|
||||
* .then(e => onFetch(e, channel, left));
|
||||
* }
|
||||
* function onFetch(e, channel, left) {
|
||||
* if (!e.messages.length) return Promise.resolve();
|
||||
* left -= e.messages.length;
|
||||
* console.log(`Received ${e.messages.length}, left: ${left}`);
|
||||
* if (left <= 0) return Promise.resolve();
|
||||
* return fetchMessagesEx(channel, left);
|
||||
* }
|
||||
*/
|
||||
fetchMessages(limit, before, after) {
|
||||
return ITextChannel.prototype.fetchMessages.apply(this, arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an array of cached pinned messages in this channel.
|
||||
*
|
||||
* Pinned message cache is updated only if all pinned messages have been
|
||||
* loaded with `IDirectMessageChannel.fetchPinned()`.
|
||||
*
|
||||
* Returns an empty array if channel no longer exists or if pinned messages
|
||||
* have not been fetched yet.
|
||||
* @returns {Array<IMessage>}
|
||||
* @readonly
|
||||
*/
|
||||
get pinnedMessages() {
|
||||
return this._discordie.Messages.forChannelPinned(this.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to fetch pinned messages for this channel.
|
||||
*
|
||||
* Promise resolves with an Object with following structure:
|
||||
* ```js
|
||||
* {
|
||||
* channelId: String,
|
||||
* messages: Array<IMessage>
|
||||
* }
|
||||
* ```
|
||||
* @returns {Promise<Object, Error>}
|
||||
*/
|
||||
fetchPinned() {
|
||||
return new Promise((rs, rj) => {
|
||||
rest(this._discordie).channels.getPinnedMessages(this.id)
|
||||
.then(e => {
|
||||
e.messages = e.messages
|
||||
.map(msg => this._discordie.Messages.get(msg.id));
|
||||
return rs(e);
|
||||
})
|
||||
.catch(rj);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to send a message to this channel. Messages over 2000
|
||||
* characters will be rejected by the server.
|
||||
*
|
||||
* Use `uploadFile` if you want to send a message with an attachment.
|
||||
* @param {String|Array<String>} content
|
||||
* Strings will be sent as is, arrays - joined with a newline character.
|
||||
* @param {IUser|IGuildMember|Array<IUser>|Array<IGuildMember>} [mentions]
|
||||
* Deprecated: left for backward compatibility.
|
||||
* @param {boolean} [tts]
|
||||
* @param {Object} [embed]
|
||||
* Refer to [official API documentation](https://discordapp.com/developers/docs/resources/channel#embed-object)
|
||||
* for embed structure description.
|
||||
* @returns {Promise<IMessage, Error>}
|
||||
* @example
|
||||
* var guild = client.Guilds.find(g => g.name == "test");
|
||||
* if (!guild) return console.log("invalid guild");
|
||||
*
|
||||
* var channel = guild.generalChannel;
|
||||
*
|
||||
* channel.sendMessage("regular message");
|
||||
* channel.sendMessage("test with tts", true);
|
||||
*
|
||||
* var user = client.Users.find(u => u.username == "test");
|
||||
* if (!user) return console.log("invalid user");
|
||||
*
|
||||
* channel.sendMessage("mentioning user " + user.mention);
|
||||
* channel.sendMessage("@everyone or @here mention if you have permissions");
|
||||
*
|
||||
* channel.sendMessage("message with an embed", false, {
|
||||
* color: 0x3498db,
|
||||
* author: {name: "author name"},
|
||||
* title: "This is an embed",
|
||||
* url: "http://google.com",
|
||||
* timestamp: "2016-11-13T03:43:32.127Z",
|
||||
* fields: [{name: "some field", value: "some value"}],
|
||||
* footer: {text: "footer text"}
|
||||
* });
|
||||
*/
|
||||
sendMessage(content, mentions, tts, embed) {
|
||||
return ITextChannel.prototype.sendMessage.apply(this, arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to upload data to this channel.
|
||||
* Images require a `filename` with a valid extension to actually be uploaded.
|
||||
* @param {Buffer|ReadableStream|String} readableStream
|
||||
* Data to upload or filename as a string
|
||||
* @param {String} filename
|
||||
* Actual filename to show, required for non-string `readableStream`
|
||||
* @param {String} [content] - Additional comment message for attachment
|
||||
* @param {boolean} [tts]
|
||||
* @returns {Promise<IMessage, Error>}
|
||||
* @example
|
||||
* channel.uploadFile(fs.readFileSync("test.png"), "test.png"); // Buffer
|
||||
* channel.uploadFile(fs.createReadStream("test.png"), "test.png"); // Stream
|
||||
* channel.uploadFile("test.png"); // File
|
||||
* channel.uploadFile("test.png", null, "file with message");
|
||||
* channel.uploadFile("test.png", null, "file with message and tts", true);
|
||||
*/
|
||||
uploadFile(readableStream, filename, content, mentions, tts) {
|
||||
return ITextChannel.prototype.uploadFile.apply(this, arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to send typing status for this channel.
|
||||
*
|
||||
* Discord client displays it for 10 seconds, sends every 5 seconds.
|
||||
* Stops showing typing status if receives a message from the user.
|
||||
* @returns {Promise}
|
||||
*/
|
||||
sendTyping() {
|
||||
return ITextChannel.prototype.sendTyping.apply(this, arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to close this channel (direct message channels only).
|
||||
* @returns {Promise}
|
||||
*/
|
||||
close() {
|
||||
return rest(this._discordie).channels.deleteChannel(this.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to ring specified recipients.
|
||||
* Has no effect if call has not started yet.
|
||||
*
|
||||
* Bot accounts cannot use this endpoint.
|
||||
* @param {Array<IUser|String>} [recipients]
|
||||
* @return {Promise}
|
||||
*/
|
||||
ring(recipients) {
|
||||
if (recipients && !Array.isArray(recipients))
|
||||
throw new TypeError("Param 'recipients' is not an array");
|
||||
|
||||
if (recipients) recipients = recipients.map(u => u.valueOf());
|
||||
return rest(this._discordie).channels.calls
|
||||
.ring(this.id, recipients);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to decline an incoming call (if no arguments passed) or
|
||||
* stop ringing for specified recipients.
|
||||
*
|
||||
* Bot accounts cannot use this endpoint.
|
||||
* @param {Array<IUser|String>} [recipients]
|
||||
* @return {Promise}
|
||||
*/
|
||||
stopRinging(recipients) {
|
||||
if (recipients && !Array.isArray(recipients))
|
||||
throw new TypeError("Param 'recipients' is not an array");
|
||||
|
||||
if (recipients) recipients = recipients.map(u => u.valueOf());
|
||||
return rest(this._discordie).channels.calls
|
||||
.stopRinging(this.id, recipients);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to change the server region hosting the call.
|
||||
*
|
||||
* Bot accounts cannot use this endpoint.
|
||||
* @param {String} region
|
||||
* @return {Promise}
|
||||
*/
|
||||
changeCallRegion(region) {
|
||||
return rest(this._discordie).channels.calls.changeRegion(this.id, region);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to add a user to this private channel.
|
||||
*
|
||||
* Bot accounts cannot use this endpoint.
|
||||
* @param {IUser|IGuildMember} user
|
||||
* @return {Promise}
|
||||
*/
|
||||
addRecipient(user) {
|
||||
user = user.valueOf();
|
||||
return rest(this._discordie).channels.dm.addRecipient(this.id, user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to remove a user from this private channel.
|
||||
*
|
||||
* Bot accounts cannot use this endpoint.
|
||||
* @param {IUser|IGuildMember} user
|
||||
* @return {Promise}
|
||||
*/
|
||||
removeRecipient(user) {
|
||||
user = user.valueOf();
|
||||
return rest(this._discordie).channels.dm.removeRecipient(this.id, user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to set a name for this private channel.
|
||||
* @param {String} name
|
||||
* @return {Promise<IDirectMessageChannel, Error>}
|
||||
*/
|
||||
setName(name) {
|
||||
return new Promise((rs, rj) => {
|
||||
rest(this._discordie).channels.dm.setName(this.id, name)
|
||||
.then(() => rs(this))
|
||||
.catch(rj);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to set an icon for this private channel.
|
||||
* @param {String|Buffer|null} icon
|
||||
* @return {Promise<IDirectMessageChannel, Error>}
|
||||
*/
|
||||
setIcon(icon) {
|
||||
if (icon instanceof Buffer) {
|
||||
icon = Utils.imageToDataURL(icon);
|
||||
} else if (icon === undefined) {
|
||||
icon = this.icon;
|
||||
}
|
||||
|
||||
return new Promise((rs, rj) => {
|
||||
rest(this._discordie).channels.dm.setIcon(this.id, icon)
|
||||
.then(() => rs(this))
|
||||
.catch(rj);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates or joins a call.
|
||||
* Only one call can be connected at the same time.
|
||||
*
|
||||
* Joining calls with bot accounts is not supported.
|
||||
* @param {boolean} [selfMute]
|
||||
* @param {boolean} [selfDeaf]
|
||||
* @returns {Promise<VoiceConnectionInfo, Error|Number>}
|
||||
*/
|
||||
joinCall(selfMute, selfDeaf) {
|
||||
selfMute = !!selfMute;
|
||||
selfDeaf = !!selfDeaf;
|
||||
|
||||
if (!this._valid)
|
||||
return Promise.reject(new Error("Channel does not exist"));
|
||||
|
||||
const call = this._discordie._calls.get(this._directMessageChannelId);
|
||||
if (call && call.unavailable)
|
||||
return Promise.reject(new Error("Call is unavailable"));
|
||||
|
||||
if (this._discordie._user && this._discordie._user.bot)
|
||||
throw new Error("Joining calls with bot accounts is not supported");
|
||||
|
||||
const vc = this._discordie.VoiceConnections;
|
||||
return vc._getOrCreate(null, this.id, selfMute, selfDeaf);
|
||||
}
|
||||
|
||||
/**
|
||||
* Leaves call if joined.
|
||||
*/
|
||||
leaveCall() {
|
||||
const info = this.getVoiceConnectionInfo();
|
||||
if (info) return info.voiceConnection.disconnect();
|
||||
|
||||
this._discordie.VoiceConnections
|
||||
.cancelIfPending(null, this._directMessageChannelId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves `VoiceConnectionInfo` for the call of this channel.
|
||||
* @returns {VoiceConnectionInfo|null}
|
||||
*/
|
||||
getVoiceConnectionInfo() {
|
||||
return this._discordie.VoiceConnections
|
||||
.getForChannel(this._directMessageChannelId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether current user is in the call.
|
||||
* @returns {boolean}
|
||||
* @readonly
|
||||
*/
|
||||
get joinedCall() {
|
||||
const vc = this._discordie.VoiceConnections;
|
||||
const pendingChannel = vc.getPendingChannel(null);
|
||||
const channelId = this._directMessageChannelId;
|
||||
return !!(pendingChannel && pendingChannel === channelId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an array of users in the call.
|
||||
*
|
||||
* Returns null if call does not exist in cache or has not started yet.
|
||||
* @returns {Array<IUser>|null}
|
||||
* @readonly
|
||||
*/
|
||||
get usersInCall() {
|
||||
const call = this._discordie._calls.get(this._directMessageChannelId);
|
||||
return this._discordie.Users.usersInCall(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets call from cache.
|
||||
*
|
||||
* Returns null if call does not exist in cache or has not started yet.
|
||||
* @returns {ICall|null}
|
||||
* @readonly
|
||||
*/
|
||||
get call() {
|
||||
const call = this._discordie._calls.get(this._directMessageChannelId);
|
||||
return call ? this._call : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches call info through gateway socket.
|
||||
*
|
||||
* Currently there are no ways to fetch call info for all channels at once.
|
||||
* @return {Promise<ICall|null, Error>}
|
||||
*/
|
||||
fetchCall() {
|
||||
const gateway = this._discordie.gatewaySocket;
|
||||
if (!gateway || !gateway.connected)
|
||||
return Promise.reject(new Error("No gateway socket (not connected)"));
|
||||
|
||||
return new Promise((rs, rj) => {
|
||||
const call = this._discordie._calls.get(this._directMessageChannelId);
|
||||
if (call) return rs(this._call);
|
||||
|
||||
gateway.callConnect(this._directMessageChannelId);
|
||||
|
||||
setTimeout(() => {
|
||||
const call = this._discordie._calls.get(this._directMessageChannelId);
|
||||
rs(call ? this._call : null);
|
||||
}, 1000);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
IDirectMessageChannel._inherit(Channel, function modelPropertyGetter(key) {
|
||||
return this._discordie._channels.get(this._directMessageChannelId)[key];
|
||||
});
|
||||
|
||||
/**
|
||||
* @readonly
|
||||
* @instance
|
||||
* @memberOf IDirectMessageChannel
|
||||
* @name name
|
||||
* @returns {String}
|
||||
*/
|
||||
IDirectMessageChannel._setValueOverride("name", function(name) {
|
||||
const UNNAMED = "Unnamed";
|
||||
if (!this._valid) return UNNAMED;
|
||||
|
||||
const type = this.type;
|
||||
if (type === ChannelTypes.DM) {
|
||||
const recipient = this.recipients[0];
|
||||
return recipient ? recipient.username : name;
|
||||
}
|
||||
if (type === ChannelTypes.GROUP_DM) {
|
||||
return name || this.recipients.map(u => u.username).join(", ") || UNNAMED;
|
||||
}
|
||||
|
||||
return name;
|
||||
});
|
||||
|
||||
/**
|
||||
* Gets recipients of this channel.
|
||||
* @readonly
|
||||
* @instance
|
||||
* @memberOf IDirectMessageChannel
|
||||
* @name recipients
|
||||
* @returns {Array<IUser>|null}
|
||||
*/
|
||||
IDirectMessageChannel._setValueOverride("recipients", function(recipients) {
|
||||
const users = [];
|
||||
if (!recipients) return users;
|
||||
for (let id of recipients.values()) {
|
||||
const user = this._discordie.Users.get(id);
|
||||
if (user) users.push(user);
|
||||
}
|
||||
return users;
|
||||
});
|
||||
|
||||
|
||||
module.exports = IDirectMessageChannel;
|
72
node_modules/discordie/lib/interfaces/IDirectMessageChannelCollection.js
generated
vendored
Normal file
72
node_modules/discordie/lib/interfaces/IDirectMessageChannelCollection.js
generated
vendored
Normal file
@ -0,0 +1,72 @@
|
||||
"use strict";
|
||||
|
||||
const ICollectionBase = require("./ICollectionBase");
|
||||
const IDirectMessageChannel = require("./IDirectMessageChannel");
|
||||
const Utils = require("../core/Utils");
|
||||
const Constants = require("../Constants");
|
||||
const ChannelTypes = Constants.ChannelTypes;
|
||||
|
||||
const rest = require("../networking/rest");
|
||||
|
||||
/**
|
||||
* @interface
|
||||
* @extends ICollectionBase
|
||||
*/
|
||||
class IDirectMessageChannelCollection extends ICollectionBase {
|
||||
constructor(discordie, valuesGetter, valueGetter) {
|
||||
super({
|
||||
valuesGetter: valuesGetter,
|
||||
valueGetter: valueGetter,
|
||||
itemFactory: (id) => new IDirectMessageChannel(this._discordie, id)
|
||||
});
|
||||
this._discordie = discordie;
|
||||
Utils.privatify(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a DM channel from cache or makes a request to create one.
|
||||
* @param {IUser|IGuildMember|String} recipient
|
||||
* @returns {Promise<IDirectMessageChannel, Error>}
|
||||
*/
|
||||
getOrOpen(recipient) {
|
||||
const existing = this.find(c =>
|
||||
c.type === ChannelTypes.DM &&
|
||||
c.recipients.length === 1 &&
|
||||
c.recipients[0].equals(recipient)
|
||||
);
|
||||
if (existing)
|
||||
return Promise.resolve(existing);
|
||||
return this.open(recipient);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to create a DM channel.
|
||||
* @param {IUser|IGuildMember|String} recipient
|
||||
* @returns {Promise<IDirectMessageChannel, Error>}
|
||||
*/
|
||||
open(recipient) {
|
||||
recipient = recipient.valueOf();
|
||||
return this.createGroupDM([recipient]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to create a group DM channel.
|
||||
*
|
||||
* Bot accounts cannot use this endpoint.
|
||||
* @param {Array<IUser|IGuildMember|String>} [recipients]
|
||||
* @returns {Promise<IDirectMessageChannel, Error>}
|
||||
*/
|
||||
createGroupDM(recipients) {
|
||||
recipients = recipients || [];
|
||||
recipients = recipients.filter(u => u).map(u => u.valueOf());
|
||||
const userId = this._discordie.User.id;
|
||||
return new Promise((rs, rj) => {
|
||||
rest(this._discordie)
|
||||
.users.createDirectMessageChannel(userId, recipients)
|
||||
.then(c => rs(this._discordie.DirectMessageChannels.get(c.id)))
|
||||
.catch(rj);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = IDirectMessageChannelCollection;
|
542
node_modules/discordie/lib/interfaces/IGuild.js
generated
vendored
Normal file
542
node_modules/discordie/lib/interfaces/IGuild.js
generated
vendored
Normal file
@ -0,0 +1,542 @@
|
||||
"use strict";
|
||||
|
||||
const Constants = require("../Constants");
|
||||
const Endpoints = Constants.Endpoints;
|
||||
|
||||
const IBase = require("./IBase");
|
||||
const IChannel = require("./IChannel");
|
||||
const IGuildMember = require("./IGuildMember");
|
||||
const IUser = require("./IUser");
|
||||
const IRole = require("./IRole");
|
||||
const Utils = require("../core/Utils");
|
||||
const Guild = require("../models/Guild");
|
||||
|
||||
const rest = require("../networking/rest");
|
||||
|
||||
/**
|
||||
* @interface
|
||||
* @model Guild
|
||||
* @extends IBase
|
||||
*/
|
||||
class IGuild extends IBase {
|
||||
constructor(discordie, guildId) {
|
||||
super();
|
||||
Utils.definePrivate(this, {
|
||||
_discordie: discordie,
|
||||
_guildId: guildId
|
||||
});
|
||||
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an acronym string for this guild.
|
||||
* (Text that shows up as guild icon in the client if there is no image icon.)
|
||||
* @returns {String}
|
||||
* @readonly
|
||||
*/
|
||||
get acronym() {
|
||||
if (!this.name) return "";
|
||||
return this.name.replace(/\w+/g, match => match[0]).replace(/\s/g, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a string URL of image icon of this guild.
|
||||
* @returns {String|null}
|
||||
* @readonly
|
||||
*/
|
||||
get iconURL() {
|
||||
if (!this.icon) return null;
|
||||
return Constants.CDN_ENDPOINT +
|
||||
Endpoints.CDN_GUILD_ICON(this.id, this.icon);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a string URL of invite splash image of this guild.
|
||||
* @returns {String|null}
|
||||
* @readonly
|
||||
*/
|
||||
get splashURL() {
|
||||
if (!this.splash) return null;
|
||||
return Constants.CDN_ENDPOINT +
|
||||
Endpoints.CDN_GUILD_SPLASH(this.id, this.splash);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the `user` is the owner of this guild.
|
||||
* @param {IGuildMember|IUser|IAuthenticatedUser|String} user
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isOwner(user) {
|
||||
if (!user) return false;
|
||||
if (!this.owner_id) return false;
|
||||
return this.owner_id === user.valueOf();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns afk channel of this guild.
|
||||
* @returns {IChannel|null}
|
||||
* @readonly
|
||||
*/
|
||||
get afk_channel() {
|
||||
if (!this.afk_channel_id) return null;
|
||||
const afk_channel = this._discordie.Channels.get(this.afk_channel_id);
|
||||
return afk_channel ? afk_channel : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the owner of this guild.
|
||||
*
|
||||
* Returns null if the owner user is not in cache.
|
||||
*
|
||||
* See `.isOwner(user)` if you want to safely check if the `user` is owner.
|
||||
* @returns {IAuthenticatedUser|IUser|null}
|
||||
* @readonly
|
||||
*/
|
||||
get owner() {
|
||||
if (!this.owner_id) return null;
|
||||
const owner = this._discordie.Users.get(this.owner_id);
|
||||
if (!owner) return null;
|
||||
if (this._discordie.User.equals(owner))
|
||||
return this._discordie.User;
|
||||
return owner;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an array of text and voice channels of this guild.
|
||||
* @returns {Array<IChannel>}
|
||||
* @readonly
|
||||
*/
|
||||
get channels() {
|
||||
return this._discordie.Channels.forGuild(this.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an array of text channels of this guild.
|
||||
* @returns {Array<ITextChannel>}
|
||||
* @readonly
|
||||
*/
|
||||
get textChannels() {
|
||||
return this._discordie.Channels.textForGuild(this.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an array of voice channels of this guild.
|
||||
* @returns {Array<IVoiceChannel>}
|
||||
* @readonly
|
||||
*/
|
||||
get voiceChannels() {
|
||||
return this._discordie.Channels.voiceForGuild(this.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns general channel of this guild.
|
||||
* @returns {ITextChannel}
|
||||
* @readonly
|
||||
*/
|
||||
get generalChannel() {
|
||||
return this._discordie.Channels.get(this.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to edit this guild,
|
||||
* substituting `undefined` or `null` properties with current values.
|
||||
*
|
||||
* Passing `null` in `icon` or `afkChannelId` will remove current
|
||||
* icon/channel. Use `undefined` instead of `null` in this case.
|
||||
* @param {String} [name]
|
||||
* @param {String|Buffer|null} [icon]
|
||||
* @param {String} [region]
|
||||
* @param {IChannel|String|null} [afkChannelId] - Channel or an id string
|
||||
* @param {Number} [afkTimeout] - 60, 300, 900, 1800 or 3600 seconds
|
||||
* @param {Number} [verificationLevel]
|
||||
* See Discordie.VerificationLevel
|
||||
* @param {Number} [defaultMessageNotifications]
|
||||
* See Discordie.UserNotificationSettings
|
||||
* @returns {Promise<IGuild, Error>}
|
||||
*/
|
||||
edit(name, icon, region, afkChannelId, afkTimeout, verificationLevel,
|
||||
defaultMessageNotifications) {
|
||||
const guild = this._discordie._guilds.get(this._guildId);
|
||||
name = name || guild.name;
|
||||
region = region || guild.region;
|
||||
afkTimeout = afkTimeout || guild.afk_timeout;
|
||||
|
||||
const opt = (value, _) => value != null ? value : _;
|
||||
verificationLevel =
|
||||
opt(verificationLevel, guild.verification_level);
|
||||
defaultMessageNotifications =
|
||||
opt(defaultMessageNotifications, guild.default_message_notifications);
|
||||
|
||||
if (icon instanceof Buffer) {
|
||||
icon = Utils.imageToDataURL(icon);
|
||||
} else if (icon === undefined) {
|
||||
icon = guild.icon;
|
||||
}
|
||||
|
||||
if (afkChannelId === undefined) {
|
||||
afkChannelId = guild.afk_channel_id;
|
||||
} else if (afkChannelId != null) {
|
||||
afkChannelId = afkChannelId.valueOf();
|
||||
}
|
||||
|
||||
return new Promise((rs, rj) => {
|
||||
rest(this._discordie)
|
||||
.guilds.patchGuild(
|
||||
guild.id,
|
||||
name, icon, region,
|
||||
afkChannelId, afkTimeout,
|
||||
verificationLevel,
|
||||
defaultMessageNotifications
|
||||
)
|
||||
.then(() => rs(this))
|
||||
.catch(rj);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to create a channel in this guild.
|
||||
* @param {Number} type - See IChannel / Discordie.ChannelTypes
|
||||
* @param {String} name
|
||||
* @param {Array<IPermissionOverwrite>} [permissionOverwrites]
|
||||
* @param {Number} [bitrate] - Only for voice channels
|
||||
* @param {Number} [userLimit] - Only for voice channels
|
||||
* @returns {Promise<ITextChannel|IVoiceChannel, Error>}
|
||||
*/
|
||||
createChannel(type, name, permissionOverwrites, bitrate, userLimit) {
|
||||
permissionOverwrites = permissionOverwrites || [];
|
||||
if (!Array.isArray(permissionOverwrites))
|
||||
throw TypeError("Param 'permissionOverwrites' must be an array");
|
||||
|
||||
permissionOverwrites = permissionOverwrites.map(v => {
|
||||
return typeof v.getRaw === "function" ? v.getRaw() : null;
|
||||
}).filter(v => v);
|
||||
|
||||
return new Promise((rs, rj) => {
|
||||
rest(this._discordie)
|
||||
.channels.createChannel(this.id,
|
||||
type, name, permissionOverwrites, bitrate, userLimit
|
||||
)
|
||||
.then(channel => rs(this._discordie.Channels.get(channel.id)))
|
||||
.catch(rj);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to create a role in this guild.
|
||||
* @returns {Promise<IRole, Error>}
|
||||
*/
|
||||
createRole() {
|
||||
return new Promise((rs, rj) => {
|
||||
rest(this._discordie).guilds.roles.createRole(this.id)
|
||||
.then(role => rs(new IRole(this._discordie, role.id, this.id)))
|
||||
.catch(rj);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to create an invite for general channel in this guild.
|
||||
*
|
||||
* See `IChannel.createInvite` for more info.
|
||||
* @see IChannel.createInvite
|
||||
* @param {Object} options
|
||||
* @returns {Promise<Object, Error>}
|
||||
*/
|
||||
createInvite(options) {
|
||||
return this._discordie.Invites.create(this.generalChannel, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an array containing members of this guild.
|
||||
* @returns {Array<IGuildMember>}
|
||||
* @readonly
|
||||
*/
|
||||
get members() {
|
||||
return this._discordie.Users.membersForGuild(this.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to delete this guild.
|
||||
*
|
||||
* Returns a rejected promise if the user **is not** owner.
|
||||
* @returns {Promise}
|
||||
*/
|
||||
delete() {
|
||||
if (!this.owner.equals(this._discordie.User))
|
||||
return Promise.reject();
|
||||
return rest(this._discordie).guilds.deleteGuild(this.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to delete this guild.
|
||||
*
|
||||
* Returns a rejected promise if the user **is** owner.
|
||||
* @returns {Promise}
|
||||
*/
|
||||
leave() {
|
||||
if (this.owner.equals(this._discordie.User))
|
||||
return Promise.reject();
|
||||
return rest(this._discordie).guilds.leaveGuild(this.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to ban a user (does not have to be a member of the guild).
|
||||
*
|
||||
* Additionally delete `deleteMessageForDays` number of days worth of their
|
||||
* messages from all channels of the guild.
|
||||
* @param {IUser|String} user - User or an id string
|
||||
* @param deleteMessageForDays - Number of days worth of messages to delete
|
||||
* (min 0, max 7)
|
||||
* @returns {Promise}
|
||||
*/
|
||||
ban(user, deleteMessageForDays) {
|
||||
user = user.valueOf();
|
||||
return rest(this._discordie)
|
||||
.guilds.bans.banMember(this.id, user, deleteMessageForDays);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to unban a user.
|
||||
* @param {IUser|String} user - User or an id string
|
||||
* @returns {Promise}
|
||||
*/
|
||||
unban(user) {
|
||||
user = user.valueOf();
|
||||
return rest(this._discordie).guilds.bans.unbanMember(this.id, user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to get ban list of this guild.
|
||||
* @returns {Promise<Array<IUser>, Error>}
|
||||
*/
|
||||
getBans() {
|
||||
return new Promise((rs, rj) => {
|
||||
rest(this._discordie).guilds.bans.getBans(this.id)
|
||||
.then(bans => {
|
||||
const bannedUsers = bans.map(ban => {
|
||||
return new IUser(this._discordie, ban.user.id);
|
||||
});
|
||||
return rs(bannedUsers);
|
||||
})
|
||||
.catch(rj);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to get estimate of members affected by prune request.
|
||||
*
|
||||
* Promise resolves with an Object with following structure:
|
||||
* ```js
|
||||
* {
|
||||
* guildId: String,
|
||||
* days: Number, // same as parameter passed
|
||||
* estimate: Number
|
||||
* }
|
||||
* ```
|
||||
* @param {Number} days - Number of days from 1 to 7, default 1
|
||||
* @returns {Promise<Object, Error>}
|
||||
*/
|
||||
getPruneEstimate(days) {
|
||||
return rest(this._discordie).guilds.prune.getPrune(this.id, days);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to prune members.
|
||||
*
|
||||
* Promise resolves with an Object with following structure:
|
||||
* ```js
|
||||
* {
|
||||
* guildId: String,
|
||||
* days: Number, // same as parameter passed
|
||||
* pruned: Number
|
||||
* }
|
||||
* ```
|
||||
* @param {Number} days - Number of days from 1 to 7, default 1
|
||||
* @returns {Promise<Object, Error>}
|
||||
*/
|
||||
pruneMembers(days) {
|
||||
// make it also accept object from .getPruneEstimate(days)
|
||||
if (days && days.hasOwnProperty("days")) {
|
||||
days = days.days;
|
||||
}
|
||||
return rest(this._discordie).guilds.prune.postPrune(this.id, days);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to get a list of invites of this guild.
|
||||
* @returns {Promise<Array<Object>, Error>}
|
||||
*/
|
||||
getInvites() {
|
||||
return rest(this._discordie).guilds.getInvites(this.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to get a list of voice regions available for this guild.
|
||||
* @returns {Promise<Array<Object>, Error>}
|
||||
*/
|
||||
fetchRegions() {
|
||||
return rest(this._discordie).voice.getRegions(this.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to transfer ownership of this guild to `user`.
|
||||
* @param {IGuildMember|IUser|String} user - User or an id string
|
||||
* @returns {Promise<IGuild, Error>}
|
||||
*/
|
||||
transferOwnership(user) {
|
||||
return new Promise((rs, rj) => {
|
||||
rest(this._discordie)
|
||||
.guilds.transferOwnership(this.id, user.valueOf())
|
||||
.then(() => rs(this))
|
||||
.catch(rj);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to get widget (external embed) settings.
|
||||
*
|
||||
* Promise resolves with an Object with following structure:
|
||||
* ```js
|
||||
* {
|
||||
* enabled: boolean,
|
||||
* channel_id: String|null
|
||||
* }
|
||||
* ```
|
||||
* @return {Promise<Object, Error>}
|
||||
*/
|
||||
getWidget() {
|
||||
return rest(this._discordie).guilds.getEmbed(this.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to set widget (external embed) settings.
|
||||
* @param {Object} options
|
||||
* Object `{enabled: boolean, channelId or channel_id: String}`.
|
||||
* Both options are optional.
|
||||
* @return {Promise<Object, Error>}
|
||||
*/
|
||||
editWidget(options) {
|
||||
return rest(this._discordie).guilds.patchEmbed(this.id, options || {});
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to fetch emojis for this guild.
|
||||
*
|
||||
* Only user and whitelisted bot accounts can use this endpoint.
|
||||
*
|
||||
* Promise resolves with an array of Objects with following structure:
|
||||
* ```js
|
||||
* {
|
||||
* "managed": false,
|
||||
* "name": 'abc',
|
||||
* "roles": [],
|
||||
* "user": {
|
||||
* "username": "testuser",
|
||||
* "discriminator": "3273",
|
||||
* "id": "000000000000000000",
|
||||
* "avatar": null
|
||||
* },
|
||||
* "require_colons": true,
|
||||
* "id": "000000000000000000"
|
||||
* }
|
||||
* ```
|
||||
* @return {Promise<Array<Object>, Error>}
|
||||
*/
|
||||
fetchEmoji() {
|
||||
return rest(this._discordie).guilds.emoji.getEmoji(this.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to create an emoji.
|
||||
*
|
||||
* Returned object does not contain `user` property.
|
||||
*
|
||||
* Only user and whitelisted bot accounts can use this endpoint.
|
||||
* @param {Buffer|String} image - Buffer or base64 image string
|
||||
* @param {String} name
|
||||
* @return {Promise<Object, Error>}
|
||||
*/
|
||||
uploadEmoji(image, name) {
|
||||
if (image instanceof Buffer) {
|
||||
image = Utils.imageToDataURL(image);
|
||||
}
|
||||
|
||||
return rest(this._discordie).guilds.emoji.postEmoji(this.id, image, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to delete the specified emoji.
|
||||
*
|
||||
* Only user and whitelisted bot accounts can use this endpoint.
|
||||
* @param {Object|String} emoji - Emoji object or an id string
|
||||
* @return {Promise<Object, Error>}
|
||||
*/
|
||||
deleteEmoji(emoji) {
|
||||
if (emoji && emoji.id) emoji = emoji.id;
|
||||
|
||||
return rest(this._discordie).guilds.emoji.deleteEmoji(this.id, emoji);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to edit the specified emoji.
|
||||
*
|
||||
* Returned object does not contain `user` property.
|
||||
*
|
||||
* Only user and whitelisted bot accounts can use this endpoint.
|
||||
* @param {Object|String} emoji - Emoji object or an id string
|
||||
* @param {Object} options
|
||||
* Optional properties to edit:
|
||||
* `{name: String, roles: Array<IRole>|Array<String>}`
|
||||
* @return {Promise<Object, Error>}
|
||||
*/
|
||||
editEmoji(emoji, options) {
|
||||
if (emoji && emoji.id) emoji = emoji.id;
|
||||
if (!options) return Promise.resolve();
|
||||
|
||||
options = Object.assign({}, options);
|
||||
|
||||
const roles = options.roles;
|
||||
if (roles && !Array.isArray(roles)) {
|
||||
throw new TypeError("Param 'roles' must be an array");
|
||||
}
|
||||
if (Array.isArray(roles)) {
|
||||
options.roles = roles.filter(role => role).map(role => role.valueOf());
|
||||
}
|
||||
|
||||
return rest(this._discordie)
|
||||
.guilds.emoji.patchEmoji(this.id, emoji, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a string URL of an emoji.
|
||||
* @returns {String|null}
|
||||
*/
|
||||
getEmojiURL(emoji) {
|
||||
if (emoji && emoji.id) emoji = emoji.id;
|
||||
if (!emoji) return null;
|
||||
return Constants.CDN_ENDPOINT + Endpoints.CDN_EMOJI(emoji);
|
||||
}
|
||||
}
|
||||
|
||||
IGuild._inherit(Guild, function modelPropertyGetter(key) {
|
||||
return this._discordie._guilds.get(this._guildId)[key];
|
||||
});
|
||||
|
||||
/**
|
||||
* Creates an array of roles of this guild.
|
||||
* @readonly
|
||||
* @instance
|
||||
* @memberOf IGuild
|
||||
* @name roles
|
||||
* @returns {Array<IRole>}
|
||||
*/
|
||||
IGuild._setValueOverride("roles", function(rolesRaw) {
|
||||
const roles = [];
|
||||
if (!rolesRaw) return roles;
|
||||
for (let role of rolesRaw.values()) {
|
||||
roles.push(new IRole(this._discordie, role.id, this.id));
|
||||
}
|
||||
return roles;
|
||||
});
|
||||
|
||||
module.exports = IGuild;
|
78
node_modules/discordie/lib/interfaces/IGuildCollection.js
generated
vendored
Normal file
78
node_modules/discordie/lib/interfaces/IGuildCollection.js
generated
vendored
Normal file
@ -0,0 +1,78 @@
|
||||
"use strict";
|
||||
|
||||
const ICollectionBase = require("./ICollectionBase");
|
||||
const IGuild = require("./IGuild");
|
||||
const Utils = require("../core/Utils");
|
||||
|
||||
const rest = require("../networking/rest");
|
||||
|
||||
/**
|
||||
* @interface
|
||||
* @extends ICollectionBase
|
||||
*/
|
||||
class IGuildCollection extends ICollectionBase {
|
||||
constructor(discordie, valuesGetter, valueGetter) {
|
||||
super({
|
||||
valuesGetter: valuesGetter,
|
||||
valueGetter: valueGetter,
|
||||
itemFactory: (id) => new IGuild(this._discordie, id)
|
||||
});
|
||||
this._discordie = discordie;
|
||||
Utils.privatify(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to create a guild.
|
||||
* @param {String} name
|
||||
* @param {String} region
|
||||
* @param {Buffer|null} [icon]
|
||||
* @param {Array<IRole|Object>} [roles]
|
||||
* @param {Array<IChannel|Object>} [channels]
|
||||
* @param {Number} [verificationLevel]
|
||||
* See Discordie.VerificationLevel
|
||||
* @param {Number} [defaultMessageNotifications]
|
||||
* See Discordie.UserNotificationSettings
|
||||
* @returns {Promise<IGuild, Error>}
|
||||
*/
|
||||
create(name, region, icon,
|
||||
roles, channels,
|
||||
verificationLevel, defaultMessageNotifications) {
|
||||
if (icon instanceof Buffer) {
|
||||
icon = Utils.imageToDataURL(icon);
|
||||
}
|
||||
|
||||
const toRaw = (data, param) => {
|
||||
data = data || [];
|
||||
if (!Array.isArray(data))
|
||||
throw TypeError("Param '" + param + "' must be an array");
|
||||
|
||||
return data.map(v => {
|
||||
return typeof v.getRaw === "function" ? v.getRaw() : null;
|
||||
}).filter(v => v);
|
||||
};
|
||||
|
||||
roles = toRaw(roles, "roles");
|
||||
channels = toRaw(channels, "channels");
|
||||
|
||||
return new Promise((rs, rj) => {
|
||||
rest(this._discordie).guilds.createGuild(
|
||||
name, region, icon,
|
||||
roles, channels,
|
||||
verificationLevel, defaultMessageNotifications
|
||||
)
|
||||
.then(guild => rs(this._discordie.Guilds.get(guild.id)))
|
||||
.catch(rj);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to get a default list of voice regions.
|
||||
* Use IGuild.fetchRegions for getting guild-specific list.
|
||||
* @returns {Promise<Array<Object>, Error>}
|
||||
*/
|
||||
fetchRegions() {
|
||||
return rest(this._discordie).voice.getRegions();
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = IGuildCollection;
|
291
node_modules/discordie/lib/interfaces/IGuildMember.js
generated
vendored
Normal file
291
node_modules/discordie/lib/interfaces/IGuildMember.js
generated
vendored
Normal file
@ -0,0 +1,291 @@
|
||||
"use strict";
|
||||
|
||||
const IBase = require("./IBase");
|
||||
const IUser = require("./IUser");
|
||||
const IRole = require("./IRole");
|
||||
const GuildMember = require("../models/GuildMember");
|
||||
const Utils = require("../core/Utils");
|
||||
|
||||
const rest = require("../networking/rest");
|
||||
|
||||
/**
|
||||
* @interface
|
||||
* @model GuildMember
|
||||
* @extends IUser
|
||||
*/
|
||||
class IGuildMember extends IUser {
|
||||
constructor(discordie, userId, guildId) {
|
||||
super(discordie, userId);
|
||||
Utils.definePrivate(this, {_guildId: guildId});
|
||||
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Current status of the member.
|
||||
* @returns {String}
|
||||
* @readonly
|
||||
*/
|
||||
get status() {
|
||||
return this._discordie._presences.getStatus(this.id, this._guildId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Current game the member is playing.
|
||||
* @returns {Object|null}
|
||||
* @readonly
|
||||
*/
|
||||
get game() {
|
||||
return this._discordie._presences.getGame(this.id, this._guildId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Name of the current game the member is playing.
|
||||
* @returns {String|null}
|
||||
* @readonly
|
||||
*/
|
||||
get gameName() {
|
||||
return this.game ? this.game.name : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Previous status of the member.
|
||||
* @returns {String}
|
||||
* @readonly
|
||||
*/
|
||||
get previousStatus() {
|
||||
return this._discordie._presences.getPreviousStatus(this.id, this._guildId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Previous game the member was playing.
|
||||
* @returns {Object|null}
|
||||
* @readonly
|
||||
*/
|
||||
get previousGame() {
|
||||
return this._discordie._presences.getPreviousGame(this.id, this._guildId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Name of the previous game the member was playing.
|
||||
* @returns {String|null}
|
||||
* @readonly
|
||||
*/
|
||||
get previousGameName() {
|
||||
return this.previousGame ? this.previousGame.name : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets guild of this member.
|
||||
* @returns {IGuild|null}
|
||||
* @readonly
|
||||
*/
|
||||
get guild() {
|
||||
return this._discordie.Guilds.get(this._guildId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets `nick` of this member if set, otherwise returns `username`.
|
||||
* @returns {String|null}
|
||||
* @readonly
|
||||
*/
|
||||
get name() {
|
||||
return this.nick ? this.nick : this.username;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the first voice channel that this member is currently in.
|
||||
* @returns {IVoiceChannel|null}
|
||||
*/
|
||||
getVoiceChannel() {
|
||||
return super.getVoiceChannel(this._guildId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to kick this member (from the guild they belong to).
|
||||
* @returns {Promise}
|
||||
*/
|
||||
kick() {
|
||||
return rest(this._discordie)
|
||||
.guilds.members.kickMember(this._guildId, this.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to ban this member (from the guild they belong to).
|
||||
*
|
||||
* Additionally delete `deleteMessageForDays` number of days worth of their
|
||||
* messages from all channels of the guild.
|
||||
* @param deleteMessageForDays - Number of days worth of messages to delete
|
||||
* (min 0, max 7)
|
||||
* @returns {Promise}
|
||||
*/
|
||||
ban(deleteMessageForDays) {
|
||||
return rest(this._discordie)
|
||||
.guilds.bans.banMember(this._guildId, this._userId, deleteMessageForDays);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to unban this member (from the guild they belonged to).
|
||||
* @returns {Promise}
|
||||
*/
|
||||
unban() {
|
||||
return rest(this._discordie)
|
||||
.guilds.bans.unbanMember(this._guildId, this._userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to mute this member globally in the guild.
|
||||
*
|
||||
* Returns a resolved promise if the member is already muted.
|
||||
* @returns {Promise}
|
||||
*/
|
||||
serverMute(mute) {
|
||||
if (mute === undefined) mute = true;
|
||||
if (mute == this.mute) return Promise.resolve();
|
||||
return rest(this._discordie)
|
||||
.guilds.members.setMute(this._guildId, this.id, mute);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to unmute this member globally in the guild.
|
||||
*
|
||||
* Returns a resolved promise if the member is already unmuted.
|
||||
* @returns {Promise}
|
||||
*/
|
||||
serverUnmute() {
|
||||
return this.serverMute(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to deafen this member globally in the guild.
|
||||
*
|
||||
* Returns a resolved promise if the member is already deafened.
|
||||
* @returns {Promise}
|
||||
*/
|
||||
serverDeafen(deaf) {
|
||||
if (deaf === undefined) deaf = true;
|
||||
if (deaf == this.deaf) return Promise.resolve();
|
||||
return rest(this._discordie)
|
||||
.guilds.members.setDeaf(this._guildId, this.id, deaf);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to undeafen this member globally in the guild.
|
||||
*
|
||||
* Returns a resolved promise if the member is already undeafened.
|
||||
* @returns {Promise}
|
||||
*/
|
||||
serverUndeafen() {
|
||||
return this.serverDeafen(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this member has the specified role.
|
||||
* @param {IRole|String} role - Role or an id string
|
||||
* @returns {Promise}
|
||||
*/
|
||||
hasRole(role) {
|
||||
role = role.valueOf();
|
||||
return this.getRaw().roles.indexOf(role) >= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns (adds) the specified role to this member.
|
||||
* @param {IRole|String} role - Role or an id string
|
||||
* @returns {Promise}
|
||||
*/
|
||||
assignRole(role) {
|
||||
role = role.valueOf();
|
||||
const rawMember = this.getRaw();
|
||||
if (!rawMember || !rawMember.roles)
|
||||
return Promise.reject(new Error("Member does not exist"));
|
||||
// raw roles are mutable, copying with .slice()
|
||||
const roleIds = rawMember.roles.slice();
|
||||
const roleIndex = roleIds.indexOf(role);
|
||||
|
||||
if (roleIndex >= 0) return Promise.resolve();
|
||||
roleIds.push(role);
|
||||
|
||||
return rest(this._discordie)
|
||||
.guilds.members.setRoles(this._guildId, this.id, roleIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unassigns (removes) the specified role from this member.
|
||||
* @param {IRole|String} role - Role or an id string
|
||||
* @returns {Promise}
|
||||
*/
|
||||
unassignRole(role) {
|
||||
role = role.valueOf();
|
||||
const rawMember = this.getRaw();
|
||||
if (!rawMember || !rawMember.roles)
|
||||
return Promise.reject(new Error("Member does not exist"));
|
||||
// raw roles are mutable, copying with .slice()
|
||||
const roleIds = rawMember.roles.slice();
|
||||
const roleIndex = roleIds.indexOf(role);
|
||||
|
||||
if (roleIndex < 0) return Promise.resolve();
|
||||
roleIds.splice(roleIndex, 1);
|
||||
|
||||
return rest(this._discordie)
|
||||
.guilds.members.setRoles(this._guildId, this.id, roleIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets specified roles for this member: overwrites all existing roles
|
||||
* with a new set of roles.
|
||||
* @param {Array<IRole|String>} roles - Array of roles or id strings
|
||||
* @returns {Promise}
|
||||
*/
|
||||
setRoles(roles) {
|
||||
const roleIds = roles.map(role => role.valueOf());
|
||||
return rest(this._discordie)
|
||||
.guilds.members.setRoles(this._guildId, this.id, roleIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves this member to the specified voice channel.
|
||||
* @param {IChannel|String} channel - Channel or an id string
|
||||
* @returns {Promise}
|
||||
*/
|
||||
setChannel(channel) {
|
||||
channel = channel.valueOf();
|
||||
return rest(this._discordie)
|
||||
.guilds.members.setChannel(this._guildId, this.id, channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to set a nickname for this member.
|
||||
*
|
||||
* Requires permission `MANAGE_NICKNAMES`.
|
||||
* @param {String} nick
|
||||
* @returns {Promise}
|
||||
*/
|
||||
setNickname(nick) {
|
||||
return rest(this._discordie)
|
||||
.guilds.members.setNickname(this._guildId, this.id, nick);
|
||||
}
|
||||
}
|
||||
|
||||
IGuildMember._inherit(GuildMember, function modelPropertyGetter(key) {
|
||||
return this._discordie._members.getMember(this._guildId, this._userId)[key];
|
||||
});
|
||||
|
||||
/**
|
||||
* Creates an array of roles assigned to this member.
|
||||
* @readonly
|
||||
* @instance
|
||||
* @memberOf IGuildMember
|
||||
* @name roles
|
||||
* @returns {Array<IRole>}
|
||||
*/
|
||||
IGuildMember._setValueOverride("roles", function(roleIds) {
|
||||
const roles = [];
|
||||
if (!roleIds) return roles;
|
||||
for (let roleId of roleIds) {
|
||||
roles.push(new IRole(this._discordie, roleId, this._guildId));
|
||||
}
|
||||
return roles;
|
||||
});
|
||||
|
||||
module.exports = IGuildMember;
|
101
node_modules/discordie/lib/interfaces/IInviteManager.js
generated
vendored
Normal file
101
node_modules/discordie/lib/interfaces/IInviteManager.js
generated
vendored
Normal file
@ -0,0 +1,101 @@
|
||||
"use strict";
|
||||
|
||||
const Utils = require("../core/Utils");
|
||||
|
||||
const rest = require("../networking/rest");
|
||||
|
||||
/**
|
||||
* @interface
|
||||
*/
|
||||
class IInviteManager {
|
||||
constructor(discordie) {
|
||||
this._discordie = discordie;
|
||||
Utils.privatify(this);
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to create an invite.
|
||||
* See `IChannel.createInvite` for more info.
|
||||
* @see IChannel.createInvite
|
||||
* @param {IChannel|String} channel
|
||||
* @param {Object} options
|
||||
* @returns {Promise<Object, Error>}
|
||||
*/
|
||||
create(channel, options) {
|
||||
options = options || {
|
||||
max_age: 60 * 30,
|
||||
// value in seconds
|
||||
max_uses: 0,
|
||||
// pretty obvious
|
||||
temporary: false
|
||||
// temporary membership, kicks members without roles on disconnect
|
||||
};
|
||||
channel = channel.valueOf();
|
||||
return rest(this._discordie).invites.createInvite(channel, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to regenerate existing invite.
|
||||
* @param {Object|String} code
|
||||
* @returns {Promise<Object, Error>}
|
||||
*/
|
||||
regenerate(code) {
|
||||
if (code && code.code) code = code.code;
|
||||
const options = {regenerate: code};
|
||||
return rest(this._discordie).invites.createInvite(channel, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to revoke existing invite.
|
||||
* @param {Object|String} code
|
||||
* @returns {Promise<Object, Error>}
|
||||
*/
|
||||
revoke(code) {
|
||||
if (code && code.code) code = code.code;
|
||||
return rest(this._discordie).invites.deleteInvite(code);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to resolve existing invite.
|
||||
* @param {Object|String} code
|
||||
* @returns {Promise<Object, Error>}
|
||||
* @example
|
||||
* client.Invites.resolve("Zt5yW").then(console.log).catch(console.log);
|
||||
* // Example response:
|
||||
* {
|
||||
* "code": "Zt5yW",
|
||||
* "guild": {
|
||||
* "splash_hash": null,
|
||||
* "id": "00000000000000000",
|
||||
* "name": "test"
|
||||
* },
|
||||
* "channel": {
|
||||
* "type": "text",
|
||||
* "id": "000000000000000000",
|
||||
* "name": "testchannel"
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
resolve(code) {
|
||||
if (code && code.code) code = code.code;
|
||||
return rest(this._discordie).invites.getInvite(code);
|
||||
}
|
||||
|
||||
/**
|
||||
* **Deprecated**: Only works with user accounts.
|
||||
* Bot accounts can be invited by users with Manage Server permission using
|
||||
* the `https://discordapp.com/oauth2/authorize?client_id=%APP_ID%&scope=bot`
|
||||
* page. See official Discord API documentation for more info.
|
||||
*
|
||||
* Makes a request to accept existing invite.
|
||||
* @param {Object|String} code
|
||||
* @returns {Promise<Object, Error>}
|
||||
*/
|
||||
accept(code) {
|
||||
if (code && code.code) code = code.code;
|
||||
return rest(this._discordie).invites.postInvite(code);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = IInviteManager;
|
430
node_modules/discordie/lib/interfaces/IMessage.js
generated
vendored
Normal file
430
node_modules/discordie/lib/interfaces/IMessage.js
generated
vendored
Normal file
@ -0,0 +1,430 @@
|
||||
"use strict";
|
||||
|
||||
const Constants = require("../Constants");
|
||||
const MessageTypes = Constants.MessageTypes;
|
||||
|
||||
const IBase = require("./IBase");
|
||||
const IRole = require("./IRole");
|
||||
const IUser = require("./IUser");
|
||||
const Utils = require("../core/Utils");
|
||||
const Message = require("../models/Message");
|
||||
|
||||
const rest = require("../networking/rest");
|
||||
|
||||
/**
|
||||
* @interface
|
||||
* @model Message
|
||||
* @extends IBase
|
||||
* @description
|
||||
* Chat message. Can be a system message depending on type:
|
||||
*
|
||||
* ```js
|
||||
* Discordie.MessageTypes: {
|
||||
* DEFAULT: 0,
|
||||
* RECIPIENT_ADD: 1,
|
||||
* RECIPIENT_REMOVE: 2,
|
||||
* CALL: 3,
|
||||
* CHANNEL_NAME_CHANGE: 4,
|
||||
* CHANNEL_ICON_CHANGE: 5,
|
||||
* CHANNEL_PINNED_MESSAGE: 6
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
class IMessage extends IBase {
|
||||
constructor(discordie, messageId) {
|
||||
super();
|
||||
Utils.definePrivate(this, {
|
||||
_discordie: discordie,
|
||||
_messageId: messageId
|
||||
});
|
||||
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether this message is cached.
|
||||
* @param {IMessage} message
|
||||
* @returns {boolean}
|
||||
* @readonly
|
||||
*/
|
||||
get isCached() {
|
||||
return !!this._valid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether this message was edited by the author.
|
||||
*
|
||||
* Returns null if message does not exist in cache.
|
||||
* @returns {boolean|null}
|
||||
* @readonly
|
||||
*/
|
||||
get isEdited() {
|
||||
return this.isCached ? this.edited_timestamp != null : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether this message is from a private channel (direct message).
|
||||
*
|
||||
* Returns null if message/channel does not exist in cache.
|
||||
* @returns {boolean|null}
|
||||
* @readonly
|
||||
*/
|
||||
get isPrivate() {
|
||||
return this._discordie._channels.isPrivate(this.channel_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the message is a system message.
|
||||
* @returns {boolean|null}
|
||||
* @readonly
|
||||
*/
|
||||
get isSystem() {
|
||||
return this.type !== MessageTypes.DEFAULT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a system message string depending on message `type`.
|
||||
* @returns {String|null}
|
||||
* @readonly
|
||||
*/
|
||||
get systemMessage() {
|
||||
if (!this._valid) return null;
|
||||
|
||||
const type = this.type;
|
||||
|
||||
const user = this.author || {};
|
||||
const target = this.mentions[0] || {};
|
||||
|
||||
if (type === MessageTypes.RECIPIENT_ADD) {
|
||||
return user.username + " added " + target.username + " to the group.";
|
||||
}
|
||||
|
||||
if (type === MessageTypes.RECIPIENT_REMOVE) {
|
||||
if (user.id !== target.id) {
|
||||
return user.username + " added " + target.username + " to the group.";
|
||||
} else {
|
||||
return user.username + " left the group.";
|
||||
}
|
||||
}
|
||||
|
||||
if (type === MessageTypes.CALL) {
|
||||
const localUserId = this._discordie._user && this._discordie._user.id;
|
||||
const isActive =
|
||||
this._discordie._calls.isActive(this.channel_id, this.id);
|
||||
const isMissed =
|
||||
!isActive &&
|
||||
this.call && this.call.participants &&
|
||||
this.call.participants.indexOf(localUserId) < 0;
|
||||
|
||||
if (isMissed) {
|
||||
return "You missed a call from " + user.username + ".";
|
||||
}
|
||||
|
||||
if (isActive) {
|
||||
return user.username + " started a call. Join the call.";
|
||||
} else {
|
||||
return user.username + " started a call.";
|
||||
}
|
||||
}
|
||||
|
||||
if (type === MessageTypes.CHANNEL_NAME_CHANGE) {
|
||||
return user.username + " changed the channel name: " + this.content;
|
||||
}
|
||||
|
||||
if (type === MessageTypes.CHANNEL_ICON_CHANGE) {
|
||||
return user.username + " changed the channel icon.";
|
||||
}
|
||||
|
||||
if (type === MessageTypes.CHANNEL_PINNED_MESSAGE) {
|
||||
return user.username +
|
||||
" pinned a message to this channel. See all the pins.";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves username that should be displayed with this message.
|
||||
* @return {String|null}
|
||||
* @readonly
|
||||
*/
|
||||
get displayUsername() {
|
||||
if (!this._valid) return null;
|
||||
const member = this.member;
|
||||
const author = this.author;
|
||||
const nick = member ? member.nick : null;
|
||||
const username = author ? author.username : null;
|
||||
return nick || username;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets channel of this message.
|
||||
*
|
||||
* Returns null if message does not exist in cache.
|
||||
* @returns {ITextChannel|IDirectMessageChannel|null}
|
||||
* @readonly
|
||||
*/
|
||||
get channel() {
|
||||
if (this.isPrivate) {
|
||||
return this._discordie.DirectMessageChannels.get(this.channel_id);
|
||||
}
|
||||
return this._discordie.Channels.get(this.channel_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets guild of this message.
|
||||
*
|
||||
* Returns null if message does not exist in cache or from a private
|
||||
* channel (direct message).
|
||||
* @returns {IGuild|null}
|
||||
* @readonly
|
||||
*/
|
||||
get guild() {
|
||||
if (this.isPrivate || !this.isCached) return null;
|
||||
return this.channel ? this.channel.guild : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets member instance of author.
|
||||
*
|
||||
* Returns null for private channels, if message does not exist in cache,
|
||||
* the author is no longer a member of the guild, or it is a webhook message.
|
||||
* @returns {IGuildMember|null}
|
||||
* @readonly
|
||||
*/
|
||||
get member() {
|
||||
if (this.isPrivate || !this.isCached) return null;
|
||||
return this._discordie.Users.getMember(this.guild.id, this.author.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an array of all known (cached) versions of this message (including
|
||||
* the latest).
|
||||
* Sorted from latest (first) to oldest (last).
|
||||
* Does not include embeds.
|
||||
* @returns {Array<Object>}
|
||||
* @readonly
|
||||
*/
|
||||
get edits() {
|
||||
return this._discordie._messages.getEdits(this.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves user and channel references in `content` property to proper names.
|
||||
* References that are not found in cache will be left as is and not resolved.
|
||||
*
|
||||
* Returns null if this message is not cached.
|
||||
* @returns {String|null}
|
||||
* @example
|
||||
* var content = message.content;
|
||||
* // 'just a message for <@157838423632817262> in <#78826383786329613>'
|
||||
* var resolvedContent = message.resolveContent();
|
||||
* // 'just a message for @testie in #general'
|
||||
* var resolvedContent = client.Messages.resolveContent(message.content);
|
||||
* // 'just a message for @testie in #general'
|
||||
*/
|
||||
resolveContent() {
|
||||
if (!this.isCached) return null;
|
||||
return this._discordie.Messages.resolveContent(this.content, this.guild);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to edit this message.
|
||||
*
|
||||
* Editing of other users' messages is not allowed, server will send an
|
||||
* `Error` `Forbidden` and returned promise will be rejected if you attempt
|
||||
* to do so.
|
||||
*
|
||||
* See `IMessageCollection.editMessage` if you are looking for a method
|
||||
* that can operate on JSON or raw message id.
|
||||
* @param {String} [content]
|
||||
* @param {Object} [embed]
|
||||
* Refer to [official API documentation](https://discordapp.com/developers/docs/resources/channel#embed-object)
|
||||
* for embed structure description.
|
||||
* @returns {Promise<IMessage, Error>}
|
||||
*/
|
||||
edit(content, embed) {
|
||||
if (Array.isArray(content)) content = content.join("\n");
|
||||
if (content && typeof content !== "string") content = String(content);
|
||||
|
||||
return new Promise((rs, rj) => {
|
||||
rest(this._discordie)
|
||||
.channels.patchMessage(this.channel_id, this.id, content, embed)
|
||||
.then(() => rs(this))
|
||||
.catch(rj);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to delete this message.
|
||||
*
|
||||
* See `IMessageCollection.deleteMessage` if you are looking for a method
|
||||
* that can operate on JSON or raw message id.
|
||||
* @returns {Promise}
|
||||
*/
|
||||
delete() {
|
||||
return rest(this._discordie)
|
||||
.channels.deleteMessage(this.channel_id, this.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to pin this message.
|
||||
*
|
||||
* See `IMessageCollection.pinMessage` if you are looking for a method
|
||||
* that can operate on JSON or raw message id.
|
||||
* @returns {Promise<IMessage, Error>}
|
||||
*/
|
||||
pin() {
|
||||
return new Promise((rs, rj) => {
|
||||
rest(this._discordie)
|
||||
.channels.pinMessage(this.channel_id, this.id)
|
||||
.then(() => rs(this))
|
||||
.catch(rj);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to unpin this message.
|
||||
*
|
||||
* See `IMessageCollection.unpinMessage` if you are looking for a method
|
||||
* that can operate on JSON or raw message id.
|
||||
* @returns {Promise<IMessage, Error>}
|
||||
*/
|
||||
unpin() {
|
||||
return new Promise((rs, rj) => {
|
||||
rest(this._discordie)
|
||||
.channels.unpinMessage(this.channel_id, this.id)
|
||||
.then(() => rs(this))
|
||||
.catch(rj);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to fetch users who reacted to this message with the
|
||||
* specified emoji.
|
||||
* @param {Object|String} emoji
|
||||
* Partial emoji `{id: String|null, name: String}` or a unicode emoji
|
||||
* @param {Number} [limit] - Max 100 users per fetch
|
||||
* @param {IUser|String} [after] - Start list from specified user id
|
||||
* @return {Promise<Array<IUser>, Error>}
|
||||
*/
|
||||
fetchReactions(emoji, limit, after) {
|
||||
emoji = Utils.emojiToCode(emoji);
|
||||
limit = limit || 100;
|
||||
after = after ? after.valueOf() : after;
|
||||
|
||||
return new Promise((rs, rj) => {
|
||||
rest(this._discordie)
|
||||
.channels.getReactions(this.channel_id, this.id, emoji, limit, after)
|
||||
.then(users => rs(users.map(user => client.Users.get(user.id))))
|
||||
.catch(rj);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to add a reaction to this message with the specified
|
||||
* emoji.
|
||||
* @param {Object|String} emoji
|
||||
* Partial emoji `{id: String|null, name: String}` or a unicode emoji
|
||||
* @return {Promise}
|
||||
* @example
|
||||
* message.addReaction(message.reactions[0].emoji);
|
||||
* message.addReaction("\uD83D\uDE2C");
|
||||
*/
|
||||
addReaction(emoji) {
|
||||
emoji = Utils.emojiToCode(emoji);
|
||||
|
||||
return rest(this._discordie)
|
||||
.channels.addReaction(this.channel_id, this.id, emoji);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to remove a reaction to this message with the specified
|
||||
* emoji.
|
||||
* @param {Object|String} emoji
|
||||
* Partial emoji `{id: String|null, name: String}` or a unicode emoji
|
||||
* @param {IUser|String} [user] - Remove reaction of another user
|
||||
* @return {Promise}
|
||||
*/
|
||||
removeReaction(emoji, user) {
|
||||
emoji = Utils.emojiToCode(emoji);
|
||||
user = user ? user.valueOf() : user;
|
||||
|
||||
return rest(this._discordie)
|
||||
.channels.removeReaction(this.channel_id, this.id, emoji, user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to remove all reactions from this message.
|
||||
* @return {Promise}
|
||||
*/
|
||||
clearReactions() {
|
||||
return rest(this._discordie)
|
||||
.channels.deleteReactions(this.channel_id, this.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to send a reply to channel the message was from, prefixing
|
||||
* content with author's mention in non-private channels.
|
||||
* @param {String|Array<String>} content
|
||||
* Strings will be sent as is, arrays - joined with a newline character.
|
||||
* @param {IUser|IGuildMember|Array<IUser>|Array<IGuildMember>} [mentions]
|
||||
* Deprecated: left for backward compatibility.
|
||||
* @param {boolean} [tts]
|
||||
* @param {Object} [embed]
|
||||
* Refer to [official API documentation](https://discordapp.com/developers/docs/resources/channel#embed-object)
|
||||
* for embed structure description.
|
||||
* @returns {Promise<IMessage, Error>}
|
||||
*/
|
||||
reply(content, mentions, tts, embed) {
|
||||
if (this.isPrivate) {
|
||||
return this.channel.sendMessage(content, mentions, tts, embed);
|
||||
}
|
||||
return this.channel
|
||||
.sendMessage(`${this.author.mention}, ${content}`, mentions, tts, embed);
|
||||
}
|
||||
}
|
||||
|
||||
IMessage._inherit(Message, function modelPropertyGetter(key) {
|
||||
return this._discordie._messages.get(this._messageId)[key];
|
||||
});
|
||||
IMessage._setSuppressErrors(true);
|
||||
|
||||
/**
|
||||
* @readonly
|
||||
* @instance
|
||||
* @memberOf IMessage
|
||||
* @name author
|
||||
* @returns {IUser}
|
||||
*/
|
||||
IMessage._setValueOverride("author", function(user) {
|
||||
if (user && this.webhook_id) {
|
||||
const factory = () => new IUser(this._discordie, user.id, user);
|
||||
return this._discordie.Users._getOrCreateInterface(user, factory);
|
||||
}
|
||||
return user ? this._discordie.Users.get(user.id) : null;
|
||||
});
|
||||
|
||||
/**
|
||||
* @readonly
|
||||
* @instance
|
||||
* @memberOf IMessage
|
||||
* @name mentions
|
||||
* @returns {Array<IUser>}
|
||||
*/
|
||||
IMessage._setValueOverride("mentions", function(v) {
|
||||
return v ? v.map(u => this._discordie.Users.get(u.id)) : [];
|
||||
});
|
||||
|
||||
/**
|
||||
* @readonly
|
||||
* @instance
|
||||
* @memberOf IMessage
|
||||
* @name mention_roles
|
||||
* @returns {Array<IRole>}
|
||||
*/
|
||||
IMessage._setValueOverride("mention_roles", function(rolesRaw) {
|
||||
if (!rolesRaw || !this.guild) return [];
|
||||
var guildId = this.guild.id;
|
||||
return rolesRaw.map(id => new IRole(this._discordie, id, guildId));
|
||||
});
|
||||
|
||||
module.exports = IMessage;
|
374
node_modules/discordie/lib/interfaces/IMessageCollection.js
generated
vendored
Normal file
374
node_modules/discordie/lib/interfaces/IMessageCollection.js
generated
vendored
Normal file
@ -0,0 +1,374 @@
|
||||
"use strict";
|
||||
|
||||
const ICollectionBase = require("./ICollectionBase");
|
||||
const IMessage = require("./IMessage");
|
||||
const IChannel = require("./IChannel");
|
||||
const Utils = require("../core/Utils");
|
||||
|
||||
const rest = require("../networking/rest");
|
||||
|
||||
/**
|
||||
* @interface
|
||||
* @extends ICollectionBase
|
||||
* @description
|
||||
* Collection with all cached messages.
|
||||
*
|
||||
* **Includes deleted messages** - you can filter them by checking
|
||||
* `IMessage.deleted` boolean.
|
||||
*/
|
||||
class IMessageCollection extends ICollectionBase {
|
||||
constructor(discordie, valuesGetter, valueGetter) {
|
||||
super({
|
||||
valuesGetter: valuesGetter,
|
||||
valueGetter: valueGetter,
|
||||
itemFactory: (id) => new IMessage(this._discordie, id)
|
||||
});
|
||||
this._discordie = discordie;
|
||||
Utils.privatify(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an array of cached messages in `channel`, sorted in order of
|
||||
* arrival (message cache is sorted on message insertion, not when this
|
||||
* getter is invoked).
|
||||
*
|
||||
* Returns an empty array if channel no longer exists.
|
||||
*
|
||||
* > **Note:** Message cache also includes deleted messages.
|
||||
* > You can filter them by checking `IMessage.deleted` boolean.
|
||||
* @param {IChannel|String} channel
|
||||
* @returns {Array<IMessage>}
|
||||
*/
|
||||
forChannel(channel) {
|
||||
var cache = this._discordie._messages.getChannelCache(channel.valueOf());
|
||||
if (!cache || !cache.size) return [];
|
||||
return cache.map(message => this._getOrCreateInterface(message));
|
||||
}
|
||||
|
||||
/**
|
||||
* Purges channel cache.
|
||||
* @param {IChannel|String} channel
|
||||
*/
|
||||
purgeChannelCache(channel) {
|
||||
channel = channel.valueOf();
|
||||
return this._discordie._messages.purgeChannelCache(channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an array of cached pinned messages in `channel`.
|
||||
*
|
||||
* Pinned message cache is updated only if all pinned messages have been
|
||||
* loaded with `ITextChannel.fetchPinned()`.
|
||||
*
|
||||
* Returns an empty array if channel no longer exists or if pinned messages
|
||||
* have not been fetched yet.
|
||||
* @param {IChannel|String} channel
|
||||
* @returns {Array<IMessage>}
|
||||
*/
|
||||
forChannelPinned(channel) {
|
||||
var cache = this._discordie._messages.getChannelPinned(channel.valueOf());
|
||||
if (!cache) return [];
|
||||
return cache.map(msg => this._getOrCreateInterface(msg));
|
||||
}
|
||||
|
||||
/**
|
||||
* Purges pinned message cache for `channel`.
|
||||
* @param {IChannel|String} channel
|
||||
*/
|
||||
purgeChannelPinned(channel) {
|
||||
channel = channel.valueOf();
|
||||
return this._discordie._messages.purgeChannelPinned(channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Purges pinned message cache globally.
|
||||
*/
|
||||
purgePinned() {
|
||||
return this._discordie._messages.purgePinned();
|
||||
}
|
||||
|
||||
/**
|
||||
* Purges edits cache globally.
|
||||
*/
|
||||
purgeEdits() {
|
||||
return this._discordie._messages.purgeEdits();
|
||||
}
|
||||
|
||||
/**
|
||||
* Purges message cache globally.
|
||||
*/
|
||||
purgeAllCache() {
|
||||
return this._discordie._messages.purgeAllCache();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets channel message cache limit.
|
||||
* @param {IChannel|String} channel
|
||||
* @returns {Number}
|
||||
*/
|
||||
getChannelMessageLimit(channel) {
|
||||
channel = channel.valueOf();
|
||||
return this._discordie._messages.getChannelMessageLimit(channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets channel message cache limit (with a minimum of 1).
|
||||
* Limit reverts to default when channel (or cache) is destroyed.
|
||||
* Returns false if limit is invalid or channel does not exist.
|
||||
* @param {IChannel|String} channel
|
||||
* @param {Number} limit
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
setChannelMessageLimit(channel, limit) {
|
||||
channel = channel.valueOf();
|
||||
return this._discordie._messages.setChannelMessageLimit(channel, limit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets global message cache limit per channel.
|
||||
* @returns {Number}
|
||||
*/
|
||||
getMessageLimit() {
|
||||
return this._discordie._messages.getMessageLimit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets global message cache limit per channel (with a minimum of 1).
|
||||
* Does not affect channels with custom limits if new is lower than current.
|
||||
* @param {Number} limit
|
||||
*/
|
||||
setMessageLimit(limit) {
|
||||
return this._discordie._messages.setMessageLimit(limit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets global edits cache limit per message.
|
||||
* @returns {Number}
|
||||
*/
|
||||
getEditsLimit() {
|
||||
return this._discordie._messages.getEditsLimit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets global edits cache limit per message.
|
||||
* @param {Number} limit
|
||||
*/
|
||||
setEditsLimit(limit) {
|
||||
return this._discordie._messages.setEditsLimit(limit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to edit a message.
|
||||
* Alternative method for editing messages that are not in cache.
|
||||
*
|
||||
* Editing of other users' messages is not allowed, server will send an
|
||||
* `Error` `Forbidden` and returned promise will be rejected if you attempt
|
||||
* to do so.
|
||||
*
|
||||
* Parameter `messageId` can be an object with fields `{channel_id, id}`,
|
||||
* where `id` is a String message id, `channel_id` is a String channel id.
|
||||
*
|
||||
* Parameter `channelId` is ignored when `messageId` is an object or
|
||||
* an instance of `IMessage`.
|
||||
*
|
||||
* Returns a promise that resolves to a JSON object of the edited message.
|
||||
*
|
||||
* @param {String|Object} [content]
|
||||
* @param {IMessage|Object|String} messageId
|
||||
* @param {String} channelId - Ignored if `messageId` is an object with `id`
|
||||
* @param {Object} [embed]
|
||||
* Refer to [official API documentation](https://discordapp.com/developers/docs/resources/channel#embed-object)
|
||||
* for embed structure description.
|
||||
* @returns {Promise<Object, Error>}
|
||||
* @example
|
||||
* var message = client.Messages.find(m => true); // get any message
|
||||
* client.Messages.editMessage("new content", message);
|
||||
*
|
||||
* var jsonMessage = {id: message.id, channel_id: message.channel_id};
|
||||
* client.Messages.editMessage("new content", jsonMessage);
|
||||
*
|
||||
* client.Messages.editMessage("new content", message.id, message.channel_id);
|
||||
*/
|
||||
editMessage(content, messageId, channelId, embed) {
|
||||
if (Array.isArray(content)) content = content.join("\n");
|
||||
if (content && typeof content !== "string") content = String(content);
|
||||
|
||||
var message = {id: messageId, channel_id: channelId};
|
||||
|
||||
if (messageId && messageId.id) {
|
||||
message.id = messageId.id;
|
||||
message.channel_id = messageId.channel_id || messageId.channelId;
|
||||
}
|
||||
|
||||
return rest(this._discordie)
|
||||
.channels.patchMessage(message.channel_id, message.id, content, embed);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to delete a message.
|
||||
* Alternative method for deleting messages that are not in cache.
|
||||
*
|
||||
* Parameter `messageId` can be an object with fields `{channel_id, id}`,
|
||||
* where `id` is a String message id, `channel_id` is a String channel id.
|
||||
*
|
||||
* Parameter `channelId` is ignored when `messageId` is an object or
|
||||
* an instance of `IMessage`.
|
||||
*
|
||||
* @param {IMessage|Object|String} messageId
|
||||
* @param {String} channelId - Ignored if `messageId` is an object with `id`
|
||||
* @returns {Promise}
|
||||
* @example
|
||||
* var message = client.Messages.find(m => true); // get any message
|
||||
* client.Messages.deleteMessage(message);
|
||||
*
|
||||
* var jsonMessage = {id: message.id, channel_id: message.channel_id};
|
||||
* client.Messages.deleteMessage(jsonMessage);
|
||||
*
|
||||
* client.Messages.deleteMessage(message.id, message.channel_id);
|
||||
*/
|
||||
deleteMessage(messageId, channelId) {
|
||||
var message = {id: messageId, channel_id: channelId};
|
||||
|
||||
if (messageId && messageId.id) {
|
||||
message.id = messageId.id;
|
||||
message.channel_id = messageId.channel_id || messageId.channelId;
|
||||
}
|
||||
|
||||
return rest(this._discordie)
|
||||
.channels.deleteMessage(message.channel_id, message.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to pin a message.
|
||||
* Alternative method for pinning messages that are not in cache.
|
||||
*
|
||||
* Accepts same parameters as `IMessageCollection.deleteMessage`.
|
||||
*
|
||||
* @param {IMessage|Object|String} messageId
|
||||
* @param {String} channelId - Ignored if `messageId` is an object with `id`
|
||||
* @returns {Promise}
|
||||
*/
|
||||
pinMessage(messageId, channelId) {
|
||||
var message = {id: messageId, channel_id: channelId};
|
||||
|
||||
if (messageId && messageId.id) {
|
||||
message.id = messageId.id;
|
||||
message.channel_id = messageId.channel_id || messageId.channelId;
|
||||
}
|
||||
|
||||
return rest(this._discordie)
|
||||
.channels.pinMessage(message.channel_id, message.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to unpin a message.
|
||||
* Alternative method for unpinning messages that are not in cache.
|
||||
*
|
||||
* Accepts same parameters as `IMessageCollection.deleteMessage`.
|
||||
*
|
||||
* @param {IMessage|Object|String} messageId
|
||||
* @param {String} channelId - Ignored if `messageId` is an object with `id`
|
||||
* @returns {Promise}
|
||||
*/
|
||||
unpinMessage(messageId, channelId) {
|
||||
var message = {id: messageId, channel_id: channelId};
|
||||
|
||||
if (messageId && messageId.id) {
|
||||
message.id = messageId.id;
|
||||
message.channel_id = messageId.channel_id || messageId.channelId;
|
||||
}
|
||||
|
||||
return rest(this._discordie)
|
||||
.channels.unpinMessage(message.channel_id, message.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to delete multiple messages.
|
||||
*
|
||||
* If `messages` array contains instances of `IMessage`, parameter `channel`
|
||||
* is not required as it will be determined from the first message instance.
|
||||
* Also deleted messages will be omitted from the request.
|
||||
*
|
||||
* If `messages` array is empty, returned promise resolves instantly
|
||||
* without sending a request.
|
||||
* @param {Array<IMessage|String>} messages
|
||||
* @param {IChannel|String} [channel]
|
||||
* Channel or channel id, required is `messages` is an array of string ids
|
||||
* @returns {Promise}
|
||||
*/
|
||||
deleteMessages(messages, channel) {
|
||||
if (!Array.isArray(messages))
|
||||
throw new TypeError("Param 'messages' must be an array");
|
||||
|
||||
messages = messages.filter(m => {
|
||||
if (m instanceof IMessage)
|
||||
return !m.deleted;
|
||||
return true;
|
||||
});
|
||||
|
||||
if (!messages.length) return Promise.resolve();
|
||||
|
||||
var internalMessage = messages.find(v => v.channel_id);
|
||||
if (!internalMessage && !channel)
|
||||
throw new TypeError("Param 'channel' must be defined for arrays of ids");
|
||||
|
||||
channel = (internalMessage && !channel) ?
|
||||
internalMessage.channel_id :
|
||||
channel.valueOf();
|
||||
|
||||
// bulk-delete returns 'Bad Request' in this case
|
||||
if (messages.length === 1) {
|
||||
return rest(this._discordie)
|
||||
.channels.deleteMessage(channel, messages[0].valueOf());
|
||||
}
|
||||
|
||||
return rest(this._discordie)
|
||||
.channels.deleteMessages(channel, messages.map(v => v.valueOf()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves user and channel references to proper names.
|
||||
* References that are not found in cache will be left as is and not resolved.
|
||||
* @param {String} content
|
||||
* @param {IGuild|String} [guild]
|
||||
* Optional guild to resolve roles and nicknames from
|
||||
* @returns {String}
|
||||
* @example
|
||||
* var content = message.content;
|
||||
* // 'just a message for <@157838423632817262> in <#78826383786329613>'
|
||||
* var resolvedContent = message.resolveContent();
|
||||
* // 'just a message for @testie in #general'
|
||||
* var resolvedContent = client.Messages.resolveContent(message.content);
|
||||
* // 'just a message for @testie in #general'
|
||||
*/
|
||||
resolveContent(content, guild) {
|
||||
if (typeof content !== "string")
|
||||
throw new TypeError("Param 'content' is not a string");
|
||||
if (guild) {
|
||||
var guildId = guild.valueOf();
|
||||
guild = this._discordie.Guilds.get(guildId);
|
||||
}
|
||||
return content.replace(/<(@!?|#|@&)([0-9]+)>/g, (match, type, id) => {
|
||||
if (type === "@" || type === "@!") { // user
|
||||
var user = this._discordie.Users.get(id);
|
||||
if (!user) return match;
|
||||
if (guild && type === "@!") {
|
||||
var member = user.memberOf(guild);
|
||||
return (member && ("@" + member.name)) || match;
|
||||
}
|
||||
return (user && ("@" + user.username)) || match;
|
||||
}
|
||||
else if (type === "#") { // channel
|
||||
var channel = this._discordie.Channels.get(id);
|
||||
return (channel && ("#" + channel.name)) || match;
|
||||
}
|
||||
else if (type === "@&") { // role
|
||||
if (!guild || !guild.roles) return match;
|
||||
var role = guild.roles.find(r => r.id === id);
|
||||
return (role && ("@" + role.name)) || match;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = IMessageCollection;
|
121
node_modules/discordie/lib/interfaces/IPermissionOverwrite.js
generated
vendored
Normal file
121
node_modules/discordie/lib/interfaces/IPermissionOverwrite.js
generated
vendored
Normal file
@ -0,0 +1,121 @@
|
||||
"use strict";
|
||||
|
||||
const IBase = require("./IBase");
|
||||
const IPermissions = require("./IPermissions");
|
||||
const Utils = require("../core/Utils");
|
||||
const PermissionOverwrite = require("../models/PermissionOverwrite");
|
||||
|
||||
const Constants = require("../Constants");
|
||||
const ChannelTypes = Constants.ChannelTypes;
|
||||
const PermissionSpecs = Constants.PermissionSpecs;
|
||||
|
||||
const rest = require("../networking/rest");
|
||||
|
||||
/**
|
||||
* @interface
|
||||
* @model PermissionOverwrite
|
||||
* @extends IBase
|
||||
*/
|
||||
class IPermissionOverwrite extends IBase {
|
||||
constructor(discordie, overwriteId, channelId) {
|
||||
super();
|
||||
this._discordie = discordie;
|
||||
this._overwriteId = overwriteId;
|
||||
this._channelId = channelId;
|
||||
|
||||
const channel = discordie._channels.get(channelId) || {};
|
||||
|
||||
const spec = (channel.type == ChannelTypes.GUILD_VOICE ?
|
||||
PermissionSpecs.VoiceChannel :
|
||||
PermissionSpecs.TextChannel
|
||||
);
|
||||
this._allow = new IPermissions(this.getRaw().allow, spec);
|
||||
this._deny = new IPermissions(this.getRaw().deny, spec);
|
||||
|
||||
Utils.privatify(this);
|
||||
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets date and time the member or role of this overwrite was created at.
|
||||
* @returns {Date}
|
||||
* @readonly
|
||||
* @ignore
|
||||
*/
|
||||
get createdAt() {
|
||||
return new Date(Utils.timestampFromSnowflake(this.id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads original permissions from cache and updates this object.
|
||||
*/
|
||||
reload() {
|
||||
const raw = this.getRaw();
|
||||
if (!raw) return;
|
||||
this._allow.raw = raw.allow;
|
||||
this._deny.raw = raw.deny;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to commit changes made to this permission overwrite object.
|
||||
* @returns {Promise<IPermissionOverwrite, Error>}
|
||||
*/
|
||||
commit() {
|
||||
return new Promise((rs, rj) => {
|
||||
const raw = this.getRaw();
|
||||
raw.allow = this._allow.raw;
|
||||
raw.deny = this._deny.raw;
|
||||
|
||||
rest(this._discordie)
|
||||
.channels.putPermissionOverwrite(this._channelId, raw)
|
||||
.then(() => rs(this))
|
||||
.catch(e => {
|
||||
this.reload();
|
||||
return rj(e);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to delete this permission overwrite.
|
||||
* @returns {Promise}
|
||||
*/
|
||||
delete() {
|
||||
return rest(this._discordie)
|
||||
.channels.deletePermissionOverwrite(this._channelId, this.id);
|
||||
}
|
||||
}
|
||||
|
||||
IPermissionOverwrite._inherit(PermissionOverwrite, function(key) {
|
||||
const channel = this._discordie._channels.get(this._channelId);
|
||||
if (!channel) return null;
|
||||
const overwrite = channel.permission_overwrites
|
||||
.find(o => o.id == this._overwriteId);
|
||||
if (!overwrite) return null;
|
||||
return overwrite[key];
|
||||
});
|
||||
|
||||
/**
|
||||
* @readonly
|
||||
* @instance
|
||||
* @memberOf IPermissionOverwrite
|
||||
* @name allow
|
||||
* @returns {IPermissions}
|
||||
*/
|
||||
IPermissionOverwrite._setValueOverride("allow", function(v) {
|
||||
return this._allow;
|
||||
});
|
||||
|
||||
/**
|
||||
* @readonly
|
||||
* @instance
|
||||
* @memberOf IPermissionOverwrite
|
||||
* @name deny
|
||||
* @returns {IPermissions}
|
||||
*/
|
||||
IPermissionOverwrite._setValueOverride("deny", function(v) {
|
||||
return this._deny;
|
||||
});
|
||||
|
||||
module.exports = IPermissionOverwrite;
|
202
node_modules/discordie/lib/interfaces/IPermissions.js
generated
vendored
Normal file
202
node_modules/discordie/lib/interfaces/IPermissions.js
generated
vendored
Normal file
@ -0,0 +1,202 @@
|
||||
"use strict";
|
||||
|
||||
const Constants = require("../Constants");
|
||||
const Permissions = Constants.Permissions;
|
||||
const PermissionsDefault = Constants.PermissionsDefault;
|
||||
|
||||
/**
|
||||
* @interface
|
||||
* @description
|
||||
* Wrapper for numeric permission values.
|
||||
*
|
||||
* Contains boolean getters/setters (different for roles and channels).
|
||||
*
|
||||
* - `.Text` section only exists for text channels;
|
||||
* - `.Voice` section only exists for voice channels;
|
||||
* - `.General` section exists for both;
|
||||
* - Roles contain all properties - both `.Text` and `.Voice` sections.
|
||||
*
|
||||
* Example of role permission properties:
|
||||
* ```
|
||||
* General: {
|
||||
* CREATE_INSTANT_INVITE,
|
||||
* KICK_MEMBERS,
|
||||
* BAN_MEMBERS,
|
||||
* ADMINISTRATOR,
|
||||
* MANAGE_CHANNELS,
|
||||
* MANAGE_GUILD,
|
||||
* CHANGE_NICKNAME,
|
||||
* MANAGE_NICKNAMES,
|
||||
* MANAGE_ROLES,
|
||||
* MANAGE_WEBHOOKS,
|
||||
* MANAGE_EMOJIS,
|
||||
* },
|
||||
* Text: {
|
||||
* READ_MESSAGES,
|
||||
* SEND_MESSAGES,
|
||||
* SEND_TTS_MESSAGES,
|
||||
* MANAGE_MESSAGES,
|
||||
* EMBED_LINKS,
|
||||
* ATTACH_FILES,
|
||||
* READ_MESSAGE_HISTORY,
|
||||
* MENTION_EVERYONE,
|
||||
* EXTERNAL_EMOTES,
|
||||
* ADD_REACTIONS,
|
||||
* },
|
||||
* Voice: {
|
||||
* CONNECT,
|
||||
* SPEAK,
|
||||
* MUTE_MEMBERS,
|
||||
* DEAFEN_MEMBERS,
|
||||
* MOVE_MEMBERS,
|
||||
* USE_VAD,
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* Example of text channel permission properties:
|
||||
* ```
|
||||
* General: {
|
||||
* CREATE_INSTANT_INVITE,
|
||||
* MANAGE_CHANNEL,
|
||||
* MANAGE_PERMISSIONS
|
||||
* },
|
||||
* Text: {
|
||||
* READ_MESSAGES,
|
||||
* SEND_MESSAGES,
|
||||
* SEND_TTS_MESSAGES,
|
||||
* MANAGE_MESSAGES,
|
||||
* EMBED_LINKS,
|
||||
* ATTACH_FILES,
|
||||
* READ_MESSAGE_HISTORY,
|
||||
* MENTION_EVERYONE,
|
||||
* EXTERNAL_EMOTES,
|
||||
* ADD_REACTIONS,
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @example
|
||||
* var guild = client.Guilds.find(g => g.name == "test");
|
||||
* guild.createRole().then(role => {
|
||||
* var perms = role.permissions;
|
||||
* perms.General.KICK_MEMBERS = true;
|
||||
* perms.General.BAN_MEMBERS = true;
|
||||
* perms.Text.MENTION_EVERYONE = true;
|
||||
*
|
||||
* var newRoleName = "Testing";
|
||||
* var color = 0xE74C3C; // red
|
||||
* var hoist = true; // display as separate group
|
||||
*
|
||||
* role.commit(newRoleName, color, hoist);
|
||||
* }).catch(err => console.log("Failed to create role:", err));
|
||||
*/
|
||||
class IPermissions {
|
||||
constructor(raw, permissionSpec) {
|
||||
this.raw = raw || 0;
|
||||
for (let type in permissionSpec) {
|
||||
this[type] = {};
|
||||
for (let permission in permissionSpec[type]) {
|
||||
const bit = permissionSpec[type][permission];
|
||||
Object.defineProperty(this[type], permission, {
|
||||
enumerable: true,
|
||||
get: () => (this.raw & bit) === bit,
|
||||
set: (v) => v ? (this.raw |= bit) : (this.raw &= ~bit)
|
||||
});
|
||||
}
|
||||
Object.seal(this[type]);
|
||||
}
|
||||
Object.seal(this);
|
||||
}
|
||||
|
||||
inspect() { return JSON.parse(JSON.stringify(this)); }
|
||||
|
||||
setAll() { this.raw = IPermissions.ALL; }
|
||||
unsetAll() { this.raw = IPermissions.NONE; }
|
||||
|
||||
static get ALL() { return (~0 >>> 0); }
|
||||
static get DEFAULT() { return PermissionsDefault; }
|
||||
static get NONE() { return 0; }
|
||||
|
||||
static resolveRaw(user, context) {
|
||||
// referencing here to avoid circular require()
|
||||
const IUser = require("./IUser");
|
||||
const IAuthenticatedUser = require("./IAuthenticatedUser");
|
||||
const IChannel = require("./IChannel");
|
||||
const IGuild = require("./IGuild");
|
||||
const IGuildMember = require("./IGuildMember");
|
||||
|
||||
if (!(user instanceof IUser) && !(user instanceof IAuthenticatedUser))
|
||||
throw new TypeError("user must be an instance of IUser");
|
||||
if (!(context instanceof IChannel) && !(context instanceof IGuild))
|
||||
throw new TypeError("context must be an instance of IChannel or IGuild");
|
||||
|
||||
if (!context._valid) throw new Error("Invalid context");
|
||||
|
||||
let overwrites = null;
|
||||
if (context instanceof IChannel) {
|
||||
overwrites = context.getRaw().permission_overwrites;
|
||||
context = context.guild;
|
||||
}
|
||||
|
||||
if (context.isOwner(user))
|
||||
return IPermissions.ALL;
|
||||
|
||||
const member = user instanceof IGuildMember ?
|
||||
user : context._discordie.Users.getMember(context.id, user.id);
|
||||
|
||||
if (!member) throw new Error("User is not a member of the context");
|
||||
|
||||
const contextRaw = context.getRaw();
|
||||
const roleEveryone = contextRaw ? contextRaw.roles.get(context.id) : null;
|
||||
|
||||
// apply default permissions
|
||||
let permissions = roleEveryone ?
|
||||
roleEveryone.permissions : IPermissions.DEFAULT;
|
||||
|
||||
// then roles assigned for member
|
||||
const memberRoles = member ? member.roles : null;
|
||||
if (memberRoles) {
|
||||
permissions = memberRoles.reduce(
|
||||
(ps, role) => ps | role.permissions.raw,
|
||||
permissions
|
||||
);
|
||||
}
|
||||
|
||||
if (permissions & Permissions.General.ADMINISTRATOR)
|
||||
return IPermissions.ALL;
|
||||
|
||||
if (overwrites) {
|
||||
const applyOverwrite = (overwrite) => {
|
||||
if (!overwrite) return;
|
||||
permissions &= ~overwrite.deny;
|
||||
permissions |= overwrite.allow;
|
||||
};
|
||||
|
||||
// then channel specific @everyone role
|
||||
const overwriteEveryone = overwrites.find(o => o.id == context.id);
|
||||
applyOverwrite(overwriteEveryone);
|
||||
|
||||
if (member) {
|
||||
// then member roles for channel
|
||||
if (memberRoles)
|
||||
memberRoles.forEach(role =>
|
||||
applyOverwrite(overwrites.find(o => o.id == role.id))
|
||||
);
|
||||
|
||||
// then member specific permissions for channel
|
||||
const overwriteMember = overwrites.find(o => o.id == member.id);
|
||||
applyOverwrite(overwriteMember);
|
||||
}
|
||||
}
|
||||
|
||||
return permissions;
|
||||
}
|
||||
|
||||
static resolve(user, context) {
|
||||
return new IPermissions(
|
||||
IPermissions.resolveRaw(user, context),
|
||||
Permissions
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = IPermissions;
|
132
node_modules/discordie/lib/interfaces/IRole.js
generated
vendored
Normal file
132
node_modules/discordie/lib/interfaces/IRole.js
generated
vendored
Normal file
@ -0,0 +1,132 @@
|
||||
"use strict";
|
||||
|
||||
const IBase = require("./IBase");
|
||||
const IPermissions = require("./IPermissions");
|
||||
const Utils = require("../core/Utils");
|
||||
const Role = require("../models/Role");
|
||||
|
||||
const Constants = require("../Constants");
|
||||
const PermissionSpecs = Constants.PermissionSpecs;
|
||||
|
||||
const rest = require("../networking/rest");
|
||||
|
||||
/**
|
||||
* @interface
|
||||
* @extends IBase
|
||||
* @model Role
|
||||
*/
|
||||
class IRole extends IBase {
|
||||
constructor(discordie, roleId, guildId) {
|
||||
super();
|
||||
Utils.definePrivate(this, {
|
||||
_discordie: discordie,
|
||||
_roleId: roleId,
|
||||
_guildId: guildId
|
||||
});
|
||||
Utils.definePrivate(this, {
|
||||
_permissions: new IPermissions(
|
||||
this.getRaw("permissions"),
|
||||
PermissionSpecs.Role
|
||||
)
|
||||
});
|
||||
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a mention from this role's id.
|
||||
* @returns {String}
|
||||
* @readonly
|
||||
* @example
|
||||
* channel.sendMessage(role.mention + ", example mention");
|
||||
*/
|
||||
get mention() {
|
||||
return `<@&${this.id}>`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads original permissions from cache and updates this object.
|
||||
*/
|
||||
reload() {
|
||||
const rawPermissions = this.getRaw("permissions");
|
||||
if (!rawPermissions) return;
|
||||
this._permissions.raw = rawPermissions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to commit changes made to this role object.
|
||||
* @param {String} [name]
|
||||
* @param {Number} [color] - RGB color number
|
||||
* @param {boolean} [hoist] - true if role should be displayed separately
|
||||
* @param {boolean} [mentionable]
|
||||
* @returns {Promise}
|
||||
*/
|
||||
commit(name, color, hoist, mentionable) {
|
||||
const everyone = (this.id == this._guildId);
|
||||
if (!name || everyone) name = this.name;
|
||||
if (hoist === undefined || hoist === null || everyone) hoist = this.hoist;
|
||||
if (color === undefined || color === null || everyone) color = this.color;
|
||||
if (mentionable === undefined || mentionable === null || everyone) {
|
||||
mentionable = this.mentionable;
|
||||
}
|
||||
|
||||
return new Promise((rs, rj) => {
|
||||
rest(this._discordie).guilds.roles.patchRole(
|
||||
this._guildId, this.id,
|
||||
name, this.permissions.raw, color, hoist, mentionable
|
||||
)
|
||||
.then(() => rs(this))
|
||||
.catch(err => {
|
||||
this.reload();
|
||||
return rj(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves this role to `position` and makes a batch role update request.
|
||||
* @param {Number} position
|
||||
* @returns {Promise}
|
||||
*/
|
||||
setPosition(position) {
|
||||
const guild = this._discordie.Guilds.get(this._guildId);
|
||||
if (!guild) return Promise.reject(new Error("Guild does not exist"));
|
||||
|
||||
// maybe todo: disallow assigning position 0 (role @everyone)
|
||||
const changes = Utils.reorderObjects(guild.roles, this, position);
|
||||
if (!changes) return Promise.resolve();
|
||||
|
||||
return rest(this._discordie)
|
||||
.guilds.roles.batchPatchRoles(this._guildId, changes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to delete this role.
|
||||
* @returns {Promise}
|
||||
*/
|
||||
delete() {
|
||||
return rest(this._discordie)
|
||||
.guilds.roles.deleteRole(this._guildId, this.id);
|
||||
}
|
||||
}
|
||||
|
||||
IRole._inherit(Role, function modelPropertyGetter(key) {
|
||||
const guild = this._discordie._guilds.get(this._guildId);
|
||||
if (!guild) return null;
|
||||
const role = guild.roles.get(this._roleId);
|
||||
if (!role) return null;
|
||||
return role[key];
|
||||
});
|
||||
|
||||
/**
|
||||
* @readonly
|
||||
* @instance
|
||||
* @memberOf IRole
|
||||
* @name permissions
|
||||
* @returns {IPermissions}
|
||||
*/
|
||||
IRole._setValueOverride("permissions", function(v) {
|
||||
return this._permissions;
|
||||
});
|
||||
|
||||
module.exports = IRole;
|
283
node_modules/discordie/lib/interfaces/ITextChannel.js
generated
vendored
Normal file
283
node_modules/discordie/lib/interfaces/ITextChannel.js
generated
vendored
Normal file
@ -0,0 +1,283 @@
|
||||
"use strict";
|
||||
|
||||
const Utils = require("../core/Utils");
|
||||
const User = require("../models/User");
|
||||
const IChannel = require("./IChannel");
|
||||
const IUser = require("./IUser");
|
||||
|
||||
const Constants = require("../Constants");
|
||||
const Permissions = Constants.Permissions;
|
||||
|
||||
const rest = require("../networking/rest");
|
||||
|
||||
/**
|
||||
* @interface
|
||||
* @model Channel
|
||||
* @extends IChannel
|
||||
*/
|
||||
class ITextChannel extends IChannel {
|
||||
constructor(discordie, channelId) {
|
||||
super(discordie, channelId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a mention from this channel's id.
|
||||
* @returns {String}
|
||||
* @readonly
|
||||
* @example
|
||||
* channel.sendMessage(channel.mention + ", example mention");
|
||||
*/
|
||||
get mention() {
|
||||
return `<#${this.id}>`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an array of IGuildMember that
|
||||
* have permissions to read this channel.
|
||||
* @returns {Array<IGuildMember>}
|
||||
* @readonly
|
||||
*/
|
||||
get members() {
|
||||
return this._discordie.Users.membersForChannel(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a value indicating whether it is a default (general) channel.
|
||||
* @returns {boolean}
|
||||
* @readonly
|
||||
*/
|
||||
get isDefaultChannel() {
|
||||
return this.guild_id === this.id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a value indicating whether all messages were loaded.
|
||||
* @returns {boolean}
|
||||
* @readonly
|
||||
*/
|
||||
get allMessagesLoaded() {
|
||||
return !this._discordie._messages.channelHasMore(this.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an array of cached messages in this channel, sorted in order of
|
||||
* arrival (message cache is sorted on message insertion, not when this
|
||||
* getter is invoked).
|
||||
*
|
||||
* Returns an empty array if channel no longer exists.
|
||||
*
|
||||
* > **Note:** Message cache also includes deleted messages.
|
||||
* > You can filter them by checking `IMessage.deleted` boolean.
|
||||
* @returns {Array<IMessage>}
|
||||
* @readonly
|
||||
*/
|
||||
get messages() {
|
||||
return this._discordie.Messages.forChannel(this.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to fetch messages for this channel.
|
||||
*
|
||||
* Discord API does not allow fetching more than 100 messages at once.
|
||||
*
|
||||
* Promise resolves with an Object with following structure:
|
||||
* ```js
|
||||
* {
|
||||
* messages: Array<IMessage>,
|
||||
* limit: Number, // same as parameter passed or default value
|
||||
* before: String | null, // message id
|
||||
* after: String | null // message id
|
||||
* }
|
||||
* ```
|
||||
* @param {Number|null} [limit] - Default is 100
|
||||
* @param {IMessage|String|null} [before] - Message or message id
|
||||
* @param {IMessage|String|null} [after] - Message or message id
|
||||
* @returns {Promise<Object, Error>}
|
||||
* @example
|
||||
* var guild = client.Guilds.find(g => g.name == "test");
|
||||
* var channel = guild.generalChannel;
|
||||
*
|
||||
* // simple fetch:
|
||||
* channel.fetchMessages().then(() => {
|
||||
* console.log("[simple] messages in cache: " + channel.messages.length);
|
||||
* });
|
||||
*
|
||||
* // fetching more than 100 messages into cache sequentially:
|
||||
* fetchMessagesEx(channel, 420).then(() => {
|
||||
* console.log("[extended] messages in cache: " + channel.messages.length);
|
||||
* });
|
||||
*
|
||||
* // fetch more messages just like Discord client does
|
||||
* function fetchMessagesEx(channel, left) {
|
||||
* // message cache is sorted on insertion
|
||||
* // channel.messages[0] will get oldest message
|
||||
* var before = channel.messages[0];
|
||||
* return channel.fetchMessages(Math.min(left, 100), before)
|
||||
* .then(e => onFetch(e, channel, left));
|
||||
* }
|
||||
* function onFetch(e, channel, left) {
|
||||
* if (!e.messages.length) return Promise.resolve();
|
||||
* left -= e.messages.length;
|
||||
* console.log(`Received ${e.messages.length}, left: ${left}`);
|
||||
* if (left <= 0) return Promise.resolve();
|
||||
* return fetchMessagesEx(channel, left);
|
||||
* }
|
||||
*/
|
||||
fetchMessages(limit, before, after) {
|
||||
if (!limit) limit = 100;
|
||||
if (before) before = before.valueOf();
|
||||
if (after) after = after.valueOf();
|
||||
return new Promise((rs, rj) => {
|
||||
rest(this._discordie).channels.getMessages(this.id, limit, before, after)
|
||||
.then(e => {
|
||||
e.messages = e.messages
|
||||
.map(msg => this._discordie.Messages.get(msg.id));
|
||||
return rs(e);
|
||||
})
|
||||
.catch(rj);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an array of cached pinned messages in this channel.
|
||||
*
|
||||
* Pinned message cache is updated only if all pinned messages have been
|
||||
* loaded with `ITextChannel.fetchPinned()`.
|
||||
*
|
||||
* Returns an empty array if channel no longer exists or if pinned messages
|
||||
* have not been fetched yet.
|
||||
* @returns {Array<IMessage>}
|
||||
* @readonly
|
||||
*/
|
||||
get pinnedMessages() {
|
||||
return this._discordie.Messages.forChannelPinned(this.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to fetch pinned messages for this channel.
|
||||
*
|
||||
* Promise resolves with an Object with following structure:
|
||||
* ```js
|
||||
* {
|
||||
* channelId: String,
|
||||
* messages: Array<IMessage>
|
||||
* }
|
||||
* ```
|
||||
* @returns {Promise<Object, Error>}
|
||||
*/
|
||||
fetchPinned() {
|
||||
return new Promise((rs, rj) => {
|
||||
rest(this._discordie).channels.getPinnedMessages(this.id)
|
||||
.then(e => {
|
||||
e.messages = e.messages
|
||||
.map(msg => this._discordie.Messages.get(msg.id));
|
||||
return rs(e);
|
||||
})
|
||||
.catch(rj);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to send a message to this channel. Messages over 2000
|
||||
* characters will be rejected by the server.
|
||||
*
|
||||
* Use `uploadFile` if you want to send a message with an attachment.
|
||||
* @param {String|Array<String>} content
|
||||
* Strings will be sent as is, arrays - joined with a newline character.
|
||||
* @param {IUser|IGuildMember|Array<IUser>|Array<IGuildMember>} [mentions]
|
||||
* Deprecated: left for backward compatibility.
|
||||
* @param {boolean} [tts]
|
||||
* @param {Object} [embed]
|
||||
* Refer to [official API documentation](https://discordapp.com/developers/docs/resources/channel#embed-object)
|
||||
* for embed structure description.
|
||||
* @returns {Promise<IMessage, Error>}
|
||||
* @example
|
||||
* var guild = client.Guilds.find(g => g.name == "test");
|
||||
* if (!guild) return console.log("invalid guild");
|
||||
*
|
||||
* var channel = guild.generalChannel;
|
||||
*
|
||||
* channel.sendMessage("regular message");
|
||||
* channel.sendMessage("test with tts", true);
|
||||
*
|
||||
* var user = client.Users.find(u => u.username == "test");
|
||||
* if (!user) return console.log("invalid user");
|
||||
*
|
||||
* channel.sendMessage("mentioning user " + user.mention);
|
||||
* channel.sendMessage("@everyone or @here mention if you have permissions");
|
||||
*
|
||||
* channel.sendMessage("message with an embed", false, {
|
||||
* color: 0x3498db,
|
||||
* author: {name: "author name"},
|
||||
* title: "This is an embed",
|
||||
* url: "http://google.com",
|
||||
* timestamp: "2016-11-13T03:43:32.127Z",
|
||||
* fields: [{name: "some field", value: "some value"}],
|
||||
* footer: {text: "footer text"}
|
||||
* });
|
||||
*/
|
||||
sendMessage(content, mentions, tts, embed) {
|
||||
if (Array.isArray(content)) content = content.join("\n");
|
||||
if (typeof content !== "string") content = String(content);
|
||||
|
||||
if (!Array.isArray(mentions)) {
|
||||
embed = tts;
|
||||
tts = mentions;
|
||||
mentions = [];
|
||||
}
|
||||
mentions = Utils.convertMentions(mentions);
|
||||
return new Promise((rs, rj) => {
|
||||
rest(this._discordie)
|
||||
.channels.createMessage(this.id, content, mentions, tts, embed)
|
||||
.then(msg => rs(this._discordie.Messages.get(msg.id)))
|
||||
.catch(rj);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to send typing status for this channel.
|
||||
*
|
||||
* Discord client displays it for 10 seconds, sends every 5 seconds.
|
||||
* Stops showing typing status if receives a message from the user.
|
||||
* @returns {Promise}
|
||||
*/
|
||||
sendTyping() {
|
||||
return rest(this._discordie).channels.postTyping(this.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to upload data to this channel.
|
||||
* Images require a `filename` with a valid extension to actually be uploaded.
|
||||
* @param {Buffer|ReadableStream|String} readableStream
|
||||
* Data to upload or filename as a string
|
||||
* @param {String} filename
|
||||
* Actual filename to show, required for non-string `readableStream`
|
||||
* @param {String} [content] - Additional comment message for attachment
|
||||
* @param {boolean} [tts]
|
||||
* @returns {Promise<IMessage, Error>}
|
||||
* @example
|
||||
* channel.uploadFile(fs.readFileSync("test.png"), "test.png"); // Buffer
|
||||
* channel.uploadFile(fs.createReadStream("test.png"), "test.png"); // Stream
|
||||
* channel.uploadFile("test.png"); // File
|
||||
* channel.uploadFile("test.png", null, "file with message");
|
||||
* channel.uploadFile("test.png", null, "file with message and tts", true);
|
||||
*/
|
||||
uploadFile(readableStream, filename, content, mentions, tts) {
|
||||
if (mentions === true) {
|
||||
tts = mentions;
|
||||
mentions = [];
|
||||
}
|
||||
mentions = Utils.convertMentions(mentions);
|
||||
return new Promise((rs, rj) => {
|
||||
rest(this._discordie)
|
||||
.channels.uploadFile(
|
||||
this.id, readableStream, filename,
|
||||
content, mentions, tts
|
||||
)
|
||||
.then(msg => rs(this._discordie.Messages.get(msg.id)))
|
||||
.catch(rj);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ITextChannel;
|
285
node_modules/discordie/lib/interfaces/IUser.js
generated
vendored
Normal file
285
node_modules/discordie/lib/interfaces/IUser.js
generated
vendored
Normal file
@ -0,0 +1,285 @@
|
||||
"use strict";
|
||||
|
||||
const IBase = require("./IBase");
|
||||
const IPermissions = require("./IPermissions");
|
||||
const Utils = require("../core/Utils");
|
||||
const User = require("../models/User");
|
||||
const Constants = require("../Constants");
|
||||
const Endpoints = Constants.Endpoints;
|
||||
|
||||
/**
|
||||
* @interface
|
||||
* @model User
|
||||
* @extends IBase
|
||||
* @description
|
||||
* Object representing a user, user-bot, or a webhook-bot.
|
||||
*
|
||||
* Both bots have the `bot` property set to true.
|
||||
*
|
||||
* Each webhook-bot object is unique to a message and may have different
|
||||
* username and avatar, the user collection only contains last seen data.
|
||||
* Use `IMessage.author` to get a message-specific object.
|
||||
*/
|
||||
class IUser extends IBase {
|
||||
constructor(discordie, userId, webhookUser) {
|
||||
super();
|
||||
Utils.definePrivate(this, {
|
||||
_discordie: discordie,
|
||||
_userId: userId,
|
||||
_webhookUser: webhookUser
|
||||
});
|
||||
|
||||
if (this.constructor == IUser) {
|
||||
Object.freeze(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets date and time the account was registered (created) at.
|
||||
* @returns {Date}
|
||||
* @readonly
|
||||
*/
|
||||
get registeredAt() {
|
||||
return new Date(Utils.timestampFromSnowflake(this.id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets current JPG or GIF avatar URL.
|
||||
* @returns {String|null}
|
||||
* @readonly
|
||||
*/
|
||||
get avatarURL() {
|
||||
const avatar = this.avatar;
|
||||
if (!avatar) return null;
|
||||
|
||||
var fmt = "jpg";
|
||||
if (avatar.length >= 2 && avatar[0] === "a" && avatar[1] === "_") {
|
||||
fmt = "gif";
|
||||
}
|
||||
|
||||
return Constants.CDN_ENDPOINT + Endpoints.CDN_AVATAR(this.id, avatar, fmt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets current JPG avatar URL.
|
||||
* @returns {String|null}
|
||||
* @readonly
|
||||
*/
|
||||
get staticAvatarURL() {
|
||||
const avatar = this.avatar;
|
||||
if (!avatar) return null;
|
||||
return Constants.CDN_ENDPOINT + Endpoints.CDN_AVATAR(this.id, avatar);
|
||||
}
|
||||
|
||||
/**
|
||||
* Current status of the user.
|
||||
* @returns {String}
|
||||
* @readonly
|
||||
*/
|
||||
get status() {
|
||||
return this._discordie._presences.getStatus(this.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Current game the user is playing.
|
||||
* @returns {Object|null}
|
||||
* @readonly
|
||||
*/
|
||||
get game() {
|
||||
return this._discordie._presences.getGame(this.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Name of the current game the user is playing.
|
||||
* @returns {String|null}
|
||||
* @readonly
|
||||
*/
|
||||
get gameName() {
|
||||
return this.game ? this.game.name : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Previous status of the user.
|
||||
* @returns {String}
|
||||
* @readonly
|
||||
*/
|
||||
get previousStatus() {
|
||||
return this._discordie._presences.getPreviousStatus(this.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Previous game the user was playing.
|
||||
* @returns {Object|null}
|
||||
* @readonly
|
||||
*/
|
||||
get previousGame() {
|
||||
return this._discordie._presences.getPreviousGame(this.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Name of the previous game the user was playing.
|
||||
* @returns {String|null}
|
||||
* @readonly
|
||||
*/
|
||||
get previousGameName() {
|
||||
return this.previousGame ? this.previousGame.name : null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks whether the user is mentioned in a `message`.
|
||||
* @param {IMessage} message
|
||||
* @param {boolean} ignoreImplicitMentions
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isMentioned(message, ignoreImplicitMentions) {
|
||||
const IMessage = require("./IMessage");
|
||||
|
||||
if (!message) return false;
|
||||
if (!(message instanceof IMessage)) {
|
||||
if (message.id) message = message.id;
|
||||
message = this._discordie.Messages.get(message);
|
||||
if (!message) return false;
|
||||
}
|
||||
|
||||
return message.mentions.some(mention => mention.id === this.id) ||
|
||||
(ignoreImplicitMentions === true ? false : message.mention_everyone);
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens or gets existing Direct Message channel.
|
||||
* @returns {Promise<IDirectMessageChannel, Error>}
|
||||
*/
|
||||
openDM() {
|
||||
return this._discordie.DirectMessageChannels.getOrOpen(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to get a guild member interface, returns null if this user is not
|
||||
* a member of the `guild` or `guild` is not in cache.
|
||||
* @param {IGuild|String} guild
|
||||
* @returns {IGuildMember|null}
|
||||
*/
|
||||
memberOf(guild) {
|
||||
return this._discordie.Users.getMember(guild.valueOf(), this.id) || null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves permissions for user in `context`.
|
||||
*
|
||||
* Returns a helper object with getter boolean properties.
|
||||
*
|
||||
* Throws:
|
||||
*
|
||||
* - ** `"user must be an instance of IUser"` **
|
||||
*
|
||||
* If the method was called without binding to a `IUser` object
|
||||
* (as a function).
|
||||
*
|
||||
* - ** `"context must be an instance of IChannel or IGuild"` **
|
||||
*
|
||||
* If context type is invalid.
|
||||
*
|
||||
* - ** `"Invalid context"` **
|
||||
*
|
||||
* If context object no longer exists in cache.
|
||||
*
|
||||
* - ** `"User is not a member of the context"` **
|
||||
*
|
||||
* If this user is not a member of the guild or
|
||||
* guild the channel belongs to.
|
||||
*
|
||||
* See documentation of `IPermissions` for list of possible permissions.
|
||||
* @param {IChannel|IGuild} context
|
||||
* @returns {IPermissions}
|
||||
* @example
|
||||
* const guild = client.Guilds.find(g => g.name == "test");
|
||||
* const channel = guild.channels.find(c => c.name == "restricted");
|
||||
* const user = guild.members.find(m => m.username == "testuser");
|
||||
*
|
||||
* const guildPerms = user.permissionsFor(guild); // resolves to role permissions
|
||||
* const channelPerms = user.permissionsFor(channel); // resolves to channel permissions
|
||||
*
|
||||
* console.log(guildPerms.General.MANAGE_ROLES); // false
|
||||
* console.log(guildPerms.Text.READ_MESSAGES); // true
|
||||
|
||||
* // The `restricted` channel has `READ_MESSAGES` denied
|
||||
* console.log(channelPerms.Text.READ_MESSAGES); // false
|
||||
*/
|
||||
permissionsFor(context) {
|
||||
return IPermissions.resolve(this, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves permissions for user in `context` and checks if
|
||||
* user has `permission`.
|
||||
*
|
||||
* See `IUser.permissionsFor` method for list of throwable errors.
|
||||
*
|
||||
* See documentation of `IPermissions` for full list of possible permissions.
|
||||
* @param {Number} permission - One or multiple permission bits
|
||||
* @param {IChannel|IGuild} context
|
||||
* @returns {boolean}
|
||||
* @example
|
||||
* const guild = client.Guilds.find(g => g.name == "test");
|
||||
* const channel = guild.channels.find(c => c.name == "node_discordie");
|
||||
* const user = guild.members.find(m => m.username == "testuser");
|
||||
* user.can(Discordie.Permissions.General.KICK_MEMBERS, guild); // resolves to role permissions
|
||||
* user.can(Discordie.Permissions.Text.READ_MESSAGES, channel); // resolves to channel permissions
|
||||
*/
|
||||
can(permission, context) {
|
||||
return (IPermissions.resolveRaw(this, context) & permission) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the first voice channel that member of `guild` currently in.
|
||||
* @param {IGuild|String|null} guild
|
||||
* Guild or an id string, null for private call
|
||||
* (call channel is only available if recipient is in call with current user)
|
||||
* @returns {IVoiceChannel|null}
|
||||
*/
|
||||
getVoiceChannel(guild) {
|
||||
const state = this._discordie._voicestates.getUserStateInGuild(
|
||||
(guild ? guild.valueOf() : null), this.id
|
||||
);
|
||||
if (!state) return null;
|
||||
return this._discordie.Channels.get(state.channel_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a mention from this user's id.
|
||||
* @returns {String}
|
||||
* @readonly
|
||||
* @example
|
||||
* channel.sendMessage(user.mention + ", example mention");
|
||||
*/
|
||||
get mention() {
|
||||
return `<@${this.id}>`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a nickname mention from this user's id.
|
||||
* @returns {String}
|
||||
* @readonly
|
||||
*/
|
||||
get nickMention() {
|
||||
return `<@!${this.id}>`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this is a non-user bot object such as webhook-bot.
|
||||
* @return {boolean}
|
||||
*/
|
||||
get isWebhook() {
|
||||
const nonUserBot =
|
||||
this.bot && this.discriminator === Constants.NON_USER_BOT_DISCRIMINATOR;
|
||||
return !!this._webhookUser || nonUserBot;
|
||||
}
|
||||
}
|
||||
|
||||
IUser._inherit(User, function modelPropertyGetter(key) {
|
||||
if (this._webhookUser) return this._webhookUser[key];
|
||||
return this._discordie._users.get(this._userId)[key];
|
||||
});
|
||||
|
||||
module.exports = IUser;
|
256
node_modules/discordie/lib/interfaces/IUserCollection.js
generated
vendored
Normal file
256
node_modules/discordie/lib/interfaces/IUserCollection.js
generated
vendored
Normal file
@ -0,0 +1,256 @@
|
||||
"use strict";
|
||||
|
||||
const Constants = require("../Constants");
|
||||
const StatusTypes = Constants.StatusTypes;
|
||||
const Permissions = Constants.Permissions;
|
||||
const ICollectionBase = require("./ICollectionBase");
|
||||
const IGuild = require("./IGuild");
|
||||
const IGuildMember = require("./IGuildMember");
|
||||
const IChannel = require("./IChannel");
|
||||
const IUser = require("./IUser");
|
||||
const IDirectMessageChannel = require("./IDirectMessageChannel");
|
||||
const Utils = require("../core/Utils");
|
||||
|
||||
/**
|
||||
* @interface
|
||||
* @extends ICollectionBase
|
||||
*/
|
||||
class IUserCollection extends ICollectionBase {
|
||||
constructor(discordie, valuesGetter, valueGetter) {
|
||||
super({
|
||||
valuesGetter: valuesGetter,
|
||||
valueGetter: valueGetter,
|
||||
itemFactory: (id) => new IUser(this._discordie, id)
|
||||
});
|
||||
Utils.definePrivate(this, {_discordie: discordie});
|
||||
}
|
||||
|
||||
/**
|
||||
* Request members and wait until cache populates for all guilds or
|
||||
* an array of guilds.
|
||||
* Request is made over gateway websocket.
|
||||
*
|
||||
* Will request members for all guilds if no arguments passed.
|
||||
*
|
||||
* By default Discord sends only online members if there are more than 250
|
||||
* (offline and online total) joined in a guild.
|
||||
*
|
||||
* Returned promise will resolve when all members have been fetched.
|
||||
* Returned promise will reject if all or some members have not been received
|
||||
* within 60 seconds or primary gateway websocket disconnected.
|
||||
*
|
||||
* If all members for chosen guilds are already in cache - returns a
|
||||
* resolved promise.
|
||||
*
|
||||
* > **Note:** When guilds become unavailable or deleted
|
||||
* > (events `GUILD_UNAVAILABLE` and `GUILD_DELETE`)
|
||||
* > all members will also be deleted from cache.
|
||||
* @param {IGuild|String|Array<IGuild|String>} [guilds]
|
||||
* @returns {Promise}
|
||||
* @example
|
||||
* client.Users.fetchMembers()
|
||||
* .then(() => console.log("Received members for all guilds"));
|
||||
*
|
||||
* client.Users.fetchMembers([guild1, guild2, guild3])
|
||||
* .then(() => console.log("Received members for 3 guilds"));
|
||||
*
|
||||
* var p1 = client.Users.fetchMembers(guild1);
|
||||
* p1.catch(err => console.log("Failed to receive guild1 members: " + err));
|
||||
* var p2 = client.Users.fetchMembers(guild2);
|
||||
* var p3 = client.Users.fetchMembers(guild3);
|
||||
* Promise.all([p1, p2, p3])
|
||||
* .then(() => console.log("Received members for 3 guilds"));
|
||||
* .catch(err => console.log("Failed to receive some members: " + err));
|
||||
*/
|
||||
fetchMembers(guilds) {
|
||||
if (guilds) {
|
||||
if (guilds.map) guilds = guilds.map(guild => guild.valueOf());
|
||||
else guilds = [guilds.valueOf()];
|
||||
}
|
||||
return this._discordie._members.fetchMembers(guilds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a `IGuildMember` for specified `user` of `guild`.
|
||||
*
|
||||
* Returns null if the user is not a member of the guild.
|
||||
* @param {IGuild|String} guild - Guild or an id string
|
||||
* @param {IUser|String} user - User or an id string
|
||||
* @returns {IGuildMember|null}
|
||||
*/
|
||||
getMember(guild, user) {
|
||||
guild = guild.valueOf();
|
||||
user = user.valueOf();
|
||||
var member = this._discordie._members.getMember(guild, user);
|
||||
if (!member) return null;
|
||||
return this._getOrCreateInterface(member,
|
||||
() => new IGuildMember(this._discordie, user, guild)
|
||||
);
|
||||
}
|
||||
/**
|
||||
* Creates an array of `IGuildMember` for `guild`.
|
||||
* @param {IGuild|String} guild - Guild or an id string
|
||||
* @returns {Array<IGuildMember>}
|
||||
*/
|
||||
membersForGuild(guild) {
|
||||
guild = guild.valueOf();
|
||||
|
||||
const members = [];
|
||||
const guildMembers = this._discordie._members.get(guild);
|
||||
if (!guildMembers) return members;
|
||||
for (var member of guildMembers.values()) {
|
||||
members.push(this._getOrCreateInterface(member,
|
||||
() => new IGuildMember(this._discordie, member.id, guild)
|
||||
));
|
||||
}
|
||||
return members;
|
||||
}
|
||||
/**
|
||||
* Creates an array of `IGuildMember` that have permissions to read `channel`.
|
||||
*
|
||||
* > **Note:** This method computes permissions for all members and may be CPU
|
||||
* > intensive for large guilds.
|
||||
* @param {ITextChannel|String} channel - Channel or an id string
|
||||
* @returns {Array<IGuildMember>}
|
||||
*/
|
||||
membersForChannel(channel) {
|
||||
if (!(channel instanceof IChannel))
|
||||
channel = this._discordie.Channels.get(channel);
|
||||
|
||||
if (!channel) return [];
|
||||
|
||||
const guild = channel.guild;
|
||||
if (!guild) throw new Error("Channel does not exist");
|
||||
|
||||
const guildMembers = channel.guild.members;
|
||||
if (!guildMembers) return [];
|
||||
return guildMembers.filter(m =>
|
||||
m.can(Permissions.Text.READ_MESSAGES, channel)
|
||||
);
|
||||
}
|
||||
/**
|
||||
* Creates an array of `IGuildMember` containing
|
||||
* active members in a voice `channel`.
|
||||
* @param {IVoiceChannel|String} channel - Channel or an id string
|
||||
* @returns {Array<IGuildMember>}
|
||||
*/
|
||||
membersInVoiceChannel(channel) {
|
||||
if (!(channel instanceof IChannel))
|
||||
channel = this._discordie.Channels.get(channel);
|
||||
|
||||
if (!channel) return [];
|
||||
|
||||
const members = [];
|
||||
const guildMembers = this._discordie._members.get(channel.guild_id);
|
||||
if (!guildMembers) return members;
|
||||
|
||||
const userMap = this._discordie._voicestates.getStatesInChannel(channel.id);
|
||||
for (var id of userMap.keys()) {
|
||||
const member = guildMembers.get(id);
|
||||
if (!member) continue;
|
||||
members.push(this._getOrCreateInterface(member,
|
||||
() => new IGuildMember(this._discordie, id, channel.guild_id)
|
||||
));
|
||||
}
|
||||
return members;
|
||||
}
|
||||
/**
|
||||
* Creates an array of `IUser` containing users in a private voice channel.
|
||||
* @param {IDirectMessageChannel|String} channel - Channel or an id string
|
||||
* @returns {Array<IUser>}
|
||||
*/
|
||||
usersInCall(channel) {
|
||||
if (!(channel instanceof IDirectMessageChannel))
|
||||
channel = this._discordie.DirectMessageChannels.get(channel);
|
||||
|
||||
if (!channel) return [];
|
||||
const users = [];
|
||||
|
||||
const userMap = this._discordie._voicestates.getStatesInChannel(channel.id);
|
||||
for (var id of userMap.keys()) {
|
||||
const user = this.get(id);
|
||||
if (user) users.push(user);
|
||||
}
|
||||
return users;
|
||||
}
|
||||
/**
|
||||
* Creates an array of `IGuildMember` for `guild` that are currently online.
|
||||
* @param {IGuild|String} guild - Guild or an id string
|
||||
* @returns {Array<IGuildMember>}
|
||||
*/
|
||||
onlineMembersForGuild(guild) {
|
||||
guild = guild.valueOf();
|
||||
|
||||
const members = [];
|
||||
const presences = this._discordie._presences;
|
||||
const guildMembers = this._discordie._members.get(guild);
|
||||
if (!guildMembers) return members;
|
||||
for (var member of guildMembers.values()) {
|
||||
if (presences.getStatus(member.id) != StatusTypes.OFFLINE) {
|
||||
members.push(this._getOrCreateInterface(member,
|
||||
() => new IGuildMember(this._discordie, member.id, guild)
|
||||
));
|
||||
}
|
||||
}
|
||||
return members;
|
||||
}
|
||||
/**
|
||||
* Creates an array of `IGuildMember` that
|
||||
* have permissions to read `channel` and currently online.
|
||||
*
|
||||
* > **Note:** This method computes permissions for all members and may be CPU
|
||||
* > intensive for large guilds.
|
||||
* @param {ITextChannel|String} channel - Channel or an id string
|
||||
* @returns {Array<IGuildMember>}
|
||||
*/
|
||||
onlineMembersForChannel(channel) {
|
||||
return this.membersForChannel(channel).filter(
|
||||
m => m.status != StatusTypes.OFFLINE
|
||||
);
|
||||
}
|
||||
/**
|
||||
* Creates an array of `IGuildMember` for `guild` that are currently offline.
|
||||
*
|
||||
* Does not guarantee every offline member unless
|
||||
* `IUserCollection.fetchMembers` has been called for the `guild`.
|
||||
*
|
||||
* @param {IGuild|String} guild - Guild or an id string
|
||||
* @returns {Array<IGuildMember>}
|
||||
*/
|
||||
offlineMembersForGuild(guild) {
|
||||
guild = guild.valueOf();
|
||||
|
||||
const members = [];
|
||||
const presences = this._discordie._presences;
|
||||
const guildMembers = this._discordie._members.get(guild);
|
||||
if (!guildMembers) return members;
|
||||
for (var member of guildMembers.values()) {
|
||||
if (presences.getStatus(member.id) == StatusTypes.OFFLINE) {
|
||||
members.push(this._getOrCreateInterface(member,
|
||||
() => new IGuildMember(this._discordie, member.id, guild)
|
||||
));
|
||||
}
|
||||
}
|
||||
return members;
|
||||
}
|
||||
/**
|
||||
* Creates an array of `IGuildMember` that
|
||||
* have permissions to read `channel` and currently offline.
|
||||
*
|
||||
* Does not guarantee every offline member unless
|
||||
* `IUserCollection.fetchMembers` has been called for the guild the `channel`
|
||||
* belongs to.
|
||||
*
|
||||
* > **Note:** This method computes permissions for all members and may be CPU
|
||||
* > intensive for large guilds.
|
||||
* @param {ITextChannel|String} channel - Channel or an id string
|
||||
* @returns {Array<IGuildMember>}
|
||||
*/
|
||||
offlineMembersForChannel(channel) {
|
||||
return this.membersForChannel(channel).filter(
|
||||
m => m.status == StatusTypes.OFFLINE
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = IUserCollection;
|
113
node_modules/discordie/lib/interfaces/IVoiceChannel.js
generated
vendored
Normal file
113
node_modules/discordie/lib/interfaces/IVoiceChannel.js
generated
vendored
Normal file
@ -0,0 +1,113 @@
|
||||
"use strict";
|
||||
|
||||
const Utils = require("../core/Utils");
|
||||
const User = require("../models/User");
|
||||
const IChannel = require("./IChannel");
|
||||
|
||||
/**
|
||||
* @interface
|
||||
* @model Channel
|
||||
* @extends IChannel
|
||||
*/
|
||||
class IVoiceChannel extends IChannel {
|
||||
constructor(discordie, channelId) {
|
||||
super(discordie, channelId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an array of members joined in this voice channels.
|
||||
* @returns {Array<IGuildMember>}
|
||||
* @readonly
|
||||
*/
|
||||
get members() {
|
||||
return this._discordie.Users.membersInVoiceChannel(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether current user is in this voice channel.
|
||||
* @returns {boolean}
|
||||
* @readonly
|
||||
*/
|
||||
get joined() {
|
||||
const vc = this._discordie.VoiceConnections;
|
||||
const pendingChannel = vc.getPendingChannel(this.guild_id);
|
||||
return !!(pendingChannel && pendingChannel === this._channelId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Joins this voice channel.
|
||||
* Creates a new voice connection if there are no active connections for
|
||||
* this channels' guild.
|
||||
*
|
||||
* > **Note:** One account can be only in one channel per guild.
|
||||
* > Promise will resolve instantly and contain the same instance
|
||||
* > if connection to the server is already established.
|
||||
*
|
||||
* If there is a pending connection for the guild this channel belongs to,
|
||||
* it will return the same promise.
|
||||
*
|
||||
* Checks permissions locally and returns a rejected promise with:
|
||||
*
|
||||
* - **`Error "Missing permission"`** if `Voice.CONNECT` permission is denied.
|
||||
*
|
||||
* - **`Error "Channel is full"`** if `Voice.MOVE_MEMBERS` permission is
|
||||
* denied and channel is full.
|
||||
*
|
||||
* Returns a rejected promise with **`Error "Channel does not exist"`** if
|
||||
* guild is unavailable or channel does not exist in cache.
|
||||
*
|
||||
* Returned promise can be cancelled or rejected: see `VOICE_DISCONNECTED`
|
||||
* event for more info.
|
||||
*
|
||||
* @param {boolean} [selfMute]
|
||||
* @param {boolean} [selfDeaf]
|
||||
* @returns {Promise<VoiceConnectionInfo, Error|Number>}
|
||||
*/
|
||||
join(selfMute, selfDeaf) {
|
||||
selfMute = !!selfMute;
|
||||
selfDeaf = !!selfDeaf;
|
||||
|
||||
if (!this._valid)
|
||||
return Promise.reject(new Error("Channel does not exist"));
|
||||
|
||||
// check permissions locally
|
||||
// since server silently drops invalid voice state updates
|
||||
if (!this.joined) {
|
||||
const permissions = this._discordie.User.permissionsFor(this);
|
||||
if (!permissions.Voice.CONNECT)
|
||||
return Promise.reject(new Error("Missing permission"));
|
||||
|
||||
if (this.user_limit > 0) {
|
||||
const states = this._discordie._voicestates.getStatesInChannel(this.id);
|
||||
if (states.size >= this.user_limit) {
|
||||
if (!permissions.Voice.MOVE_MEMBERS)
|
||||
return Promise.reject(new Error("Channel is full"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const vc = this._discordie.VoiceConnections;
|
||||
return vc._getOrCreate(this.guild_id, this._channelId, selfMute, selfDeaf);
|
||||
}
|
||||
|
||||
/**
|
||||
* Leaves this voice channel if joined.
|
||||
*/
|
||||
leave() {
|
||||
const info = this.getVoiceConnectionInfo();
|
||||
if (info) return info.voiceConnection.disconnect();
|
||||
|
||||
this._discordie.VoiceConnections
|
||||
.cancelIfPending(this.guild_id, this._channelId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves `VoiceConnectionInfo` for this voice channel.
|
||||
* @returns {VoiceConnectionInfo|null}
|
||||
*/
|
||||
getVoiceConnectionInfo() {
|
||||
return this._discordie.VoiceConnections.getForChannel(this._channelId);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = IVoiceChannel;
|
215
node_modules/discordie/lib/interfaces/IVoiceConnection.js
generated
vendored
Normal file
215
node_modules/discordie/lib/interfaces/IVoiceConnection.js
generated
vendored
Normal file
@ -0,0 +1,215 @@
|
||||
"use strict";
|
||||
|
||||
const Utils = require("../core/Utils");
|
||||
const ExternalEncoderFactory = require("../voice/players/ExternalEncoderFactory");
|
||||
|
||||
function initInterface(_interface, _options) {
|
||||
if (!_interface)
|
||||
throw new TypeError("Invalid interface");
|
||||
if (_options) _interface.initialize(_options);
|
||||
return _interface;
|
||||
}
|
||||
|
||||
/**
|
||||
* @interface
|
||||
*/
|
||||
class IVoiceConnection {
|
||||
constructor(discordie, gatewaySocket, voiceSocket) {
|
||||
// todo: ssrc to user
|
||||
//discordie.Dispatcher.on(Events.VOICE_SPEAKING, e => {
|
||||
// if (e.socket == voicews) this.emit("speaking", - bla - resolve ssrc)
|
||||
//});
|
||||
|
||||
this._gatewaySocket = gatewaySocket;
|
||||
this._voiceSocket = voiceSocket;
|
||||
this._lastChannelId = null;
|
||||
this._discordie = discordie;
|
||||
Utils.privatify(this);
|
||||
|
||||
if (!this.canStream)
|
||||
throw new Error("Failed to create IVoiceConnection");
|
||||
}
|
||||
dispose() {
|
||||
this._lastChannelId = this.channelId;
|
||||
this._gatewaySocket = null;
|
||||
this._voiceSocket = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether this voice connection is no longer valid.
|
||||
* @returns {boolean}
|
||||
* @readonly
|
||||
*/
|
||||
get disposed() {
|
||||
return !this._voiceSocket;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether this voice connection is fully initialized.
|
||||
* @returns {boolean}
|
||||
* @readonly
|
||||
*/
|
||||
get canStream() {
|
||||
return this._voiceSocket && this._voiceSocket.canStream;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets channel of this voice connection.
|
||||
*
|
||||
* Returns last channel it was connected to if voice connection has been
|
||||
* disposed.
|
||||
* Returns null if guild became unavailable or channel doesn't exist in cache.
|
||||
* @returns {IChannel|null}
|
||||
* @readonly
|
||||
*/
|
||||
get channel() {
|
||||
const channelId = this.channelId;
|
||||
if (!channelId) return null;
|
||||
return this._discordie.Channels.get(channelId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets channel id of this voice connection.
|
||||
*
|
||||
* Returns last channel id it was connected to if voice connection has been
|
||||
* disposed.
|
||||
* @returns {String|null}
|
||||
* @readonly
|
||||
*/
|
||||
get channelId() {
|
||||
if (this._lastChannelId) return this._lastChannelId;
|
||||
|
||||
const gw = this._gatewaySocket;
|
||||
if (!gw) return null;
|
||||
|
||||
const voiceState = gw.voiceStates.get(this.guildId);
|
||||
if (!voiceState) return null;
|
||||
|
||||
return voiceState.channelId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets guild of this voice connection.
|
||||
*
|
||||
* Returns null if this is a private call, or guild became unavailable or
|
||||
* doesn't exist in cache.
|
||||
* @returns {IGuild|null}
|
||||
* @readonly
|
||||
*/
|
||||
get guild() {
|
||||
const gw = this._gatewaySocket;
|
||||
if (!gw) return null;
|
||||
return this._discordie.Guilds.get(this.guildId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets guild id of this voice connection.
|
||||
*
|
||||
* Returns null if this is a private call.
|
||||
* @returns {String|null}
|
||||
* @readonly
|
||||
*/
|
||||
get guildId() {
|
||||
return this._voiceSocket ? this._voiceSocket.guildId : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves a user object from source id assigned to this voice connection.
|
||||
* @param {Number} ssrc
|
||||
* @returns {IUser}
|
||||
*/
|
||||
ssrcToUser(ssrc) {
|
||||
if (this.disposed) return null;
|
||||
const userid = this._discordie._voicestates.ssrcToUserId(this, ssrc);
|
||||
if (!userid) return null;
|
||||
return this._discordie.Users.get(userid) || null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves a member object from source id assigned to this voice connection.
|
||||
* @param {Number} ssrc
|
||||
* @returns {IGuildMember}
|
||||
*/
|
||||
ssrcToMember(ssrc) {
|
||||
if (this.disposed) return null;
|
||||
const userid = this._discordie._voicestates.ssrcToUserId(this, ssrc);
|
||||
if (!userid) return null;
|
||||
return this._discordie.Users.getMember(this.guild, userid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes encoder and gets stream for this voice connection.
|
||||
*
|
||||
* Calls without arguments return existing encoder without reinitialization.
|
||||
*
|
||||
* See `AudioEncoder.initialize()` method for list of options.
|
||||
* @param [options]
|
||||
* @returns {AudioEncoderStream}
|
||||
*/
|
||||
getEncoderStream(options) {
|
||||
const encoder = this.getEncoder(options);
|
||||
if (!encoder) return null;
|
||||
return encoder._stream;
|
||||
}
|
||||
createDecoderStream(options) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an external encoder.
|
||||
*
|
||||
* Accepts options object with `type` property (default `{type: "ffmpeg"}`).
|
||||
* Each type supports additional options.
|
||||
* See docs for returned classes for usage info.
|
||||
* @param {Object} [options]
|
||||
* @returns {FFmpegEncoder|
|
||||
* OggOpusPlayer|
|
||||
* WebmOpusPlayer}
|
||||
*/
|
||||
createExternalEncoder(options) {
|
||||
if (!this._voiceSocket) return null;
|
||||
return ExternalEncoderFactory.create(this, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes encoder instance for this voice connection.
|
||||
*
|
||||
* Calls without arguments return existing encoder without reinitialization.
|
||||
*
|
||||
* See `AudioEncoder.initialize()` method for list of options.
|
||||
* @param {Object} [options]
|
||||
* @returns {AudioEncoder}
|
||||
*/
|
||||
getEncoder(options) {
|
||||
if (!this._voiceSocket) return null;
|
||||
return initInterface(this._voiceSocket.audioEncoder, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes decoder instance for this voice connection.
|
||||
*
|
||||
* Calls without arguments return existing decoder without reinitialization.
|
||||
* @param {Object} [options]
|
||||
* @returns {AudioDecoder}
|
||||
*/
|
||||
getDecoder(options) {
|
||||
if (!this._voiceSocket) return null;
|
||||
return initInterface(this._voiceSocket.audioDecoder, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnects this voice connection.
|
||||
*/
|
||||
disconnect() {
|
||||
this._disconnect();
|
||||
}
|
||||
|
||||
_disconnect(error) {
|
||||
if (!this._gatewaySocket) return;
|
||||
if (this.guildId || this.channelId) {
|
||||
this._gatewaySocket.disconnectVoice(this.guildId, false, error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = IVoiceConnection;
|
230
node_modules/discordie/lib/interfaces/IWebhookManager.js
generated
vendored
Normal file
230
node_modules/discordie/lib/interfaces/IWebhookManager.js
generated
vendored
Normal file
@ -0,0 +1,230 @@
|
||||
"use strict";
|
||||
|
||||
const Utils = require("../core/Utils");
|
||||
|
||||
const rest = require("../networking/rest");
|
||||
|
||||
function webhookToId(webhook) {
|
||||
if (!webhook) throw new TypeError("Param 'webhook' is invalid");
|
||||
if (typeof webhook === "string") return webhook;
|
||||
return webhook.id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @interface
|
||||
* @description
|
||||
* Wrapper for webhook methods.
|
||||
*
|
||||
* Example webhook object:
|
||||
* ```js
|
||||
* {
|
||||
* "name": "abc",
|
||||
* "channel_id": "78231142373424474",
|
||||
* "token": "EtuNYHGkElBlE7BE266Jk...NzHvccXaUCQUOY64NbFWz9zbQ",
|
||||
* "avatar": null,
|
||||
* "guild_id": "78231498370026660",
|
||||
* "id": "232330225768333313",
|
||||
* "user": {
|
||||
* "username": "testuser",
|
||||
* "discriminator": "3273",
|
||||
* "id": "000000000000000000",
|
||||
* "avatar": null
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
class IWebhookManager {
|
||||
constructor(discordie) {
|
||||
this._discordie = discordie;
|
||||
Utils.privatify(this);
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* **Requires logging in with an API token.**
|
||||
*
|
||||
* Makes a request to get webhook objects for the specified guild.
|
||||
* @param {IGuild|String} guild
|
||||
* @return {Promise<Array<Object>, Error>}
|
||||
*/
|
||||
fetchForGuild(guild) {
|
||||
guild = guild.valueOf();
|
||||
return rest(this._discordie).webhooks.getGuildWebhooks(guild);
|
||||
}
|
||||
|
||||
/**
|
||||
* **Requires logging in with an API token.**
|
||||
*
|
||||
* Makes a request to get webhook objects for the specified channel.
|
||||
* @param {IChannel|String} channel
|
||||
* @return {Promise<Array<Object>, Error>}
|
||||
*/
|
||||
fetchForChannel(channel) {
|
||||
channel = channel.valueOf();
|
||||
return rest(this._discordie).webhooks.getChannelWebhooks(channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* **Requires logging in with an API token.**
|
||||
*
|
||||
* Makes a request to create a webhook for the channel.
|
||||
*
|
||||
* Promise resolves with a webhook object.
|
||||
* @param {IChannel} channel
|
||||
* @param {Object} options
|
||||
* Object with properties `{name: String, avatar: Buffer|String|null}`.
|
||||
*
|
||||
* String avatars must be base64 data-url encoded.
|
||||
* @return {Promise<Object, Error>}
|
||||
*/
|
||||
create(channel, options) {
|
||||
channel = channel.valueOf();
|
||||
|
||||
options = options || {};
|
||||
if (options.avatar instanceof Buffer) {
|
||||
options.avatar = Utils.imageToDataURL(options.avatar);
|
||||
}
|
||||
|
||||
return rest(this._discordie).webhooks.createWebhook(channel, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to fetch a webhook object.
|
||||
*
|
||||
* Promise resolves with a webhook object (does not contain a `user` object
|
||||
* if fetched with `token` param).
|
||||
* @param {Object|String} webhook - Webhook object or id.
|
||||
* @param {String} token
|
||||
* Webhook token, not required if currently logged in
|
||||
* with an account that has access to the webhook.
|
||||
* @return {Promise<Object, Error>}
|
||||
*/
|
||||
fetch(webhook, token) {
|
||||
const webhookId = webhookToId(webhook);
|
||||
return rest(this._discordie).webhooks.getWebhook(webhookId, token);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to edit the specified webhook.
|
||||
*
|
||||
* Promise resolves with a webhook object (does not contain a `user` object
|
||||
* if edited with `token` param).
|
||||
* @param {Object|String} webhook - Webhook object or id.
|
||||
* @param {String} token
|
||||
* Webhook token, not required and can be set to null if currently logged in
|
||||
* with an account that has access to the webhook.
|
||||
* @param {Object} options
|
||||
* Object with properties `{name: String, avatar: Buffer|String|null}`.
|
||||
*
|
||||
* String avatars must be base64 data-url encoded.
|
||||
* @return {Promise<Object, Error>}
|
||||
*/
|
||||
edit(webhook, token, options) {
|
||||
const webhookId = webhookToId(webhook);
|
||||
|
||||
options = options || {};
|
||||
if (options.avatar instanceof Buffer) {
|
||||
options.avatar = Utils.imageToDataURL(options.avatar);
|
||||
}
|
||||
|
||||
return rest(this._discordie)
|
||||
.webhooks.patchWebhook(webhookId, token, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to delete the specified webhook.
|
||||
* @param {Object|String} webhook - Webhook object or id.
|
||||
* @param {String} token
|
||||
* Webhook token, not required and can be set to null if currently logged in
|
||||
* with an account that has access to the webhook.
|
||||
* @return {Promise}
|
||||
*/
|
||||
delete(webhook, token) {
|
||||
const webhookId = webhookToId(webhook);
|
||||
return rest(this._discordie)
|
||||
.webhooks.deleteWebhook(webhookId, token);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to execute the specified webhook.
|
||||
*
|
||||
* > **Note:** Embeds in file uploads are not supported.
|
||||
* @param {Object|String} webhook - Webhook object or id.
|
||||
* @param {String} token - Required unless webhook object contains token.
|
||||
* @param {Object} options
|
||||
* Refer to [official API documentation](https://discordapp.com/developers/docs/)
|
||||
* for more information.
|
||||
* @param {boolean} [wait]
|
||||
* Wait for server confirmation of message delivery,
|
||||
* returned promise will contain a raw message object or an error if message
|
||||
* creation failed.
|
||||
* @return {Promise}
|
||||
* @example
|
||||
* const webhookId = "232330225768333313";
|
||||
* const token = "EtuNYHGkElBlE7BE266Jk...NzHvccXaUCQUOY64NbFWz9zbQ";
|
||||
* client.Webhooks.execute(webhookId, token, {content: "text message"});
|
||||
* client.Webhooks.execute(webhookId, token, {
|
||||
* // text message
|
||||
* content: "text message",
|
||||
* username: "Different Username",
|
||||
* avatar_url: "https://localhost/test.png",
|
||||
* tts: false,
|
||||
* embeds: [{
|
||||
* color: 0x3498db,
|
||||
* author: {name: "who dis"},
|
||||
* title: "This is an embed",
|
||||
* description: "Nobody will read this anyway",
|
||||
* url: "http://google.com",
|
||||
* timestamp: "2016-10-03T03:32:31.205Z",
|
||||
* fields: [{name: "some field", value: "some value"}],
|
||||
* footer: {text: "footer text"}
|
||||
* }]
|
||||
* });
|
||||
*
|
||||
* client.Webhooks.execute(webhookId, token, {
|
||||
* // file upload
|
||||
* content: "text message",
|
||||
* username: "Different Username",
|
||||
* file: fs.readFileSync("test.png"),
|
||||
* filename: "test.png"
|
||||
* });
|
||||
*/
|
||||
execute(webhook, token, options, wait) {
|
||||
const webhookId = webhookToId(webhook);
|
||||
token = token || webhook.token;
|
||||
return rest(this._discordie)
|
||||
.webhooks.executeWebhook(webhookId, token, options, wait);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a request to execute the specified webhook with slack-compatible
|
||||
* options.
|
||||
* @param {Object|String} webhook - Webhook object or id.
|
||||
* @param {String} token - Required unless webhook object contains token.
|
||||
* @param {Object} options
|
||||
* Refer to [Slack's documentation](https://api.slack.com/incoming-webhooks)
|
||||
* for more information.
|
||||
*
|
||||
* Discord does not support Slack's `channel`, `icon_emoji`, `mrkdwn`,
|
||||
* or `mrkdwn_in` properties.
|
||||
* @param {boolean} [wait]
|
||||
* Wait for server confirmation of message delivery, defaults to true.
|
||||
* When set to false, a message that is not saved does not return an error.
|
||||
* @return {Promise}
|
||||
* @example
|
||||
* const webhookId = "232330225768333313";
|
||||
* const token = "EtuNYHGkElBlE7BE266Jk...NzHvccXaUCQUOY64NbFWz9zbQ";
|
||||
* client.Webhooks.executeSlack(webhookId, token, {
|
||||
* text: "text message",
|
||||
* username: "Different Username"
|
||||
* });
|
||||
*/
|
||||
executeSlack(webhook, token, options, wait) {
|
||||
const webhookId = webhookToId(webhook);
|
||||
token = token || webhook.token;
|
||||
return rest(this._discordie)
|
||||
.webhooks.executeSlackWebhook(webhookId, token, options, wait);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = IWebhookManager;
|
Reference in New Issue
Block a user