npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

telegraf-admin-for-bots

v0.0.7

Published

Библиотека для быстрого добавления административного интерфейса в Telegram-бот. Предоставляет два компонента:

Downloads

26

Readme

telegraf-admin-for-bots

Библиотека для быстрого добавления административного интерфейса в Telegram-бот. Предоставляет два компонента:

  • AdminBot — интерактивное Telegram-меню для управления ботом прямо из чата
  • AdminServer — HTTP REST API для внешних административных панелей

Содержание


Установка

# npm
npm install telegraf-admin-for-bots

# yarn
yarn add telegraf-admin-for-bots

Пакет требует telegraf как peer dependency:

npm install telegraf

Требования к интеграции

Интерфейс TypedDB

Библиотека не зависит от конкретной БД. Нужно передать объект, реализующий интерфейс TypedDB. Ниже полный список методов:

interface TypedDB {
  // Пользователи
  findUsersByQuery(query: string): Promise<User[]>;
  findUserById(userId: string | number): Promise<User | null>;
  getUsers(): Promise<User[]>;
  getUserStats(): Promise<any>;
  extendSubscription(userId: string | number, days: number): Promise<boolean>;
  activatePromoSubscription(
    userId: string | number,
    data: { days: number },
  ): Promise<boolean>;
  deleteSubscription(userId: string | number): Promise<boolean>;
  getUserReports(userId: string | number): Promise<UserReport[]>;
  addPromoCodeToUser(
    userId: string | number,
    promoCode: string,
  ): Promise<boolean>;

  // Подписки
  getAllSubscriptions(): Promise<Subscription[]>;

  // Обращения
  getReports(): Promise<UserReport[]>;
  getReportById(reportId: string): Promise<UserReport | null>;
  saveReportReply(
    reportId: string,
    author: string,
    text: string,
  ): Promise<void>;

  // Рассылки
  getAllBroadcasts(status?: string | null): Promise<Broadcast[]>;
  getBroadcast(id: string): Promise<Broadcast | null>;
  saveBroadcast(broadcast: Broadcast): Promise<void>;
  deleteBroadcast(id: string): Promise<boolean>;

  // Промокоды
  createPromoCode(
    data: Omit<Promo, "isActive"> & { isActive?: boolean },
  ): Promise<Promo>;
  deletePromocode(code: string): Promise<boolean>;
  getAllPromoCodes(): Promise<Promo[]>;

  // Платежи
  getAllPayments(): Promise<Payment[]>;
  getPaymentsStats(): Promise<{
    currentMonth: PaymentStats;
    lastMonth: PaymentStats;
  }>;

  // Рефералы
  getRefferals(): Promise<any[]>;
  countRefferalsByRefLink(link: string): Promise<any>;

  // Инлайн-реклама
  getAds(filter?: Partial<PostContentAd>): Promise<PostContentAd[]>;
  getAdById(id: string): Promise<PostContentAd | null>;
  createAd(data: PostContentAd): Promise<PostContentAd>;
  updateAd(
    id: string,
    data: Partial<PostContentAd>,
  ): Promise<PostContentAd | null>;
  deleteAd(id: string): Promise<boolean>;
  addAdViewToUser(userId: string, adId: string): Promise<PostContentAdView>;
  getAdForUser(userId: string, type: string): Promise<PostContentAd | null>;
}

Интерфейс BotApp

Объект вашего бота должен иметь следующую форму:

interface BotApp {
  bot: Telegraf<any>; // Экземпляр Telegraf
  sendTestBroadcast(broadcast: Broadcast): void; // Отправить тестовую рассылку себе
  replyToUserReport(userId: number, message: string, text: string): void; // Ответить на обращение
}

AdminBot

Добавляет Telegram-меню администратора прямо в ваш бот. Доступно по команде /admin.

Подключение

const { AdminBot } = require("telegram-admin-server");

class MyAdminBot {
  constructor(bot, db, scheduleService) {
    this.adminBot = new AdminBot(
      bot, // BotApp — объект с полями bot, sendTestBroadcast, replyToUserReport
      {
        // AdminBotConfig — включить/выключить модули
        broadcast: true,
        subscriptions: true,
        promocodes: true,
        reports: true,
        referral: true,
        payments: true,
        postcontentAd: true,
      },
      [123456789], // Массив Telegram ID администраторов
      db, // Объект TypedDB
      scheduleService, // Сервис планировщика рассылок
      [], // Кастомные сцены (см. раздел расширения)
    );
  }

