Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions slack-bridge/broker-bridge.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ import {
createRateLimiter,
sanitizeOutboundText,
} from "./security.mjs";
import {
formatGitHubEvent,
shouldSkipEvent,
parseIgnoredUsers,
extractActor,
} from "./github-events.mjs";
import {
canonicalizeEnvelope,
canonicalizeProtocolRequest,
Expand Down Expand Up @@ -135,6 +141,8 @@ if (ALLOWED_USERS.length === 0) {
logWarn("⚠️ SLACK_ALLOWED_USERS not set — all workspace members can interact");
}

const GITHUB_IGNORED_USERS = parseIgnoredUsers(process.env.GITHUB_IGNORED_USERS);
Comment thread
benvinegar marked this conversation as resolved.

const slackRateLimiter = createRateLimiter({ maxRequests: 5, windowMs: 60_000 });
const apiRateLimiter = createRateLimiter({ maxRequests: 30, windowMs: 60_000 });

Expand Down Expand Up @@ -864,6 +872,46 @@ async function handleSlackPayload(slackEventEnvelopePayload) {
return true;
}

async function handleGitHubEvent(type, payload) {
const actor = extractActor(type, payload);
const repo = payload?.repository?.full_name || "unknown/repo";
logInfo(`🐙 github event: ${type} (action: ${payload?.action || "n/a"}) repo: ${repo} actor: ${actor || "n/a"}`);

// Filtering: skip noisy or self-generated events
const skipReason = shouldSkipEvent(type, payload, GITHUB_IGNORED_USERS);
if (skipReason) {
logInfo(` ↳ skipping: ${skipReason}`);
return true;
}

const { message, isPing, isUnknown } = formatGitHubEvent(type, payload);

if (isPing) {
logInfo(" ↳ ping event — webhook configured successfully");
return true;
}

if (isUnknown) {
logWarn(` ↳ unhandled github event type: ${type} — forwarding minimal summary`);
}

if (!message) {
logWarn(` ↳ formatter returned no message for ${type} — skipping`);
return true;
}

refreshSocket();
const currentSocket = socketPath;
if (!currentSocket) {
logError("🔌 no pi socket found for github event — agent may not be running");
return true;
}

await enqueue(() => sendToAgent(currentSocket, message));
logInfo(` ↳ forwarded to agent`);
return true;
}

async function handleDashboardEvent(type, payload) {
logInfo(`📊 dashboard event: ${type}`, JSON.stringify(payload).slice(0, 200));
// TODO: implement dashboard event handling (env updates, config changes)
Expand Down Expand Up @@ -896,6 +944,8 @@ async function processPulledMessage(message) {
switch (payload.source) {
case "slack":
return handleSlackPayload(payload.payload);
case "github":
return handleGitHubEvent(payload.type, payload.payload);
case "dashboard":
return handleDashboardEvent(payload.type, payload.payload);
case "system":
Expand Down
Loading