This plugin template is built on a modern TypeScript-based architecture that runs on Cloudflare Workers, providing a serverless execution environment for UbiquityOS plugins. The architecture consists of several key components:
- Worker Runtime: Built on Cloudflare Workers using the
wrangler
framework - Plugin SDK Integration: Leverages
@ubiquity-os/plugin-sdk
for core plugin functionality - Type Safety: Comprehensive TypeScript type system with runtime validation
- Event Handling: Event-driven architecture with GitHub webhook support
- Configuration Management: JSON-schema based configuration system
-
Worker Entry Point (
src/worker.ts
):- Initializes the plugin using
createPlugin
from the SDK - Handles incoming webhook requests
- Manages environment variables and plugin settings
- Configures logging and error handling
- Initializes the plugin using
-
Plugin Logic (
src/index.ts
):- Contains the main plugin routing logic
- Handles event type validation and routing
- Dispatches events to appropriate handlers
-
Event Handlers (
src/handlers/
):- Contain specific logic for different GitHub events
- Implement plugin commands and functionality
- Handle GitHub API interactions
-
Type System (
src/types/
):- Defines plugin settings schema
- Provides event type guards
- Manages environment variable types
- Ensures type safety throughout the application
The plugin uses a multi-layered configuration approach:
-
Manifest (
manifest.json
):{ "name": "ts-template", "ubiquity:listeners": ["issue_comment.created"], "commands": { "hello": { "description": "Hello command with an argument." } }, "configuration": { "properties": { "configurableResponse": { "type": "string", "default": "Hello, world!" } } } }
-
Environment Variables:
- Runtime configuration via
.env
files - Cloudflare Worker secrets for production
- Type-safe environment variable handling
- Runtime configuration via
-
Plugin Settings:
- User-configurable options defined in manifest
- Runtime validation using JSON Schema
- Organization/repository level overrides
The template provides a robust development workflow:
-
Local Development:
bun worker
for local testing- Hot-reloading development server
- Local webhook testing support
-
Testing Infrastructure:
- Jest-based test suite
- Mock system for GitHub API
- Type-safe test utilities
-
Code Quality:
- ESLint configuration
- Prettier formatting
- Husky git hooks
- Conventional commits
-
Deployment:
- Automated Cloudflare Workers deployment
- GitHub Actions integration
- Environment-specific configurations
- A good understanding of how the kernel works and how to interact with it.
- A basic understanding of the Ubiquibot configuration and how to define your plugin's settings.
- Create a new repository using this template.
- Clone the repository to your local machine.
- Install the dependencies preferably using
bun
.
- If your plugin is to be used as a slash command which should have faster response times as opposed to longer running GitHub action tasks, you should use the
worker
type.
- Ensure you understand and have setup the kernel.
- Update compute.yml with your plugin's name and update the
id
. - Update context.ts with the events that your plugin will fire on.
- Update manifest.json with a proper description of your plugin.
- Update plugin-input.ts to match the
with:
settings in your org or repo level configuration.
- Your plugin config should look similar to this:
plugins:
- name: hello-world
id: hello-world
uses:
- plugin: http://localhost:4000
with:
# Define configurable items here and the kernel will pass these to the plugin.
configurableResponse: "Hello, is it me you are looking for?"
customStringsUrl: "https://raw.githubusercontent.com/ubiquibot/plugin-template/development/strings.json"
At this stage, your plugin will fire on your defined events with the required settings passed in from the kernel. You can now start writing your plugin's logic.
- Start building your plugin by adding your logic to the plugin.ts file.
bun worker
- to run the worker locally.- To trigger the worker,
POST
requests to http://localhost:4000/ with an event payload similar to:
await fetch("http://localhost:4000/", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
stateId: "",
eventName: "",
eventPayload: "",
settings: "",
ref: "",
authToken: "",
}),
});
A full example can be found here.
For testing purposes, the worker can be deployed through the Worker Deploy and Worker Delete workflows. It requires to
create a personal Cloudflare Account, and fill the CLOUDFLARE_ACCOUNT_ID
and CLOUDFLARE_API_TOKEN
within your
GitHub Action Secrets.
- Ensure the kernel is running and listening for events.
- Fire an event in/to the repo where the kernel is installed. This can be done in a number of ways, the easiest being via the GitHub UI or using the GitHub API, such as posting a comment, opening an issue, etc in the org/repo where the kernel is installed.
- The kernel will process the event and dispatch it using the settings defined in your
.ubiquibot-config.yml
. - The
compute.yml
workflow will run and execute your plugin's logic. - You can view the logs in the Actions tab of your repo.
Nektos Act - a tool for running GitHub Actions locally.
- Full Ubiquibot Configuration - helpful for defining your plugin's settings as they are strongly typed and will be validated by the kernel.
- Ubiquibot V1 - helpful for porting V1 functionality to V2, helper/utility functions, types, etc. Everything is based on the V1 codebase but with a more modular approach. When using V1 code, keep in mind that most all code will need refactored to work with the new V2 architecture.
- Start/Stop Slash Command - simple
- Assistive Pricing Plugin - complex
- Conversation Rewards - really complex