Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Telesp

Beta — ESP32-based Telegram bot with a web dashboard for managing custom commands, API integration, media attachments, and inline keyboards.

Telesp turns an ESP32 into a full-featured Telegram bot. Manage everything through a clean web interface — no coding required after initial flash.


Features

  • Custom Commands — Create any /command with a custom reply
  • API Integration — Call any REST API when a command is invoked, use response data in replies
  • Placeholder System — Dynamic placeholders: {first_name}, {query}, {time}, {response:key.path}, {eval:expression}
  • Media Attachments — Send photos, videos, documents, or audio from URLs
  • Inline Buttons — URL buttons and callback buttons with placeholder support
  • Web Dashboard — Full management UI served directly from the ESP32
  • Wi-Fi Setup Wizard — First-boot AP mode with step-by-step browser setup
  • NTP Sync — Real-time clock for date/time placeholders
  • OTA Configurable — All settings changeable from the dashboard (timezone, Wi-Fi, bot token)
  • Import/Export — Full config import via JSON file

Hardware Requirements

Component Requirement
Board ESP32-C3 (ESP32-C3-DevKitM-1)
Flash 4MB+
PSRAM Not required
Power USB-C (5V)

ESP32 (Xtensa) variants should also work with minor platform changes.


Quick Start

1. Build & Flash

# Clone or copy the project
cd telesp

# Build firmware
pio run

# Upload firmware
pio run --target upload

# Upload filesystem (web UI files)
pio run --target uploadfs

2. Connect to the Setup Portal

  1. Power the ESP32 via USB
  2. On first boot, it creates a Wi-Fi AP named ESP32_Bot_Setup
  3. Connect your phone/laptop to that network
  4. Open http://192.168.4.1 in a browser

3. Setup Wizard

Step 1 — Wi-Fi: Select your network, enter password, click Connect. Wait for the ESP to join your network.

Step 2 — Telegram: Create a bot via @BotFather on Telegram, copy the token, paste it into the wizard. The ESP verifies the token automatically.

Step 3 — Done: Configuration is saved and the ESP reboots. After reboot, the dashboard loads at the ESP's IP on your local network.


Dashboard

The web dashboard has three tabs:

Info

  • Wi-Fi signal strength, uptime, free memory, IP address
  • Bot online/offline status
  • Live system logs with auto-scroll

Commands

  • List of all registered commands
  • Add / Edit — opens the command editor modal
  • Delete — removes a command

Command Editor

Field Description
Command Trigger Must start with / (e.g., /weather)
Reply Text Message the bot sends; supports placeholders
API URL (optional) REST endpoint called when command runs; supports placeholders
Media Type (optional) photo, video, document, or audio
Media URL (optional) Direct URL of the media file
Inline Buttons (optional) Array of buttons with text and URL or callback data

API Test — Click "Test" to call the API URL directly from the browser. The response JSON is parsed and clickable {response:...} placeholders are generated automatically.

Settings

  • Timezone — UTC offset for {time} / {date} placeholders (UTC-12 to UTC+14)
  • Bot Token — Change token (triggers reboot)
  • Wi-Fi — Change network (reconnects immediately)
  • Import Config — Upload a complete config.json file (overwrites all settings, reboots)

Sidebar Controls

  • Start / Stop — Pause or resume the bot
  • Restart — Reboot the ESP32
  • Factory Reset — Delete all settings and restart fresh

Placeholder System

Standard Placeholders

Placeholder Resolves to
{message} Full incoming message text
{sender} Sender's username or ID
{first_name} Sender's first name
{last_name} Sender's last name
{full_name} first_name + " " + last_name
{command} The matched command (e.g., /weather)
{query} Everything after the command
{chatid} Numeric chat ID
{time} Current time (HH:MM:SS) — NTP-synced
{date} Current date (YYYY-MM-DD) — NTP-synced
{uptime} ESP32 uptime (e.g., 2d 4h 30m)

API Response Placeholders

After the bot calls an API URL, the response JSON is parsed and accessible via {response:key.path}:

// API returns:
{ "main": { "temp": 28.5 }, "weather": [{ "description": "clear sky" }] }

// Reply template:
Temp: {response:main.temp}°C, {response:weather.0.description}
// Result:
Temp: 28.5°C, clear sky
  • Arrays are indexed with .0, .1, etc.
  • Nested objects use dot notation: response:user.address.city

Math Expressions

Use {eval:expression} for basic arithmetic:

{eval:{query}*2+5}
{eval:({first_name} == "admin" ? 1 : 0)}

Supports +, -, *, / and parentheses.

Processing Order

  1. API URL placeholders are replaced (before the API call)
  2. API is called, response JSON is fetched
  3. {response:...} placeholders in the reply are resolved
  4. Standard placeholders ({first_name}, {query}, etc.) and {eval:...} are resolved

Inline Buttons

Buttons support URL links and callback data:

