@abdarrahmanabdelnasir/relay-node 0.1.20 → 0.1.22

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.
@@ -40,8 +40,19 @@ export function useDiscordAdapter(opts) {
40
40
  memberRoles,
41
41
  });
42
42
  if (!filterResult.allowed) {
43
- // Silently ignore (filtered by config)
44
- console.log(`[commandless] Message filtered: ${filterResult.reason}`);
43
+ // If this is a premium-only feature and the user is not premium,
44
+ // send a friendly explanation instead of silently ignoring.
45
+ if (filterResult.reason === 'Premium only') {
46
+ try {
47
+ await message.reply("This command is part of this bot's premium features, and your account is not marked as premium for this bot.");
48
+ }
49
+ catch {
50
+ // ignore reply failures
51
+ }
52
+ }
53
+ else {
54
+ console.log(`[commandless] Message filtered: ${filterResult.reason}`);
55
+ }
45
56
  return;
46
57
  }
47
58
  }
@@ -10,6 +10,7 @@ export interface BotConfig {
10
10
  enabledUsers: string[];
11
11
  disabledUsers: string[];
12
12
  premiumRoleIds: string[];
13
+ premiumUserIds: string[];
13
14
  enabledCommandCategories: string[];
14
15
  disabledCommands: string[];
15
16
  commandMode: 'all' | 'category_based' | 'whitelist' | 'blacklist';
@@ -137,7 +137,10 @@ export class ConfigCache {
137
137
  // Check permission mode
138
138
  switch (this.config.permissionMode) {
139
139
  case 'premium_only': {
140
- const isPremium = roles.some(roleId => this.config.premiumRoleIds.includes(roleId));
140
+ const isPremiumRole = roles.some(roleId => this.config.premiumRoleIds.includes(roleId));
141
+ const premiumIds = (this.config.premiumUserIds || []).map(String);
142
+ const isPremiumUser = premiumIds.includes(String(userId));
143
+ const isPremium = isPremiumRole || isPremiumUser;
141
144
  if (!isPremium) {
142
145
  return { allowed: false, reason: 'Premium only' };
143
146
  }
@@ -172,7 +175,10 @@ export class ConfigCache {
172
175
  return { allowed: true };
173
176
  const now = Date.now();
174
177
  const roles = memberRoles || [];
175
- const isPremium = roles.some(roleId => this.config.premiumRoleIds.includes(roleId));
178
+ const isPremiumRole = roles.some(roleId => this.config.premiumRoleIds.includes(roleId));
179
+ const premiumIds = (this.config.premiumUserIds || []).map(String);
180
+ const isPremiumUser = premiumIds.includes(String(userId));
181
+ const isPremium = isPremiumRole || isPremiumUser;
176
182
  // User rate limit
177
183
  const userLimit = isPremium ? this.config.premiumRateLimit : this.config.freeRateLimit;
178
184
  const userKey = `user:${userId}`;
@@ -43,8 +43,19 @@ function useDiscordAdapter(opts) {
43
43
  memberRoles,
44
44
  });
45
45
  if (!filterResult.allowed) {
46
- // Silently ignore (filtered by config)
47
- console.log(`[commandless] Message filtered: ${filterResult.reason}`);
46
+ // If this is a premium-only feature and the user is not premium,
47
+ // send a friendly explanation instead of silently ignoring.
48
+ if (filterResult.reason === 'Premium only') {
49
+ try {
50
+ await message.reply("This command is part of this bot's premium features, and your account is not marked as premium for this bot.");
51
+ }
52
+ catch {
53
+ // ignore reply failures
54
+ }
55
+ }
56
+ else {
57
+ console.log(`[commandless] Message filtered: ${filterResult.reason}`);
58
+ }
48
59
  return;
49
60
  }
50
61
  }
@@ -10,6 +10,7 @@ export interface BotConfig {
10
10
  enabledUsers: string[];
11
11
  disabledUsers: string[];
12
12
  premiumRoleIds: string[];
13
+ premiumUserIds: string[];
13
14
  enabledCommandCategories: string[];
14
15
  disabledCommands: string[];
15
16
  commandMode: 'all' | 'category_based' | 'whitelist' | 'blacklist';
@@ -140,7 +140,10 @@ class ConfigCache {
140
140
  // Check permission mode
141
141
  switch (this.config.permissionMode) {
142
142
  case 'premium_only': {
143
- const isPremium = roles.some(roleId => this.config.premiumRoleIds.includes(roleId));
143
+ const isPremiumRole = roles.some(roleId => this.config.premiumRoleIds.includes(roleId));
144
+ const premiumIds = (this.config.premiumUserIds || []).map(String);
145
+ const isPremiumUser = premiumIds.includes(String(userId));
146
+ const isPremium = isPremiumRole || isPremiumUser;
144
147
  if (!isPremium) {
145
148
  return { allowed: false, reason: 'Premium only' };
146
149
  }
@@ -175,7 +178,10 @@ class ConfigCache {
175
178
  return { allowed: true };
176
179
  const now = Date.now();
177
180
  const roles = memberRoles || [];
178
- const isPremium = roles.some(roleId => this.config.premiumRoleIds.includes(roleId));
181
+ const isPremiumRole = roles.some(roleId => this.config.premiumRoleIds.includes(roleId));
182
+ const premiumIds = (this.config.premiumUserIds || []).map(String);
183
+ const isPremiumUser = premiumIds.includes(String(userId));
184
+ const isPremium = isPremiumRole || isPremiumUser;
179
185
  // User rate limit
180
186
  const userLimit = isPremium ? this.config.premiumRateLimit : this.config.freeRateLimit;
181
187
  const userKey = `user:${userId}`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abdarrahmanabdelnasir/relay-node",
3
- "version": "0.1.20",
3
+ "version": "0.1.22",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "main": "dist/index.js",