A framework for building GitHub Apps to automate and improve your workflow
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
The Server class provides a built-in HTTP server for receiving GitHub webhooks, serving web interfaces, and handling custom HTTP requests with extensible middleware support.
Built-in HTTP server with webhook handling, static file serving, and custom route support.
/**
* HTTP server for handling webhooks and web requests
*/
class Server {
/**
* Create a new server instance
* @param options - Server configuration options
*/
constructor(options: ServerOptions = {});
/**
* Get the Probot framework version
* @returns Version string
*/
static get version(): string;
}Usage Examples:
import { Server, Probot } from "probot";
// Basic server setup
const server = new Server({
port: 3000,
host: "localhost",
Probot: Probot,
});
// Server with custom options
const server = new Server({
port: process.env.PORT || 3000,
webhookPath: "/api/github/webhooks",
enablePing: true,
enableStaticFiles: true,
loggingOptions: {
level: "info",
},
});Access to server configuration and runtime properties.
/**
* Port the server is configured to listen on
*/
get port(): number;
/**
* Host the server is configured to bind to
*/
get host(): string;
/**
* Server instance version (same as Probot version)
*/
get version(): string;Usage Examples:
const server = new Server({ port: 3000, host: "0.0.0.0" });
console.log(`Server will start on ${server.host}:${server.port}`);
console.log(`Server version: ${server.version}`);Methods for registering custom HTTP request handlers.
/**
* Add a custom HTTP request handler
* @param handler - Handler function for processing HTTP requests
*/
addHandler(handler: Handler): void;
/**
* Load a handler factory function
* @param appFn - Factory function that returns a handler
*/
async loadHandlerFactory(appFn: HandlerFactory): Promise<void>;
/**
* Load an application function that may register handlers
* @param appFn - Application function to load
*/
async load(appFn: ApplicationFunction): Promise<void>;Usage Examples:
// Add custom handler
server.addHandler((req, res) => {
if (req.url === "/health") {
res.writeHead(200, { "Content-Type": "application/json" });
res.end(JSON.stringify({ status: "ok", timestamp: new Date().toISOString() }));
return true; // Handler processed the request
}
return false; // Pass to next handler
});
// Handler factory
const createAPIHandler = (app: Probot, options) => {
return (req, res) => {
if (req.url?.startsWith("/api/v1/")) {
// Custom API logic
res.writeHead(200, { "Content-Type": "application/json" });
res.end(JSON.stringify({ message: "API endpoint" }));
return true;
}
return false;
};
};
await server.loadHandlerFactory(createAPIHandler);
// Application function that adds handlers
const appWithRoutes = (app: Probot, { addHandler }) => {
// Register webhook handlers
app.on("issues.opened", async (context) => {
// Handle webhook
});
// Add custom HTTP routes
addHandler((req, res) => {
if (req.url === "/dashboard") {
res.writeHead(200, { "Content-Type": "text/html" });
res.end("<h1>Dashboard</h1>");
return true;
}
return false;
});
};
await server.load(appWithRoutes);Methods for starting and stopping the HTTP server.
/**
* Start the HTTP server with all configured handlers
* Sets up default handlers for webhooks, ping, static files, and 404s
* @returns Promise resolving to Node.js HTTP server instance
*/
async start(): Promise<HttpServer>;
/**
* Stop the HTTP server and clean up resources
* Closes webhook proxy connections if configured
*/
async stop(): Promise<void>;Usage Examples:
import { Server, Probot } from "probot";
const server = new Server({
port: 3000,
Probot: Probot,
});
// Load application
await server.load((app) => {
app.on("push", async (context) => {
context.log.info("Push received");
});
});
// Start server
const httpServer = await server.start();
console.log(`Server started on port ${server.port}`);
// Graceful shutdown
process.on("SIGTERM", async () => {
console.log("Shutting down server...");
await server.stop();
process.exit(0);
});Automatically configured to handle GitHub webhook events at the specified webhook path.
// Default webhook path: "/api/github/webhooks"
// Handles POST requests with GitHub webhook payloads
// Verifies webhook signatures using the configured secret
// Parses payloads and triggers registered event handlersOptional health check endpoint for monitoring server availability.
// Endpoint: GET /ping
// Response: "PONG" with 200 status
// Enabled with: enablePing: true in ServerOptionsUsage Examples:
const server = new Server({
enablePing: true,
});
// GET /ping -> "PONG"Optional static file serving for web interfaces and assets.
// Serves files from ./static directory
// Endpoint: GET /static/*
// Enabled with: enableStaticFiles: true in ServerOptionsUsage Examples:
const server = new Server({
enableStaticFiles: true,
});
// Files in ./static/logo.png -> GET /static/logo.png
// Files in ./static/css/styles.css -> GET /static/css/styles.cssDefault 404 handler for unmatched requests.
// Returns 404 status for unhandled requests
// Enabled with: enableNotFound: true in ServerOptions (default: true)
// Can be disabled to allow custom 404 handlinginterface ServerOptions {
/** Current working directory */
cwd?: string;
/** Logger instance for server logs */
log?: Logger;
/** Port to listen on */
port?: number;
/** Host to bind to */
host?: string;
/** Webhook endpoint path */
webhookPath?: string;
/** Smee.io proxy URL for development */
webhookProxy?: string;
/** Enable GET /ping endpoint */
enablePing?: boolean;
/** Enable 404 not found handler */
enableNotFound?: boolean;
/** Enable static file serving from ./static */
enableStaticFiles?: boolean;
/** Probot class to use for app instances */
Probot: typeof Probot;
/** HTTP request logging configuration */
loggingOptions?: LoggingOptions;
/** Octokit request configuration */
request?: RequestRequestOptions;
}
type Handler = (
req: IncomingMessage,
res: ServerResponse
) => void | boolean | Promise<void | boolean>;
type HandlerFactory = (
app: Probot,
options: ApplicationFunctionOptions
) => Handler | Promise<Handler>;
type ApplicationFunction = (
app: Probot,
options: ApplicationFunctionOptions
) => void | Promise<void>;
interface LoggingOptions {
/** Log level for HTTP requests */
level?: "trace" | "debug" | "info" | "warn" | "error" | "fatal" | "silent";
/** Custom logger instance */
logger?: Logger;
/** Custom serializers for request/response logging */
serializers?: Record<string, (obj: any) => any>;
}
interface ApplicationFunctionOptions {
/** Current working directory */
cwd: string;
/** Function to register custom HTTP handlers */
addHandler: (handler: Handler) => void;
/** Additional options */
[key: string]: unknown;
}import express from "express";
import { createNodeMiddleware } from "probot";
const app = express();
// Create Probot middleware
const probotMiddleware = await createNodeMiddleware((app) => {
app.on("issues.opened", async (context) => {
// Handle GitHub webhooks
});
});
// Mount Probot middleware
app.use("/github", probotMiddleware);
// Add other Express routes
app.get("/", (req, res) => {
res.send("Hello World");
});
app.listen(3000);import Fastify from "fastify";
import { createNodeMiddleware } from "probot";
const fastify = Fastify();
// Create Probot handler
const probotHandler = await createNodeMiddleware((app) => {
app.on("push", async (context) => {
// Handle webhooks
});
});
// Register as Fastify plugin
fastify.register(async (fastify) => {
fastify.all("/webhooks/*", async (request, reply) => {
return probotHandler(request.raw, reply.raw);
});
});
await fastify.listen({ port: 3000 });import { createServer } from "http";
import { createNodeMiddleware } from "probot";
const middleware = await createNodeMiddleware((app) => {
app.on("repository.created", async (context) => {
context.log.info("New repository created");
});
});
const server = createServer(async (req, res) => {
// Try Probot middleware first
const handled = await middleware(req, res);
if (!handled) {
// Handle other routes
res.writeHead(404);
res.end("Not Found");
}
});
server.listen(3000);type HandlerFactory = (
app: Probot,
options: ApplicationFunctionOptions
) => Handler | Promise<Handler>;Install with Tessl CLI
npx tessl i tessl/npm-probot