zhin-prompt-interaction

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Zhin Prompt Interaction Guide

Zhin Prompt交互指南

Use this skill to collect interactive input from users during conversations in Zhin plugins. The
Prompt
class supports text, number, confirmation, list, option selection, and Schema-driven input.
本技能可用于在Zhin插件的对话过程中收集用户的交互式输入。
Prompt
类支持文本、数字、确认、列表、选项选择以及Schema驱动的输入。

Creating a Prompt

创建Prompt

ts
import { usePlugin, Prompt, MessageCommand } from 'zhin.js'

const plugin = usePlugin()

plugin.addCommand(
  new MessageCommand('setup')
    .desc('Interactive setup wizard')
    .action(async (message) => {
      const prompt = new Prompt(plugin, message)

      const name = await prompt.text('What is your name?')
      const age = await prompt.number('How old are you?')
      const confirm = await prompt.confirm('Is this correct?')

      if (confirm) {
        return `Welcome, ${name} (age ${age})!`
      }
      return 'Setup cancelled.'
    })
)
ts
import { usePlugin, Prompt, MessageCommand } from 'zhin.js'

const plugin = usePlugin()

plugin.addCommand(
  new MessageCommand('setup')
    .desc('Interactive setup wizard')
    .action(async (message) => {
      const prompt = new Prompt(plugin, message)

      const name = await prompt.text('What is your name?')
      const age = await prompt.number('How old are you?')
      const confirm = await prompt.confirm('Is this correct?')

      if (confirm) {
        return `Welcome, ${name} (age ${age})!`
      }
      return 'Setup cancelled.'
    })
)

Prompt Types

Prompt类型

Text Input

文本输入

ts
const name = await prompt.text('Enter your name')

// With timeout (ms) and default value
const name = await prompt.text('Enter your name', 30000, 'Anonymous', 'Timed out')
ts
const name = await prompt.text('Enter your name')

// With timeout (ms) and default value
const name = await prompt.text('Enter your name', 30000, 'Anonymous', 'Timed out')

Number Input

数字输入

ts
const count = await prompt.number('How many items?')

// With timeout and default
const count = await prompt.number('How many items?', 30000, 1, 'Timed out')
ts
const count = await prompt.number('How many items?')

// With timeout and default
const count = await prompt.number('How many items?', 30000, 1, 'Timed out')

Confirmation

确认输入

ts
// User must type "yes" to confirm
const ok = await prompt.confirm('Are you sure?')

// Custom confirmation word
const ok = await prompt.confirm('Continue?', 'ok')

// With timeout and default
const ok = await prompt.confirm('Continue?', 'yes', 30000, false, 'Timed out')
ts
// User must type "yes" to confirm
const ok = await prompt.confirm('Are you sure?')

// Custom confirmation word
const ok = await prompt.confirm('Continue?', 'ok')

// With timeout and default
const ok = await prompt.confirm('Continue?', 'yes', 30000, false, 'Timed out')

List Input

列表输入

Collect multiple values separated by a delimiter:
ts
// Text list (comma-separated by default)
const tags = await prompt.list('Enter tags')
// User types: "tag1,tag2,tag3"  → ['tag1', 'tag2', 'tag3']

// Number list with custom separator
const scores = await prompt.list('Enter scores', {
  type: 'number',
  separator: ' ',
  defaultValue: [0],
  timeout: 60000,
})
收集以分隔符分隔的多个值:
ts
// Text list (comma-separated by default)
const tags = await prompt.list('Enter tags')
// User types: "tag1,tag2,tag3"  → ['tag1', 'tag2', 'tag3']

// Number list with custom separator
const scores = await prompt.list('Enter scores', {
  type: 'number',
  separator: ' ',
  defaultValue: [0],
  timeout: 60000,
})

Option Selection (Pick)

选项选择(Pick)

ts
// Single select
const color = await prompt.pick('Choose a color', {
  type: 'text',
  options: [
    { label: 'Red', value: 'red' },
    { label: 'Green', value: 'green' },
    { label: 'Blue', value: 'blue' },
  ],
})
// Displays:
// Choose a color
// 1.Red
// 2.Green
// 3.Blue
// User types: "2" → 'green'