[
  { "text": "Open Website", "url": "https://example.com" },
  { "text": "Run Command", "callback_data": "/status" }
]

All button fields (text, url, callback_data) support every placeholder type including {response:...}.

When a callback button is tapped, the bot processes the callback_data as if it were a new text command — including API calls, media, and nested buttons.


Media Attachments

Set media_type and media_url on any command to send media instead of plain text:

media_type Sent as
photo sendPhoto
video sendVideo
document sendDocument
audio sendAudio

The reply text becomes the media caption. All placeholders work in both the URL and the caption. Buttons can be attached to media messages.


Configuration File (/config.json)

{
  "wifi_ssid": "MyNetwork",
  "wifi_pass": "password123",
  "bot_token": "123456789:ABCdef...",
  "bot_username": "MyBot",
  "setup_done": true,
  "timezone_offset": 420,
  "commands": [
    {
      "cmd": "/start",
      "reply": "Hello {first_name}!",
      "api_url": "",
      "media_url": "",
      "media_type": "",
      "buttons": []
    }
  ]
}

Web API Endpoints

Method Path Description
GET /api/info System info (WiFi, uptime, memory, bot status)
GET /api/commands List all commands
POST /api/commands/save Create/update a command
POST /api/commands/delete Delete a command
GET /api/logs System log buffer
GET /api/settings Get timezone, bot username
POST /api/settings Save timezone/bot token
POST /api/settings/wifi Change Wi-Fi credentials
POST /api/settings/import Import full config JSON
POST /api/reboot Reboot ESP32
POST /api/reset Factory reset
POST /api/bot/toggle Start/stop the bot
GET /api/wifi/scan Scan available networks
POST /api/setup/wifi Setup step 1: Wi-Fi
GET /api/setup/status Setup step 1: poll status
POST /api/setup/telegram Setup step 2: verify token

Building from Source

Prerequisites

Commands

# Build firmware
pio run

# Upload firmware
pio run --target upload

# Upload filesystem (web UI)
pio run --target uploadfs

# Both at once
pio run --target upload --target uploadfs

# Serial monitor
pio device monitor -b 115200

Project Structure

telesp/
├── platformio.ini          # Build configuration
├── src/
│   ├── main.cpp            # Entry point, WiFi, config, task spawning
│   ├── telegram.cpp        # Telegram bot logic (800 lines)
│   ├── webserver.cpp       # Web server handlers (410 lines)
│   ├── commands.cpp        # Command CRUD operations
│   └── logging.cpp         # Circular log buffer
├── include/
│   ├── config.h            # Global variable declarations
│   ├── telegram.h
│   ├── webserver.h
│   ├── commands.h
│   └── logging.h
└── data/                   # Web UI (uploaded to LittleFS)
    ├── dashboard.html
    ├── dashboard.js
    ├── setup.html
    ├── setup.js
    └── style.css

Platform Config

[env:esp32-c3-devkitm-1]
platform = espressif32
board = esp32-c3-devkitm-1
framework = arduino
board_build.filesystem = littlefs
monitor_speed = 115200
build_flags =
    -D ARDUINO_USB_MODE=1
    -D ARDUINO_USB_CDC_ON_BOOT=1
lib_deps =
    bblanchon/ArduinoJson @ ^7.0.4

Technical Notes

  • Threading: The bot runs on Core 0 as a FreeRTOS task (30KB stack). The web server runs on the main loop.
  • Connection: Single persistent TLS connection to api.telegram.org:443 with keep-alive.
  • Polling: Long-polling getUpdates (timeout=3s, limit=1, offset-based).
  • API Calls: Per-command HTTP requests use HTTPClient with WiFiClientSecure (8s timeout).
  • Concurrency: commands_mutex protects the shared command cache; logMutex protects the log buffer.
  • Migration: Old /commands.json files are automatically migrated to /config.json on boot.

Troubleshooting

Problem Likely Cause Fix
ESP doesn't show setup AP Already configured Hold reset button or trigger factory reset
Bot doesn't respond Token invalid or bot paused Check token in Settings tab; check bot_status in Info tab
{response:...} not working API response too large or key path wrong Test API from dashboard to verify response structure
Serial gibberish Wrong baud rate Use pio device monitor -b 115200
Web UI not loading Filesystem not uploaded Run pio run --target uploadfs

Feedback & Contributing

Telesp is in beta — bugs are expected, and feedback is welcome.

Report a Bug / Request a Feature

When reporting a bug, please include:

  • ESP32 board model
  • PlatformIO build logs (if applicable)
  • Serial monitor output showing the error
  • Steps to reproduce
  • Expected vs actual behavior

Contribute

  1. Fork the repository
  2. Create a feature branch (git checkout -b feat/my-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin feat/my-feature)
  5. Open a Pull Request

Please keep code style consistent with the existing codebase (same indentation, naming conventions, etc.).


License

MIT

About

ESP32-based Telegram bot with a web dashboard for managing custom commands, API integration, media attachments, and inline keyboards.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages