@yaebal/web
run your bot on edge/web runtimes — Cloudflare Workers, Deno Deploy, Bun, Vercel Edge — via
webhooks. no long-polling: each incoming Request becomes one update.
install
pnpm add @yaebal/webedge: a fetch handler
webhook(bot) returns a standard (Request) => Promise<Response>.
Drop it into any runtime that speaks fetch — that's all an edge bot needs.
import { Bot } from "@yaebal/core";
import { webhook, setWebhook } from "@yaebal/web";
// Cloudflare Workers / Deno Deploy / Vercel Edge — no long-polling, just fetch
export default {
fetch(request: Request, env: { BOT_TOKEN: string; SECRET: string }) {
const bot = new Bot(env.BOT_TOKEN);
bot.command("start", (ctx) => ctx.reply("running on the edge ⚡"));
return webhook(bot, { secretToken: env.SECRET })(request);
},
};standalone: serve on Bun / Deno
For a long-running web server (not edge), serve() uses the runtime's native fetch
server. On Node, use nodeWebhookCallback from @yaebal/core instead.
import { Bot } from "@yaebal/core";
import { serve } from "@yaebal/web";
const bot = new Bot(process.env.BOT_TOKEN!);
bot.on("message:text", (ctx) => ctx.reply(ctx.text));
// Bun or Deno — starts a native fetch server
serve(bot, { port: 8080, secretToken: process.env.SECRET });register the webhook
Tell Telegram where to send updates. The secretToken you set here must match the one
you pass to webhook() — it's checked in constant time on every request.
import { setWebhook, deleteWebhook } from "@yaebal/web";
// run once on deploy to point Telegram at your URL
await setWebhook(bot, "https://my-worker.workers.dev/", {
secretToken: process.env.SECRET,
allowedUpdates: ["message", "callback_query"],
dropPendingUpdates: true,
});
// switch back to long-polling later
await deleteWebhook(bot);api
| export | what |
|---|---|
webhook(bot, options?) | fetch handler for edge/web runtimes |
serve(bot, options?) | standalone server on Bun or Deno |
setWebhook(bot, url, options?) | register the webhook with Telegram |
deleteWebhook(bot, dropPending?) | remove the webhook |
The whole package is
fetch-first with zero node: imports, so it (and the
core it wraps) runs on Node, Bun, Deno and edge. Looking for the operator dashboard? That moved to @yaebal/panel.