// Multi-select
const colors = await prompt.pick('Choose colors', {
  type: 'text',
  multiple: true,
  separator: ',',
  options: [
    { label: 'Red', value: 'red' },
    { label: 'Green', value: 'green' },
    { label: 'Blue', value: 'blue' },
  ],
})
// User types: "1,3" → ['red', 'blue']
ts
// Single select
const color = await prompt.pick('Choose a color', {
  type: 'text',
  options: [
    { label: 'Red', value: 'red' },
    { label: 'Green', value: 'green' },
    { label: 'Blue', value: 'blue' },
  ],
})
// Displays:
// Choose a color
// 1.Red
// 2.Green
// 3.Blue
// User types: "2" → 'green'

// Multi-select
const colors = await prompt.pick('Choose colors', {
  type: 'text',
  multiple: true,
  separator: ',',
  options: [
    { label: 'Red', value: 'red' },
    { label: 'Green', value: 'green' },
    { label: 'Blue', value: 'blue' },
  ],
})
// User types: "1,3" → ['red', 'blue']

Schema-based Input

基于Schema的输入

Collect structured input driven by Schema definitions:
ts
import { Schema } from '@zhin.js/schema'

// Single schema value
const value = await prompt.getValueWithSchema(
  Schema.string().description('Enter your email')
)

// Multiple schema values at once
const result = await prompt.getValueWithSchemas({
  name: Schema.string().description('Your name'),
  age: Schema.number().description('Your age'),
  admin: Schema.boolean().description('Are you admin?'),
})
// result = { name: 'Alice', age: 25, admin: true }
通过Schema定义收集结构化输入:
ts
import { Schema } from '@zhin.js/schema'

// Single schema value
const value = await prompt.getValueWithSchema(
  Schema.string().description('Enter your email')
)

// Multiple schema values at once
const result = await prompt.getValueWithSchemas({
  name: Schema.string().description('Your name'),
  age: Schema.number().description('Your age'),
  admin: Schema.boolean().description('Are you admin?'),
})
// result = { name: 'Alice', age: 25, admin: true }

Supported Schema Types

支持的Schema类型

TypePrompt Used
string
text()
number
number()
boolean
confirm()
object
Recursively prompts each field
list
list()
date
Text input parsed as Date
regexp
Text input parsed as RegExp
const
Returns the default value
Schema with
options
pick()
类型使用的Prompt
string
text()
number
number()
boolean
confirm()
object
递归提示每个字段
list
list()
date
解析为Date的文本输入
regexp
解析为RegExp的文本输入
const
返回默认值
options
的Schema
pick()

Timeout and Error Handling

超时与错误处理

All prompts accept a timeout parameter (default: 3 minutes). On timeout, the default value is used if provided, otherwise an error is thrown:
ts
try {
  const name = await prompt.text('Enter name', 10000) // 10 seconds
} catch (error) {
  // error.message = 'Input timeout'
  await message.$reply('You took too long!')
}
所有Prompt都支持超时参数(默认:3分钟)。超时后,如果设置了默认值则使用默认值,否则抛出错误:
ts
try {
  const name = await prompt.text('Enter name', 10000) // 10 seconds
} catch (error) {
  // error.message = 'Input timeout'
  await message.$reply('You took too long!')
}

Using One-time Middleware

使用一次性中间件

For lower-level control, use
prompt.middleware()
directly:
ts
prompt.middleware(
  (input) => {
    if (input instanceof Error) {
      // Timeout occurred
      return
    }
    // input is the raw message string
    console.log('User said:', input)
  },
  60000,           // timeout in ms
  'Input timed out' // timeout message
)
如需更底层的控制,可直接使用
prompt.middleware()
ts
prompt.middleware(
  (input) => {
    if (input instanceof Error) {
      // Timeout occurred
      return
    }
    // input is the raw message string
    console.log('User said:', input)
  },
  60000,           // timeout in ms
  'Input timed out' // timeout message
)

Checklist

检查清单

  • Create
    Prompt
    with
    new Prompt(plugin, message)
    inside a command action.
  • Choose the appropriate prompt type for each input.
  • Always handle timeouts with default values or try/catch.
  • Use Schema-based prompts for structured configuration collection.
  • The prompt automatically matches user sessions by adapter-bot-channel-sender.
  • 在命令动作中通过
    new Prompt(plugin, message)
    创建
    Prompt
    实例。
  • 为每个输入选择合适的Prompt类型。
  • 始终通过默认值或try/catch处理超时情况。
  • 使用基于Schema的Prompt来收集结构化配置信息。
  • Prompt会自动通过adapter-bot-channel-sender匹配用户会话。