  start(stage) {
    // Передаём stage бота — adminBot добавит в него свои сцены
    this.adminBot.attach(stage);
  }
}

Команды бота

| Команда | Описание | | -------- | ----------------------------------- | | /admin | Открыть главное меню администратора | | /user | Вернуться в пользовательский режим |

Главное меню

Кнопки в меню отображаются динамически в зависимости от включённых модулей:

| Кнопка | Модуль | Описание | | ----------------- | --------------- | --------------------------------------------- | | 👥 Пользователи | всегда | Поиск, просмотр профиля, управление подпиской | | 📊 Статистика | всегда | Сводка по пользователям и платежам | | 📢 Рассылки | broadcast | Создание и управление рассылками | | 📝 Обращения | reports | Просмотр и ответ на сообщения пользователей | | 🎁 Промокоды | promocodes | Создание и удаление промокодов | | 💰 Платежи | payments | История и статистика платежей | | 📈 Инлайн реклама | postcontentAd | Управление встроенной рекламой в постах |


AdminServer

Запускает HTTP-сервер с REST API для внешней административной панели.

Подключение через createAdminServer

const { createAdminServer } = require("telegram-admin-server");

const adminServer = createAdminServer(
  bot, // BotApp
  db, // TypedDB
  scheduler, // Сервис планировщика
  {
    port: 3105, // Порт (по умолчанию 3105)
    features: { broadcast: true }, // Включённые функции (по умолчанию все включены)
    baseUrl: "https://my-domain.com", // Базовый URL (опционально)
    customRoutes: [], // Кастомные роуты (см. раздел расширения)
  },
);

adminServer.start();

Переменные окружения

| Переменная | Описание | | ----------------- | ------------------------------------------------------ | | ADMIN_API_TOKEN | Токен для авторизации запросов к API (обязательно) |

Авторизация

