Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 26 additions & 3 deletions packages/bot/src/adapters/discord.ts
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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...");

Expand Down Expand Up @@ -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 <assetCode> [issuerDomain|issuerAddress]\nExample: !trustline USDC circle.com');
Expand Down
17 changes: 14 additions & 3 deletions packages/bot/src/adapters/telegram.ts
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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)\n<i>Real balance integration coming soon!</i>', { 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 <assetCode> [issuerDomain|issuerAddress]\nExample: /trustline USDC circle.com');
Expand Down Expand Up @@ -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.");
}
Expand Down
37 changes: 37 additions & 0 deletions packages/bot/src/commands.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**
* Command aliases mapping
* Maps base commands to their supported shorter or localized versions
*/
export const COMMAND_ALIASES: Record<string, string[]> = {
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;
}