zhin-adapter-development

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Zhin Adapter Development Guide

Zhin 适配器开发指南

Use this skill to create custom platform adapters that connect Zhin to chat platforms (QQ, Discord, Telegram, etc.).
使用本技能创建自定义平台适配器,将Zhin与QQ、Discord、Telegram等聊天平台连接起来。

Adapter Architecture

适配器架构

An adapter manages multiple Bot instances for a single platform. Each Bot connects to the platform and handles message sending/receiving.
Adapter (platform)
├── Bot 1 (account A)
├── Bot 2 (account B)
└── Tools (platform-specific capabilities)
一个适配器为单一平台管理多个Bot实例。每个Bot连接到平台并处理消息的发送与接收。
Adapter (platform)
├── Bot 1 (account A)
├── Bot 2 (account B)
└── Tools (platform-specific capabilities)

Minimal Adapter

最小化适配器

ts
import { Adapter, Bot, Plugin, Message } from '@zhin.js/core'

// 1. Define Bot config type
interface MyBotConfig {
  token: string
  name: string
}

// 2. Define platform message type
interface MyMessage {
  id: string
  content: string
  channelId: string
  senderId: string
}

// 3. Create Bot class
class MyBot extends Bot<MyBotConfig, MyMessage> {
  $connected = false

  async $connect() {
    // Connect to platform API
    this.$connected = true
  }

  async $disconnect() {
    // Disconnect from platform
    this.$connected = false
  }

  async $sendMessage(options: { id: string; type: string; content: string }) {
    // Send message via platform API
    return 'message-id'
  }

  async $recallMessage(messageId: string) {
    // Recall/delete a message
  }
}

// 4. Create Adapter class
class MyAdapter extends Adapter<MyBot> {
  constructor(plugin: Plugin, config: Adapter.BotConfig<MyBot>[]) {
    super(plugin, 'my-platform' as any, config)
  }

  createBot(config: MyBotConfig): MyBot {
    return new MyBot(config)
  }
}

// 5. Register the adapter
Adapter.register('my-platform', MyAdapter as any)
ts
import { Adapter, Bot, Plugin, Message } from '@zhin.js/core'

// 1. Define Bot config type
interface MyBotConfig {
  token: string
  name: string
}

// 2. Define platform message type
interface MyMessage {
  id: string
  content: string
  channelId: string
  senderId: string
}

// 3. Create Bot class
class MyBot extends Bot<MyBotConfig, MyMessage> {
  $connected = false

  async $connect() {
    // Connect to platform API
    this.$connected = true
  }

  async $disconnect() {
    // Disconnect from platform
    this.$connected = false
  }

  async $sendMessage(options: { id: string; type: string; content: string }) {
    // Send message via platform API
    return 'message-id'
  }

  async $recallMessage(messageId: string) {
    // Recall/delete a message
  }
}

// 4. Create Adapter class
class MyAdapter extends Adapter<MyBot> {
  constructor(plugin: Plugin, config: Adapter.BotConfig<MyBot>[]) {
    super(plugin, 'my-platform' as any, config)
  }

  createBot(config: MyBotConfig): MyBot {
    return new MyBot(config)
  }
}

// 5. Register the adapter
Adapter.register('my-platform', MyAdapter as any)

Using the Adapter in a Plugin

在插件中使用适配器

ts
import { usePlugin, Adapter } from 'zhin.js'

const plugin = usePlugin()

// Create and start adapter
const adapter = new MyAdapter(plugin, [
  { token: 'bot-token-1', name: 'bot1' },
])

plugin.onMounted(async () => {
  await adapter.start()
})

plugin.onDispose(async () => {
  await adapter.stop()
})
ts
import { usePlugin, Adapter } from 'zhin.js'

const plugin = usePlugin()

// Create and start adapter
const adapter = new MyAdapter(plugin, [
  { token: 'bot-token-1', name: 'bot1' },
])

plugin.onMounted(async () => {
  await adapter.start()
})

plugin.onDispose(async () => {
  await adapter.stop()
})

Message Handling

消息处理

When a message arrives from the platform, emit it on the adapter:
ts
class MyAdapter extends Adapter<MyBot> {
  private handleIncomingMessage(rawMsg: MyMessage) {
    const message = new Message({
      $adapter: 'my-platform',
      $bot: rawMsg.botId,
      $channel: { id: rawMsg.channelId, type: 'group' },
      $sender: { id: rawMsg.senderId, name: rawMsg.senderName },
      $content: rawMsg.content,
      $raw: rawMsg.content,
      $reply: async (content) => {
        // Reply implementation
        return 'reply-id'
      },
    })
    // This triggers the middleware pipeline
    this.emit('message.receive', message)
  }
}
当平台收到消息时,在适配器上触发事件:
ts
class MyAdapter extends Adapter<MyBot> {
  private handleIncomingMessage(rawMsg: MyMessage) {
    const message = new Message({
      $adapter: 'my-platform',
      $bot: rawMsg.botId,
      $channel: { id: rawMsg.channelId, type: 'group' },
      $sender: { id: rawMsg.senderId, name: rawMsg.senderName },
      $content: rawMsg.content,
      $raw: rawMsg.content,
      $reply: async (content) => {
        // Reply implementation
        return 'reply-id'
      },
    })
    // This triggers the middleware pipeline
    this.emit('message.receive', message)
  }
}