Все запросы к /api/* должны содержать токен одним из способов:

x-api-key: your-token
Authorization: Bearer your-token

Конфигурация функций

Объект AdminBotConfig / features управляет доступными модулями:

{
  broadcast: boolean; // Рассылки
  subscriptions: boolean; // Управление подписками
  promocodes: boolean; // Промокоды
  reports: boolean; // Обращения пользователей
  referral: boolean; // Реферальная система
  payments: boolean; // Платежи
  postcontentAd: boolean; // Инлайн-реклама в постах
}

Отключённые модули не отображаются в меню бота и не регистрируют соответствующие HTTP-роуты.


HTTP API

Базовый путь: /api. Все запросы требуют авторизации.

Пользователи

| Метод | Путь | Описание | | ----- | ---------------------- | ---------------------------------- | | GET | /api/users?query=... | Поиск пользователей | | GET | /api/users/all | Все пользователи | | GET | /api/users/:id | Пользователь по ID | | GET | /api/stats | Статистика (пользователи, платежи) |

Подписки (требует subscriptions: true)

| Метод | Путь | Тело | Описание | | -------- | -------------------------------------------- | ------------------ | --------------------------- | | GET | /api/subscriptions | — | Список всех подписок | | POST | /api/users/:id/extend-subscription | { days: number } | Продлить подписку | | POST | /api/users/:id/activate-promo-subscription | { days: number } | Активировать промо-подписку | | DELETE | /api/users/:id/subscription | — | Удалить подписку |

Обращения (требует reports: true)

| Метод | Путь | Тело | Описание | | ------ | ------------------------------ | ------------------ | ---------------------------------- | | GET | /api/reports | — | Все обращения | | GET | /api/reports/:reportId | — | Обращение по ID | | POST | /api/reports/:reportId/reply | { text: string } | Ответить на обращение | | GET | /api/users/:id/reports | — | Обращения конкретного пользователя |

Рассылки (требует broadcast: true)

| Метод | Путь | Описание | | -------- | ------------------------------- | ------------------------------------------------------------------------------- | | GET | /api/broadcasts?status=... | Список рассылок (фильтр по статусу: pending, progress, done, cancelled) | | GET | /api/broadcasts/:id | Рассылка по ID | | POST | /api/broadcasts | Создать рассылку | | DELETE | /api/broadcasts/:id | Удалить рассылку | | POST | /api/broadcasts/:id/send-test | Отправить тестовую рассылку |

Тело для создания рассылки:

{
  "title": "Название",
  "type": "text | photo | video",
  "text": "Текст сообщения",
  "mediaUrl": "https://...",
  "scheduledAt": "2025-12-31T12:00:00Z",
  "excludePaid": false,
  "linkButtons": [{ "text": "Кнопка", "url": "https://..." }]
}

Промокоды (требует promocodes: true)

| Метод | Путь | Описание | | -------- | -------------------------- | --------------------------------- | | GET | /api/promocodes | Все промокоды | | POST | /api/promocodes | Создать промокод | | DELETE | /api/promocodes/:code | Удалить промокод | | POST | /api/users/:id/promocode | Применить промокод к пользователю |

Платежи (требует payments: true)

| Метод | Путь | Описание | | ----- | --------------------- | ------------------------------------- | | GET | /api/payments | Все платежи | | GET | /api/payments/stats | Статистика за текущий и прошлый месяц |

Инлайн-реклама (требует postcontentAd: true)

| Метод | Путь | Описание | | -------- | -------------- | ----------------------- | | GET | /api/ads | Список рекламных блоков | | GET | /api/ads/:id | Рекламный блок по ID | | POST | /api/ads | Создать рекламный блок | | PATCH | /api/ads/:id | Обновить рекламный блок | | DELETE | /api/ads/:id | Удалить рекламный блок |

Рефералы (требует referral: true)

| Метод | Путь | Описание | | ----- | ------------------------- | -------------------------------- | | GET | /api/referrals | Все рефералы | | GET | /api/referrals?link=... | Статистика по реферальной ссылке |


Расширение: кастомные сцены

Можно добавить собственные Telegraf-сцены в меню администратора. Они отображаются как кнопки в главном меню и полностью доступны внутри admin-контекста.

const { Scenes } = require("telegraf");

// Создаём кастомную сцену
const MyCustomScene = new Scenes.BaseScene("MyCustomScene");

MyCustomScene.enter(async (ctx) => {
  await ctx.reply("Добро пожаловать в кастомный раздел!");
});

MyCustomScene.on("text", async (ctx) => {
  // ctx.services — доступны все сервисы библиотеки
  const users = await ctx.services.userService.getAll();
  await ctx.reply(`Всего пользователей: ${users.length}`);
  await ctx.scene.enter("MainAdminMenuScene");
});

// Передаём сцену при создании AdminBot
const adminBot = new AdminBot(bot, config, [ADMIN_ID], db, scheduler, [
  {
    name: "MyCustomScene", // Имя сцены (должно совпадать с именем в BaseScene)
    scene: MyCustomScene, // Экземпляр сцены
    buttonText: "🔧 Мой раздел", // Кнопка в главном меню (опционально)
  },
  {
    name: "MyChildScene", // Дочерняя сцена без кнопки в главном меню
    scene: MyChildScene,
  },
]);

Внутри кастомных сцен через ctx доступны все сервисы библиотеки:

ctx.services.userService; // UserService
ctx.services.broadcastService; // BroadcastService
ctx.services.reportService; // ReportService
ctx.services.promocodeService; // PromocodeService
ctx.services.subscriptionService;
ctx.services.refferService;
ctx.services.paymentService;
ctx.services.postContentService;

Расширение: кастомные HTTP-роуты

Можно добавить собственные роуты в AdminServer. Они автоматически защищены той же авторизацией, что и встроенные.

const adminServer = createAdminServer(bot, db, scheduler, {
  customRoutes: [
    {
      method: "get",
      path: "/api/my-stats",
      handler: async (req, res, next, bot, db) => {
        const users = await db.getUsers();
        res.json({ count: users.length });
      },
    },
    {
      method: "post",
      path: "/api/notify",
      handler: async (req, res, next, bot, db) => {
        const { userId, message } = req.body;
        await bot.bot.telegram.sendMessage(userId, message);
        res.json({ ok: true });
      },
    },
  ],
});

Обработчик получает:

| Аргумент | Тип | Описание | | -------- | ------------------ | ------------------ | | req | Express.Request | Запрос | | res | Express.Response | Ответ | | next | NextFunction | Express next | | bot | BotApp | Объект вашего бота | | db | TypedDB | Объект базы данных |