Skip to content

Instantly share code, notes, and snippets.

@waptik
Last active March 27, 2025 14:19
Show Gist options
  • Save waptik/2038ad8f167b7af6d25d34ff9b070a2f to your computer and use it in GitHub Desktop.
Save waptik/2038ad8f167b7af6d25d34ff9b070a2f to your computer and use it in GitHub Desktop.
This is a minimal codebase of getting grammY to work with nextjs pages directory. Please use this version of `next-connect`: `"next-connect": "^0.13.0",`
import { Bot, Context } from "grammy";
export const bot = new Bot<Context>(process.env.TELEGRAM_BOT_TOKEN ?? "");
import { bot } from "path/to/bot";
const WEBAPP_URL = "" // URL to your production main site(eg. https://my-secrete-webapp.tld)
const handleGracefulShutdown = async () => {
await bot.stop();
process.exit();
};
if (process.env.NODE_ENV==="development") {
// Graceful shutdown handlers
process.once("SIGTERM", handleGracefulShutdown);
process.once("SIGINT", handleGracefulShutdown);
}
export const startTelegramBotInDev = async () => {
if (!bot.isInited()) {
await bot.start();
}
};
export const startTelegramBotInProduction = async () => {
const webhookUrl = `${WEBAPP_URL}/api/telegram-webhook?token=${env.TELEGRAM_BOT_WEBHOOK_TOKEN}`;
const webhookInfo = await bot.api.getWebhookInfo();
if (webhookInfo.url !== webhookUrl) {
await bot.api.deleteWebhook();
await bot.api.setWebhook(webhookUrl);
}
} catch (_) { }
};
import { NextApiRequest, NextApiResponse } from "next";
import nc from "next-connect";
import { BotError } from "grammy";
import { startTelegramBotInDev } from "path/to/start";
// this is to test the bot locally by visiting http://localhost:3000/api/telegram-dev?action=start
const handler = nc<NextApiRequest, NextApiResponse>({
attachParams: true,
onError: (err, _req, res, next) => {
if (err instanceof BotError) {
res.status(200).send({});
} else {
console.error(err);
res.status(500).end("Something broke!");
}
next();
},
})
.get((req, _res, next) => {
if (process.env.NODE_ENV==="development") {
next();
}
})
.get(async (req: NextApiRequest, res: NextApiResponse) => {
try {
if (req.query && req.query.action !== "start") {
res.status(500).send({ error: { message: "Wrong gateway." } });
return;
}
await startTelegramBotInDev();
res.status(200).send("ok");
} catch (error) {
res.status(500).json({ error });
}
});
export default handler;
// path: /pages/api/telegram-dev.ts
import { NextApiRequest, NextApiResponse } from "next";
import nc from "next-connect";
import { BotError, webhookCallback } from "grammy";
import { bot } from "path/to/bot";
import { startTelegramBotInProduction } from "path/to/start";
const isProd = process.env.NODE_ENV === "production"
const handler = nc<NextApiRequest, NextApiResponse>({
attachParams: true,
onError: (err, _req, res, next) => {
if (err instanceof BotError) {
res.status(200).send({});
} else {
res.status(500).end("Something broke!");
}
next();
},
})
.post((req, _res, next) => {
if (req.query && req.query.token === process.env.TELEGRAM_BOT_WEBHOOK_TOKEN) {
next();
}
})
.post(webhookCallback(bot, "next-js"))
.get(async (req, res) => {
// this is used to automatically setup your webhook by visiting https://my-secrete-webapp.tld/api/telegram-webhook?token=[YOUR-BOT-TOKEN]
// replace [YOUR-BOT-TOKEN] with your telegram bot token
// only do so after you have deployed your bot in production
try {
if (process.env.NODE_ENV !=="production" || (req.query && req.query.token !== process.env.TELEGRAM_BOT_WEBHOOK_TOKEN)) {
return res.status(500).send({ error: { message: "Wrong gateway." } });
}
await startTelegramBotInProduction();
} finally {
return res.status(200).send("ok");
}
});
export default handler;
// path: /pages/api/telegram-webhook.ts
@mortezae
Copy link

mortezae commented Jul 2, 2024

typo in start.ts#L6: console.info

@waptik
Copy link
Author

waptik commented Jul 2, 2024

typo in start.ts#L6: console.info

Thanks! I fixed it and removed non important code from the entire structure so as to minimize unexpected errors

@erfanium
Copy link

did you try this with app directory?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment