levix-bot 3.3.0-rc.2 → 4.0.0

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.
Files changed (118) hide show
  1. package/README.md +13 -9
  2. package/app.cjs +49 -46
  3. package/package.json +9 -1
  4. package/public/dashboard/assets/index-BBBXWzM0.js +391 -0
  5. package/public/dashboard/assets/index-pYaivHON.css +1 -0
  6. package/public/dashboard/index.html +19 -0
  7. package/public/dashboard.css +391 -66
  8. package/public/dashboard.js +593 -42
  9. package/scheduler.cjs +9 -14
  10. package/src/auth/use-database-auth-state.js +2 -4
  11. package/src/bootstrap/core.js +2 -5
  12. package/src/bootstrap/panel.js +10 -5
  13. package/src/cli.js +3 -5
  14. package/src/commands/autoschedule.cjs +1 -4
  15. package/src/commands/blacklist.cjs +22 -20
  16. package/src/commands/block.cjs +2 -4
  17. package/src/commands/calc.cjs +9 -16
  18. package/src/commands/digit.cjs +97 -0
  19. package/src/commands/gemini.cjs +147 -161
  20. package/src/commands/group/add.cjs +7 -16
  21. package/src/commands/group/antiSpam.cjs +5 -11
  22. package/src/commands/group/antilink.cjs +34 -28
  23. package/src/commands/group/approveall.cjs +3 -11
  24. package/src/commands/group/clearwarns.cjs +2 -5
  25. package/src/commands/group/demote.cjs +3 -8
  26. package/src/commands/group/kick.cjs +12 -15
  27. package/src/commands/group/media.cjs +17 -24
  28. package/src/commands/group/members.cjs +1 -2
  29. package/src/commands/group/promote.cjs +4 -12
  30. package/src/commands/group/removeall.cjs +2 -5
  31. package/src/commands/group/setpp.cjs +1 -1
  32. package/src/commands/group/setrules.cjs +2 -8
  33. package/src/commands/group/setwarn.cjs +4 -2
  34. package/src/commands/group/tagadmins.cjs +2 -5
  35. package/src/commands/group/warn.cjs +26 -24
  36. package/src/commands/group/warns.cjs +1 -2
  37. package/src/commands/group/welcome.cjs +13 -17
  38. package/src/commands/group.cjs +7 -10
  39. package/src/commands/help.cjs +6 -12
  40. package/src/commands/lang.cjs +104 -0
  41. package/src/commands/listschedules.cjs +2 -6
  42. package/src/commands/loop.cjs +6 -13
  43. package/src/commands/memory.cjs +19 -32
  44. package/src/commands/mod.cjs +97 -35
  45. package/src/commands/perm.cjs +18 -56
  46. package/src/commands/ping.cjs +1 -5
  47. package/src/commands/poll.cjs +1 -1
  48. package/src/commands/rand.cjs +2 -5
  49. package/src/commands/schedule.cjs +4 -8
  50. package/src/commands/score.cjs +8 -2
  51. package/src/commands/setprefix.cjs +2 -2
  52. package/src/commands/shortlink.cjs +7 -15
  53. package/src/commands/shutdown.cjs +1 -1
  54. package/src/commands/sticker.cjs +222 -0
  55. package/src/commands/stt.cjs +136 -68
  56. package/src/commands/todo.cjs +9 -15
  57. package/src/commands/tts.cjs +10 -16
  58. package/src/commands/unblock.cjs +2 -6
  59. package/src/commands/weather.cjs +5 -12
  60. package/src/config/ai-persona.md +5 -3
  61. package/src/config/available-models.json +1156 -0
  62. package/src/config/baileys.config.js +2 -1
  63. package/src/config/brand.esm.js +1 -10
  64. package/src/config/constants.js +1 -1
  65. package/src/config/defaults.cjs +66 -66
  66. package/src/config/lock.cjs +2 -2
  67. package/src/config/modelCapabilities.cjs +172 -0
  68. package/src/config/runtime-config.cjs +8 -13
  69. package/src/config/secrets.cjs +18 -10
  70. package/src/config/settings.cjs +94 -10
  71. package/src/config/vault.cjs +107 -0
  72. package/src/core/connection.js +13 -12
  73. package/src/core/events.js +41 -23
  74. package/src/core/proxy.js +7 -7
  75. package/src/core/session.js +91 -48
  76. package/src/core/socket.js +12 -15
  77. package/src/db/db.cjs +14 -6
  78. package/src/db/store.cjs +221 -87
  79. package/src/domain/caddy.js +1 -1
  80. package/src/domain/command.js +40 -19
  81. package/src/domain/detect.js +1 -1
  82. package/src/domain/system.js +2 -5
  83. package/src/handlers/command.handler.js +22 -43
  84. package/src/handlers/group.handler.js +13 -13
  85. package/src/handlers/message.handler.js +11 -21
  86. package/src/index.js +8 -4
  87. package/src/middleware/antispam.middleware.js +46 -23
  88. package/src/middleware/blacklist.middleware.js +14 -9
  89. package/src/middleware/forward-tracking.middleware.js +3 -2
  90. package/src/middleware/permissions.middleware.js +7 -10
  91. package/src/panel/login-throttle.cjs +43 -0
  92. package/src/panel/session-auth.cjs +17 -0
  93. package/src/routes/dashboard.api.esm.js +394 -72
  94. package/src/services/aiAgent.cjs +136 -49
  95. package/src/services/aiProviders.cjs +193 -47
  96. package/src/services/aiRouter.cjs +137 -0
  97. package/src/services/aiTools.cjs +305 -128
  98. package/src/services/llmDiscovery.cjs +481 -0
  99. package/src/services/modelRegistry.cjs +412 -0
  100. package/src/utils/datetime.cjs +2 -2
  101. package/src/utils/lid-helper.esm.js +7 -7
  102. package/src/utils/logger.cjs +1 -1
  103. package/src/utils/markdownParser.cjs +159 -0
  104. package/src/utils/memory.cjs +43 -13
  105. package/src/utils/messageContent.cjs +40 -0
  106. package/src/utils/normalizeJid.esm.js +7 -7
  107. package/src/utils/numerals.cjs +75 -0
  108. package/src/utils/permissions.esm.js +10 -15
  109. package/src/utils/providerUrl.cjs +281 -0
  110. package/src/utils/recurrence.cjs +7 -11
  111. package/src/utils/sendBotMessage.esm.js +4 -14
  112. package/src/utils/statusMessage.cjs +5 -13
  113. package/src/utils/storage.cjs +10 -0
  114. package/src/utils/storage.esm.js +11 -0
  115. package/src/utils/textDecode.cjs +4 -9
  116. package/src/utils/thumbnail.cjs +8 -14
  117. package/src/utils/typing.esm.js +12 -12
  118. package/views/dashboard.ejs +134 -106
