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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@n0xgg04/nezon

v1.2.6

Published

NestJS framework for building Mezon bots

Readme

Nezon

Nezon là thư viện NestJS giúp xây dựng bot cho nền tảng Mezon nhanh chóng, tương tự trải nghiệm của Necord với Discord.

📚 Xem tài liệu đầy đủ

Tính năng chính

  • Decorator command: Định nghĩa text command bằng @Command, hỗ trợ alias, prefix riêng và tự động phân tích tham số.
  • Decorator component: Bắt sự kiện nút bấm (và các component khác) qua @Component, hỗ trợ pattern/regex cho button_id, kèm @ComponentTarget để lấy ngay Message đã cache. Hỗ trợ named parameters (RESTful pattern) như /user/:user_id/:action.
  • Injection ngữ cảnh typed: Các decorator @Message, @Channel, @Clan, @User, @MessageContent, @Args, @AutoContext… trả về đối tượng typed từ mezon-sdk hoặc helper của Nezon. Namespace Nezon cung cấp alias type (Nezon.Message, Nezon.AutoContext, ...).
  • SmartMessage builder: SmartMessage.text/system/image/voice giúp dựng payload gửi tin nhắn mà không phải thao tác trực tiếp với ChannelMessageContent. Hỗ trợ thêm buttons, images, embeds, files.
  • ButtonBuilder & onClick handlers: Tạo button với fluent API, hỗ trợ inline onClick handler tự động đăng ký và resolve context.
  • EmbedBuilder: Tạo rich embeds với fields, images, thumbnails, và form inputs (text fields, select fields).
  • Lifecycle tự động: Khởi tạo, đăng nhập bot, binding event/command/component và shutdown được xử lý trong NezonModule.
  • Caching nội bộ: Hạn chế gọi API lặp lại khi truy cập channel/clan/user/message trong cùng một lần xử lý command.

Cài đặt

Tạo project mới (Khuyến nghị)

Tạo một Mezon bot project mới với template sẵn:

npx create-mezon-bot my-bot

Hoặc:

npm create mezon-bot my-bot

Lệnh này sẽ tự động:

  • Tạo cấu trúc project NestJS
  • Cài đặt tất cả dependencies
  • Tạo example handlers với các tính năng demo
  • Cấu hình NezonModule

Sau đó chỉ cần:

cd my-bot
cp .env.example .env
# Edit .env với MEZON_TOKEN và MEZON_BOT_ID
yarn start:dev

Cài đặt vào project hiện có

Trong dự án NestJS của bạn:

yarn add @n0xgg04/nezon

Đảm bảo đã cài mezon-sdk (được khai báo trong peer dependency).

Khởi tạo module

import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { NezonModule } from '@n0xgg04/nezon';

@Module({
  imports: [
    ConfigModule.forRoot({ isGlobal: true }),
    NezonModule.forRoot({
      token: process.env.MEZON_TOKEN ?? '',
      botId: process.env.MEZON_BOT_ID ?? '',
    }),
  ],
})
export class AppModule {}

Ví dụ command cơ bản

import { Injectable } from '@nestjs/common';
import {
  Command,
  Args,
  AutoContext,
  MessageContent,
  SmartMessage,
} from '@n0xgg04/nezon';
import type { Nezon } from '@n0xgg04/nezon';

@Injectable()
export class PingHandler {
  @Command({ name: 'ping', aliases: ['pong'] })
  async onPing(
    @Args() args: Nezon.Args,
    @AutoContext() [message]: Nezon.AutoContext,
    @MessageContent() content?: string,
  ) {
    const suffix = args.length ? args.join(' ') : 'pong';
    await message.reply(SmartMessage.text(`✅ ${suffix} (${content})`));
  }
}

Ví dụ button với ButtonBuilder

Sử dụng setCustomId với @Component

import { Injectable } from '@nestjs/common';
import {
  Command,
  AutoContext,
  Component,
  ComponentParams,
  SmartMessage,
  ButtonBuilder,
  ButtonStyle,
} from '@n0xgg04/nezon';
import type { Nezon } from '@n0xgg04/nezon';

