feat: Add comprehensive plugin API documentation and example plugin
- Introduced PLUGIN_API.md for detailed plugin development guidelines. - Implemented PLUGIN_SYSTEM_IMPLEMENTATION.md summarizing all requested features. - Created example-plugin showcasing all API features including commands, message interceptors, settings, and notifications. - Added plugin-metadata.json for the example plugin with relevant metadata.
This commit is contained in:
161
example-plugin/index.js
Normal file
161
example-plugin/index.js
Normal file
@@ -0,0 +1,161 @@
|
||||
// Example plugin for Paarrot - Demonstrates all plugin API features
|
||||
// This plugin showcases commands, message interceptors, settings, logging, and more
|
||||
|
||||
module.exports = {
|
||||
name: "Example Plugin",
|
||||
version: "2.0.0",
|
||||
|
||||
/**
|
||||
* Called when the plugin is loaded
|
||||
* @param {PluginContext} ctx - The plugin context with access to all APIs
|
||||
*/
|
||||
onLoad: async (ctx) => {
|
||||
ctx.log('🎉 Example plugin is loading...');
|
||||
|
||||
try {
|
||||
// 1. Register commands with args
|
||||
ctx.commands.register({
|
||||
name: "shrug",
|
||||
description: "Send a shrug emoji",
|
||||
run: () => {
|
||||
ctx.log('Shrug command executed');
|
||||
return "¯\\_(ツ)_/¯";
|
||||
}
|
||||
});
|
||||
|
||||
ctx.commands.register({
|
||||
name: "echo",
|
||||
args: ["text"],
|
||||
description: "Echo back your text",
|
||||
run: ({ text }) => {
|
||||
ctx.log('Echo command:', text);
|
||||
return text || "Nothing to echo!";
|
||||
}
|
||||
});
|
||||
|
||||
ctx.commands.register({
|
||||
name: "wave",
|
||||
description: "Wave at someone",
|
||||
args: ["name"],
|
||||
run: ({ name }) => {
|
||||
return `👋 Hey ${name || 'everyone'}!`;
|
||||
}
|
||||
});
|
||||
|
||||
// 2. Message interceptors
|
||||
ctx.messages.onBeforeSend((msg) => {
|
||||
// Auto-expand abbreviations
|
||||
if (msg.content === "brb") {
|
||||
msg.content = "be right back!";
|
||||
ctx.log('Expanded brb to full phrase');
|
||||
}
|
||||
if (msg.content === "omw") {
|
||||
msg.content = "on my way!";
|
||||
}
|
||||
});
|
||||
|
||||
ctx.messages.onReceive((msg) => {
|
||||
// Log all received messages (for debugging)
|
||||
ctx.log(`Received message in ${msg.roomId}:`, msg.content.substring(0, 50));
|
||||
});
|
||||
|
||||
// 3. Define settings
|
||||
ctx.settings.define({
|
||||
autoShrug: {
|
||||
type: "boolean",
|
||||
label: "Auto Shrug",
|
||||
description: "Automatically append ¯\\_(ツ)_/¯ to messages ending with '?'",
|
||||
default: false
|
||||
},
|
||||
theme: {
|
||||
type: "select",
|
||||
label: "Plugin Theme",
|
||||
description: "Choose your preferred theme",
|
||||
options: [
|
||||
{ value: "dark", label: "Dark" },
|
||||
{ value: "light", label: "Light" },
|
||||
{ value: "purple", label: "Purple" }
|
||||
],
|
||||
default: "dark"
|
||||
},
|
||||
customPrefix: {
|
||||
type: "string",
|
||||
label: "Custom Prefix",
|
||||
description: "Prefix for plugin commands",
|
||||
default: "[Plugin]"
|
||||
}
|
||||
});
|
||||
|
||||
// Use settings
|
||||
const autoShrug = ctx.settings.get('autoShrug');
|
||||
if (autoShrug) {
|
||||
ctx.log('Auto shrug is enabled!');
|
||||
ctx.messages.onBeforeSend((msg) => {
|
||||
if (msg.content.endsWith('?')) {
|
||||
msg.content += ' ¯\\_(ツ)_/¯';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 4. Listen to raw Matrix events
|
||||
ctx.matrix.on('Room.timeline', (event) => {
|
||||
if (event.getType() === 'm.room.message') {
|
||||
const content = event.getContent();
|
||||
if (content.body?.includes('hello')) {
|
||||
ctx.log('Someone said hello!');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 5. Background tasks
|
||||
ctx.timers.setInterval(() => {
|
||||
ctx.log('Background task running... (every 30s)');
|
||||
// You could check for notifications, clean up data, etc.
|
||||
}, 30000);
|
||||
|
||||
// 6. Notifications
|
||||
ctx.notify({
|
||||
title: "Example Plugin",
|
||||
body: "Plugin loaded successfully!",
|
||||
type: "success"
|
||||
});
|
||||
|
||||
// 7. Custom UI renderer (conceptual - would need UI integration)
|
||||
ctx.ui.registerRenderer("custom-message", (msg) => {
|
||||
ctx.log('Rendering custom message:', msg);
|
||||
// Return custom React component
|
||||
return null;
|
||||
});
|
||||
|
||||
// 8. Export API for other plugins
|
||||
this.exports = {
|
||||
greet: (name) => {
|
||||
return `Hello, ${name}!`;
|
||||
},
|
||||
version: "2.0.0"
|
||||
};
|
||||
|
||||
ctx.log('✅ Example plugin loaded successfully!');
|
||||
ctx.log('Registered commands: /shrug, /echo, /wave');
|
||||
ctx.log('Settings:', {
|
||||
autoShrug: ctx.settings.get('autoShrug'),
|
||||
theme: ctx.settings.get('theme'),
|
||||
prefix: ctx.settings.get('customPrefix')
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
ctx.error('Failed to load example plugin:', error);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Called when the plugin is unloaded or disabled
|
||||
*/
|
||||
onUnload: async () => {
|
||||
console.log('[ExamplePlugin] Plugin is unloading...');
|
||||
console.log('[ExamplePlugin] Cleaned up successfully!');
|
||||
},
|
||||
|
||||
// Exports for other plugins to use via ctx.require()
|
||||
exports: null // Will be set during onLoad
|
||||
};
|
||||
Reference in New Issue
Block a user