Telegram Bot with Cloudflare Workers
Before diving in, make sure you've got a few things squared away!
This project assumes you're comfortable with typescript
or javascript
.
You'll also need Node.js
and npm
installed on your machine.
A good code editor, like VS Code
, is essential for development.
Lastly, you'll require both a Telegram
account and a Cloudflare
account – these will be necessary for the project's functionality.
With those prerequisites covered, you'll be well-prepared to move forward!
What is Telegram Bot?
A Telegram bot is essentially a special Telegram account operated by software, not a human. Think of it as a programmable assistant within the Telegram app. These bots can perform a wide array of tasks, from providing automated responses and delivering news updates to managing group chats, processing payments, and even integrating with other services.
You can interact with them through commands
, buttons
, or even natural language
, depending on how they're designed.
From there, you can issue commands or follow prompts to access its various functions.
The possibilities are vast, making Telegram bots powerful tools for automation, information delivery, and even entertainment.
1. Telegram BotFather
Alright, let's get started building our Telegram bot!
The first step is to head over to Telegram and find the ever-helpful BotFather
bot.
This bot is the key to unlocking your very own creation.
Once you've located it, follow the prompts to create a new bot.
Pay close attention during this process, as the BotFather
will give you a crucial piece of information: your bot's TOKEN
.
This unique token is like your bot's password, and you'll need it to connect your code to the Telegram API and get your bot up and running.
So, keep it safe and secure, because we'll be using it soon!
2. Telegram Grammy
Want to build your own grammY bot?
Look no further than grammY, a powerful framework for crafting bots with ease!
Supporting both TypeScript
and JavaScript
, grammY
runs seamlessly on Node.js
, Deno
, and even in the browser.
The simple example above showcases its straightforward nature:
import { Bot } from "grammy";
const bot = new Bot("YOUR_TELEGRAM_BOT_TOKEN"); // <-- put your bot token between the "" (https://t.me/BotFather)
// Reply to any message with "Hi there!".
bot.on("message", (ctx) => ctx.reply("Hi there!"));
bot.start();
with just a few lines of code, you can create a bot that responds to any message with "Hi there!".
All you need is your Telegram bot token (obtained from BotFather) and you're ready to start building something amazing.
grammY
makes bot development accessible and efficient, perfect for both beginners and experienced developers.
Create a Cloudflare Worker
Cloudflare Workers offer a powerful,
serverless environment to execute your code at the edge,
and the best part is, you can harness the power of TypeScript
for a cleaner and more robust development experience,
all for free within their generous free tier!
1. Cloudflare Workers Hono
Alright, let's kick things off with a taste of serverless magic!
We're diving into the world of Cloudflare Workers and the Hono framework to build something cool.
First things first, we need to get our hands dirty by installing wrangler
, Cloudflare's command-line tool.
Once that's done (a quick npm install -g wrangler will do the trick),
we'll create a fresh project called cftelegrambot
using wrangler init cftelegrambot
.
During the setup, be sure to pick the Framework Starter
option and select Hono
as our framework of choice.
npm install -g wrangler
wrangler init cftelegrambot
# the following output will be displayed
⛅️ wrangler 3.99.0
-------------------
Using npm as package manager.
The `init` command now delegates to `create-cloudflare` instead. You can use the `--no-c3` flag to access the old implementation.
🌀 Running `npm create cloudflare\@\^2.5.0 -- grambot`...
Need to install the following packages:
create-cloudflare@2.35.1
Ok to proceed? (y)
> npx
> create-cloudflare grambot
────────────────────────────────────────────────────
👋 Welcome to create-cloudflare v2.35.1!
🧡 Let's get started.
📊 Cloudflare collects telemetry about your
usage of Create-Cloudflare.
Learn more at: https://github.com/cloudflare/
workers-sdk/blob/main/packages/create-cloudflare/telemetry.md
───────────────────────────────────────────────────
╭ Create an application with Cloudflare Step 1 of 3
│
├ In which directory do you want to create your application?
│ dir ./grambot
│
├ What would you like to start with?
│ category Framework Starter
│
├ Which development framework do you want to use?
│ framework Hono
│
├ Continue with Hono via `npx create-hono@0.14.3
grambot --template cloudflare-workers --install --pm npm`
│
Need to install the following packages:
create-hono@0.14.3
Ok to proceed? (y) y
create-hono version 0.14.3
✔ Using target directory … grambot
✔ Cloning the template
├ Copying template files
│ files copied to project directory
│
├ Installing dependencies
│ installed via `npm install`
│
╰ Application created
╭ Configuring your application for Cloudflare Step 2 of 3
│
├ Installing @cloudflare/workers-types
│ installed via npm
│
├ Adding latest types to `tsconfig.json`
│ added @cloudflare/workers-types/2023-07-01
│
├ Retrieving current workerd compatibility date
│ compatibility date 2024-12-18
│
├ Updating `src/index.ts`
│ updated `src/index.ts`
│
├ Updating `package.json` scripts
│ updated `package.json`
│
├ Do you want to use git for version control?
│ yes git
│
├ Initializing git repo
│ initialized git
│
├ Committing new files
│ git commit
│
╰ Application configured
╭ Deploy with Cloudflare Step 3 of 3
│
├ Do you want to deploy your application?
│ no deploy via `npm run deploy`
│
╰ Done
────────────────────────────────────────────────────────────
🎉 SUCCESS Application created successfully!
💻 Continue Developing
Change directories: cd grambot
Start dev server: npm run dev
Deploy: npm run deploy
📖 Explore Documentation
https://developers.cloudflare.com/workers
🐛 Report an Issue
https://github.com/cloudflare/workers-sdk/issues/new/choose
💬 Join our Community
https://discord.cloudflare.com
────────────────────────────────────────────────────────────
2. Set Bot Webhook
Alright, let's talk about hooking our Telegram bot up to the web!
To get our bot responding to commands and receiving updates,
we need to configure its webhook.
We'll be using the Grammy
bot SDK's bot.api.setMyCommands
and bot.api.setWebhook
functions for this.
Think of it as telling Telegram where to send all the juicy user interactions.
import { Bot, webhookCallback } from 'grammy'
async function setUpWebhook(host: string, telegramToken: string, webhookToken: string) {
const bot = new Bot(telegramToken);
await bot.api.setMyCommands([
{ command: 'typescript', description: 'typescript using the bot' },
{ command: 'cloudflare', description: 'cloudflare help info' },
{ command: 'vscode', description: 'vscode help info' },
{ command: 'github', description: 'github help info' },
{ command: 'help', description: 'Show help info' },
]);
const webhookEndPointURL = `https://${host}/api/telegram/webhook`;
await bot.api.setWebhook(webhookEndPointURL, {
drop_pending_updates: true,
secret_token: webhookToken,
});
}
We'll grab our bot's token securely from Cloudflare Workers secrets
and
pull the host and webhook token
from environment variables.
Now, that webhook token is a neat little security feature - you can set it to anything you like to prevent unauthorized access to your bot's webhook.
We'll then expose this setup logic via a Cloudflare Worker route at GET https://${host}/api/telegram/setup
, making it easy to trigger.
apiTelegram.get('/setup', async (c) => {
const host = c.req.header("host") || '';
if (!host) {
return c.text('host not found')
}
const webhookToken = c.env.TELEGRAM_WEBHOOK_TOKEN;
const telegramToken = c.env.TELEGRAM_TOKEN;
await setUpWebhook(host, telegramToken, webhookToken)
return c.text('telegram bot is set by grammY. All done')
})
3. Handle Bot Webhook
Let's break down how we're handling incoming Telegram updates.
First, we're initializing our bot with a unique telegramToken and then equipping it with a diverse set of command handlers,
along with specialized handlers for different message types like photo
, document
, text
, and even user reactions
.
This allows our bot to intelligently respond to a wide variety of user interactions.
If you're looking to dive deeper into the granular control you have with the bot.on
functionality,
I highly recommend checking out the Grammy documentation on Filter Queries.
import { Bot, webhookCallback } from 'grammy'
function webhookHandler(telegramToken: string, webhookToken: string) {
const bot = new Bot(telegramToken);
bot.command('typescript', (ctx) => ctx.reply('typescript to use Eric Zhou'));
bot.command('cloudflare', (ctx) => ctx.reply('cloudflare to use Eric Zhou'));
bot.command('vscode', (ctx) => ctx.reply('vscode to use Eric Zhou'));
bot.command('github', (ctx) => ctx.reply('github to use Eric Zhou'));
bot.command('help', async (ctx) => {
const commands = await ctx.api.getMyCommands();
const info = commands.reduce((acc, val) => `${acc}/${val.command} - ${val.description}\n`, '');
return ctx.reply(info);
});
bot.on(['message:photo', 'message:document'], async (ctx) => {
//todo:: not working
const file = await ctx.getFile();
const host = 'xxx.com'
const tgImgUrl = `https://${host}/img/${file.file_id}`;
return ctx.reply(
`Successfully uploaded image!\nTelegram:\n${tgImgUrl}`
);
});
bot.reaction("🎉", (ctx) => ctx.reply("whoop whoop"));
bot.reaction(["👍", "👎"], (ctx) => ctx.reply("Nice thumb"));
bot.on('message:text', ctx => ctx.reply(ctx.message.text + ' from Eric Zhou bot'));
const hh = webhookCallback(bot, 'hono', { secretToken: webhookToken })
return hh
}
The magic happens when we take this configured bot and create a dedicated handler for
our hono cloudflare worker
using webhookCallback(bot, 'hono', { secretToken: webhookToken })
.
This effectively bridges the gap between the Telegram API and our cloudflare workers Hono, allowing us to receive and process incoming webhook events securely and efficiently.
To make your Telegram bot respond to messages,
we need to connect the webhookHandler to the POST https://${host}/api/telegram/webhook
route.
apiTelegram.post('/webhook', async (c, next) => {
const hh = webhookHandler(c.env.TELEGRAM_TOKEN, c.env.TELEGRAM_WEBHOOK_TOKEN)
return await hh(c)
})
Deploy and Run
First, put your secret keys into Cloudflare workers ENV
.
Then, use wrangler deploy
to put your code online.
After that, go to https://${host}/api/telegram/setup
to setup your Telegram bot.
Now, your bot is ready and you can chat with it!
Links
- Hone Web Framework
- Cloudflare Workers
- Telegram GrammY
- Telegram BotFather
- Project Source Code
- Demo Telegram Bot