@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

terminal
pnpm add @yaebal/web

edge: 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.

worker.ts
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.

server.ts
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.

deploy.ts
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

exportwhat
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.