@crazyrabbitltc/railway-mcp
Version:
Railway MCP Server - 146+ tools with 100% Railway API coverage, comprehensive MCP testing framework, and real infrastructure management through AI assistants. Enhanced version with enterprise features, based on original work by Jason Tan.
229 lines (228 loc) • 9.45 kB
JavaScript
import { BaseService } from "./base.service.js";
import { createSuccessResponse, createErrorResponse, formatError } from "../utils/responses.js";
export class WebhookService extends BaseService {
constructor() {
super();
}
async list(projectId) {
try {
const webhooks = await this.client.webhooks.list(projectId);
const activeCount = webhooks.filter(w => w.isActive).length;
const inactiveCount = webhooks.length - activeCount;
return createSuccessResponse({
text: projectId
? `Found ${webhooks.length} webhooks for project (${activeCount} active, ${inactiveCount} inactive)`
: `Found ${webhooks.length} total webhooks (${activeCount} active, ${inactiveCount} inactive)`,
data: {
totalCount: webhooks.length,
activeCount,
inactiveCount,
webhooks: webhooks.map(webhook => ({
id: webhook.id,
url: webhook.url,
projectId: webhook.projectId,
isActive: webhook.isActive,
eventCount: webhook.events.filter(e => e.enabled).length,
lastDeliveryStatus: webhook.lastDeliveryStatus,
lastDeliveryAt: webhook.lastDeliveryAt,
createdAt: webhook.createdAt
}))
}
});
}
catch (error) {
return createErrorResponse(`Failed to list webhooks: ${formatError(error)}`);
}
}
async get(webhookId) {
try {
const webhook = await this.client.webhooks.get(webhookId);
const deliveries = await this.client.webhooks.getDeliveries(webhookId, 10);
const enabledEvents = webhook.events.filter(e => e.enabled);
const recentDeliveries = deliveries.slice(0, 5);
return createSuccessResponse({
text: `Webhook "${webhook.url}" with ${enabledEvents.length} enabled events`,
data: {
id: webhook.id,
url: webhook.url,
projectId: webhook.projectId,
isActive: webhook.isActive,
events: {
enabled: enabledEvents.map(e => e.type),
disabled: webhook.events.filter(e => !e.enabled).map(e => e.type),
total: webhook.events.length
},
delivery: {
lastStatus: webhook.lastDeliveryStatus,
lastDeliveryAt: webhook.lastDeliveryAt,
recentCount: recentDeliveries.length,
recentDeliveries: recentDeliveries.map(d => ({
id: d.id,
status: d.status,
eventType: d.event.type,
responseCode: d.responseCode,
deliveredAt: d.deliveredAt
}))
},
createdAt: webhook.createdAt,
updatedAt: webhook.updatedAt
}
});
}
catch (error) {
return createErrorResponse(`Failed to get webhook: ${formatError(error)}`);
}
}
async create(projectId, url, events) {
try {
const webhook = await this.client.webhooks.create({
projectId,
url,
events
});
return createSuccessResponse({
text: `Webhook created for ${events.length} events`,
data: {
id: webhook.id,
url: webhook.url,
projectId: webhook.projectId,
isActive: webhook.isActive,
events: events,
createdAt: webhook.createdAt
}
});
}
catch (error) {
return createErrorResponse(`Failed to create webhook: ${formatError(error)}`);
}
}
async update(webhookId, url, events, isActive) {
try {
const webhook = await this.client.webhooks.update(webhookId, {
url,
events,
isActive
});
const enabledEvents = webhook.events.filter(e => e.enabled);
return createSuccessResponse({
text: `Webhook updated successfully`,
data: {
id: webhook.id,
url: webhook.url,
isActive: webhook.isActive,
enabledEvents: enabledEvents.length,
updatedAt: webhook.updatedAt
}
});
}
catch (error) {
return createErrorResponse(`Failed to update webhook: ${formatError(error)}`);
}
}
async delete(webhookId) {
try {
const success = await this.client.webhooks.delete(webhookId);
if (success) {
return createSuccessResponse({
text: "Webhook deleted successfully"
});
}
else {
return createErrorResponse("Failed to delete webhook");
}
}
catch (error) {
return createErrorResponse(`Failed to delete webhook: ${formatError(error)}`);
}
}
async test(webhookId) {
try {
const delivery = await this.client.webhooks.test(webhookId);
return createSuccessResponse({
text: `Test webhook delivered with status: ${delivery.status}`,
data: {
id: delivery.id,
status: delivery.status,
responseCode: delivery.responseCode,
responseTime: delivery.responseTime,
eventType: delivery.event.type,
deliveredAt: delivery.deliveredAt
}
});
}
catch (error) {
return createErrorResponse(`Failed to test webhook: ${formatError(error)}`);
}
}
async getDeliveries(webhookId, limit = 50) {
try {
const deliveries = await this.client.webhooks.getDeliveries(webhookId, limit);
const successCount = deliveries.filter(d => d.status === 'SUCCESS').length;
const failedCount = deliveries.filter(d => d.status === 'FAILED').length;
const pendingCount = deliveries.filter(d => d.status === 'PENDING').length;
return createSuccessResponse({
text: `${deliveries.length} webhook deliveries (${successCount} success, ${failedCount} failed, ${pendingCount} pending)`,
data: {
totalCount: deliveries.length,
successCount,
failedCount,
pendingCount,
deliveries: deliveries.map(delivery => ({
id: delivery.id,
status: delivery.status,
eventType: delivery.event.type,
responseCode: delivery.responseCode,
responseTime: delivery.responseTime,
deliveredAt: delivery.deliveredAt,
createdAt: delivery.createdAt
}))
}
});
}
catch (error) {
return createErrorResponse(`Failed to get webhook deliveries: ${formatError(error)}`);
}
}
async getSupportedEvents() {
try {
const eventTypes = [
'DEPLOYMENT_STARTED',
'DEPLOYMENT_COMPLETED',
'DEPLOYMENT_FAILED',
'DEPLOYMENT_CRASHED',
'SERVICE_CREATED',
'SERVICE_DELETED',
'SERVICE_UPDATED',
'ENVIRONMENT_CREATED',
'ENVIRONMENT_DELETED',
'VARIABLE_CREATED',
'VARIABLE_UPDATED',
'VARIABLE_DELETED',
'DOMAIN_CREATED',
'DOMAIN_DELETED',
'VOLUME_CREATED',
'VOLUME_DELETED'
];
const eventsByCategory = {
deployment: eventTypes.filter(e => e.startsWith('DEPLOYMENT_')),
service: eventTypes.filter(e => e.startsWith('SERVICE_')),
environment: eventTypes.filter(e => e.startsWith('ENVIRONMENT_')),
variable: eventTypes.filter(e => e.startsWith('VARIABLE_')),
domain: eventTypes.filter(e => e.startsWith('DOMAIN_')),
volume: eventTypes.filter(e => e.startsWith('VOLUME_'))
};
return createSuccessResponse({
text: `${eventTypes.length} webhook event types supported`,
data: {
totalCount: eventTypes.length,
byCategory: eventsByCategory,
allEvents: eventTypes
}
});
}
catch (error) {
return createErrorResponse(`Failed to get supported events: ${formatError(error)}`);
}
}
}
export const webhookService = new WebhookService();