Skip to content

中文版

Generated reference snapshot

Original Cubic page · captured 2026-09-23 · source commit. This AI-generated page has not been verified against the current code. Use the Zhin documentation for current behavior and see known corrections.

Known correction

Commands use route directories ending in index.ts; Handlers use one named directory, such as handlers/message-receive/index.ts with an explicit event: 'message.receive'. The nested Handler file example below is unsupported. See Convention Directories.

Relevant source files

The following files were used as context for generating this wiki page:

Commands, Handlers & Middlewares

Commands, Handlers, and Middlewares represent the primary interaction layers within the Zhin.js plugin system. They process normalized message streams from platform adapters, enabling developers to build interactive chatbot capabilities ranging from structured command execution to low-level message interception. Sources: README.md, CLAUDE.md

The framework utilizes a convention-over-configuration directory structure for capability discovery. Features are identified automatically by the Plugin Runtime when placed in specific directories such as commands/, middlewares/, and handlers/. Sources: packages/toolkit/create-zhin/template/skills/plugin-init/SKILL.md

Message Processing Flow

The inbound message pipeline directs data through multiple stages of processing. Messages originate from platform adapters, pass through the middleware chain, and finally match against specific commands or handlers. Sources: README.md

This diagram illustrates the sequential flow from an inbound platform event to an outbound reply. Sources: README.md, CLAUDE.md

Commands

Commands provide a structured way to handle specific user instructions. They are defined using the defineCommand() API and are discovered from the commands/ directory of a plugin package. Sources: packages/toolkit/create-zhin/template/skills/plugin-develop/SKILL.md

Structure and Discovery

Key Components of defineCommand

PropertyTypeDescription
descriptionstringHuman-readable explanation of the command.
paramsRecord<string, ParameterDefinition>Defines typed parameters extracted from dynamic segments.
executeFunctionThe core logic executed when the command matches.

Sources: packages/toolkit/create-zhin/template/skills/plugin-develop/SKILL.md, basic/cli/src/commands/new.ts:400

typescript
// Example: commands/greet/[name]/index.ts
import { defineCommand } from 'zhin.js/command';

export default defineCommand({
  description: 'Greet a user',
  params: {
    name: { type: 'string', description: 'User name' },
  },
  execute({ params }) {
    return `Hello, ${params.name}!`;
  },
});

Sources: packages/toolkit/create-zhin/template/skills/plugin-develop/SKILL.md:65-75

Middlewares

Middlewares intercept all inbound messages before they reach commands or handlers. They are defined via defineMiddleware() and placed in the middlewares/ directory. Sources: packages/toolkit/create-zhin/template/skills/plugin-init/SKILL.md

Middleware Chain

Middlewares follow an onion-style execution pattern:

  1. They receive the message context and a next() function.
  2. If next() is called, the pipeline continues to the next middleware or the dispatcher.
  3. If next() is not called, the message is intercepted and processing stops.

Sources: packages/im/middleware/src/index.ts, README.zh-CN.md

Handlers

Handlers manage event-based interactions and are often used for more flexible message processing than strict commands. They are defined using defineHandler() and stored in the handlers/ directory. Sources: CLAUDE.md:120-125

Event Mapping

The directory path of a handler maps to local event names. For example, a file at handlers/message/receive.ts responds to the message.receive event if the event name is omitted in the definition. Sources: CLAUDE.md:123

Capabilities

  • Prompt Support: The this.prompt API is available within handlers for multi-turn interactions. Sources: CLAUDE.md:124
  • Event Filtering: Handlers can listen for specific lifecycle or platform events rather than just text messages. Sources: packages/im/handler/src/index.ts

Comparison of Capabilities

FeatureCommandsHandlersMiddlewares
Discoverycommands/handlers/middlewares/
TriggerText pattern matchEvent emissionEvery inbound message
Route SourceFile path/NameEvent nameSequential
Async SupportYesYesYes
Main UsageUser intent handlingEvent orchestrationGlobal interception/filtering

Sources: CLAUDE.md:120-125, packages/toolkit/create-zhin/template/skills/plugin-init/SKILL.md

Implementation Constraints

Developers must adhere to specific architectural constraints when implementing these features:

Summary

Commands, Handlers, and Middlewares form the backbone of the Zhin.js interaction model. Commands provide a structured, parameter-aware entry point for user tasks, Handlers allow for flexible event-driven logic, and Middlewares offer a global pipeline for message filtering and transformation. By following the project's directory conventions and using the provided define* APIs, developers can create modular and hot-reloadable bot capabilities. Sources: README.md, CLAUDE.md