Last active
August 30, 2023 12:38
-
-
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",`
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Bot, Context } from "grammy"; | |
export const bot = new Bot<Context>(process.env.TELEGRAM_BOT_TOKEN ?? ""); | |
// attach your middlewaew, commands and other stuff to your bot | |
// eg. bot.use(myCommands) | |
// path: /utils/telegram/bot.ts |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { bot } from "./bot"; | |
const WEBAPP_URL = "" // URL to your production main site(eg. https://my-secrete-webapp.tld) | |
const handleGracefulShutdown = async () => { | |
const.info("shutdown"); | |
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()) { | |
bot | |
.start({ | |
onStart: ({ username }) => { | |
logger.info({ | |
msg: "bot running...", | |
username, | |
at: new Date(), | |
}); | |
}, | |
}) | |
.catch((err) => logger.error(err)); | |
} | |
}; | |
export const startTelegramBotInProduction = async () => { | |
const webhookUrl = `${WEBAPP_URL}/api/telegram-webhook?token=${env.TELEGRAM_BOT_WEBHOOK_TOKEN}`; | |
logger.info("fetching webhook info"); | |
const webhookInfo = await bot.api.getWebhookInfo(); | |
logger.info(`existing webhook info fetched: ${webhookInfo.url}`); | |
if (webhookInfo.url === webhookUrl) { | |
logger.info("Sorry, same url, i don't wanna waste my time here."); | |
} else { | |
logger.info("deleting existing webhook"); | |
await bot.api.deleteWebhook(); | |
console.info("existing webhook deleted"); | |
logger.info(`setting new webhook to: ${webhookUrl}`); | |
await bot.api.setWebhook(webhookUrl); | |
console.info(`bot webhook set to: ${webhookUrl}`); | |
} | |
} catch (err) { | |
console.error("failed to delete/set webhook url", err); | |
} | |
}; | |
// path: /utils/telegram/start.ts |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { NextApiRequest, NextApiResponse } from "next"; | |
import nc from "next-connect"; | |
import { BotError } from "grammy"; | |
import { startTelegramBotInDev } from ""@/lib/telegram/run"; | |
// 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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { NextApiRequest, NextApiResponse } from "next"; | |
import nc from "next-connect"; | |
import { BotError, webhookCallback } from "grammy"; | |
import { bot } from "@/lib/telegram/bot"; | |
import { startTelegramBotInProduction } from "@/lib/telegram/start"; | |
import { isProd } from "~utils/constants"; | |
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(); | |
} catch (err) { | |
console.error("telegram bot error", err); | |
} finally { | |
return res.status(200).send("ok"); | |
} | |
}); | |
export default handler; | |
// path: /pages/api/telegram-webhook.ts |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment