Telegram Bot + Solana: The Complete Developer Guide
Telegram Bot + Solana: The Complete Developer Guide
Telegram bots are the backbone of crypto tooling on Solana. From token scanners to copy-trading bots, most tools traders use daily run inside Telegram. Here's how to build one from scratch.
Why Telegram?
Telegram is where crypto lives. Over 80% of Solana degens check Telegram before Twitter. Building a bot here means:
- Instant distribution — users find you via search or group shares
- No app store approval — deploy and iterate in minutes
- Rich UI — inline keyboards, callbacks, formatted messages
- Always-on — users interact 24/7, your bot runs on a $5 VPS
Prerequisites
- Node.js 18+
- A Telegram bot token (get one from @BotFather)
- Basic familiarity with
@solana/web3.js
Step 1: Set Up the Bot
const https = require('https');
const { Connection, PublicKey } = require('@solana/web3.js');
const BOT_TOKEN = 'YOUR_BOT_TOKEN';
const API_BASE = `https://api.telegram.org/bot${BOT_TOKEN}`;
const connection = new Connection('https://api.mainnet-beta.solana.com');
let offset = 0;
async function getUpdates() {
const url = `${API_BASE}/getUpdates?offset=${offset}&timeout=30`;
const res = await fetch(url);
const data = await res.json();
for (const update of data.result || []) {
offset = update.update_id + 1;
if (update.message?.text) {
await handleMessage(update.message);
}
}
}
Long polling is simpler than webhooks for getting started. You call getUpdates in a loop and Telegram sends you new messages.
Step 2: Handle Commands
async function handleMessage(msg) {
const chatId = msg.chat.id;
const text = msg.text.trim();
if (text === '/start') {
await sendMessage(chatId, 'Welcome! Paste any Solana token address to scan it.');
return;
}
// Check if it looks like a Solana address
if (/^[1-9A-HJ-NP-Za-km-z]{32,44}$/.test(text)) {
await scanToken(chatId, text);
return;
}
await sendMessage(chatId, 'Send a Solana token address to get started.');
}
async function sendMessage(chatId, text, options = {}) {
await fetch(`${API_BASE}/sendMessage`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
chat_id: chatId,
text,
parse_mode: 'Markdown',
...options,
}),
});
}
Step 3: Add Solana Integration
const { getMint } = require('@solana/spl-token');
async function scanToken(chatId, address) {
try {
const mint = new PublicKey(address);
const mintInfo = await getMint(connection, mint);
const holders = await connection.getTokenLargestAccounts(mint);
const risks = [];
if (mintInfo.mintAuthority) risks.push('Mint authority active');
if (mintInfo.freezeAuthority) risks.push('Freeze authority active');
const top10 = holders.value.slice(0, 10);
const concentration = top10.reduce((s, h) => s + Number(h.amount), 0)
/ Number(mintInfo.supply) * 100;
if (concentration > 80) risks.push(`Top 10 hold ${concentration.toFixed(0)}%`);
const score = Math.max(0, 100 - risks.length * 30);
const emoji = score >= 70 ? '🟢' : score >= 40 ? '🟡' : '🔴';
let response = `${emoji} *Safety Score: ${score}/100*\n\n`;
if (risks.length > 0) {
response += '*Risks Found:*\n' + risks.map(r => `- ${r}`).join('\n');
} else {
response += 'No major risks detected.';
}
await sendMessage(chatId, response);
} catch (err) {
await sendMessage(chatId, `Error scanning token: ${err.message}`);
}
}
Step 4: Add Inline Keyboards
Inline keyboards make your bot interactive — users tap buttons instead of typing commands.
async function sendTokenResult(chatId, address, score) {
await sendMessage(chatId, `Score: ${score}/100`, {
reply_markup: JSON.stringify({
inline_keyboard: [
[
{ text: 'Buy Token', callback_data: `buy_${address}` },
{ text: 'Set Alert', callback_data: `alert_${address}` },
],
[
{ text: 'View Holders', callback_data: `holders_${address}` },
],
],
}),
});
}
Step 5: Run Continuously
async function main() {
console.log('Bot started...');
while (true) {
try {
await getUpdates();
} catch (err) {
console.error('Polling error:', err.message);
await new Promise(r => setTimeout(r, 5000));
}
}
}
main();
Production Considerations
- Rate limiting — Solana public RPC has limits. Use Helius or QuickNode for production.
- User state — Store user settings in a JSON file or SQLite database.
- Error handling — Wrap every RPC call in try/catch. Solana is flaky.
- Concurrency — Process multiple users simultaneously with Promise.all.
- Deployment — Use PM2 on a VPS:
pm2 start bot.js --name solana-bot.
Skip the Build — Use What Already Exists
Building a Telegram bot from scratch takes weeks of iteration. @solscanitbot already has 44 commands including token scanning, trading via Jupiter, copy-trading, DCA, limit orders, whale alerts, and more.
It took 4500+ lines of pure Node.js and months of development. Try it free: t.me/solscanitbot
Want the source code? Check out devtools-site-delta.vercel.app/sol-bot-source for the full bot codebase.