diff --git a/packages/bot/src/adapters/discord.ts b/packages/bot/src/adapters/discord.ts index 57adb559..089cd2e9 100644 --- a/packages/bot/src/adapters/discord.ts +++ b/packages/bot/src/adapters/discord.ts @@ -1,6 +1,9 @@ import { Client, GatewayIntentBits, Message, TextChannel } from 'discord.js'; import { TransactionNotificationData } from './types'; import { createTrustlineOperation } from '@chen-pilot/sdk-core'; +import { normalizeCommand } from '../commands'; + +const BACKEND_URL = process.env.BACKEND_URL || 'http://localhost:3000'; export class DiscordAdapter { private client: Client; @@ -32,13 +35,33 @@ export class DiscordAdapter { this.client.on("messageCreate", async (message: Message) => { if (message.author.bot) return; - if (message.content === "!start") { + // Handle both !command and /command for consistency + if (!message.content.startsWith('!') && !message.content.startsWith('/')) return; + + const command = normalizeCommand(message.content); + + if (command === "start") { await message.reply( "Welcome to Chen Pilot! I am your AI-powered Stellar DeFi assistant." ); } - if (message.content === "!sponsor") { + if (command === "help") { + await message.reply( + "**Commands:** !start, !balance, !swap, !trustline, !sponsor\n\n" + + "You can also use short aliases like !b for balance, !t for trustline, etc." + ); + } + + if (command === "balance") { + await message.reply("💰 Your balance: 100 XLM (Placeholder)\n*Real balance integration coming soon!*"); + } + + if (command === "swap") { + await message.reply("🔄 Swap functionality is coming soon!"); + } + + if (command === "sponsor") { const userId = message.author.id; await message.reply("⏳ Requesting account sponsorship..."); @@ -71,7 +94,7 @@ export class DiscordAdapter { } } - if (message.content.startsWith('!trustline')) { + if (command === "trustline") { const args = message.content.split(' ').slice(1); if (args.length < 1) { return message.reply('Usage: !trustline [issuerDomain|issuerAddress]\nExample: !trustline USDC circle.com'); diff --git a/packages/bot/src/adapters/telegram.ts b/packages/bot/src/adapters/telegram.ts index 27ac4804..15fff2ff 100644 --- a/packages/bot/src/adapters/telegram.ts +++ b/packages/bot/src/adapters/telegram.ts @@ -1,6 +1,7 @@ import { Telegraf } from 'telegraf'; import { TransactionNotificationData } from './types'; import { createTrustlineOperation } from '@chen-pilot/sdk-core'; +import { getAliases } from '../commands'; export class TelegramAdapter { private bot: Telegraf | undefined; @@ -19,10 +20,15 @@ export class TelegramAdapter { this.bot = new Telegraf(this.token); - this.bot.start((ctx) => ctx.reply('Welcome to Chen Pilot! I am your AI-powered Stellar DeFi assistant.')); - this.bot.help((ctx) => ctx.reply('Commands: /start, /balance, /swap, /trustline')); + this.bot.command(getAliases('start'), (ctx) => ctx.reply('Welcome to Chen Pilot! I am your AI-powered Stellar DeFi assistant.')); + this.bot.command(getAliases('help'), (ctx) => ctx.reply('Commands: /start, /balance, /swap, /trustline\n\nYou can also use short aliases like /b for balance, /t for trustline, etc.')); - this.bot.command('trustline', async (ctx) => { + // Balance command alias support + this.bot.command(getAliases('balance'), async (ctx) => { + await ctx.reply('💰 Your balance: 100 XLM (Placeholder)\nReal balance integration coming soon!', { parse_mode: 'HTML' }); + }); + + this.bot.command(getAliases('trustline'), async (ctx) => { const args = ctx.message.text.split(' ').slice(1); if (args.length < 1) { return ctx.reply('Usage: /trustline [issuerDomain|issuerAddress]\nExample: /trustline USDC circle.com'); @@ -53,6 +59,11 @@ export class TelegramAdapter { } }); + // Swap command alias support + this.bot.command(getAliases('swap'), async (ctx) => { + await ctx.reply('🔄 Swap functionality is coming soon!', { parse_mode: 'HTML' }); + }); + this.bot.launch(); console.log("✅ Telegram bot initialized."); } diff --git a/packages/bot/src/commands.ts b/packages/bot/src/commands.ts new file mode 100644 index 00000000..cadf1c68 --- /dev/null +++ b/packages/bot/src/commands.ts @@ -0,0 +1,37 @@ +/** + * Command aliases mapping + * Maps base commands to their supported shorter or localized versions + */ +export const COMMAND_ALIASES: Record = { + start: ['start', 's', 'inicio'], + balance: ['balance', 'b', 'bal', 'saldo'], + trustline: ['trustline', 't', 'tl', 'confianza'], + sponsor: ['sponsor', 'sp', 'patrocinio'], + swap: ['swap', 'sw', 'intercambio'], + help: ['help', 'h', 'ayuda'], +}; + +/** + * Gets all aliases for a base command including the base command itself + */ +export function getAliases(baseCommand: string): string[] { + return COMMAND_ALIASES[baseCommand] || [baseCommand]; +} + +/** + * Normalizes a command string by removing the prefix and resolving aliases + */ +export function normalizeCommand(commandText: string): string { + if (!commandText) return ''; + + // Remove prefix (/ for Telegram, ! for Discord) and convert to lowercase + const cleanCommand = commandText.trim().toLowerCase().replace(/^[\/!]/, '').split(' ')[0]; + + for (const [base, aliases] of Object.entries(COMMAND_ALIASES)) { + if (base === cleanCommand || aliases.includes(cleanCommand)) { + return base; + } + } + + return cleanCommand; +}