diff --git a/src/bot/bot.js b/src/bot/bot.js
index 8ce99f4..9bee0f8 100644
--- a/src/bot/bot.js
+++ b/src/bot/bot.js
@@ -1,5 +1,4 @@
import { createTelegramApi } from './telegram-api.js';
-import { createInfoCommand } from './commands/info.js';
import { createAddGroupCommand } from './commands/add-group.js';
import { createDeleteGroupCommand } from './commands/delete-group.js';
import { createListGroupCommand } from './commands/list-group.js';
@@ -13,7 +12,6 @@ import { createCheckAppScoresCommand } from './commands/check-app-scores.js';
import { createRawAppleAppCommand } from './commands/raw-apple-app.js';
import { createRawGoogleAppCommand } from './commands/raw-google-app.js';
-// HTML parse mode for all messages (Java parity).
const PARSE_MODE = 'HTML';
export function createBot(config, store, appleScraper, googleScraper) {
@@ -51,9 +49,14 @@ export function createBot(config, store, appleScraper, googleScraper) {
},
};
- // Java command identifiers — keep names matching exactly.
const commands = {
- info: createInfoCommand(),
+ info: async (msg, sender, args) => {
+ if (args.length !== 0) {
+ await sender.sendMessage(msg.chat.id, 'Invalid arguments');
+ return;
+ }
+ await sender.sendMessage(msg.chat.id, `Id của nhóm là ${msg.chat.id}\n`);
+ },
addgroup: createAddGroupCommand(config, store),
delgroup: createDeleteGroupCommand(config, store),
listgroup: createListGroupCommand(config, store),
diff --git a/src/bot/commands/add-apple-app.js b/src/bot/commands/add-apple-app.js
index dc2fe93..7d649de 100644
--- a/src/bot/commands/add-apple-app.js
+++ b/src/bot/commands/add-apple-app.js
@@ -1,11 +1,10 @@
import { buildAppleRequestByBundleId, buildAppleRequestByTrackId } from '../../api/apple-scraper.js';
-import { authorizeGroup, getCommandArguments, splitArgs } from './command-utils.js';
+import { authorizeGroup } from './command-utils.js';
-// /addapple [country=vn] — Java AddAppleAppCommand.
+// /addapple [country=vn]
export function createAddAppleAppCommand(store, appleScraper) {
- return async (msg, sender) => {
+ return async (msg, sender, args) => {
if (!(await authorizeGroup(msg.chat.id, store, sender))) return;
- const args = splitArgs(getCommandArguments(msg.text));
if (args.length < 1 || args.length > 2) {
await sender.sendMessage(msg.chat.id, 'Invalid arguments');
return;
diff --git a/src/bot/commands/add-google-app.js b/src/bot/commands/add-google-app.js
index 29b2fec..b9bcc52 100644
--- a/src/bot/commands/add-google-app.js
+++ b/src/bot/commands/add-google-app.js
@@ -1,11 +1,10 @@
import { buildGoogleRequest } from '../../api/google-scraper.js';
-import { authorizeGroup, getCommandArguments, splitArgs } from './command-utils.js';
+import { authorizeGroup } from './command-utils.js';
-// /addgoogle [country=vn] — Java AddGoogleAppCommand.
+// /addgoogle [country=vn]
export function createAddGoogleAppCommand(store, googleScraper) {
- return async (msg, sender) => {
+ return async (msg, sender, args) => {
if (!(await authorizeGroup(msg.chat.id, store, sender))) return;
- const args = splitArgs(getCommandArguments(msg.text));
if (args.length < 1 || args.length > 2) {
await sender.sendMessage(msg.chat.id, 'Invalid arguments');
return;
diff --git a/src/bot/commands/add-group.js b/src/bot/commands/add-group.js
index 34e0513..e692a77 100644
--- a/src/bot/commands/add-group.js
+++ b/src/bot/commands/add-group.js
@@ -1,10 +1,9 @@
-import { getCommandArguments, requireAdminUser, splitArgs } from './command-utils.js';
+import { requireAdminUser } from './command-utils.js';
-// /addgroup [groupId] — Java AddGroupCommand. Admin-only.
+// /addgroup [groupId] — admin-only. Defaults to current chat.
export function createAddGroupCommand(config, store) {
- return async (msg, sender) => {
+ return async (msg, sender, args) => {
if (!(await requireAdminUser(msg.from.id, msg.chat.id, config, sender))) return;
- const args = splitArgs(getCommandArguments(msg.text));
if (args.length > 1) {
await sender.sendMessage(msg.chat.id, 'Invalid arguments');
return;
diff --git a/src/bot/commands/check-app-scores.js b/src/bot/commands/check-app-scores.js
index 56acd37..9162d9e 100644
--- a/src/bot/commands/check-app-scores.js
+++ b/src/bot/commands/check-app-scores.js
@@ -1,12 +1,11 @@
import { buildTable } from '../../util/table.js';
-import { authorizeGroup, getCommandArguments, splitArgs } from './command-utils.js';
+import { authorizeGroup } from './command-utils.js';
-// /checkappscore — Java CheckAppScoreCommand. Reports score + ratings.
-// Score rounded to 1 decimal (Java Precision.round(score, 1) parity).
+// /checkappscore — reports score + ratings. Score rounded to 1 decimal.
export function createCheckAppScoresCommand(store, appleScraper, googleScraper) {
- return async (msg, sender) => {
+ return async (msg, sender, args) => {
if (!(await authorizeGroup(msg.chat.id, store, sender))) return;
- if (splitArgs(getCommandArguments(msg.text)).length !== 0) {
+ if (args.length !== 0) {
await sender.sendMessage(msg.chat.id, 'Invalid arguments');
return;
}
diff --git a/src/bot/commands/check-app.js b/src/bot/commands/check-app.js
index c4fc550..fdb6024 100644
--- a/src/bot/commands/check-app.js
+++ b/src/bot/commands/check-app.js
@@ -1,12 +1,12 @@
import { buildTable } from '../../util/table.js';
import { daysBetween, formatDateInTz } from '../../util/time.js';
-import { authorizeGroup, getCommandArguments, splitArgs } from './command-utils.js';
+import { authorizeGroup } from './command-utils.js';
-// /checkapp — Java CheckAppCommand. Reports update status per app, per store.
+// /checkapp — reports update status per app, per store.
export function createCheckAppCommand(config, store, appleScraper, googleScraper) {
- return async (msg, sender) => {
+ return async (msg, sender, args) => {
if (!(await authorizeGroup(msg.chat.id, store, sender))) return;
- if (splitArgs(getCommandArguments(msg.text)).length !== 0) {
+ if (args.length !== 0) {
await sender.sendMessage(msg.chat.id, 'Invalid arguments');
return;
}
diff --git a/src/bot/commands/command-utils.js b/src/bot/commands/command-utils.js
index 223a39b..63ba5fb 100644
--- a/src/bot/commands/command-utils.js
+++ b/src/bot/commands/command-utils.js
@@ -1,17 +1,3 @@
-export function splitArgs(text) {
- if (!text) return [];
- return text.trim().split(/\s+/).filter((s) => s.length > 0);
-}
-
-// Strips the "/" or "/@botname" prefix from message.text.
-export function getCommandArguments(text) {
- if (!text) return '';
- const trimmed = text.trim();
- const space = trimmed.indexOf(' ');
- if (space < 0) return '';
- return trimmed.slice(space + 1).trim();
-}
-
export async function authorizeGroup(chatId, store, sender) {
try {
const ok = await store.admin.hasGroup(chatId);
diff --git a/src/bot/commands/delete-apple-app.js b/src/bot/commands/delete-apple-app.js
index e970db3..37c8262 100644
--- a/src/bot/commands/delete-apple-app.js
+++ b/src/bot/commands/delete-apple-app.js
@@ -1,10 +1,9 @@
-import { authorizeGroup, getCommandArguments, splitArgs } from './command-utils.js';
+import { authorizeGroup } from './command-utils.js';
-// /delapple — Java DeleteAppleAppCommand.
+// /delapple
export function createDeleteAppleAppCommand(store) {
- return async (msg, sender) => {
+ return async (msg, sender, args) => {
if (!(await authorizeGroup(msg.chat.id, store, sender))) return;
- const args = splitArgs(getCommandArguments(msg.text));
if (args.length !== 1) {
await sender.sendMessage(msg.chat.id, 'Invalid arguments');
return;
diff --git a/src/bot/commands/delete-google-app.js b/src/bot/commands/delete-google-app.js
index f9ecc1a..32537fa 100644
--- a/src/bot/commands/delete-google-app.js
+++ b/src/bot/commands/delete-google-app.js
@@ -1,10 +1,9 @@
-import { authorizeGroup, getCommandArguments, splitArgs } from './command-utils.js';
+import { authorizeGroup } from './command-utils.js';
-// /delgoogle — Java DeleteGoogleAppCommand.
+// /delgoogle
export function createDeleteGoogleAppCommand(store) {
- return async (msg, sender) => {
+ return async (msg, sender, args) => {
if (!(await authorizeGroup(msg.chat.id, store, sender))) return;
- const args = splitArgs(getCommandArguments(msg.text));
if (args.length !== 1) {
await sender.sendMessage(msg.chat.id, 'Invalid arguments');
return;
diff --git a/src/bot/commands/delete-group.js b/src/bot/commands/delete-group.js
index 4778550..7e0bfb0 100644
--- a/src/bot/commands/delete-group.js
+++ b/src/bot/commands/delete-group.js
@@ -1,10 +1,9 @@
-import { getCommandArguments, requireAdminUser, splitArgs } from './command-utils.js';
+import { requireAdminUser } from './command-utils.js';
-// /delgroup [groupId] — Java DeleteGroupCommand. Admin-only.
+// /delgroup [groupId] — admin-only.
export function createDeleteGroupCommand(config, store) {
- return async (msg, sender) => {
+ return async (msg, sender, args) => {
if (!(await requireAdminUser(msg.from.id, msg.chat.id, config, sender))) return;
- const args = splitArgs(getCommandArguments(msg.text));
if (args.length > 1) {
await sender.sendMessage(msg.chat.id, 'Invalid arguments');
return;
diff --git a/src/bot/commands/info.js b/src/bot/commands/info.js
deleted file mode 100644
index 0caa790..0000000
--- a/src/bot/commands/info.js
+++ /dev/null
@@ -1,12 +0,0 @@
-import { getCommandArguments, splitArgs } from './command-utils.js';
-
-// /info — Java InfoCommand. Reports the chat (group) ID.
-export function createInfoCommand() {
- return async (msg, sender) => {
- if (splitArgs(getCommandArguments(msg.text)).length !== 0) {
- await sender.sendMessage(msg.chat.id, 'Invalid arguments');
- return;
- }
- await sender.sendMessage(msg.chat.id, `Id của nhóm là ${msg.chat.id}\n`);
- };
-}
diff --git a/src/bot/commands/list-app.js b/src/bot/commands/list-app.js
index 4119307..40e5671 100644
--- a/src/bot/commands/list-app.js
+++ b/src/bot/commands/list-app.js
@@ -1,11 +1,11 @@
import { buildTable } from '../../util/table.js';
-import { authorizeGroup, getCommandArguments, splitArgs } from './command-utils.js';
+import { authorizeGroup } from './command-utils.js';
-// /listapp — Java ListAppCommand. Two tables (Apple / Google) of tracked apps.
+// /listapp — two tables (Apple / Google) of tracked apps.
export function createListAppCommand(store) {
- return async (msg, sender) => {
+ return async (msg, sender, args) => {
if (!(await authorizeGroup(msg.chat.id, store, sender))) return;
- if (splitArgs(getCommandArguments(msg.text)).length !== 0) {
+ if (args.length !== 0) {
await sender.sendMessage(msg.chat.id, 'Invalid arguments');
return;
}
diff --git a/src/bot/commands/list-group.js b/src/bot/commands/list-group.js
index af70d72..47e134f 100644
--- a/src/bot/commands/list-group.js
+++ b/src/bot/commands/list-group.js
@@ -1,10 +1,10 @@
-import { getCommandArguments, requireAdminUser, splitArgs } from './command-utils.js';
+import { requireAdminUser } from './command-utils.js';
-// /listgroup — Java ListGroupCommand. Admin-only.
+// /listgroup — admin-only.
export function createListGroupCommand(config, store) {
- return async (msg, sender) => {
+ return async (msg, sender, args) => {
if (!(await requireAdminUser(msg.from.id, msg.chat.id, config, sender))) return;
- if (splitArgs(getCommandArguments(msg.text)).length !== 0) {
+ if (args.length !== 0) {
await sender.sendMessage(msg.chat.id, 'Invalid arguments');
return;
}
diff --git a/src/bot/commands/raw-apple-app.js b/src/bot/commands/raw-apple-app.js
index 2a2342a..82a62f0 100644
--- a/src/bot/commands/raw-apple-app.js
+++ b/src/bot/commands/raw-apple-app.js
@@ -1,11 +1,8 @@
import { buildAppleRequestByBundleId, buildAppleRequestByTrackId } from '../../api/apple-scraper.js';
-import { getCommandArguments, splitArgs } from './command-utils.js';
-// /rawappleapp [country=vn] — Java RawAppleAppCommand.
-// Sends raw upstream JSON as a Telegram document attachment.
+// /rawappleapp [country=vn] — sends raw upstream JSON as a document.
export function createRawAppleAppCommand(appleScraper) {
- return async (msg, sender) => {
- const args = splitArgs(getCommandArguments(msg.text));
+ return async (msg, sender, args) => {
if (args.length < 1 || args.length > 2) {
await sender.sendMessage(msg.chat.id, 'Invalid arguments');
return;
diff --git a/src/bot/commands/raw-google-app.js b/src/bot/commands/raw-google-app.js
index 73dd2c3..f3c3ddd 100644
--- a/src/bot/commands/raw-google-app.js
+++ b/src/bot/commands/raw-google-app.js
@@ -1,10 +1,8 @@
import { buildGoogleRequest } from '../../api/google-scraper.js';
-import { getCommandArguments, splitArgs } from './command-utils.js';
-// /rawgoogleapp [country=vn] — Java RawGoogleAppCommand.
+// /rawgoogleapp [country=vn]
export function createRawGoogleAppCommand(googleScraper) {
- return async (msg, sender) => {
- const args = splitArgs(getCommandArguments(msg.text));
+ return async (msg, sender, args) => {
if (args.length < 1 || args.length > 2) {
await sender.sendMessage(msg.chat.id, 'Invalid arguments');
return;
diff --git a/src/bot/dispatch.js b/src/bot/dispatch.js
index c3a809d..e5dcc52 100644
--- a/src/bot/dispatch.js
+++ b/src/bot/dispatch.js
@@ -4,8 +4,9 @@ export async function dispatch(message, deps) {
const { sender, commands, config, logger } = deps;
if (!message?.text || message.text[0] !== '/') return;
- const name = parseCommandName(message.text, config.telegramBotUsername);
- if (!name) return;
+ const parsed = parseCommand(message.text, config.telegramBotUsername);
+ if (!parsed) return;
+ const { name, args } = parsed;
const handler = commands[name];
if (!handler) {
@@ -18,7 +19,7 @@ export async function dispatch(message, deps) {
'Executing command',
);
try {
- await handler(message, sender);
+ await handler(message, sender, args);
} catch (err) {
logger.error({ err: err.message, command: name }, 'command failed');
try {
@@ -29,14 +30,22 @@ export async function dispatch(message, deps) {
}
}
-// Extracts "info" from "/info", "/info arg", "/info@bot", "/info@bot arg".
-function parseCommandName(text, botUsername) {
- const space = text.indexOf(' ');
- const head = space < 0 ? text.slice(1) : text.slice(1, space);
+// Extracts name + args from "/cmd", "/cmd arg", "/cmd@bot", "/cmd@bot arg".
+// Returns null if the @bot suffix targets a different bot.
+function parseCommand(text, botUsername) {
+ const trimmed = text.trim();
+ const space = trimmed.indexOf(' ');
+ const head = space < 0 ? trimmed.slice(1) : trimmed.slice(1, space);
+ const argText = space < 0 ? '' : trimmed.slice(space + 1).trim();
+
const at = head.indexOf('@');
- if (at < 0) return head;
- const cmd = head.slice(0, at);
- const target = head.slice(at + 1);
- if (botUsername && target && target.toLowerCase() !== botUsername.toLowerCase()) return null;
- return cmd;
+ let name = head;
+ if (at >= 0) {
+ name = head.slice(0, at);
+ const target = head.slice(at + 1);
+ if (botUsername && target && target.toLowerCase() !== botUsername.toLowerCase()) return null;
+ }
+
+ const args = argText ? argText.split(/\s+/) : [];
+ return { name, args };
}