forge-remote 0.1.15 → 0.1.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/session-manager.js +6 -1
- package/src/webhook-server.js +30 -0
package/package.json
CHANGED
package/src/session-manager.js
CHANGED
|
@@ -924,9 +924,14 @@ async function runClaudeProcess(sessionId, prompt) {
|
|
|
924
924
|
|
|
925
925
|
// If this session was triggered by a webhook with a reply URL,
|
|
926
926
|
// post Claude's last response back to the source (e.g., Slack).
|
|
927
|
+
if (sess?.webhookMeta) {
|
|
928
|
+
log.info(
|
|
929
|
+
`Webhook meta for ${sessionId}: replyUrl=${sess.webhookMeta.replyUrl || "none"}, lastText=${(sess.lastAssistantText || "").slice(0, 50) || "none"}`,
|
|
930
|
+
);
|
|
931
|
+
}
|
|
927
932
|
if (sess?.webhookMeta?.replyUrl && sess.lastAssistantText) {
|
|
928
933
|
postToSlack(sess.webhookMeta.replyUrl, sess.lastAssistantText).catch(
|
|
929
|
-
() => {},
|
|
934
|
+
(err) => log.error(`Slack reply error: ${err.message}`),
|
|
930
935
|
);
|
|
931
936
|
}
|
|
932
937
|
|
package/src/webhook-server.js
CHANGED
|
@@ -321,6 +321,36 @@ async function handleWebhookPost(req, res, webhookId, sourceIp) {
|
|
|
321
321
|
return sendJson(res, 400, { error: "invalid JSON body" });
|
|
322
322
|
}
|
|
323
323
|
|
|
324
|
+
// 7a. Slack event_callback handling — extract message from event envelope
|
|
325
|
+
// and ignore bot messages to prevent infinite reply loops.
|
|
326
|
+
if (source === "slack" && payload.type === "event_callback") {
|
|
327
|
+
const event = payload.event;
|
|
328
|
+
if (!event) {
|
|
329
|
+
return sendJson(res, 200, { status: "ignored", reason: "no event" });
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
// Ignore bot messages (including our own replies) to prevent loops.
|
|
333
|
+
if (event.bot_id || event.subtype === "bot_message") {
|
|
334
|
+
return sendJson(res, 200, { status: "ignored", reason: "bot message" });
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
// Ignore message edits/deletes — only handle new messages.
|
|
338
|
+
if (event.subtype && event.subtype !== "file_share") {
|
|
339
|
+
return sendJson(res, 200, {
|
|
340
|
+
status: "ignored",
|
|
341
|
+
reason: `subtype: ${event.subtype}`,
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
// Flatten the Slack event into the payload for template rendering.
|
|
346
|
+
// This lets templates use {{text}}, {{user}}, {{channel}} directly.
|
|
347
|
+
payload = { ...payload, ...event };
|
|
348
|
+
|
|
349
|
+
log.info(
|
|
350
|
+
`Slack message from user ${event.user || "unknown"} in channel ${event.channel || "unknown"}: "${(event.text || "").slice(0, 80)}"`,
|
|
351
|
+
);
|
|
352
|
+
}
|
|
353
|
+
|
|
324
354
|
const prompt = renderTemplate(config.promptTemplate || "", payload);
|
|
325
355
|
const projectPath = config.projectPath || process.cwd();
|
|
326
356
|
const model = config.model || "sonnet";
|