Building Telegram Mini Apps with React and Bot Integration

Telegram Mini Apps (formerly WebApps) let you create rich web applications that run directly within Telegram. They’re perfect for adding interactive features to your Telegram bot, from simple forms to complex interfaces. Let’s build one using React!

Prerequisites

Creating Your Bot

  1. Message @BotFather on Telegram
  2. Use /newbot to create a new bot
  3. Enable Mini Apps:
    /mybots → Your Bot → Bot Settings → Menu Button → Configure Menu Button
    
  4. Save your bot token - you’ll need it later

Setting Up the React Project

Create a new React project using Vite and install the necessary dependencies:

npm create vite@latest telegram-mini-app -- --template react
cd telegram-mini-app
npm install @twa-dev/sdk
npm install

Initializing the Mini App

Create src/telegram.js to handle Telegram-specific functionality:

import WebApp from '@twa-dev/sdk';

export const initTelegramApp = () => {
  WebApp.enableClosingConfirmation();
  WebApp.setHeaderColor('#2481cc');
  WebApp.setBackgroundColor('#ffffff');
  
  // Ready event
  WebApp.ready();
};

export const getUserData = () => {
  return WebApp.initDataUnsafe?.user || null;
};

export const sendDataToBot = (data) => {
  WebApp.sendData(JSON.stringify(data));
};

export const closeApp = () => {
  WebApp.close();
};

Building the React Interface

Update your App.jsx with a basic interface:

import { useEffect, useState } from 'react';
import { initTelegramApp, getUserData, sendDataToBot, closeApp } from './telegram';
import './App.css';

function App() {
  const [user, setUser] = useState(null);
  const [message, setMessage] = useState('');

  useEffect(() => {
    initTelegramApp();
    setUser(getUserData());
  }, []);

  const handleSubmit = (e) => {
    e.preventDefault();
    sendDataToBot({ message });
    closeApp();
  };

  return (
    <div className="app">
      <header>
        <h1>Mini App Demo</h1>
        {user && <p>Welcome, {user.first_name}!</p>}
      </header>

      <main>
        <form onSubmit={handleSubmit}>
          <textarea
            value={message}
            onChange={(e) => setMessage(e.target.value)}
            placeholder="Enter your message..."
          />
          <button type="submit">Send to Bot</button>
        </form>
      </main>
    </div>
  );
}

export default App;

Add some basic styling in App.css:

.app {
  max-width: 600px;
  margin: 0 auto;
  padding: 20px;
}

form {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

textarea {
  padding: 12px;
  border: 1px solid #ddd;
  border-radius: 8px;
  min-height: 100px;
}

button {
  padding: 12px 24px;
  background: #2481cc;
  color: white;
  border: none;
  border-radius: 8px;
  cursor: pointer;
}

button:hover {
  background: #1a6dad;
}

Creating the Bot Backend

Create a new directory for your bot and initialize it:

mkdir telegram-bot
cd telegram-bot
npm init -y
npm install node-telegram-bot-api express cors

Create server.js:

const TelegramBot = require('node-telegram-bot-api');
const express = require('express');
const cors = require('cors');

const token = 'YOUR_BOT_TOKEN';
const webAppUrl = 'YOUR_MINI_APP_URL'; // After deployment

const bot = new TelegramBot(token, { polling: true });
const app = express();

app.use(cors());
app.use(express.json());

// Handle /start command
bot.onText(/\/start/, (msg) => {
  const chatId = msg.chat.id;
  
  bot.sendMessage(chatId, 'Welcome! Try our Mini App:', {
    reply_markup: {
      keyboard: [[{
        text: 'Open Mini App',
        web_app: { url: webAppUrl }
      }]],
      resize_keyboard: true
    }
  });
});

// Handle Mini App data
bot.on('web_app_data', async (msg) => {
  const chatId = msg.chat.id;
  const data = JSON.parse(msg.web_app_data.data);
  
  await bot.sendMessage(chatId, `Received: ${data.message}`);
});

// Start the server
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
});

Deployment

  1. Deploy your React app to a static hosting service (like Vercel or Netlify)
  2. Deploy your bot to a hosting service (like Heroku or DigitalOcean)
  3. Update webAppUrl in your bot code with the deployed Mini App URL
  4. Update your bot’s menu button with the same URL through BotFather

Security Considerations

Always validate incoming data from Telegram. Here’s a validation helper:

const crypto = require('crypto');

function validateTelegramData(initData, botToken) {
  const secret = crypto
    .createHmac('sha256', 'WebAppData')
    .update(botToken)
    .digest();

  const data = Object.fromEntries(new URLSearchParams(initData));
  const checkString = Object.keys(data)
    .filter(key => key !== 'hash')
    .sort()
    .map(key => `${key}=${data[key]}`)
    .join('\n');

  const hash = crypto
    .createHmac('sha256', secret)
    .update(checkString)
    .digest('hex');

  return hash === data.hash;
}

Testing Your Mini App

  1. Start a chat with your bot
  2. Click the “Open Mini App” button
  3. Enter a message and submit
  4. Verify that your bot receives and responds to the message

Best Practices

  1. Performance: Keep your bundle size small and optimize images
  2. Error Handling: Implement proper error boundaries and user feedback
  3. UI/UX: Follow Telegram’s design guidelines for a native feel
  4. Security: Always validate incoming data and use HTTPS
  5. State Management: Use React Context for complex state if needed

Conclusion

You now have a working Telegram Mini App integrated with a bot! This foundation can be extended to create more complex applications like games, forms, or interactive tools. Check the official documentation for more features and capabilities.

MirzoDev

© 2024 MirzoDev

Email Telegram GitHub