Message Lifecycle

消息生命周期

  1. Platform receives raw message.
  2. Adapter converts to
    Message
    object.
  3. message.receive
    event triggers the root plugin middleware pipeline.
  4. Middleware chain processes the message (logging, command matching, etc.).
  1. 平台接收原始消息。
  2. 适配器将其转换为
    Message
    对象。
  3. message.receive
    事件触发根插件中间件流水线。
  4. 中间件链处理消息(日志记录、命令匹配等)。

Registering Adapter Tools

注册适配器工具

Adapters can provide tools for the AI service:
ts
class MyAdapter extends Adapter<MyBot> {
  constructor(plugin: Plugin, config: any[]) {
    super(plugin, 'my-platform' as any, config)
    this.registerDefaultTools() // Adds send_message and list_bots

    // Add custom platform tools
    this.addTool({
      name: 'my_platform_get_user',
      description: 'Get user info from my-platform',
      parameters: {
        type: 'object',
        properties: {
          userId: { type: 'string', description: 'User ID' },
        },
        required: ['userId'],
      },
      execute: async (args) => {
        return await this.getUserInfo(args.userId)
      },
    })
  }
}
适配器可以为AI服务提供工具:
ts
class MyAdapter extends Adapter<MyBot> {
  constructor(plugin: Plugin, config: any[]) {
    super(plugin, 'my-platform' as any, config)
    this.registerDefaultTools() // Adds send_message and list_bots

    // Add custom platform tools
    this.addTool({
      name: 'my_platform_get_user',
      description: 'Get user info from my-platform',
      parameters: {
        type: 'object',
        properties: {
          userId: { type: 'string', description: 'User ID' },
        },
        required: ['userId'],
      },
      execute: async (args) => {
        return await this.getUserInfo(args.userId)
      },
    })
  }
}

Default Tools (via
registerDefaultTools
)

默认工具(通过
registerDefaultTools

  • {platform}_send_message
    — Send message to a target
  • {platform}_list_bots
    — List connected bots
  • {platform}_send_message
    — 向目标发送消息
  • {platform}_list_bots
    — 列出已连接的Bot

Before-Send Hook

发送前钩子

Adapters support
before.sendMessage
hooks for message transformation:
ts
plugin.root.on('before.sendMessage', async (options) => {
  // Modify options.content before sending
  return options
})
适配器支持
before.sendMessage
钩子用于消息转换:
ts
plugin.root.on('before.sendMessage', async (options) => {
  // Modify options.content before sending
  return options
})

Adapter Lifecycle Events

适配器生命周期事件

EventDescription
message.receive
A message was received
message.private.receive
A private message received
message.group.receive
A group message received
call.recallMessage
Request to recall a message
事件描述
message.receive
收到一条消息
message.private.receive
收到一条私聊消息
message.group.receive
收到一条群聊消息
call.recallMessage
请求撤回一条消息

Configuration in
zhin.config.yml

zhin.config.yml
中的配置

yaml
bots:
  - name: my-platform
    context: my-platform
    token: bot-token-here

plugins:
  - my-adapter-plugin
yaml
bots:
  - name: my-platform
    context: my-platform
    token: bot-token-here

plugins:
  - my-adapter-plugin

Checklist

检查清单

  • Extend
    Adapter
    abstract class with your platform name.
  • Create a
    Bot
    subclass implementing
    $connect
    ,
    $disconnect
    ,
    $sendMessage
    ,
    $recallMessage
    .
  • Use
    Adapter.register(name, factory)
    to register the adapter factory.
  • Emit
    message.receive
    with a
    Message
    object when messages arrive.
  • Call
    registerDefaultTools()
    in the constructor for AI tool support.
  • Implement
    start()
    and
    stop()
    lifecycle in the plugin via
    onMounted
    /
    onDispose
    .
  • 使用你的平台名称扩展
    Adapter
    抽象类。
  • 创建
    Bot
    子类,实现
    $connect
    $disconnect
    $sendMessage
    $recallMessage
    方法。
  • 使用
    Adapter.register(name, factory)
    注册适配器工厂。
  • 当收到消息时,使用
    Message
    对象触发
    message.receive
    事件。
  • 在构造函数中调用
    registerDefaultTools()
    以支持AI工具。
  • 通过
    onMounted
    /
    onDispose
    在插件中实现
    start()
    stop()
    生命周期方法。