Sentry integration plugin for GramIO.
npm install @gramio/sentry @sentry/nodeImportant
You must call Sentry.init() before extending the bot with the plugin.
import * as Sentry from "@sentry/node";
import { Bot } from "gramio";
import { sentryPlugin } from "@gramio/sentry";
Sentry.init({ dsn: process.env.SENTRY_DSN });
const bot = new Bot(process.env.BOT_TOKEN!)
.extend(sentryPlugin())
.on("message", (context) => {
context.sentry.addBreadcrumb({
category: "bot",
message: "Processing message",
});
// Errors are automatically captured with user/chat context
throw new Error("Will be captured by Sentry");
});
await bot.start();- Error tracking — Unhandled errors in handlers are captured via
onErrorwithuser_id,chat_id,chat_type, andupdate_typetags - API error tracking — Telegram API errors (e.g. rate limits, forbidden) are captured via
onResponseErrorwith method name and error code - User identification — Sets Sentry user from
context.fromon each update - Breadcrumbs — Records each incoming update as a breadcrumb, and optionally each outgoing API call
- Lifecycle — Logs bot start/stop as breadcrumbs, flushes events on shutdown
sentryPlugin({
setUser: true, // Auto-set Sentry user from context.from (default: true)
breadcrumbs: true, // Add breadcrumb for each incoming update (default: true)
tracing: false, // Add breadcrumbs for outgoing API calls (default: false)
})Inside any handler you get context.sentry with these methods:
| Method | Description |
|---|---|
captureException(error, captureContext?) |
Report an error to Sentry |
captureMessage(message, captureContext?) |
Send a message event to Sentry |
addBreadcrumb(breadcrumb) |
Record a breadcrumb |
setTag(key, value) |
Set a tag on the current scope |
setContext(name, context) |
Attach structured context data |
setExtra(name, extra) |
Attach extra data to events |
withScope(callback) |
Run code in an isolated Sentry scope |
startSpan(options, callback) |
Create a performance span |
bot.on("message", async (context) => {
try {
await riskyOperation();
} catch (error) {
context.sentry.captureException(error);
return context.send("Something went wrong");
}
});bot.on("message", async (context) => {
await context.sentry.startSpan(
{ name: "handle-message" },
async () => {
await processMessage(context);
},
);
});