discord-self-lite 0.1.3 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "discord-self-lite",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "description": "Lightweight Discord selfbot library",
5
5
  "keywords": [
6
6
  "discord",
@@ -128,6 +128,22 @@ class Client extends EventEmitter {
128
128
  const data = await this.rest.fetchGuild(id);
129
129
  const guild = new Guild(this, this.rest, data);
130
130
  this.guilds.set(id, guild); // Update cache with fresh data
131
+
132
+ // Also fetch and cache the client's member information for this guild
133
+ try {
134
+ const memberData = await this.rest.fetchGuildMember(id);
135
+ const GuildMember = require("./GuildMember");
136
+ const member = new GuildMember(this, memberData, guild);
137
+ guild._members.set(this.user.id, member);
138
+ } catch (error) {
139
+ // If fetching member fails, continue without it
140
+ // This might happen if the bot doesn't have permission or other issues
141
+ console.warn(
142
+ `Failed to fetch member data for guild ${id}:`,
143
+ error.message,
144
+ );
145
+ }
146
+
131
147
  return guild;
132
148
  }
133
149
 
@@ -1,4 +1,6 @@
1
1
  const Channel = require("./Channel");
2
+ const GuildMember = require("./GuildMember");
3
+ const DiscordAPIError = require("./DiscordAPIError");
2
4
 
3
5
  /**
4
6
  * Represents a Discord guild (server)
@@ -31,6 +33,9 @@ class Guild {
31
33
  this.id = this.id || data.id;
32
34
  this.name = this.name || data.name;
33
35
  }
36
+
37
+ // Cache for guild members
38
+ this._members = new Map();
34
39
  }
35
40
 
36
41
  /**
@@ -116,6 +121,69 @@ class Guild {
116
121
  const format = options.format || "png";
117
122
  return `https://cdn.discordapp.com/banners/${this.id}/${this.data.banner}.${format}?size=${size}`;
118
123
  }
124
+
125
+ /**
126
+ * Fetch members for this guild
127
+ * @param {object} [options={}] - Fetch options
128
+ * @param {number} [options.limit=1000] - Number of members to fetch
129
+ * @param {string} [options.after] - Member ID to fetch after
130
+ * @returns {Promise<Array<GuildMember>>} Array of guild member instances
131
+ */
132
+ async fetchMembers(options = {}) {
133
+ const { limit = 1000 } = options;
134
+
135
+ try {
136
+ const membersData = await this.client.rest.fetchGuildMembers(this.id, {
137
+ limit,
138
+ });
139
+
140
+ const members = [];
141
+ for (const memberData of membersData) {
142
+ const member = new GuildMember(this.client, memberData, this);
143
+ this._members.set(member.user.id, member);
144
+ members.push(member);
145
+ }
146
+
147
+ return members;
148
+ } catch (error) {
149
+ throw new DiscordAPIError(
150
+ `Failed to fetch guild members: ${error.message}`,
151
+ );
152
+ }
153
+ }
154
+
155
+ /**
156
+ * Get the members collection with a 'me' property
157
+ * @returns {object} Members collection with Map methods and 'me' property
158
+ */
159
+ get members() {
160
+ const membersMap = this._members;
161
+ const client = this.client;
162
+
163
+ return {
164
+ // Map methods
165
+ get: (key) => membersMap.get(key),
166
+ set: (key, value) => membersMap.set(key, value),
167
+ has: (key) => membersMap.has(key),
168
+ delete: (key) => membersMap.delete(key),
169
+ clear: () => membersMap.clear(),
170
+ size: membersMap.size,
171
+ [Symbol.iterator]: () => membersMap[Symbol.iterator](),
172
+
173
+ // Special 'me' property
174
+ get me() {
175
+ return membersMap.get(client.user?.id);
176
+ },
177
+ };
178
+ }
179
+
180
+ /**
181
+ * Set the members cache
182
+ * @param {Map} value - The members map
183
+ */
184
+ set members(value) {
185
+ this._members = value;
186
+ }
119
187
  }
