Installation
Five minutes from nothing to a message on your phone. The hard part is Telegram's, not ours, and it is two chats with a bot.
Copy this
Install the module
npx nuxt module add nuxt-pigeon
That adds it to nuxt.config for you. If you would rather do it by hand:
pnpm add nuxt-pigeon
export default defineNuxtConfig({
modules: ['nuxt-pigeon'],
nuxtPigeon: {
channels: {
telegram: true,
},
},
})
Get a bot token
Open @BotFather in Telegram and send /newbot. It asks for a
name and a username, then hands you a token that looks like
8123456789:AAF....
Get your chat id
Write any message to your new bot. It will not answer, that is fine. Then open this in a browser, with your token in it:
https://api.telegram.org/bot<YOUR_TOKEN>/getUpdates
Look for "chat":{"id":123456789. That number is your chat id.
Put both in .env
PIGEON_TELEGRAM_BOT_TOKEN=8123456789:AAF...
PIGEON_TELEGRAM_CHAT_ID=123456789
Send something
export default defineEventHandler(async () => {
await telegram.send('It works.')
return { sent: true }
})
Run it
pnpm dev
Open http://localhost:3000/api/hello. Your phone buzzes.
What just happened
telegramwas not imported. Channels are auto imported inserver/, likedefineEventHandleris.- The token was never passed. It is read from the environment at request time, so the same build runs in staging and production with different credentials.
- Nothing was constructed. No client, no instance, no setup call.
- The message went out over one
fetch, with a timeout, two retries on a 5xx, and growing delays between them. That is the default, and you can turn all of it off.
Where the credentials come from
Three places, in this order. The first one that has a value wins.
| Order | Source | Example |
|---|---|---|
| 1 | nuxt.config | telegram: { token: '…' } |
| 2 | Nuxt runtime config | NUXT_PIGEON_CHANNELS_TELEGRAM_TOKEN |
| 3 | The module's own variable | PIGEON_TELEGRAM_BOT_TOKEN |
In practice you use the third one and never think about the other two. The exception is the app whose users enter the token on a settings page: that is credentials at runtime.
nuxt.config. It is committed, and for Discord and Slack the
url alone is the credential. Only .env is right, and .env belongs in
.gitignore.What will cost you an hour
getUpdatesreturns an empty list until you have written to the bot. The bot cannot start a conversation, Telegram forbids it. You go first, always.- A group chat id is negative, for example
-1001234567890. That minus sign is part of it. - In a group the bot only sees messages meant for it, because privacy mode is on by
default. To read everything, make it an admin or turn privacy off in
@BotFather with
/setprivacy.
Read more
- Telegram Bot API - the full reference
- Sending - formatting, limits, and every option
- Receiving - getting messages back out of Telegram