Telegram Bots with Node.js
Telegram has been my go to chat platform for a couple of years now. I've been able to automate A LOT of things with it such as
What are we going to build?
We'll build two things during this project
- A Telegram bot that takes an input, runs a function and returns the output
- Connect our app to a Web3 RPC Node, in this cause we'll use Quicknode so please go ahead and make an account on Quicknode.io
Project setup
- Please follow this guide to set up a Node.js project.
- Setup a free Quicknode endpoint and choose ETH Mainnet
insert screenshot here
Create a bot via BotFather
BotFather is the official way of creating bots on Telegram.
- start the bot by chatting with BotFather
- execute
/newbot
to create a new bot - give the bot a username and a name
- (optional) you can set a description and a profile picture
After you've followed this proces, you should get this text from him.
Project setup
I'm assuming you've followed this guide to setup your Node.js environment. I'll call my project telegram-bot-example
.
mkdir telegram-bot-example
cd telegram-bot-example
git init
npm init -y
echo "node_modules/" > .gitignore
We'll now install the dependencies
node-telegram-bot-api
for the Telegram botdotenv
for the environment variablesweb3
for connecting to the Web3 RPC Node we now have thanks to Quicknode
Defining the environment variables
- Create a file called
.env
for the CLI lovers
- Copy the following content into it
Copy and paste the URL from Quicknode and paste it in
WEB3_PROVIDER_URL
Part 1: Create the Telegram bot
- Create a file called
app.js
- Add the following code. This is the core of our bot.
app.js
const TelegramBot = require('node-telegram-bot-api'); require('dotenv').config(); const bot = new TelegramBot(process.env.TELEGRAM_TOKEN, { polling: true }); bot.on("polling_error", (msg) => console.log(msg)); bot.on('message', async (msg) => { const chatId = msg.chat.id; let text = msg.text ? msg.text : ''; bot.sendMessage(chatId, 'hey there! this is what you asked me ' + text); });
We don't need to pass the TELEGRAM_TOKEN as a string anymore because it's been defined in the .env file. #lifehacks lol
- Run the bot
Part 2: Connect to the Web3 RPC Node
- Create a file called
web3.js
- Add the following code, we're doing a simple
getBlock
callweb3.jsconst Web3 = require("web3"); require('dotenv').config(); async function getBlock() { const url = process.env.WEB3_PROVIDER_URL; const web3 = new Web3(url); const block = await web3.eth.getBlock("latest"); return await block; } // getBlock().then(console.log) module.exports = { getBlock };
See? Connecting to Web3 is not that hard anymore.
- Uncomment the line
getBlock().then(console.log)
to test the file independently You should get an output like this{ baseFeePerGas: 12011862285, difficulty: '12152901669249817', extraData: '0x466c6578706f6f6c2f53312f4252202d204c6973626f6e', gasLimit: 30000000, gasUsed: 9195298, hash: '0xbf04f30cb73aed0583999108603616027c2b4ab500daa0f33a1052d353b869f7', ... }
This is the data within the latest mined block
Part 3: Custom Telegram commands
Let's extend our bot with a custom /getLatestBlock
command
const TelegramBot = require('node-telegram-bot-api');
require('dotenv').config();
const bot = new TelegramBot(process.env.TELEGRAM_TOKEN, { polling: true });
bot.on("polling_error", (msg) => console.log(msg));
bot.on('message', async (msg) => {
const chatId = msg.chat.id;
let text = msg.text ? msg.text : '';
if (text.includes('/getLatestBlock')) {
bot.sendMessage(chatId, 'getting latest block...');
}
});
The following block will wait for the user to call the command /getLatestBlock
Part 4: Connect the bot to the Web3 RPC Node
First we need to add the module we made earlier to the app.js
file
Now we slightly modify the code to return blockhash when the user calls the command /getLatestBlock
if (text.includes('/getLatestBlock')) {
bot.sendMessage(chatId, 'getting latest block...');
const block = await web3.getBlock();
bot.sendMessage(chatId, 'Latest blockhash: ' + block.hash);
}
The full code should look like this
const TelegramBot = require('node-telegram-bot-api');
const web3 = require('./web3');
require('dotenv').config();
const bot = new TelegramBot(process.env.TELEGRAM_TOKEN, { polling: true });
bot.on("polling_error", (msg) => console.log(msg));
bot.on('message', async (msg) => {
const chatId = msg.chat.id;
let text = msg.text ? msg.text : '';
if (text.includes('/getLatestBlock')) {
const block = await web3.getBlock();
bot.sendMessage(chatId, 'Latest blockhash: ' + block.hash);
}
});
const Web3 = require("web3");
require('dotenv').config();
async function getBlock() {
const url = process.env.WEB3_PROVIDER_URL;
const web3 = new Web3(url);
const block = await web3.eth.getBlock("latest");
return await block;
}
module.exports = { getBlock };
You can view the full project code here
Conclusion
What have we learned?
- Create a simple Telegram bot
- Register and create a account at Quicknode
- Connect the bot to the Web3 RPC Node
- Custom Telegram commands
/getLatestBlock
- Environment variables such as
TELEGRAM_TOKEN
andWEB3_PROVIDER_URL
- Export functions to be used in other files, like how the function
getBlock()
inweb3.js
was used inapp.js
Next steps?
That's for you to find out
- Learn how to reister the custom commands via BotFather
- Create more custom commands and play around with the possibilities of Web3
Maybe getting the ETH balance of a wallet? Hmmmm ....
Thanks for reading!