@Injectable()
export class ButtonHandler {
  @Command('button')
  async askForConfirm(@AutoContext() [message]: Nezon.AutoContext) {
    await message.reply(
      SmartMessage.text('Nhấn nút để xác nhận.').addButton(
        new ButtonBuilder()
          .setCustomId('/demo/success/12345')
          .setLabel('Confirm')
          .setStyle(ButtonStyle.Success),
      ),
    );
  }

  @Component({ pattern: '/demo/success/:source_id' })
  async onConfirm(
    @ComponentParams('source_id') sourceId: string | undefined,
    @AutoContext() [message]: Nezon.AutoContext,
  ) {
    await message.reply(
      SmartMessage.text(`Đã xác nhận với source ID: ${sourceId}`),
    );
  }
}

Sử dụng onClick handler (khuyến nghị)

import { Injectable } from '@nestjs/common';
import {
  Command,
  AutoContext,
  SmartMessage,
  ButtonBuilder,
  ButtonStyle,
} from '@n0xgg04/nezon';
import type { Nezon } from '@n0xgg04/nezon';

@Injectable()
export class ButtonHandler {
  @Command('onclick')
  async onClickDemo(@AutoContext() [message]: Nezon.AutoContext) {
    await message.reply(
      SmartMessage.text('Click the buttons below!')
        .addButton(
          new ButtonBuilder()
            .setLabel('Button 1')
            .setStyle(ButtonStyle.Primary)
            .onClick(async (context) => {
              await context.message.reply(
                SmartMessage.text('Button 1 was clicked!'),
              );
            }),
        )
        .addButton(
          new ButtonBuilder()
            .setLabel('Button 2')
            .setStyle(ButtonStyle.Success)
            .onClick(async ({ message, channel, user }) => {
              const channelName = channel?.name ?? 'unknown';
              const userName = user?.username ?? 'unknown';
              await message.reply(
                SmartMessage.text(
                  `Button 2 was clicked by ${userName} in ${channelName}!`,
                ),
              );
            }),
        ),
    );
  }
}

Ví dụ Embed với EmbedBuilder

import { Injectable } from '@nestjs/common';
import {
  Command,
  AutoContext,
  SmartMessage,
  EmbedBuilder,
} from '@n0xgg04/nezon';

@Injectable()
export class EmbedHandler {
  @Command('embed')
  async onEmbedDemo(@AutoContext() [message]: Nezon.AutoContext) {
    await message.reply(
      SmartMessage.text('').addEmbed(
        new EmbedBuilder()
          .setColor('#abcdef')
          .setTitle('Example Embed')
          .setThumbnail('https://example.com/thumb.jpg')
          .addField('Field 1', 'Value 1', true)
          .addField('Field 2', 'Value 2', true)
          .setImage('https://example.com/image.jpg')
          .setFooter('Example footer'),
      ),
    );
  }
}

Description với Markdown

await message.reply(
  SmartMessage.text('').addEmbed(
    new EmbedBuilder()
      .setColor('#E91E63')
      .setTitle('[SPECIALIZED] The basic managerial skill(s) is(are)')
      .setDescriptionMarkdown(
        [
          '1 - business strategy, human resource practices, organisational capabilities',
          '2 - marketing strategy, human resource practices, organisational capabilities',
          '3 - business strategy, human resource practices, organisational structure',
          '4 - marketing strategy, human resource practices, organisational structure',
          '5 - to supervise',
          '6 - to stimulate',
          '7 - to motivate',
          '8 - all of the above',
        ],
        { after: '(Chọn đáp án đúng tương ứng phía bên dưới!)' },
      ),
  ),
);

Ví dụ Form với EmbedBuilder

import { Injectable } from '@nestjs/common';
import {
  Command,
  AutoContext,
  SmartMessage,
  EmbedBuilder,
  ButtonBuilder,
  ButtonStyle,
} from '@n0xgg04/nezon';