120
188
 
121
189
  module.exports = Guild;
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Represents a Discord guild member
3
+ */
4
+ class GuildMember {
5
+ /**
6
+ * Create a new GuildMember instance
7
+ * @param {Client} client - The Discord client
8
+ * @param {object} data - Raw member data from Discord API
9
+ * @param {Guild} guild - The guild this member belongs to
10
+ */
11
+ constructor(client, data, guild) {
12
+ this.client = client;
13
+ this.guild = guild;
14
+ this.data = data;
15
+ this._permissions = null;
16
+
17
+ // Copy all member properties
18
+ for (const [key, value] of Object.entries(data)) {
19
+ const camelKey = key.replace(/_([a-z])/g, (_, letter) =>
20
+ letter.toUpperCase(),
21
+ );
22
+ this[camelKey] = value;
23
+ }
24
+
25
+ // Handle user data separately
26
+ if (data.user) {
27
+ this.user = data.user;
28
+ this.id = data.user.id;
29
+ }
30
+
31
+ this.roles = this.roles || [];
32
+ this.joinedAt = this.joinedAt || data.joined_at;
33
+ }
34
+
35
+ /**
36
+ * Check if this member is the client user
37
+ * @returns {boolean} True if this member represents the client
38
+ */
39
+ get isClient() {
40
+ return this.id === this.client.user?.id;
41
+ }
42
+
43
+ /**
44
+ * Get the member's display name (nickname or username)
45
+ * @returns {string} The display name
46
+ */
47
+ get displayName() {
48
+ return this.nick || this.user?.username || "Unknown";
49
+ }
50
+
51
+ /**
52
+ * Get the member's permissions in this guild
53
+ * @returns {Array<string>} Array of permission strings
54
+ */
55
+ get permissions() {
56
+ // This is a simplified implementation
57
+ // In a full implementation, you'd calculate permissions based on roles
58
+ return this._permissions;
59
+ }
60
+
61
+ set permissions(value) {
62
+ this._permissions = value ?? null;
63
+ }
64
+
65
+ /**
66
+ * Check if the member has specific permissions
67
+ * @param {Array<string>} permissions - Permission flags to check
68
+ * @returns {boolean} True if member has all permissions
69
+ */
70
+ hasPermission() {
71
+ // TODO: Implement proper permission checking
72
+ // Simplified implementation - always return true for now
73
+ return true;
74
+ }
75
+ }
76
+
77
+ module.exports = GuildMember;
@@ -1,6 +1,8 @@
1
1
  const sendMessage = require("./methods/sendMessage");
2
2
  const react = require("./methods/react");
3
3
  const clickButton = require("./methods/clickButton");
4
+ const fetchGuildMembers = require("./methods/fetchGuildMembers");
5
+ const fetchGuildMember = require("./methods/fetchGuildMember");
4
6
  const DiscordAPIError = require("../../classes/DiscordAPIError");
5
7
 
