My personal Telegram bot.
To develop this application you need to perform these tasks:
- Compile TypeScript files in watch mode.
- Create an HTTP tunnel with ngrok and forward webhook events from the public URL that ngrok assigns to you, to
localhost:8080
. - Watch the JavaScript files in
dist/
and restart the functions-framework web server. I use entr for this. - Make HTTP POST requests to the public URL that ngrok assigns to you, using an HTTP client like curl.
ℹ️ Note:
You could create a script which combines these 4 tasks, but the output would be an absolute mess, so it's better to open 4 terminals (or 4 panes in Tmux).
In one terminal, compile TypeScript files in watch mode:
npm run build:watch -w packages/telegram-bot
In another terminal, create an HTTP tunnel and forward the webhook events to localhost:8080
npm run http-tunnel -w packages/telegram-bot
Now copy the public, Forwarding
URL that ngrok assigned you and paste it in your .envrc
file (be sure not to include any trailing slashes).
ℹ️ Note:
Now you can also:
- visit http://localhost:4040/status to know the public URL ngrok assigned you.
- visit http://localhost:4040/inspect/http to inspect/replay past requests that were tunneled by ngrok.
In another terminal, reload the environment variables defined in your .envrc
, then run the script which watches the JS files in dist/
and restart the functions-framework web server:
direnv allow
npm run start:reloadable -w packages/telegram-bot
In another terminal, use an HTTP client like curl or httpie to make POST requests using some test webhook events.
Send a Message that has a bot command. Bot commands start with /
and must specify an array of MessageEntity.
Here the bot command is /foo
, so its length in UTF-16 code units is 4
.
WEBHOOK_SECRET="$(
cat ./secrets/telegram-bot.json | jq '.webhook_secret' | tr -d '"'
)" &&
curl "${TELEGRAM_BOT_URL}/telegraf" \
-X POST \
-H "Content-Type: application/json" \
-H "X-Telegram-Bot-Api-Secret-Token: ${WEBHOOK_SECRET}" \
-d "$(cat ./assets/webhook-events/telegram/command-foo.json)"
Here the bot command is /cocktail
, so its length in UTF-16 code units is 9
.
WEBHOOK_SECRET="$(
cat ./secrets/telegram-bot.json | jq '.webhook_secret' | tr -d '"'
)" &&
curl "${TELEGRAM_BOT_URL}/telegraf" \
-X POST \
-H "Content-Type: application/json" \
-H "X-Telegram-Bot-Api-Secret-Token: ${WEBHOOK_SECRET}" \
-d "$(cat ./assets/webhook-events/telegram/command-cocktail.json)"
Here the bot command is /oldschool
, so its length in UTF-16 code units is 10
.
WEBHOOK_SECRET="$(
cat ./secrets/telegram-bot.json | jq '.webhook_secret' | tr -d '"'
)" &&
curl "${TELEGRAM_BOT_URL}/telegraf" \
-X POST \
-H "Content-Type: application/json" \
-H "X-Telegram-Bot-Api-Secret-Token: ${WEBHOOK_SECRET}" \
-d "$(cat ./assets/webhook-events/telegram/command-oldschool.json)"
Here the bot command is /sendpic
, so its length in UTF-16 code units is 8
.
WEBHOOK_SECRET="$(
cat ./secrets/telegram-bot.json | jq '.webhook_secret' | tr -d '"'
)" &&
curl "${TELEGRAM_BOT_URL}/telegraf" \
-X POST \
-H "Content-Type: application/json" \
-H "X-Telegram-Bot-Api-Secret-Token: ${WEBHOOK_SECRET}" \
-d "$(cat ./assets/webhook-events/telegram/command-sendpic.json)"
Here the bot command is /sendgif
, so its length in UTF-16 code units is 8
.
WEBHOOK_SECRET="$(
cat ./secrets/telegram-bot.json | jq '.webhook_secret' | tr -d '"'
)" &&
curl "${TELEGRAM_BOT_URL}/telegraf" \
-X POST \
-H "Content-Type: application/json" \
-H "X-Telegram-Bot-Api-Secret-Token: ${WEBHOOK_SECRET}" \
-d "$(cat ./assets/webhook-events/telegram/command-sendgif.json)"
Send a text
Message.
WEBHOOK_SECRET="$(
cat ./secrets/telegram-bot.json | jq '.webhook_secret' | tr -d '"'
)" &&
curl "${TELEGRAM_BOT_URL}/telegraf" \
-X POST \
-H "Content-Type: application/json" \
-H "X-Telegram-Bot-Api-Secret-Token: ${WEBHOOK_SECRET}" \
-d "$(cat ./assets/webhook-events/telegram/text-hi.json)"
Send a Message that has a sticker.
WEBHOOK_SECRET="$(
cat ./secrets/telegram-bot.json | jq '.webhook_secret' | tr -d '"'
)" &&
curl "${TELEGRAM_BOT_URL}/telegraf" \
-X POST \
-H "Content-Type: application/json" \
-H "X-Telegram-Bot-Api-Secret-Token: ${WEBHOOK_SECRET}" \
-d "$(cat ./assets/webhook-events/telegram/sticker.json)"
TODO: I receive an error message in the Telegram chat instead of the dice.
WEBHOOK_SECRET="$(
cat ./secrets/telegram-bot.json | jq '.webhook_secret' | tr -d '"'
)" &&
curl "${TELEGRAM_BOT_URL}/telegraf" \
-X POST \
-H "Content-Type: application/json" \
-H "X-Telegram-Bot-Api-Secret-Token: ${WEBHOOK_SECRET}" \
-d "$(cat ./assets/webhook-events/telegram/command-dice.json)"
ℹ️ Note:
⏱️ To save some time, don't copy/paste these curl commands more than once per command. Instead, use the dashboard at http://localhost:4040/inspect/http to replay past requests that were tunneled by ngrok.
npm run test -w packages/telegram-bot
Deploy the application to Cloud Functions 2nd generation.
npm run deploy -w packages/telegram-bot