@Injectable()
export class FormHandler {
  @Command('form')
  async onFormDemo(@AutoContext() [message]: Nezon.AutoContext) {
    await message.reply(
      SmartMessage.build()
        .addEmbed(
          new EmbedBuilder()
            .setColor('#E91E63')
            .setTitle('POLL CREATOR')
            .addTextField('Title', 'title', {
              placeholder: 'Input title here',
              defaultValue: '',
            })
            .addTextField('Option 1️⃣', 'option_1', {
              placeholder: 'Input option 1 here',
            })
            .addSelectField(
              'Type',
              'type',
              [
                { label: 'Single choice', value: 'SINGLE' },
                { label: 'Multiple choice', value: 'MULTIPLE' },
              ],
              'SINGLE',
            )
            .setFooter('Powered by Mezon'),
        )
        .addButton(
          new ButtonBuilder().setLabel('Create').setStyle(ButtonStyle.Success),
        ),
    );
  }
}

Named Parameters trong Component

Component hỗ trợ RESTful pattern với named parameters:

@Component({ pattern: '/user/:user_id/:action' })
async onUserAction(
  @ComponentParams('user_id') userId: string | undefined,
  @ComponentParams('action') action: string | undefined,
  @ComponentParams() allParams: Record<string, string> | undefined,
  @AutoContext() [message]: Nezon.AutoContext,
) {
  console.log('User ID:', userId);
  console.log('Action:', action);
  console.log('All params:', allParams);
}

SmartMessage builder

  • SmartMessage.text(content) - Dựng payload text cơ bản
  • SmartMessage.system(content) - Áp dụng markdown triple (EMarkdownType.TRIPLE) cho toàn bộ nội dung
  • SmartMessage.image(url, { alt, filename }) - Hỗ trợ đính kèm ảnh
  • SmartMessage.voice(url, { transcript }) - Hỗ trợ đính kèm voice
  • SmartMessage.build() - Tạo SmartMessage rỗng
  • .addButton(button) - Thêm button (tự động group thành action rows)
  • .addImage(url, options) - Thêm ảnh attachment
  • .addFile(url, filename, filetype, options) - Thêm file attachment
  • .addEmbed(embed) - Thêm embed

ButtonBuilder API

  • .setCustomId(id) - Set custom ID (không thể dùng cùng với .onClick())
  • .setLabel(label) - Set label hiển thị
  • .setStyle(style) - Set style (ButtonStyle.Primary, Secondary, Success, Danger, Link)
  • .setDisabled(disabled) - Set disabled state
  • .setURL(url) - Set URL cho link button
  • .onClick(handler) - Set inline click handler (tự động generate ID, không thể dùng cùng với .setCustomId())

EmbedBuilder API

  • .setColor(color) - Set màu embed (hex string)
  • .setTitle(title) - Set tiêu đề
  • .setURL(url) - Set URL cho title
  • .setAuthor(name, iconUrl, url) - Set author
  • .setDescription(description) - Set mô tả
  • .setDescriptionMarkdown(description, options?) - Set mô tả với markdown/code block helper
  • .setThumbnail(url) - Set thumbnail
  • .addField(name, value, inline?) - Thêm field
  • .setImage(url) - Set ảnh lớn
  • .setTimestamp(timestamp?) - Set timestamp (mặc định là now)
  • .setFooter(text, iconUrl?) - Set footer
  • .addTextField(name, inputId, options) - Thêm text input field trong embed
  • .addSelectField(name, inputId, options, selectedValue?) - Thêm select field trong embed

Ví dụ module hoàn chỉnh

Repo đã kèm ứng dụng mẫu tại apps/mebot. Bạn có thể chạy thử:

cd apps/mebot
yarn install
yarn start

Đừng quên set MEZON_TOKENMEZON_BOT_ID vào biến môi trường.

Góp ý & phát triển

  • Mở issue hoặc gửi PR nếu bạn muốn bổ sung decorator mới, cải thiện type, hoặc hỗ trợ thêm loại component.
  • Kiểm tra apps/mebot để tham khảo cách kết hợp nhiều decorator.

Chúc bạn xây dựng bot Mezon thật nhanh với Nezon! 🚀