6
8
  /**
@@ -287,6 +289,27 @@ class RestManager {
287
289
  return await this.request(`/guilds/${guildId}/channels`);
288
290
  }
289
291
 
292
+ /**
293
+ * Fetch guild members
294
+ * @param {string} guildId - The guild ID
295
+ * @param {object} [options={}] - Fetch options
296
+ * @param {number} [options.limit=1000] - Number of members to fetch
297
+ * @param {string} [options.after] - Member ID to fetch after
298
+ * @returns {Promise<Array>} Array of member data
299
+ */
300
+ async fetchGuildMembers(guildId, options = {}) {
301
+ return await fetchGuildMembers(this, guildId, options);
302
+ }
303
+
304
+ /**
305
+ * Fetch the current user's member information for a guild
306
+ * @param {string} guildId - The guild ID
307
+ * @returns {Promise<object>} Member data
308
+ */
309
+ async fetchGuildMember(guildId) {
310
+ return await fetchGuildMember(this, guildId);
311
+ }
312
+
290
313
  /**
291
314
  * Fetch a specific message from a channel
292
315
  * @param {string} channelId - The channel ID
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Fetch the current user's member information for a guild
3
+ * @param {RestManager} rest - The REST manager instance
4
+ * @param {string} guildId - The guild ID
5
+ * @returns {Promise<object>} Member data
6
+ */
7
+ async function fetchGuildMember(rest, guildId) {
8
+ return await rest.request(`/users/@me/guilds/${guildId}/member`);
9
+ }
10
+
11
+ module.exports = fetchGuildMember;
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Fetch guild members
3
+ * @param {RestManager} rest - The REST manager instance
4
+ * @param {string} guildId - The guild ID
5
+ * @param {object} [options={}] - Fetch options
6
+ * @param {number} [options.limit=1000] - Number of members to fetch
7
+ * @param {string} [options.after] - Member ID to fetch after
8
+ * @returns {Promise<Array>} Array of member data
9
+ */
10
+ async function fetchGuildMembers(rest, guildId, options = {}) {
11
+ const query = new URLSearchParams(options).toString();
12
+ return await rest.request(`/guilds/${guildId}/members?${query}`, {
13
+ method: "GET",
14
+ });
15
+ }
16
+
17
+ module.exports = fetchGuildMembers;
@@ -131,6 +131,14 @@ class DiscordWebSocket extends EventEmitter {
131
131
  this.sessionId = message.d.session_id;
132
132
  this.client.sessionId = message.d.session_id;
133
133
  this.client.user = new User(this.client, message.d.user);
134
+
135
+ // Process guilds from READY payload
136
+ if (message.d.guilds) {
137
+ for (const guildData of message.d.guilds) {
138
+ this.handleGuildCreate(guildData);
139
+ }
140
+ }
141
+
134
142
  this.ready = true;
135
143
  this.client.emit("ready", message.d);
136
144
  break;
@@ -140,9 +148,7 @@ class DiscordWebSocket extends EventEmitter {
140
148
  break;
141
149
  }
142
150
  case "GUILD_CREATE": {
143
- const guild = new Guild(this.client, this.client.rest, message.d);
144
- this.client.guilds.set(guild.id, guild);
145
- this.client.emit("guildCreate", guild);
151
+ this.handleGuildCreate(message.d);
146
152
  break;
147
153
  }
148
154
  case "CHANNEL_CREATE": {
@@ -156,6 +162,40 @@ class DiscordWebSocket extends EventEmitter {
156
162
  }
157
163
  }
158
164
 
165
+ async handleGuildCreate(data) {
166
+ const guild = new Guild(this.client, this.client.rest, data);
167
+ this.client.guilds.set(guild.id, guild);
168
+
169
+ // Populate the client's member information for this guild
170
+ if (data.members) {
171
+ const clientMember = data.members.find(
172
+ (member) => member.user.id === this.client.user.id,
173
+ );
174
+ if (clientMember) {
175
+ const GuildMember = require("../../classes/GuildMember");
176
+ const member = new GuildMember(this.client, clientMember, guild);
177
+ guild._members.set(this.client.user.id, member);
178
+ }
179
+ }
180
+
181
+ // If no member data in GUILD_CREATE, fetch it from API
182
+ if (!guild._members.has(this.client.user.id)) {
183
+ try {
184
+ const memberData = await this.client.rest.fetchGuildMember(guild.id);
185
+ const GuildMember = require("../../classes/GuildMember");
186
+ const member = new GuildMember(this.client, memberData, guild);
187
+ guild._members.set(this.client.user.id, member);
188
+ } catch (err) {
189
+ console.warn(
190
+ `Failed to fetch member for guild ${guild.id}:`,
191
+ err.message,
192
+ );
193
+ }
194
+ }
195
+
196
+ this.client.emit("guildCreate", guild);
197
+ }
198
+
159
199
  reconnect() {
160
200
  if (this.reconnectAttempts >= this.maxReconnectAttempts) {
161
201
  const err = new WebSocketError("Max reconnect attempts reached");