Agent Skills: Replit Webhooks & Events

|

UncategorizedID: jeremylongshore/claude-code-plugins-plus-skills/replit-webhooks-events

Install this agent skill to your local

pnpm dlx add-skill https://github.com/jeremylongshore/claude-code-plugins-plus-skills/tree/HEAD/plugins/saas-packs/replit-pack/skills/replit-webhooks-events

Skill Files

Browse the full folder contents for replit-webhooks-events.

Download Skill

Loading file tree…

plugins/saas-packs/replit-pack/skills/replit-webhooks-events/SKILL.md

Skill Metadata

Name
replit-webhooks-events
Description
|

Replit Webhooks & Events

Overview

Integrate with Replit's event ecosystem: deployment lifecycle hooks, Replit Extensions API for workspace customization, and Agents & Automations for scheduled tasks and chatbots. Also covers external webhook endpoints hosted on Replit.

Prerequisites

  • Replit account with Deployments enabled (Core or Teams)
  • For Extensions: familiarity with React and TypeScript
  • For Automations: Replit Agent access

Instructions

Step 1: Deployment Lifecycle Monitoring

Monitor deployment events by polling or building a status dashboard:

// src/deploy-monitor.ts — Track deployment health
import express from 'express';

const app = express();
app.use(express.json());

// Health endpoint that deployment monitoring can ping
app.get('/health', async (req, res) => {
  res.json({
    status: 'healthy',
    environment: process.env.REPL_SLUG,
    region: process.env.REPLIT_DEPLOYMENT_REGION,
    deployedAt: process.env.REPLIT_DEPLOYMENT_TIMESTAMP || 'unknown',
    uptime: process.uptime(),
  });
});

// Post-deploy smoke test endpoint
app.get('/api/readiness', async (req, res) => {
  const checks = {
    database: await checkDB(),
    storage: await checkStorage(),
    secrets: checkSecrets(),
  };

  const allHealthy = Object.values(checks).every(Boolean);
  res.status(allHealthy ? 200 : 503).json({ ready: allHealthy, checks });
});

async function checkDB(): Promise<boolean> {
  try {
    const { Pool } = await import('pg');
    const pool = new Pool({ connectionString: process.env.DATABASE_URL });
    await pool.query('SELECT 1');
    await pool.end();
    return true;
  } catch { return false; }
}

async function checkStorage(): Promise<boolean> {
  try {
    const { Client } = await import('@replit/object-storage');
    const storage = new Client();
    await storage.list({ maxResults: 1 });
    return true;
  } catch { return false; }
}

function checkSecrets(): boolean {
  const required = ['DATABASE_URL', 'JWT_SECRET'];
  return required.every(k => !!process.env[k]);
}

Step 2: External Webhook Receiver

Host webhook endpoints on Replit to receive events from external services:

// src/webhooks.ts — Receive webhooks from GitHub, Stripe, etc.
import express from 'express';
import crypto from 'crypto';

const router = express.Router();

// Webhook signature verification
function verifySignature(
  payload: string,
  signature: string,
  secret: string
): boolean {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(`sha256=${expected}`)
  );
}

// GitHub webhook receiver
router.post('/webhooks/github', express.raw({ type: '*/*' }), (req, res) => {
  const signature = req.headers['x-hub-signature-256'] as string;
  const secret = process.env.GITHUB_WEBHOOK_SECRET!;

  if (!verifySignature(req.body.toString(), signature, secret)) {
    return res.status(401).json({ error: 'Invalid signature' });
  }

  const event = req.headers['x-github-event'] as string;
  const payload = JSON.parse(req.body.toString());

  // Respond immediately, process async
  res.status(200).json({ received: true });

  handleGitHubEvent(event, payload).catch(console.error);
});

async function handleGitHubEvent(event: string, payload: any) {
  switch (event) {
    case 'push':
      console.log(`Push to ${payload.ref} by ${payload.pusher.name}`);
      // Replit auto-syncs from connected GitHub — no manual deploy needed
      break;
    case 'pull_request':
      console.log(`PR #${payload.number}: ${payload.action}`);
      break;
    case 'issues':
      console.log(`Issue #${payload.issue.number}: ${payload.action}`);
      break;
  }
}

// Generic webhook receiver
router.post('/webhooks/:service', express.json(), (req, res) => {
  const { service } = req.params;
  console.log(`Webhook from ${service}:`, JSON.stringify(req.body).slice(0, 200));
  res.status(200).json({ received: true });
});

export default router;

Step 3: Replit Extensions

Build custom IDE extensions that integrate into the Replit Workspace:

// Extension entry point — React-based UI panel
import { useReplitClient } from '@replit/extensions-react';

function MyExtension() {
  const { data: files, error } = useReplitClient().fs.readDir('/');

  if (error) return <div>Error: {error.message}</div>;

  return (
    <div>
      <h2>Project Files</h2>
      <ul>
        {files?.map(f => <li key={f.path}>{f.path}</li>)}
      </ul>
    </div>
  );
}

// Extensions can access:
// - File system (read/write files)
// - Theme (match Replit's UI)
// - Database (Replit DB)
// - User info
// Each tab has isolated permissions
Publishing an Extension:
1. Create Extension from template (Extensions > Build)
2. Develop in the provided Repl workspace
3. Test with the Extensions DevTools
4. Release on the Extensions Store (public or private)

Step 4: Agents & Automations (Beta)

Create automated workflows using natural language:

Replit Agents & Automations can:
- Run on a schedule (cron-like)
- Respond to Slack/Telegram messages
- Process incoming webhooks
- Execute database queries automatically

Setup:
1. Open your Repl > Automations tab
2. Create new automation:
   - Trigger: Schedule (e.g., "every day at 9am")
   - Action: Natural language instruction
     "Query the database for users who signed up yesterday,
      format as CSV, and send to Slack #new-users channel"
3. Test and activate

Example automations:
- Daily database backup to Object Storage
- Slack bot that queries your app's API
- Scheduled data cleanup (delete old records)
- Webhook-to-Slack notification bridge

Step 5: Deployment Event Notifications

Set up external monitoring for deployment status changes:

// src/deploy-notifier.ts — Notify team on deployment events
async function notifySlack(message: string) {
  const webhookUrl = process.env.SLACK_WEBHOOK_URL;
  if (!webhookUrl) return;

  await fetch(webhookUrl, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ text: message }),
  });
}

// Call after successful startup
const startTime = Date.now();
app.listen(PORT, '0.0.0.0', async () => {
  const bootTime = ((Date.now() - startTime) / 1000).toFixed(1);
  await notifySlack(
    `Deployment started: ${process.env.REPL_SLUG}\n` +
    `Boot time: ${bootTime}s\n` +
    `URL: https://${process.env.REPL_SLUG}.replit.app`
  );
});

// Graceful shutdown notification
process.on('SIGTERM', async () => {
  await notifySlack(`Deployment stopping: ${process.env.REPL_SLUG}`);
  process.exit(0);
});

Error Handling

| Issue | Cause | Solution | |-------|-------|----------| | Webhook not received | Repl sleeping | Use Deployments for always-on | | Signature verification fails | Wrong secret | Verify secret matches provider config | | Extension not loading | API version mismatch | Update @replit/extensions-react | | Automation not triggering | Schedule syntax error | Verify cron expression in automation settings | | Webhook timeout | Processing too slow | Respond 200 immediately, process async |

Resources

Next Steps

For multi-environment setup, see replit-multi-env-setup.