Better Auth Telegram Plugin
better-auth-telegram is a plugin for the Better Auth framework, providing comprehensive Telegram authentication capabilities. It supports various Telegram login methods including the traditional Login Widget, Mini Apps, and the more modern OpenID Connect (OIDC) flow, leveraging OAuth 2.0 Authorization Code flow with PKCE. The library handles HMAC-SHA-256 verification and is built on the Web Crypto API, ensuring compatibility across diverse JavaScript runtimes like Node.js (>=22.0.0), Bun, and Cloudflare Workers, without relying on Node.js-specific `node:crypto` modules. The current stable version is 1.5.0, with an active release cadence addressing features, fixes, and compatibility. It integrates seamlessly with Better Auth's client and server-side components, and offers explicit guidance for database schema updates, making it a robust solution for integrating Telegram login into applications.
Common errors
-
Error: invalid_client
cause Incorrect client secret provided for OIDC. The bot token was used instead of the specific Web Login client secret.fixObtain the correct 'Client Secret' for Web Login from BotFather ('Bot Settings > Web Login') and use it for the `oidc.clientSecret` option. -
Not authenticated
cause Client-side requests (e.g., `linkTelegram`, `unlinkTelegram`) are not sending authentication credentials (cookies) to the server.fixConfigure your `createAuthClient` with `fetchOptions: { credentials: 'include' }`. -
Property '$ERROR_CODES' does not exist on type 'BetterAuthPlugin'.
cause Type incompatibility between `better-auth-telegram` and `better-auth` due to a change in the `better-auth`'s internal error code structure.fixUpgrade `better-auth-telegram` to version `1.1.0` or higher to resolve the type mismatch with `better-auth@^1.5.0`.
Warnings
- breaking When upgrading `better-auth` to `1.5.0` or higher, `better-auth-telegram` versions prior to `1.1.0` experienced type errors due to changes in Better Auth's error code structure (`$ERROR_CODES` changed from `Record<string, string>` to `Record<string, RawError>`).
- gotcha For OIDC authentication, the `clientSecret` is distinct from the `botToken`. Many users incorrectly use the bot token for the OIDC client secret, leading to `invalid_client` errors. The `clientSecret` must be obtained from BotFather via 'Bot Settings > Web Login'.
- gotcha When performing client-side operations like `linkTelegram` or `unlinkTelegram`, if you encounter 'Not authenticated' errors, it's likely due to missing credentials in your `fetchOptions`.
- gotcha When using OIDC-only setups, by default, the plugin adds database fields for the Login Widget/Mini Apps (`telegramId`, `telegramUsername`, `telegramPhoneNumber` to `User`, and `telegramId`, `telegramUsername` to `Account`). This can clutter your schema if not needed.
Install
-
npm install better-auth-telegram -
yarn add better-auth-telegram -
pnpm add better-auth-telegram
Imports
- telegram
const { telegram } = require('better-auth-telegram');import { telegram } from 'better-auth-telegram'; - telegramClient
import { telegramClient } from 'better-auth-telegram';import { telegramClient } from 'better-auth-telegram/client'; - telegram
import { TelegramConfig } from 'better-auth-telegram';import type { TelegramConfig } from 'better-auth-telegram';
Quickstart
import { betterAuth } from "better-auth";
import { telegram } from "better-auth-telegram";
// Ensure TELEGRAM_BOT_TOKEN is set in your environment variables.
// For local development, consider using ngrok for HTTPS as Telegram requires it.
export const auth = betterAuth({
plugins: [
telegram({
botToken: process.env.TELEGRAM_BOT_TOKEN ?? '', // Use environment variable
botUsername: "your_bot_username", // Replace with your bot's username (without @)
// Optional: Disable Login Widget if only using OIDC and to avoid schema clutter
// loginWidget: false,
// Optional: Enable OIDC and provide client secret (from BotFather > Web Login)
// oidc: { enabled: true, clientSecret: process.env.TELEGRAM_OIDC_CLIENT_SECRET ?? '' },
}),
],
});
console.log("Telegram plugin initialized for Better Auth. Make sure your environment variables are configured.");
// In a real application, you would now expose 'auth' via an API handler or similar.