Koishi Chatbot Framework
Koishi is an extensible, cross-platform chatbot framework for Node.js, currently at version 4.18.11. It facilitates the development of intelligent bots that can operate across various chat platforms like Discord and Telegram. The project maintains a rapid release cadence, with frequent patch and minor updates, ensuring timely integration of new features and bug fixes. A core differentiator is its reliance on the Satori Protocol for cross-platform interoperability, standardizing message parsing and event handling. Koishi emphasizes extensibility through a robust plugin system and a declarative command-line interface, enabling developers to build complex bot functionalities with a modular approach. It ships with full TypeScript support, providing strong typing for better developer experience and code maintainability.
Common errors
-
ReferenceError: require is not defined
cause Attempting to use CommonJS `require()` syntax in an ES module project (e.g., Node.js with `"type": "module"` or `.mjs` files). Koishi is primarily ESM-focused.fixMigrate your project to use ES module `import`/`export` syntax. Ensure your `package.json` has `"type": "module"`. -
TypeError: Cannot read properties of undefined (reading 'send')
cause Attempting to send a message from a `session` object where `session.send` is undefined, often because the session is not associated with a valid adapter or the event context does not support sending messages.fixEnsure the command or listener is invoked in a context where a valid `session` object with a connected adapter is available. Check that your Koishi instance has at least one adapter configured and successfully connected to a platform.
Warnings
- breaking The Satori Protocol received significant updates in Koishi 4.18.5 (v1.2) and 4.18.11 (v1.3), which include breaking changes. Specifically, the `subsubtype` field was removed from events, and event `id` fields were renamed to `sn`. Internal routing protocol names were also renamed from `satori` to `internal`.
- gotcha In Koishi 4.17.12, command aliases with arguments were fixed, and command names containing underscores (`_`) are now uniformly replaced with hyphens (`-`) and support fuzzy matching. This might alter the expected behavior or recognition of existing commands and their aliases.
- breaking Version 4.18.10 includes a refactor of `_fields` in `minato`. If your application directly interacts with `minato`'s database layer at a low level or relies on internal `_fields` behavior, this could be a breaking change.
- deprecated The `subsubtype` field was removed from Satori events in version 4.18.11.
Install
-
npm install koishi -
yarn add koishi -
pnpm add koishi
Imports
- Koishi
const Koishi = require('koishi')import { Koishi } from 'koishi' - Context
import { Context } from 'koishi' - h
import { h } from 'koishi' - Schema
import { Schema } from 'koishi'
Quickstart
import { Context, Schema, h, Koishi } from 'koishi';
// In a real project, you would import and configure an adapter like:
// import '@koishijs/adapter-discord';
// Define a simple plugin
class MyHelloPlugin extends Context.Plugin {
static schema = Schema.object({
greeting: Schema.string().default('Hello').description('The greeting message.')
});
constructor(ctx: Context, config: { greeting: string }) {
super(ctx, config);
// Register a command
ctx.command('greet <target:string>', 'Greets someone')
.action(({ session }, target) => {
if (!target) return 'Please tell me who to greet!';
// Use h (Hyperscript) for rich message formatting, if supported by adapter
return h('message', [
h('text', `${config.greeting}, `),
h('at', { id: session?.userId || 'unknown' }), // Placeholder for @mention
h('text', ` ${target}! `)
]);
});
// Register a simple listener
ctx.on('message', (session) => {
if (session.content === 'ping') {
session.send('pong');
}
});
ctx.logger.info('MyHelloPlugin loaded!');
}
}
async function main() {
const app = new Koishi({
prefix: '.', // Command prefix
port: 8080, // WebUI port, if enabled
// The `plugins` object is where you configure adapters and other plugins.
// For this quickstart, we'll define a dummy adapter for demonstration.
// In a real app, you'd install and configure e.g., `@koishijs/adapter-discord`.
plugins: {
'my-hello-plugin': { // Directly add the plugin to the config
greeting: 'Hey there'
}
// Example of an actual adapter config (uncomment and replace with real token/platform):
// '@koishijs/adapter-discord': {
// token: process.env.DISCORD_TOKEN || 'YOUR_DISCORD_BOT_TOKEN',
// intents: 32767 // Or specific intents
// }
}
});
// Manually register the plugin class (usually done via `app.plugin()` or config)
app.plugin(MyHelloPlugin);
try {
await app.start();
console.log('Koishi application started. Listening for commands.');
console.log('Try to run a command like ".greet World" if an adapter is configured and connected.');
} catch (error) {
console.error('Failed to start Koishi:', error);
console.warn('Ensure you have installed and configured at least one adapter (e.g., @koishijs/adapter-discord) ' +
'and provided a valid token in the plugins config if you want to connect to a chat platform.');
}
}
main();