@@ -1,10 +1,8 @@
1
1
  // commands/mod.js
2
2
 
3
3
  const { getGroupSettings, saveGroupSettings } = require("../utils/storage.cjs");
4
- const {
5
- isOwnerJidSync,
6
- isAdminInGroupSync,
7
- } = require("../utils/permissions.cjs");
4
+ const { isOwnerJidSync, isAdminInGroupSync } = require("../utils/permissions.cjs");
5
+ const { visibleText } = require("../utils/messageContent.cjs");
8
6
 
9
7
  // الهيكل الافتراضي لإعدادات المراقبة
10
8
  const defaultModSettings = {
@@ -16,11 +14,43 @@ const defaultModSettings = {
16
14
  },
17
15
  };
18
16
 
17
+ const FEATURE_KEYS = {
18
+ antilink: "antiLink",
19
+ antispam: "antiSpam",
20
+ forbiddenwords: "forbiddenWords",
21
+ };
22
+
23
+ function ensureModeration(settings) {
24
+ settings.moderation ||= JSON.parse(JSON.stringify(defaultModSettings));
25
+ settings.moderation.forbiddenWords ||= { enabled: false, list: [] };
26
+ settings.moderation.forbiddenWords.list ||= [];
27
+ return settings.moderation;
28
+ }
29
+
30
+ function featureEnabled(settings, key) {
31
+ if (key === "antiLink") return Boolean(settings.antilink?.enabled);
32
+ if (key === "antiSpam") return Boolean(settings.antispam?.enabled);
33
+ return Boolean(settings.moderation?.forbiddenWords?.enabled);
34
+ }
35
+
36
+ function setFeatureEnabled(settings, key, enabled) {
37
+ if (key === "antiLink") {
38
+ settings.antilink ||= { enabled: false, mode: "ALL", allowed_domains: [], blocked_domains: [] };
39
+ settings.antilink.enabled = enabled;
40
+ } else if (key === "antiSpam") {
41
+ settings.antispam ||= { enabled: false, message_count: 5, time_window: 10, action: "WARN" };
42
+ settings.antispam.enabled = enabled;
43
+ } else {
44
+ ensureModeration(settings).forbiddenWords.enabled = enabled;
45
+ }
46
+ }
47
+
19
48
  module.exports = {
20
49
  name: "mod",
21
50
  aliases: ["moderation", "settings"],
22
51
  description: "التحكم في إعدادات المراقبة للجروب.",
23
- usage: "mod status\nmod <enable|disable> <antiLink|antiSpam|forbiddenWords>\nmod words <add|remove> <الكلمة>\nmod words list",
52
+ usage:
53
+ "mod status\nmod <enable|disable> <antiLink|antiSpam|forbiddenWords>\nmod words <add|remove> <الكلمة>\nmod words list",
24
54
  chat: "group", // يعمل في الجروبات فقط
25
55
  botAdminRequired: false, // لا يتطلب أن يكون البوت مشرفًا لتغيير الإعدادات
26
56
 
@@ -34,70 +64,63 @@ module.exports = {
34
64
  const senderIsAdmin = isAdminInGroupSync(groupMetadata, senderId);
35
65
  const isOwner = msg.key.fromMe || isOwnerJidSync(senderId);
36
66
  if (!senderIsAdmin && !isOwner) {
37
- return sock.sendMessage(
38
- groupId,
39
- { text: "🚫 هذا الأمر للمشرفين فقط." },
40
- { quoted: msg }
41
- );
67
+ return sock.sendMessage(groupId, { text: "🚫 هذا الأمر للمشرفين فقط." }, { quoted: msg });
42
68
  }
43
69
 
44
70
  const command = args[0]?.toLowerCase();
45
- const feature = args[1]?.toLowerCase();
71
+ const feature = FEATURE_KEYS[args[1]?.toLowerCase()];
46
72
 
47
73
  // الحصول على الإعدادات الحالية للجروب أو إنشاء إعدادات افتراضية
48
- let settings = getGroupSettings(groupId) || {};
49
- if (!settings.moderation) {
50
- settings.moderation = JSON.parse(JSON.stringify(defaultModSettings)); // نسخة عميقة
51
- }
52
-
53
- const modSettings = settings.moderation;
74
+ const settings = getGroupSettings(groupId) || {};
75
+ const modSettings = ensureModeration(settings);
54
76
 
55
77
  switch (command) {
56
78
  case "enable":
57
- if (!modSettings.hasOwnProperty(feature)) {
79
+ if (!feature) {
58
80
  return sock.sendMessage(
59
81
  groupId,
60
- { text: `⚠️ الميزة "${feature}" غير موجودة.` },
61
- { quoted: msg }
82
+ { text: `⚠️ الميزة "${args[1] || ""}" غير موجودة.` },
83
+ { quoted: msg },
62
84
  );
63
85
  }
64
- modSettings[feature].enabled = true;
86
+ setFeatureEnabled(settings, feature, true);
65
87
  saveGroupSettings(groupId, settings);
66
88
  await sock.sendMessage(
67
89
  groupId,
68
90
  { text: `✅ تم تفعيل ميزة *${feature}*.` },
69
- { quoted: msg }
91
+ { quoted: msg },
70
92
  );
71
93
  break;
72
94
 
73
95
  case "disable":
74
- if (!modSettings.hasOwnProperty(feature)) {
96
+ if (!feature) {
75
97
  return sock.sendMessage(
76
98
  groupId,
77
- { text: `⚠️ الميزة "${feature}" غير موجودة.` },
78
- { quoted: msg }
99
+ { text: `⚠️ الميزة "${args[1] || ""}" غير موجودة.` },
100
+ { quoted: msg },
79
101
  );
80
102
  }
81
- modSettings[feature].enabled = false;
103
+ setFeatureEnabled(settings, feature, false);
82
104
  saveGroupSettings(groupId, settings);
83
105
  await sock.sendMessage(
84
106
  groupId,
85
107
  { text: `❌ تم تعطيل ميزة *${feature}*.` },
86
- { quoted: msg }
108
+ { quoted: msg },
87
109
  );
88
110
  break;
89
111
 
90
- case "status":
112
+ case "status": {
91
113
  let statusText = "📊 *حالة إعدادات المراقبة* 📊\n\n";
92
- for (const key in modSettings) {
93
- const status = modSettings[key].enabled ? "✅ مفعل" : "❌ معطل";
114
+ for (const key of Object.values(FEATURE_KEYS)) {
115
+ const status = featureEnabled(settings, key) ? "✅ مفعل" : "❌ معطل";
94
116
  statusText += `› *${key}*: ${status}\n`;
95
117
  }
96
118
  statusText += `\n- لعرض قائمة الكلمات الممنوعة، اكتب: \`!mod words list\``;
97
119
  await sock.sendMessage(groupId, { text: statusText }, { quoted: msg });
98
120
  break;
121
+ }
99
122
 
100
- case "words":
123
+ case "words": {
101
124
  const wordAction = args[1]?.toLowerCase();
102
125
  const word = args.slice(2).join(" ").toLowerCase();
103
126
 
@@ -106,7 +129,9 @@ module.exports = {
106
129
  return sock.sendMessage(groupId, {
107
130
  text: "الرجاء كتابة الكلمة التي تريد إضافتها.",
108
131
  });
109
- modSettings.forbiddenWords.list.push(word);
132
+ if (!modSettings.forbiddenWords.list.includes(word)) {
133
+ modSettings.forbiddenWords.list.push(word.slice(0, 100));
134
+ }
110
135
  saveGroupSettings(groupId, settings);
111
136
  await sock.sendMessage(groupId, {
112
137
  text: `✅ تم إضافة "${word}" إلى قائمة الكلمات الممنوعة.`,
@@ -116,8 +141,9 @@ module.exports = {
116
141
  return sock.sendMessage(groupId, {
117
142
  text: "الرجاء كتابة الكلمة التي تريد إزالتها.",
118
143
  });
119
- modSettings.forbiddenWords.list =
120
- modSettings.forbiddenWords.list.filter((w) => w !== word);
144
+ modSettings.forbiddenWords.list = modSettings.forbiddenWords.list.filter(
145
+ (w) => w !== word,
146
+ );
121
147
  saveGroupSettings(groupId, settings);
122
148
  await sock.sendMessage(groupId, {
123
149
  text: `🗑️ تم إزالة "${word}" من القائمة.`,
@@ -138,8 +164,9 @@ module.exports = {
138
164
  });
139
165
  }
140
166
  break;
167
+ }
141
168
 
142
- default:
169
+ default: {
143
170
  let helpText = "🤖 *أوامر التحكم في المراقبة*\n\n";
144
171
  helpText +=
145
172
  "• `!mod enable <feature>`\nلتفعيل ميزة (antilink, antispam, forbiddenwords)\n\n";
@@ -150,6 +177,41 @@ module.exports = {
150
177
  helpText += "• `!mod words list`\nلعرض قائمة الكلمات الممنوعة.";
151
178
  await sock.sendMessage(groupId, { text: helpText }, { quoted: msg });
152
179
  break;
180
+ }
153
181
  }
154
182
  },
155
183
  };
184
+
185
+ async function handleForbiddenWords(sock, msg) {
186
+ const groupId = msg.key.remoteJid;
187
+ if (!groupId?.endsWith("@g.us")) return false;
188
+
189
+ const settings = getGroupSettings(groupId) || {};
190
+ const config = settings.moderation?.forbiddenWords;
191
+ if (!config?.enabled || !Array.isArray(config.list) || !config.list.length) return false;
192
+
193
+ const body = visibleText(msg.message).toLowerCase();
194
+ if (!body || !config.list.some((word) => word && body.includes(String(word).toLowerCase()))) {
195
+ return false;
196
+ }
197
+
198
+ const senderId = msg.key.participant || msg.key.remoteJid;
199
+ const senderIds = [senderId, msg.key.participantAlt, msg.key.participantPn].filter(Boolean);
200
+ const groupMetadata = await sock.groupMetadata(groupId);
201
+ if (
202
+ msg.key.fromMe ||
203
+ senderIds.some(isOwnerJidSync) ||
204
+ senderIds.some((id) => isAdminInGroupSync(groupMetadata, id))
205
+ ) {
206
+ return false;
207
+ }
208
+
209
+ await sock.sendMessage(groupId, { delete: msg.key });
210
+ await sock.sendMessage(groupId, {
211
+ text: `🚫 يا @${senderId.split("@")[0]}، الرسالة فيها كلمة ممنوعة.`,
212
+ mentions: [senderId],
213
+ });
214
+ return true;
215
+ }
216
+
217
+ module.exports.handleForbiddenWords = handleForbiddenWords;
@@ -12,12 +12,7 @@
12
12
  // Roles live in `user_metadata` (is_owner / is_admin) and in the in-memory
13
13
  // roster, so a grant is effective on the very next message — no restart.
14
14
 
15
- const {
16
- grantRole,
17
- revokeRole,
18
- listRoles,
19
- isOwnerJidSync,
20
- } = require("../utils/permissions.cjs");
15
+ const { grantRole, revokeRole, listRoles, isOwnerJidSync } = require("../utils/permissions.cjs");
21
16
  const { sendBotMessage } = require("../utils/sendBotMessage.cjs");
22
17
  const normalizeJid = require("../utils/normalizeJid.cjs");
23
18
  const logger = require("../utils/logger.cjs");
@@ -35,16 +30,7 @@ const ROLE_WORDS = {
35
30
  };
36
31
 
37
32
  const ADD_WORDS = new Set(["add", "grant", "set", "give", "اضف", "أضف", "ضيف"]);
38
- const DEL_WORDS = new Set([
39
- "remove",
40
- "revoke",
41
- "del",
42
- "delete",
43
- "drop",
44
- "شيل",
45
- "احذف",
46
- "امسح",
47
- ]);
33
+ const DEL_WORDS = new Set(["remove", "revoke", "del", "delete", "drop", "شيل", "احذف", "امسح"]);
48
34
  const LIST_WORDS = new Set(["list", "ls", "show", "قائمة", "عرض", "الكل"]);
49
35
 
50
36
  function senderOf(msg) {
@@ -67,8 +53,7 @@ function resolveTarget(msg, args) {
67
53
  const mentioned = contextInfo?.mentionedJid?.[0];
68
54
  if (mentioned) return normalizeJid(mentioned);
69
55
 
70
- const quotedParticipant =
71
- contextInfo?.participant || contextInfo?.participantAlt;
56
+ const quotedParticipant = contextInfo?.participant || contextInfo?.participantAlt;
72
57
  if (quotedParticipant) return normalizeJid(quotedParticipant);
73
58
 
74
59
  for (const arg of args) {
@@ -93,28 +78,17 @@ async function rolesReport() {
93
78
  const lines = ["*🔑 صلاحيات البوت*", ""];
94
79
 
95
80
  lines.push(`*👑 المالكين (${owners.length}):*`);
96
- lines.push(
97
- owners.length ? owners.map((o) => `• ${labelFor(o)}`).join("\n") : "• (مفيش)"
98
- );
81
+ lines.push(owners.length ? owners.map((o) => `• ${labelFor(o)}`).join("\n") : "• (مفيش)");
99
82
 
100
83
  lines.push("", `*🛡️ الأدمنز (${admins.length}):*`);
101
- lines.push(
102
- admins.length ? admins.map((a) => `• ${labelFor(a)}`).join("\n") : "• (مفيش)"
103
- );
84
+ lines.push(admins.length ? admins.map((a) => `• ${labelFor(a)}`).join("\n") : "• (مفيش)");
104
85
 
105
86
  const envOnly = [
106
- ...bootstrapOwners.filter(
107
- (jid) => !owners.some((o) => o.jid === jid || o.lid === jid)
108
- ),
109
- ...bootstrapAdmins.filter(
110
- (jid) => !admins.some((a) => a.jid === jid || a.lid === jid)
111
- ),
87
+ ...bootstrapOwners.filter((jid) => !owners.some((o) => o.jid === jid || o.lid === jid)),
88
+ ...bootstrapAdmins.filter((jid) => !admins.some((a) => a.jid === jid || a.lid === jid)),
112
89
  ];
113
90
  if (envOnly.length) {
114
- lines.push(
115
- "",
116
- `_من الإعدادات (env/config): ${[...new Set(envOnly)].length} إدخال._`
117
- );
91
+ lines.push("", `_من الإعدادات (env/config): ${[...new Set(envOnly)].length} إدخال._`);
118
92
  }
119
93
 
120
94
  return lines.join("\n");
@@ -123,10 +97,8 @@ async function rolesReport() {
123
97
  module.exports = {
124
98
  name: "perm",
125
99
  aliases: ["perms", "owner", "admin", "role", "roles", "صلاحيات"],
126
- description:
127
- "إدارة صلاحيات البوت: إضافة/إزالة مالك أو أدمن، وعرض القائمة الحالية.",
128
- usage:
129
- "perm list\nperm add admin @عضو\nperm add owner <رقم>\nperm remove admin @عضو",
100
+ description: "إدارة صلاحيات البوت: إضافة/إزالة مالك أو أدمن، وعرض القائمة الحالية.",
101
+ usage: "perm list\nperm add admin @عضو\nperm add owner <رقم>\nperm remove admin @عضو",
130
102
  chat: "all",
131
103
 
132
104
  async execute(sock, msg, args) {
@@ -134,12 +106,7 @@ module.exports = {
134
106
  const action = String(args[0] || "").toLowerCase();
135
107
 
136
108
  if (!action || LIST_WORDS.has(action)) {
137
- return sendBotMessage(
138
- sock,
139
- jid,
140
- { text: await rolesReport() },
141
- { replyTo: msg }
142
- );
109
+ return sendBotMessage(sock, jid, { text: await rolesReport() }, { replyTo: msg });
143
110
  }
144
111
 
145
112
  const isAdd = ADD_WORDS.has(action);
@@ -156,7 +123,7 @@ module.exports = {
156
123
  "`!perm add owner <رقم>` — تعيين مالك\n" +
157
124
  "`!perm remove admin @عضو` — سحب الصلاحية",
158
125
  },
159
- { replyTo: msg }
126
+ { replyTo: msg },
160
127
  );
161
128
  }
162
129
 
@@ -181,7 +148,7 @@ module.exports = {
181
148
  "محتاج تحدد الشخص: منشن (@) أو رد على رسالته أو اكتب رقمه.\n" +
182
149
  "مثال: `!perm add admin @عضو`",
183
150
  },
184
- { replyTo: msg }
151
+ { replyTo: msg },
185
152
  );
186
153
  }
187
154
 
@@ -194,21 +161,16 @@ module.exports = {
194
161
  sock,
195
162
  jid,
196
163
  { text: "🚫 تعيين مالك جديد للمالك فقط." },
197
- { replyTo: msg }
164
+ { replyTo: msg },
198
165
  );
199
166
  }
200
167
 
201
168
  try {
202
- const record = isAdd
203
- ? await grantRole(target, role)
204
- : await revokeRole(target, role);
169
+ const record = isAdd ? await grantRole(target, role) : await revokeRole(target, role);
205
170
  const who = record ? labelFor(record) : target;
206
171
  const roleLabel = role === "owner" ? "مالك 👑" : "أدمن 🛡️";
207
172
 
208
- logger.info(
209
- { target, role, granted: isAdd, by: sender },
210
- "[perm] role change"
211
- );
173
+ logger.info({ target, role, granted: isAdd, by: sender }, "[perm] role change");
212
174
 
213
175
  return sendBotMessage(
214
176
  sock,
@@ -219,7 +181,7 @@ module.exports = {
219
181
  : `✅ تم سحب صلاحية *${roleLabel}* من *${who}*.`,
220
182
  mentions: target.includes("@") ? [target] : undefined,
221
183
  },
222
- { replyTo: msg }
184
+ { replyTo: msg },
223
185
  );
224
186
  } catch (error) {
225
187
  logger.error({ err: error }, "[perm] role change failed");
@@ -229,7 +191,7 @@ module.exports = {
229
191
  {
230
192
  text: `❌ *مقدرتش أعدّل الصلاحية*\n\n*التفاصيل:* ${error.message}`,
231
193
  },
232
- { replyTo: msg }
194
+ { replyTo: msg },
233
195
  );
234
196
  }
235
197
  },
@@ -8,10 +8,6 @@ module.exports = {
8
8
 
9
9
  async execute(sock, msg) {
10
10
  // The bot will reply with "Pong!" and quote the original message
11
- await sock.sendMessage(
12
- msg.key.remoteJid,
13
- { text: "Pong! 🏓" },
14
- { quoted: msg }
15
- );
11
+ await sock.sendMessage(msg.key.remoteJid, { text: "Pong! 🏓" }, { quoted: msg });
16
12
  },
17
13
  };
@@ -74,7 +74,7 @@ module.exports = {
74
74
  selectableCount: multi ? options.length : 1,
75
75
  },
76
76
  },
77
- { replyTo: msg }
77
+ { replyTo: msg },
78
78
  );
79
79
  },
80
80
  };
@@ -81,11 +81,8 @@ module.exports = {
81
81
  if (["dice", "die", "نرد", "زهر"].includes(mode)) {
82
82
  const result = rollDice(args[1]);
83
83
  if (result.error) return reply(result.error);
84
- const detail =
85
- result.rolls.length > 1 ? `\n(${result.rolls.join(" + ")})` : "";
86
- return reply(
87
- `🎲 *${result.total}* — ${result.count}d${result.sides}${detail}`
88
- );
84
+ const detail = result.rolls.length > 1 ? `\n(${result.rolls.join(" + ")})` : "";
85
+ return reply(`🎲 *${result.total}* — ${result.count}d${result.sides}${detail}`);
89
86
  }
90
87
 
91
88
  if (["pick", "choose", "اختار", "اختر"].includes(mode)) {
@@ -1,8 +1,5 @@
1
1
  // file: commands/schedule.js
2
- const {
3
- scheduleNewJob,
4
- saveScheduledJob,
5
- } = require("../../scheduler.cjs");
2
+ const { scheduleNewJob, saveScheduledJob } = require("../../scheduler.cjs");
6
3
  const { zonedTimeToDate, defaultTimezone } = require("../utils/datetime.cjs");
7
4
 
8
5
  const DATETIME_RE = /^(\d{1,2}):(\d{2})\s+(\d{1,2})-(\d{1,2})-(\d{4})$/;
@@ -77,10 +74,9 @@ module.exports = {
77
74
  saveScheduledJob(newJob);
78
75
 
79
76
  await sock.sendMessage(creatorJid, {
80
- text: `✅ تم جدولة رسالتك بنجاح ليتم إرسالها في:\n*${scheduleDate.toLocaleString(
81
- "ar-EG",
82
- { timeZone: defaultTimezone() }
83
- )}*`,
77
+ text: `✅ تم جدولة رسالتك بنجاح ليتم إرسالها في:\n*${scheduleDate.toLocaleString("ar-EG", {
78
+ timeZone: defaultTimezone(),
79
+ })}*`,
84
80
  });
85
81
  },
86
82
  };
@@ -49,10 +49,16 @@ function getQuotedInfo(msg) {
49
49
  const quotedContextInfo = quotedContent.contextInfo;
50
50
 
51
51
  // Extract forwarding score and isForwarded flag
52
- if (quotedContextInfo.forwardingScore !== undefined && quotedContextInfo.forwardingScore !== null) {
52
+ if (
53
+ quotedContextInfo.forwardingScore !== undefined &&
54
+ quotedContextInfo.forwardingScore !== null
55
+ ) {
53
56
  forwardingScore = quotedContextInfo.forwardingScore;
54
57
  }
55
- if (quotedContextInfo.isForwarded !== undefined && quotedContextInfo.isForwarded !== null) {
58
+ if (
59
+ quotedContextInfo.isForwarded !== undefined &&
60
+ quotedContextInfo.isForwarded !== null
61
+ ) {
56
62
  isForwarded = quotedContextInfo.isForwarded;
57
63
  }
58
64
 
@@ -18,7 +18,7 @@ module.exports = {
18
18
  const currentPrefix = runtimeConfig.getPrefix();
19
19
 
20
20
  await sock.sendMessage(chatId, {
21
- text: `البادئة الحالية للبوت: \`${currentPrefix}\`\n\nلتغيير البادئة، استخدم:\n\`${currentPrefix}setprefix <البادئة_الجديدة>\`\n\nمثال: \`${currentPrefix}setprefix /\`\n\n⚠️ ملاحظة: يمكن للمالك فقط تغيير البادئة.`
21
+ text: `البادئة الحالية للبوت: \`${currentPrefix}\`\n\nلتغيير البادئة، استخدم:\n\`${currentPrefix}setprefix <البادئة_الجديدة>\`\n\nمثال: \`${currentPrefix}setprefix /\`\n\n⚠️ ملاحظة: يمكن للمالك فقط تغيير البادئة.`,
22
22
  });
23
23
  return;
24
24
  }
@@ -34,7 +34,7 @@ module.exports = {
34
34
  logger.info(`[Prefix] Bot prefix changed to: ${newPrefix}`);
35
35
 
36
36
  await sock.sendMessage(chatId, {
37
- text: `✅ تم تغيير البادئة بنجاح إلى: \`${newPrefix}\`\n\nالآن استخدم \`${newPrefix}help\` لعرض الأوامر.\n\n⚠️ البادئة الجديدة تعمل الآن في كل المحادثات.`
37
+ text: `✅ تم تغيير البادئة بنجاح إلى: \`${newPrefix}\`\n\nالآن استخدم \`${newPrefix}help\` لعرض الأوامر.\n\n⚠️ البادئة الجديدة تعمل الآن في كل المحادثات.`,
38
38
  });
39
39
  },
40
40
  };
@@ -32,17 +32,12 @@ module.exports = {
32
32
 
33
33
  // 3. Define the API endpoint for is.gd
34
34
  // We use `encodeURIComponent` to ensure the URL is properly formatted for the API request
35
- const API_URL = `https://is.gd/create.php?format=simple&url=${encodeURIComponent(
36
- longUrl
37
- )}`;
35
+ const API_URL = `https://is.gd/create.php?format=simple&url=${encodeURIComponent(longUrl)}`;
38
36
 
39
37
  // One message: "shortening..." becomes the short link itself.
40
- const status = await createStatus(
41
- sock,
42
- msg.key.remoteJid,
43
- "🔗 بختصر الرابط...",
44
- { replyTo: msg },
45
- );
38
+ const status = await createStatus(sock, msg.key.remoteJid, "🔗 بختصر الرابط...", {
39
+ replyTo: msg,
40
+ });
46
41
 
47
42
  try {
48
43
  // 4. Make the GET request to the API
@@ -51,20 +46,17 @@ module.exports = {
51
46
  // 5. The API returns the shortened URL as plain text in the response body
52
47
  const shortUrl = response.data;
53
48
 
54
- const reply =
55
- `✅ تم اختصار الرابط بنجاح!\n\n` + `🔗 *الرابط المختصر:*\n${shortUrl}`;
49
+ const reply = `✅ تم اختصار الرابط بنجاح!\n\n` + `🔗 *الرابط المختصر:*\n${shortUrl}`;
56
50
 
57
51
  await status.finish(reply);
58
52
  } catch (error) {
59
53
  logger.error(
60
54
  error.response ? error.response.data : error.message,
61
- "[Error] in !shortlink command:"
55
+ "[Error] in !shortlink command:",
62
56
  );
63
57
 
64
58
  // The API returns a plain text error message if something goes wrong
65
- const errorMessage = error.response
66
- ? error.response.data
67
- : "حدث خطأ غير متوقع.";
59
+ const errorMessage = error.response ? error.response.data : "حدث خطأ غير متوقع.";
68
60
 
69
61
  await sock.sendMessage(msg.key.remoteJid, {
70
62
  text: `*عذرًا، حدث خطأ:*\n\n` + `\`\`\`${errorMessage}\`\`\``,
@@ -31,7 +31,7 @@ module.exports = {
31
31
  err: error.message,
32
32
  stderr: stderr,
33
33
  },
34
- `Failed to execute shutdown command: ${commandToExecute}`
34
+ `Failed to execute shutdown command: ${commandToExecute}`,
35
35
  );
36
36
 
37
37
  // We can't reliably send a message here because the process might be stopping.